Device from address - Linux

This is a discussion on Device from address - Linux ; This is *probably* an easy one... so I'd need to get the interface name given a socket bound to the interface ip address... So the information I have : socked fd AND ip address of the interface The information I ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Device from address

  1. Device from address

    This is *probably* an easy one...
    so I'd need to get the interface name given a socket bound to the
    interface ip address...

    So the information I have : socked fd AND ip address of the interface
    The information I need: a string telling me "ethSOMETHING".

    I'm looking into net tools but can't really find the right line ...
    Any hints?
    Thanks in advance!
    RM

  2. Re: Device from address

    I found something here:
    http://www.linuxquestions.org/questi...h-code-397078/
    The answer I could be interested in is by "thincuchalice" and exploits
    netlink sockets

    InuY4sha ha scritto:

    > This is *probably* an easy one...
    > so I'd need to get the interface name given a socket bound to the
    > interface ip address...
    >
    > So the information I have : socked fd AND ip address of the interface
    > The information I need: a string telling me "ethSOMETHING".
    >
    > I'm looking into net tools but can't really find the right line ...
    > Any hints?
    > Thanks in advance!
    > RM


  3. Re: Device from address

    InuY4sha writes:
    > This is *probably* an easy one...
    > so I'd need to get the interface name given a socket bound to the
    > interface ip address...
    >
    > So the information I have : socked fd AND ip address of the interface
    > The information I need: a string telling me "ethSOMETHING".


    You can use the SIOCGIFCONF-ioctl (netdevice(7)) to get
    an array of all currently bound IPv4 addresses including the names of
    the interfaces they are bound to.

    The same can be done 'somehow' via netlink, but how exactly would need
    to be determined by examining either the kernel implementation or the
    iproute2 source code using this interface.

  4. Re: Device from address


    Rainer Weikusat wrote:

    > You can use the SIOCGIFCONF-ioctl (netdevice(7)) to get
    > an array of all currently bound IPv4 addresses including the names of
    > the interfaces they are bound to.


    Ok I did this way and got what I needed... I'm posting the interesting
    piece of code:

    struct ifconf ifc;
    ifc.ifc_req = malloc(sizeof(struct ifreq)*cntr);
    do{
    free(ifc.ifc_req);
    ifc.ifc_req = malloc(sizeof(struct ifreq)*cntr);
    ifc.ifc_len = sizeof(struct ifreq)*cntr;
    if(ioctl(sockfd, SIOCGIFCONF, &ifc)<0) error(IFACE_NOT_FOUND);
    cntr++;
    } while(ifc.ifc_len==(cntr-1)*sizeof(struct ifreq));

    > The same can be done 'somehow' via netlink, but how exactly would need
    > to be determined by examining either the kernel implementation or the
    > iproute2 source code using this interface.


    Regarding this... I've written few lines copying from the example
    found in the previously reported link.. but from what I see I get a
    MUCH BIGGER routing table then I expected.. could this RT be
    accounting for other stuff such as being the equivalent of the "route -
    C" command which gives me also the cached entries?
    Thanks ...
    Oh, the code for this (maybe vars are not declared here ):

    int nlsockfd;
    struct nlmsghdr *nlMsgHdr;
    struct rtmsg *rtMsg;
    int rtLen, len=0;
    struct rtattr *rtAttr;
    char buff[8192];
    int msgSeq = 0;
    unsigned int dstaddr, srcaddr, gwaddr;
    char result[IFNAMSIZ];
    iface = malloc(IFNAMSIZ);
    nlsockfd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
    if(nlsockfd<0) {error(NLSOCK_FAILURE); return -1;}
    memset(buff,0,sizeof(buff));
    nlMsgHdr = (struct nlmsghdr *)buff;

    /** Packet creation **/
    nlMsgHdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length
    of message.
    nlMsgHdr->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel
    routing table .
    nlMsgHdr->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message
    is a request for dump.
    nlMsgHdr->nlmsg_seq = msgSeq; // Sequence of the message packet.
    nlMsgHdr->nlmsg_pid = getpid(); // PID of process sending the
    request.

    /** Sending the request **/
    dbg_print(CHR, "sock.c: NL SOCKET REQ\n");
    err=send(nlsockfd, nlMsgHdr, nlMsgHdr->nlmsg_len, 0);
    if(err<0) {error(NLSEND_FAILURE); return -1;}

    /** Getting the reply **/
    memset(nlMsgHdr, 0, sizeof(struct nlmsghdr));
    do{
    len = len + recv(nlsockfd, buff+len, sizeof(buff), 0);
    if( ((struct nlmsghdr *)(buff+len))->nlmsg_type == NLMSG_DONE )
    break;
    } while ((nlMsgHdr->nlmsg_seq != msgSeq) || (nlMsgHdr->nlmsg_pid !=
    getpid()));
    dbg_print(CHR, "sock.c: NL SOCKET REPLY\n");

    /** Parsing result to get interface **/
    while(NLMSG_OK(nlMsgHdr,len))
    {
    rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsgHdr);
    rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
    rtLen = RTM_PAYLOAD(nlMsgHdr);
    /** If the route is not for AF_INET or does not
    belong to main routing table then return.**/
    while(RTA_OK(rtAttr,rtLen))
    {
    //Check if it's the INET route and if it's the main RT (if not
    breaks)
    if((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table !=
    RT_TABLE_MAIN)) break;
    switch(rtAttr->rta_type) {
    case RTA_OIF:
    {
    if_indextoname(*(int *)RTA_DATA(rtAttr), iface);
    break;
    }
    case RTA_GATEWAY:
    {
    gwaddr = *(u_int *)RTA_DATA(rtAttr);
    break;
    }
    case RTA_PREFSRC:
    {
    srcaddr = *(u_int *)RTA_DATA(rtAttr);
    break;
    }
    break;
    case RTA_DST:
    {
    dstaddr = *(u_int *)RTA_DATA(rtAttr);
    break;
    }
    default:
    {
    break;
    }
    }

    if(src_ip!=NULL)
    {
    int i = 0;
    i=inet_addr(src_ip);
    //memcpy(taddr,&i,4);
    //printf("SRC=%04X - DST=%04X - GW=%04X - SK_ADDR=%04X - IFACE=%s
    \n",srcaddr,dstaddr,gwaddr,i,iface);
    if(iface!=NULL && memcmp(&srcaddr,&i,4)==0)
    {
    if(memcmp(iface,"lo",2)!=0) //The loopback can have this address
    too
    {
    //printf("Iface = %s\n", iface);
    memset(result,0,IFNAMSIZ);
    memcpy(result,iface,IFNAMSIZ);
    }
    }
    }

    rtAttr = RTA_NEXT(rtAttr,rtLen);
    }
    nlMsgHdr = NLMSG_NEXT(nlMsgHdr,len);
    }
    close(nlsockfd);
    memset(iface,0,IFNAMSIZ);
    memcpy(iface,result,IFNAMSIZ);
    printf("Iface = %s\n", iface);


+ Reply to Thread