0

I am struggling to get AIO working on Linux (version 3.19) for receiving packets on a RAW socket, but to no avail. I've successfully used AIO for UDP and TCP sockets, but can't make it work for a RAW socket. I've tried both IPv4 and IPv6.

Does anyone know if AIO supports RAW sockets?

Here's some code snippets from my application:

void readCallback(sigval_t sigval) {
    debug(LOG_DEBUG, "RAW packet received\n");
}

int main(int argc, char *argv[]) {
    int sock = socket(domain, SOCK_RAW, IPPROTO_RAW);
    if (-1 == sock) {
    debug(LOG_CRIT, "FAILED to create raw socket\n");
    return 1;
    }

    char *iface = "eth0";
    ifreq ifr;
    memset (&ifr, 0, sizeof(ifr));
    snprintf (ifr.ifr_name, sizeof(ifr.ifr_name), "%s", iface);
    if (ioctl (sock, SIOCGIFINDEX, &ifr) < 0) {
    debug(LOG_CRIT, "FAILED to query interface '%s' index\n", iface);
    return 1;
    }

    // Set flag so socket expects us to provide IP header.
    const int on = 1;
    if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
    debug(LOG_CRIT, "FAILED to configure raw socket on '%s'\n", iface);
    return 1;
    }

    // Bind socket to interface index.
    if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) {
    debug(LOG_CRIT, "FAILED to bind socket to %s/%u\n", iface, ifr.ifr_ifindex);
    return 1;
    }

    // listen for packets
    struct aiocb aio;
    char buf[MAX_PACKET];
    bzero((char*)&aio, sizeof(struct aiocb));
    aio.aio_fildes = sock;
    aio.aio_buf = &buf;
    aio.aio_nbytes = MAX_PACKET;
    aio.aio_offset = 0;
    aio.aio_sigevent.sigev_notify = SIGEV_THREAD;
    aio.aio_sigevent.sigev_notify_function = readCallback;
    aio.aio_sigevent.sigev_notify_attributes = NULL;
    aio.aio_sigevent.sigev_value.sival_ptr = buf;
    if (!RequestAioRead(&aio)) {
    debug(LOG_DEBUG, "FAILED to listen on raw socket...\n");
    return 1;
    }
    debug(LOG_DEBUG, "Listening on raw socket...\n");

    // main loop
    while (true) {
    usleep(100000);
    }
    close(sock);
    return 0;
}
HannesM
  • 55
  • 1
  • 11
  • yes, it does; sorry, don't have time to look at your code atm. – Oleksandr Kravchuk Jun 21 '16 at 15:53
  • Ok, great, thanks for your response. At least I know it *should* work then. I'll keep digging. – HannesM Jun 22 '16 at 05:46
  • Your response gave me the confidence to keep troubleshooting; turns out the socket protocol was wrong. The correct protocol seems to be htons(0x0800): socket(AF_PACKET, SOCK_RAW, htons(0x0800)); With this, aio seems to work fine. Thanks for your quick response! – HannesM Jun 22 '16 at 08:19
  • you're welcome; you can reply to your question and mark your answer as correct - it may be useful for others, who will google this issue and end up reading this topic. – Oleksandr Kravchuk Jun 22 '16 at 08:45

1 Answers1

1

Turns out my socket() protocol was wrong. The correct protocol seems to be htons(0x0800):

socket(AF_PACKET, SOCK_RAW, htons(0x0800));

With this, aio seems to work fine.

HannesM
  • 55
  • 1
  • 11