2010-09-16 9 views
9

Używam getifaddrs() i inet_ntop(), aby uzyskać adresy IP w systemie. Gdy system jest ustawiony na IPv6, zwracany adres jest w skróconej wersji (używając :: dla zer). Czy istnieje sposób na rozszerzenie tego adresu na pełny?rozwiń adres IPv6, dzięki czemu mogę go wydrukować na stdout

Jest to kod używam:

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 jest mile widziana.

EDIT:
Ponieważ jest to podobno bardzo trudno pojąć, dam ci przykład:

Jeśli dostanę abcd: 12 :: 3 muszę go rozwinąć do abcd: 0012: 0000: 0000: 0000: 0000: 0000: 0003
Powód? ponieważ jest to część wymagań. Proste.

+1

wersja skrócona jest prawidłowy adres IPv6 - więc dlaczego nie chcesz, aby ją rozwinąć? – Femaref

+0

, ponieważ muszę przechowywać go w całości w naszej bazie danych. to jest wymaganie. – Jessica

+1

@Jessica: Przechowujesz go jako 128-bitową liczbę całkowitą, prawda? Ponieważ przechowywanie go jako reprezentacji tekstowej jest nieco bezcelowe - istnieją adresy IPv6, które można reprezentować na wiele sposobów, właśnie ze względu na skróconą składnię '::'. – Piskvor

Odpowiedz

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

fantastyczne. pierwszy% 02x% 02: powinien być% 02x% 02x: przy okazji – Jessica

+0

@Jessica: naprawiony – 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

Użyj tego kodu. To rozwinie adres IPv6 –

Powiązane problemy