Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to bind to a specific ethernet interface?
Forum Updated to NodeBB v4.3 + New Features

How to bind to a specific ethernet interface?

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 6.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • LeoCL Offline
    LeoCL Offline
    LeoC
    wrote on last edited by
    #1

    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!

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

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

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

      1 Reply Last reply
      1
      • LeoCL Offline
        LeoCL Offline
        LeoC
        wrote on last edited by
        #3

        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.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved