2015-07-05 63 views
1

在一個內核模塊,給出sa_family初始化爲AF_UNSPEC一個struct sockaddr,我怎樣才能可靠地確定它是否是一個struct sockaddr_instruct sockaddr_in6?在Linux 3.16.0-4-686-pae(x86)上。確定是否IPv4或IPv6數據結構

struct sockaddr { 
         unsigned short  sa_family; // AF_UNSPEC 
         char    sa_data[14]; // ? 
         }; 
    struct sockaddr_in { 
         unsigned short  sin_family; 
         unsigned short  sin_port; 
         struct in_addr  sin_addr; 
         char    sin_zero[8]; 
         }; 
    struct sockaddr_in6 { 
         unsigned short  sin6_family; 
         unsigned short  sin6_port; 
         unsigned int  sin6_flowinfo; 
         struct in6_addr sin6_addr; 
         unsigned int  sin6_scope_id; 
         }; 
+0

爲什麼sa家族設置爲'AF_UNSPEC' –

+0

@GiuseppePes我不知道,它是這樣給出的。 – Sapiro

+0

什麼是模塊?自定義或在主線? – 0xAX

回答

2

通常情況下,當一些調用到內核,並給出了struct sockaddr,它也有給予struct sockaddr的長度。例如,看到sendto()

ssize_t sendto (int sockfd, const void *buf, size_t buflen, int flags, 
        const struct sockaddr *addr, socklen_t addrlen); 

使用緩衝區的大小,你應該能夠得到一個很好的猜測,你需要使用什麼類型的sockaddr

if (addr.sa_family == AF_UNSPEC) { 
    switch (addrlen) { 
     case sizeof (struct sockaddr_in): { 
      addr.sa_family = AF_INET; 
      break; 
     } 

     case sizeof (struct sockaddr_in6): { 
      addr.sa_family = AF_INET6; 
      break; 
     } 

     default: { 
      // handle error 

      break; 
     } 
    } 
} 

在理想的世界,sa_family將被設置爲AF_INET(IPv4)或AF_INET6(IPv6)中的任何一個,但不幸的是,這似乎不是這種情況。

+0

謝謝。我知道理解_why_不同的結構被使用。 – Sapiro