How can I get the interface name/index associated with a TCP socket?

前端 未结 9 484
伪装坚强ぢ
伪装坚强ぢ 2021-01-12 04:17

I\'m writing a TCP server that needs to know which interface each connection arrived from. I cannot use the address/subnet to deduce which interface was used, since there mi

相关标签:
9条回答
  • 2021-01-12 05:19

    Obviously not something I've looked into very deeply, let alone tried, this might be one for the "so crazy it just might work" basket...

    If it's really only ever going to be for Linux, you could write a custom netfilter module which tracks the incoming connections and notes which interface they come in on, and writes that information somewhere for your server application to read.

    0 讨论(0)
  • 2021-01-12 05:22

    Look at the destination address.

    Each interface is normally bound to a unique address. If multiple interfaces are bonded together, it probably doesn't matter which one it used.

    The only exception to this, is when using ipv6 anycast, but even then, you wouldn't normally have multiple interfaces on the same host with the same ip.

    0 讨论(0)
  • 2021-01-12 05:23

    Use getsockname() to get IP of local end of the TCP connection. Then use getifaddrs() to find the corresponding interface:

    struct sockaddr_in addr;
    struct ifaddrs* ifaddr;
    struct ifaddrs* ifa;
    socklen_t addr_len;
    
    addr_len = sizeof (addr);
    getsockname(sock_fd, (struct sockaddr*)&addr, &addr_len);
    getifaddrs(&ifaddr);
    
    // look which interface contains the wanted IP.
    // When found, ifa->ifa_name contains the name of the interface (eth0, eth1, ppp0...)
    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
    {
        if (ifa->ifa_addr)
        {
            if (AF_INET == ifa->ifa_addr->sa_family)
            {
                struct sockaddr_in* inaddr = (struct sockaddr_in*)ifa->ifa_addr;
    
                if (inaddr->sin_addr.s_addr == addr.sin_addr.s_addr)
                {
                    if (ifa->ifa_name)
                    {
                        // Found it
                    }
                }
            }
        }
    }
    freeifaddrs(ifaddr);
    

    Above is just a dirty example, some modifications are needed:

    1. Add missing error checks
    2. IPv6 support
    0 讨论(0)
提交回复
热议问题