2014-01-09 3 views
4

Я хочу получить IP-адрес eth0. Вот что я написал (может быть, есть способ обойти это?):Как предотвратить отказ 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 

в/и т.д./сети/интерфейсы и перезапустил сети и получили некоторый прогресс:

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

После просмотра обновлений вашего вопроса ответ кажется, что «SIOCGIFADDR не удастся, если нет IP-адреса, назначенного интерфейсу». Для вашего нового вопроса - почему соединение проваливается через несколько секунд - вы должны, вероятно, опубликовать это как отдельный вопрос. Включите вывод '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

Смежные вопросы