2010-09-16 6 views
9

J'utilise getifaddrs() et inet_ntop() pour obtenir les adresses IP sur le système. Lorsque le système est défini sur IPv6, l'adresse renvoyée est dans la version abrégée (en utilisant :: for zeros). Est-il possible d'étendre cette adresse à une adresse complète?développez une adresse IPv6 afin que je puisse l'imprimer sur stdout

Ce code J'utilise:

struct ifaddrs *myaddrs, *ifa; 
void *in_addr; 
char buf[64]; 

if(getifaddrs(&myaddrs) != 0) 
{ 
    perror("getifaddrs"); 
    exit(1); 
} 

for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) 
{ 
    if (ifa->ifa_addr == NULL) 
     continue; 
    if (!(ifa->ifa_flags & IFF_UP)) 
     continue; 

    switch (ifa->ifa_addr->sa_family) 
    { 
     case AF_INET: 
     { 
      struct sockaddr_in *s4 = (struct sockaddr_in *)ifa->ifa_addr; 
      in_addr = &s4->sin_addr; 
      break; 
     } 

     case AF_INET6: 
     { 
      struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)ifa->ifa_addr; 
      in_addr = &s6->sin6_addr; 
      break; 
     } 

     default: 
      continue; 
    } 

    if (!inet_ntop(ifa->ifa_addr->sa_family, in_addr, buf, sizeof(buf))) 
    { 
     printf("%s: inet_ntop failed!\n", ifa->ifa_name); 
    } 
    else 
    { 
     printf("IP address: %s\n", buf); 
    } 
} 

freeifaddrs(myaddrs); 
code

est très apprécié.

EDIT:
Comme il est apparemment très difficile à comprendre, je vais vous donner un exemple:

Si je ABCD: 12 :: 3 Je dois l'étendre à ABCD: 0012: 0000: 0000: 0000: 0000: 0000: 0003
La raison? parce que cela fait partie des exigences. Aussi simple que cela.

+1

la version abrégée est une adresse ipv6 valide - alors pourquoi voudriez-vous développer? – Femaref

+0

parce que je dois le stocker dans notre base de données. c'est l'exigence. – Jessica

+1

@Jessica: Vous le stockez comme un entier de 128 bits, correct? Parce que le stocker en tant que représentation textuelle est légèrement inutile - il existe des adresses IPv6 qui peuvent être représentées de plusieurs façons, précisément en raison de la syntaxe raccourcie '::'. – Piskvor

Répondre

11
void ipv6_to_str_unexpanded(char * str, const struct in6_addr * addr) { 
    sprintf(str, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", 
       (int)addr->s6_addr[0], (int)addr->s6_addr[1], 
       (int)addr->s6_addr[2], (int)addr->s6_addr[3], 
       (int)addr->s6_addr[4], (int)addr->s6_addr[5], 
       (int)addr->s6_addr[6], (int)addr->s6_addr[7], 
       (int)addr->s6_addr[8], (int)addr->s6_addr[9], 
       (int)addr->s6_addr[10], (int)addr->s6_addr[11], 
       (int)addr->s6_addr[12], (int)addr->s6_addr[13], 
       (int)addr->s6_addr[14], (int)addr->s6_addr[15]); 
} 
+2

fantastique. le premier% 02x% 02: devrait être% 02x% 02x: au fait – Jessica

+0

@Jessica: corrigé – nategoose

0
  #include<stdio.h> 
      #include <netinet/in.h> 
      #include <arpa/inet.h> 

      struct in6_addrr 
      { 
       unsigned char addr[16]; 
      }; 

      void ipv6_expander(const struct in6_addr * addr) 
      { 
       char str[40]; 
       sprintf(str,"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", 
       (int)addr->s6_addr[0], (int)addr->s6_addr[1], 
       (int)addr->s6_addr[2], (int)addr->s6_addr[3], 
       (int)addr->s6_addr[4], (int)addr->s6_addr[5], 
       (int)addr->s6_addr[6], (int)addr->s6_addr[7], 
       (int)addr->s6_addr[8], (int)addr->s6_addr[9], 
       (int)addr->s6_addr[10], (int)addr->s6_addr[11], 
       (int)addr->s6_addr[12], (int)addr->s6_addr[13], 
       (int)addr->s6_addr[14], (int)addr->s6_addr[15]); 
       printf("\nExpanded ipv6 Addr %s\n",str); 
      } 

      int main(int argc,char *argv[]) 
      { 
       struct in6_addrr ipv6; 
       printf("\nGiven IPv6 Addr %s\n",argv[1]); 
       if(inet_pton(AF_INET6,argv[1],&ipv6.addr)) 
       { 
        ipv6_expander(&ipv6.addr); 
       } 
       else 
       { 
        printf("\n error\n"); 
       } 
       return; 
      } 
+0

Utilisez ce code. Ceci étendra l'adresse ipv6 –