2013-05-02 3 views
2

특정 네트워크 인터페이스 (VLAN : eth0.32)에 할당 된 IP 주소를 읽을 수있는 프로그램을 작성 중입니다. IPv4 또는 IPv6 주소를 할당 받았는지 여부는 알 수 없으므로 프로토콜 패밀리에 대해 알지 못합니다.IPv4 및 IPv6 소켓 호환 만들기

작동 방식 : for를 사용하면 사용 가능한 네트워크 인터페이스 목록을 탐색하고 IP 주소를 읽는 내 VLAN (eth0.32)이있는 지점에서 중지합니다. 어쨌든,이 개발 시점에서 나는 IPv4 용으로 작동하지만 IPv6 지원을 구현하고자 할 때 준비 상태로두기를 원합니다.

이 프로그램은 작동하고 내가 일반적으로 소켓을 만들 경우 IPv4 주소를 읽

sd=socket(PF_INET, SOCK_DGRAM, 0); 

을하지만 IPv6를이 소켓 제품군 (PF_INET = IPv4)를 내가 할에 주소를 읽을 수 없습니다로 이 같은 :

sd=socket(PF_INET6, SOCK_DGRAM, 0); 
setsockopt(sd, SOL_SOCKET, IPV6_V6ONLY, 0, sizeof(int)); 

문제는이 IPv6를 소켓, 그것은 조건이 IP 주소를 읽을 경우를 달성하는 데 실패한다는 것입니다 :

if (ioctl(sd, SIOCGIFCONF, &ifc) == 0) 
을 당신의 도움에 미리

#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/ioctl.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <net/if.h> 

int main(int argc, char **argv) 
{ 

    struct ifconf ifc; 
    struct ifreq ifr[MAX_NETWORK_INTERFACES]; 
    int ifc_num, addr, i; 
    static uint8 sd=0; 

    sd=socket(PF_INET6, SOCK_DGRAM, 0); 
    setsockopt(sd, SOL_SOCKET, IPV6_V6ONLY, 0, sizeof(int)); //I change the socket option IPV6_V6ONLY to false, so it should be compatible with IPv4 

    if (sd > 0) 
    { 
     ifc.ifc_len = sizeof(ifr); 
     ifc.ifc_ifcu.ifcu_buf = (caddr_t)ifr; //Buffer address 

     if (ioctl(sd, SIOCGIFCONF, &ifc) == 0) 
     { 
      ifc_num = ifc.ifc_len/sizeof(struct ifreq); //Number of network interfaces found 

      for (i = 0; i < ifc_num; i++) 
      { 

       if(ifr[i].ifr_addr.sa_family != AF_INET) //If it is not an IPv4 address, we do nothing 
       { 
        continue; 
       } 

       if (strcmp(ifr[i].ifr_ifrn.ifrn_name,"eth0.32")==0) 
       { 
        if (ioctl(sd, SIOCGIFADDR, &ifr[i]) == 0) // HERE IS WHERE THE IPv6 SOCKET DOESN'T ENTER!!! 
        { 
         addr = ntohl(((struct sockaddr_in *)(&ifr[i].ifr_addr))->sin_addr.s_addr); 

        } 

        fclose(fp); 

        break; // end loop 
       } 
      } 
     } 
    } 
    return addr; 

} 

감사 : 자세한 내용은

이 내 전체 코드입니다!

+0

GetSocketForAddressForAdapter가 도움이 될 수 있습니다 - https://github.com/jselbie/stunserver/blob/master/networkutils/adapters.cpp#L111 – selbie

답변

0

getifaddrs이 아닌 ioctl SIOCGIFADDR을 사용해야합니다.

+0

이 경우'(ioctl (sd, SIOCGIFCONF, & ifc) == 0))'도 작동하지 않습니까? – Nacao

+0

@Nacao, 이러한 IOCTls는 어떤 표준도 적용되지 않으며 휴대 가능하지 않습니다. OS 설명서를 참조하십시오. 또는 SO에 관한 질문을하는 경우 사용중인 OS를 알려주십시오. 리눅스에서는'rnetlink (7)'을 사용하십시오. Windows에서 "IP 도우미"API를 원할 수도 있습니다. http://msdn.microsoft.com/en-us/library/windows/desktop/aa366071(v=vs.85).aspx – Ben

+0

빠른 답변 감사합니다. 나는 리눅스를 사용하고있다. 이 코드 구현을 IPv4 주소에 대해서만 테스트했으며 잘 작동합니다. IPv6 지원을 추가하려고 할 때 위에서 설명한 문제가 발생합니다. IPv4 용으로 다시 작동하지 않습니다. – Nacao

관련 문제