How to bind to a specific ethernet interface?



  • Hey,

    I would like to know how I can bind a socket to a specific ethernet interface and not only to an ip address.

    The device where I am running my application has two interfaces configured (eth0 and eth0.2) and I want to send multicasts through my network using eth0.2. The interfaces use the following addresses:

    eth0
    IPv6: fd::1f

    eth0.2
    IPv6: fd61:xxxx:xxxx:x::1f

    In my application, I have bind the socket as follows:

    udpSocket->bind(QHostAddress("fd61:xxxx:xxxx:x::1f"), xxxx);
    qDebug() << udpSocket->state();
    
    if(udpSocket->joinMulticastGroup(QHostAddress("ff16::02"))
    qDebug() << "joined multicast group";
    

    The application itself starts automatically on boot and starts sending the mutlicasts. The interesting part is, that the source address of multicasts is "fd::1f" which is related to eth0, but the address that I use to bind the socket to is related to eth0.2. In any case, the result of state() is always "Bounded".
    First I thought it could be a timing issue, which means that my applications starts earlier than all network settings are ready to use. But implementing a delay of several seconds didn't solve this problem. For test purposes I removed the address of eth0, so the only available address is found on eth0.2. Now, it all works finde but I don't have an ip address on eth0 anymore.
    My guess is, that the problem is somewhere in the multicast source address selection of the ip-stack.
    Anyway, since I don't know exactly where the problem comes from, I would like to bind the socket to the interface eth0.2.

    For plain c, I could use the BINDTODEVICE option, which looks like this:

    setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 4);
    

    Is there also a possibility to use something like this within Qt?

    Thanks!


  • Qt Champions 2016

    Hi
    I think yes.
    setsockopt(m_udpSocket->socketDescriptor(), SOL_SOCKET, SO_BINDTODEVICE, dev, sizeof(dev) ))

    http://doc.qt.io/qt-5/qtcpserver.html#socketDescriptor



  • Hey,
    sorry for my very late response. I had to do some other stuff in between :)

    While trying to implement the setsockopt - function, I thought I have found a very simple solution for my problem. And I do not have to use some plain C++, because it is an build-in functionality of Qt :)

    This one should do the trick:

    bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)
    

    You can define the interface that has to be used for sending the mutlicast massages. But still, I can't see the messages in the specific VLAN the udpsocket is bind to. That's weird.

    So I have no choice but to use plain C/C++. I implemented the following:

    #include "udpsock.h"
    
    udpSock::udpSock(QObject *parent) :
        QObject(parent)
    {
        qDebug() << "starting...";
    
        int sock_fd = 0;
        struct ifreq interfaces;
        sockaddr_in6 addr;
        addr.sin6_family = AF_INET6;
        addr.sin6_addr = in6addr_any;
        addr.sin6_port = htons(1337);
    
        if((sock_fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
            qDebug() << "cannot create socket";
            exit(1);
        }
    
        qDebug() << "created socket: descriptor " << sock_fd;
    
        strncpy(interfaces.ifr_name, "eth0.2", IFNAMSIZ);
    
        if(setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interfaces, sizeof(interfaces)) < 0) {
            qDebug() << "failed to bind to device";
            exit(1);
        }
    
        if((bind(sock_fd,(sockaddr*) &addr, sizeof(addr))) < 0) {
            qDebug() << "failed to bind to ip and port";
            exit(1);
        }
    
        uSock =  new QUdpSocket(this);
        if(uSock->setSocketDescriptor(sock_fd))
            qDebug() << "socket descriptor accepted";
    
        qDebug() << "state of sock: " << uSock->state();
    
        //join multicast group
        if(uSock->joinMulticastGroup(QHostAddress("ff16::01")))
            qDebug() << "com_NM: socket (send) joind multicast group";
        else
            qDebug() << "com_NM: socket (send) could not join multicast group";
    
        qDebug() << "end of code";
    }
    

    It is all working fine, except the part where the guy should join the multicast group. It just claims

    QNativeSocketEngine::joinMulticastGroup() was not called in QAbstractSocket::BoundState
    

    The qDebug (one live above the statement where to join the multicastgroup) gives me QAbstracktSocket::ConnectedState.

    What am I missing?

    Thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.