7
votes

Obtenez un IP_ADDRESS_STRING DE GETADAPTERSADESSESES ()?

gettadaptersAdresses () sera Obtenez vos adresses dans ip_adapter_unicast_address format, défini comme suit:

typedef struct _SOCKET_ADDRESS {
  LPSOCKADDR lpSockaddr;
  INT        iSockaddrLength;
} SOCKET_ADDRESS, *PSOCKET_ADDRESS;


0 commentaires

3 Réponses :


7
votes

Vous pouvez utiliser geipaddrable - Le Structure de données renvoyée contient un DWORD < Code> Dwaddr C'est l'adresse IPv4. Le code exemple sur ce premier lien devrait vous montrer ce que vous voulez. Brève extrait pour vous montrer ce que je veux dire: xxx

ip_adapter_unicast_address contient un socket_address dans adresse , lequel À Tour contient un lsockaddr dans lsockaddr - Vous pouvez convertir ceci au formulaire de chaîne IPv4 à l'aide de wsaaddresstostring .


10 commentaires

@Steve, merci mais ce n'est pas vraiment ce que je cherchais. GettadaptersAddresses () offre tellement plus d'informations - pour IPv4 et IPv6 - et j'aimerais m'en tenir à la recommandation de Microsoft. Tout ce que vous êtes manquant est une fonction de commodité "traducteur" qui prendrait IP_ADAPTER_UNICAST_ADDRESS comme paramètre et sortie une chaîne. Au lieu de réinventer la roue et de l'écrire moi-même, vous connaissez peut-être une telle fonction existante? Dans l'API elle-même ou ailleurs, peut-être un échantillon?


@Android Eve - Voir Modifier, vous pouvez utiliser wsaaddresstostring pour cela.


Encore une fois, vous démontrez une connaissance impressionnante de l'espace d'aide IP de PSDK. Grâce à votre réponse, j'ai pu repérer quelques fonctions supplémentaires, notamment RTLIPV4AdDressTostring () et RTLIPV6AdDressTostring () qui, malheureusement, existent dans le WDK, et non le PSDK. Je vais bientôt marquer votre réponse comme acceptée. Sauf si une réponse nouvelle suggère une fonction qui fait la même chose pour IPv6 et IPv4.


@Android Eve - Voir les docs - "Alors que la fonction inet_ntoa uniquement avec les adresses IPv4, la fonction wsaaddresstostring fonctionne fonctionne avec n'importe quelle adresse prise prise en charge par un fournisseur Winsock sur l'ordinateur local y compris les adresses IPv6. "


@Android Eve - Vous êtes la bienvenue - 13 ans chez Microsoft auraient dû m'avoir appris quelque chose, je suppose


Ajout d'un commentaire de plus, pour mémoriser dans un endroit une information utile associée, je viens de remarquer: la structure in6_addr utilisée inrtlipv6addresstostring () et qui est définie dans le fichier d'en-tête IN6ADDR.H, est membre du Sockaddr indirectement renvoyé par GettadaptersAdresses () . Donc, si Wsaaddresstostring () n'était pas disponible, il y aurait toujours un moyen de convertir les adresses de retour par GetAdaptersAdresses () aux chaînes, sans avoir à tout écrire à partir de zéro.


@SteveTownSend Je vois un comportement étrange sur le système d'un client avec GetiPadDrable - Certains adaptateurs ne s'affichent pas. Existe-t-il une simple liste de raisons pour les différences?


Référence croisée de la question que j'ai posée ci-dessus @stevetownSend ci-dessus: Stackoverflow.com/Questtions/13573007/...


@Will - Avez-vous essayé gettadapterAdresses ? On dirait que l'API que j'ai recommandé est IPv4 uniquement et de plus en plus obsolète. Si vous ne pouvez pas résoudre rapidement, je recevrais un code de reproduction ensemble et posteriez une autre question.


@SteveTownSend Voir la question que j'ai posté - oui c'est l'autre fonction que je travaille.



5
votes

Regardez la documentation pour Sockaddr . Cela nous amène à la documentation de Sockaddr_storage , qui est une structure d'assistance pour IPv4 et IPv6.

citation de la documentation Sockaddr: p>

Les fonctions Winsock à l'aide de Sockaddr ne sont pas strictement interprétées em> pour être pointeurs à une structure de chaussettes. La structure est interprétée différemment dans le contexte de différentes familles d'adresses. P> BlockQuote>

Pour IPv4, vous pouvez lancer un pointeur Sockaddr sur un pointeur Sockaddr_in, puis accéder aux informations d'adresse IPv4 de là. Ensuite, vous pouvez utiliser votre constructeur de chaîne préféré pour produire une chaîne formatée quadruple en pointillé. P>

struct sockaddr {
        ushort  sa_family;
        char    sa_data[14];
};

struct sockaddr_in {
        short   sin_family;
        u_short sin_port;
        struct  in_addr sin_addr;
        char    sin_zero[8];
};

struct sockaddr_in6 {
        short   sin6_family;
        u_short sin6_port;
        u_long  sin6_flowinfo;
        struct  in6_addr sin6_addr;
        u_long  sin6_scope_id;
};


0 commentaires

0
votes

Vous pouvez simplement passer _socket_address.lpsockaddr code> et _sockt_address.isockaddrlength code> comme lpsaaddress code> et dwaddresslength code> Arguments sur wsaaddresstostring code> fonction. wsaaddresstostring code> fera la conversion nécessaire pour vous, pas besoin de creuser plus profondément.

function SOCKET_ADDRESS_ToString(const Addr: SOCKET_ADDRESS): String;
var
  Len: DWORD;
begin
  if (Addr.lpSockaddr = nil) or (Addr.iSockaddrLength <= 0) then
  begin
    Result := '';
    Exit;
  end;
  Len := 0;
  WSAAddressToString(Addr.lpSockaddr, Addr.iSockaddrLength, nil, nil, Len);
  SetLength(Result, Len);
  if WSAAddressToString(Addr.lpSockaddr, Addr.iSockaddrLength, nil, PChar(Result), Len) = 0 then
    SetLength(Result, Len - 1)
  else
    Result := '';
end;


0 commentaires