0

I am trying to add an address to the multicast address list for an interface using the setsockopt function, but it fails with errno EINVAL. I put some printk's in the kernel code and it looks like the errno is ultimately being set in the kernel packet_setsockopt function because the value passed for optlen is less than the size of the packet_mreq structure. For the life of me, I can not figure out why this is happening. Here is the relevant code:

int addMulticastAddress(int ifindex, unsigned char macaddr[6]) {

    struct packet_mreq mreq;
    int fd;
    int ret = -1;


    if ((fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
        return -1;
    }

    memset(&mreq, 0, sizeof(struct packet_mreq));
    mreq.mr_ifindex = ifindex;
    mreq.mr_type = PACKET_MR_MULTICAST;
    memcpy(mreq.mr_address, macaddr, 6);
    mreq.mr_alen = 6;

    if (setsockopt(fd, SOL_PACKET,
                   PACKET_ADD_MEMBERSHIP,
                   &mreq, sizeof(struct packet_mreq) < 0)) {
        virReportSystemError(errno,
                             _("Failed to %s %s %s multicast list for '%s' interface"),
                             add ? "add" : "delete",
                             virMacAddrFormat(macaddr, macstr),
                             add ? "to" : "from", ifname);
        goto cleanup;
    }

    ret = 0;

 cleanup:
     close(fd);
     return ret;
}
Brian
  • 14,610
  • 7
  • 35
  • 43

1 Answers1

2

One of your parenthesis is at the wrong place:

if (setsockopt(fd, SOL_PACKET,
    PACKET_ADD_MEMBERSHIP,
    &mreq, sizeof(struct packet_mreq) < 0)) {

Should be:

if (setsockopt(fd, SOL_PACKET,
    PACKET_ADD_MEMBERSHIP,
    &mreq, sizeof(struct packet_mreq)) < 0) {
Christophe Vu-Brugier
  • 2,645
  • 26
  • 21