2014-01-09 248 views
4

我想獲取eth0的IP。這是我寫的東西(也許有辦法解決它?):如何防止SIOCGIFADDR失效?

int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
check(sockfd > 0, "cannot create socket\n"); 

#define INTERFACE_NAME "eth0" 
#define INTERFACE_NAME_LENGTH 4 

char *opt = INTERFACE_NAME; 
rc = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, opt, INTERFACE_NAME_LENGTH); 
check(rc == 0, "BINDTODEVICE failed"); 

struct ifreq req; 
strncpy(req.ifr_name, INTERFACE_NAME, IFNAMSIZ); 
rc = ioctl(sockfd, SIOCGIFADDR, (unsigned long)&req); 
check(rc == 0, "SIOCGIFADDR failed"); 
server_ip = ((struct sockaddr_in*)&req.ifr_addr)->sin_addr.s_addr; 
char str[50]; 
inet_ntop(AF_INET, &(server_ip), str, INET_ADDRSTRLEN); 
debug("serverip: %s", str); 

return sockfd; 

error: 
if (sockfd) close(sockfd); 
exit(1); 

我得到以下錯誤:

[ERROR] (src/server/server.c:43: errno: Cannot assign requested address) SIOCGIFADDR failed

如果我用爲wlan0同樣的方法,我得到了什麼我期望看到。

這裏是netstat的輸出:

netstat的-tulpn:

Proto | Local Address | PID 

udp | 0.0.0.0:16313 | 4666/dhclient 
udp | 0.0.0.0:68  | 4687/dhclient 
udp | 0.0.0.0:68  | 4666/dhclient 

所以,我想,我不能指定,因爲dhclients的地址?爲什麼有這麼多人?爲什麼在16313端口上有一個?

UPD:

我加

auto eth0 
iface eth0 inet static 
     address 192.168.1.1 
     netmask 255.255.255.0 

到/ etc /網絡/接口,並重新啓動聯網並得到了一些進展:

DEBUG src/server/server.c:50: serverip: 192.168.1.1 

,然後我可以成功綁定插座,但連接在幾秒鐘內無故死亡。

+2

我想你需要'req.ifr_addr.sa_family = AF_INET'來告訴SIOCGIFADDR調用你想要的是什麼類型的地址。 –

+1

@MarkPlotnick不幸的是,它沒有幫助!我使用了這段代碼:man7.org/linux/man-pages/man3/getifaddrs.3.html,據說eth0是AF_PACKET。不知道爲什麼! – staroselskii

+0

看到您的問題的更新後,答案似乎是「沒有分配給接口的IP地址時,SIOCGIFADDR將失敗」。對於您的新問題 - 爲什麼幾秒鐘後連接失敗 - 您應該將其作爲單獨的問題發佈。包含'ifconfig'的輸出和執行'connect'並傳輸數據的代碼。我的猜測是:一個以'.1'結尾的地址通常被路由器使用。您選擇的地址192.168.1.1可能已經被網絡中其他地方的路由器使用。 –

回答

0

幾年前,我曾經使用過這段代碼。這應該有所幫助。

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

int main() 
{ 
    int sock; 
    struct ifreq ifr; 

    char ifname[10] = "eth0"; 

    sock = socket(AF_INET, SOCK_STREAM, 0); 

    //Type of address to retrieve - IPv4 IP address 
    ifr.ifr_addr.sa_family = AF_INET; 

    //Copy the interface name in the ifreq structure 
    strncpy(ifr.ifr_name , ifname , 30); 

    ioctl(sock, SIOCGIFADDR, &ifr); 

    close(fd); 

    //display result 
    printf("%s - %s\n" , iface , inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); 

    return 0; 
} 
+0

與我上面張貼的不一樣嗎? – staroselskii

+0

作爲其他人指出上面你已經錯過了這條線req.ifr_addr.sa_family = AF_INET –

+1

正如我上面寫的那樣,這條線沒有幫助:-( – staroselskii