After cleaning the rust and dust off, I'm happy to see my tech skills remain intact.
It still feels good :)
Nowadays, I'm working on a novel network threat detection engine for my new startup. I'll be sharing some stuff that I think would be of value to people out there.
Here's the first one:
We've decided to utilize FreeBSD's netmap fast packet I/O API for managing packet input/output at high speeds. Since the documentation is quite limited, it's hard to find a minimal working sample code demonstrating netmap functionality.
Below is a simple packet receiver code which just counts the number of packet received off the wire:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <poll.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <net/netmap_user.h>
int
main(int argc, char **argv)
{
struct netmap_if *nifp;
struct netmap_ring *ring;
struct nmreq nmr;
struct pollfd fds;
int fd = 0;
void *p = NULL;
int i = 0;
void *buf = NULL;
int tot = 0;
int nret = 0;
if (argc < 2) {
printf("%s int\n", argv[0]);
return(1);
}
if ((fd = open("/dev/netmap", O_RDWR)) < 0) {
perror("open");
return(1);
}
bzero(&nmr, sizeof(nmr));
strcpy(nmr.nr_name, argv[1]);
nmr.nr_version = NETMAP_API;
/* Register interface for Netmap mode, bypass OS stack */
if (ioctl(fd, NIOCREGIF, &nmr) != 0) {
perror("ioctl");
return(1);
}
/* MAP kernerl ring buffers to userspace */
/* MAP kernerl ring buffers to userspace */
if ((p = mmap(0, nmr.nr_memsize, PROT_READ | PROT_WRITE, MAP_SHARED , fd, 0)) == NULL) {
perror("mmap");
return(1);
}
nifp = NETMAP_IF(p, nmr.nr_offset);
ring = NETMAP_RXRING(nifp, 0);
fds.fd = fd;
fds.events = POLLIN;
for (;;) {
poll(&fds, 1, 1000);
while (!nm_ring_empty(ring)) {
i = ring->cur;
buf = NETMAP_BUF(ring, ring->slot[i].buf_idx);
/* Insert your cool stuff here */
ring->head = ring->cur = nm_ring_next(ring, i);
nret++;
}
if (ioctl(fd, NIOCRXSYNC, NULL) != 0)
perror("sync ioctl");
tot += nret;
printf("recv'd %d packets, total: %d\n", nret, tot);
nret = 0;
}
return 0;
}