How can I prevent SIOCGIFADDR from failing?

I want to get eth0 IP. Here is what I wrote (maybe there is a way around this?):

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); 

I get the following error:

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

If I use the same method with wlan0, I get what I expected to see.

Here is the netstat output:

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 

So, I suppose that I cannot assign an address due to dhclients? Why are there so many of them? and why is there one on port 16313?

UPD:

I added

auto eth0
iface eth0 inet static
        address 192.168.1.1
        netmask 255.255.255.0

in / etc / network / interfaces and restarted the network and got some progress:

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

and then I can successfully bind the socket, but the connection does not die in seconds.

+5
source share
2 answers

. .

#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

IP eth0

getifaddrs.

ifaddrs* pList = NULL;
ifaddrs* pAdapter = NULL;
ifaddrs* pAdapterFound = NULL;
const char* pszAdapterName = "eth0";
int family = AF_INET; // can be AF_INET6 if you want ipv6

int result = getifaddrs(&pList);
if (result > 0)
{
    pAdapter = pList;

    while (pAdapter)
    {
        if ((pAdapter->ifa_addr != NULL) && (pAdapter->ifa_name != NULL) && (family == pAdapter->ifa_addr->sa_family))
        {
            if (strcmp(pAdapter->ifa_name, pszAdapterName) == 0)
            {
                pAdapterFound = pAdapter;
                break;
            }
        }
        pAdapter = pAdapter->ifa_next;
    }

    if (pAdapterFound)
    {
        if (family == AF_INET)
        {
            sockaddr_in addr4 =  *(sockaddr_in*)(pAdapter->ifa_addr);
        }
        else if (family == AF_INET6)
        {
            sockaddr_in6 addr6 =  *(sockaddr_in6*)(pAdapter->ifa_addr);
        }
    }

    if (pList)
    {
        freeifaddrs(pList);
        pList = NULL;
    }
}
0

All Articles