/*- * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 69): * wrote this file. As long as you retain this notice you * can do whatever you want with this stuff. If we meet some day, and you think * this stuff is worth it, you can buy me a beer in return. -Shteryana Shopova * ---------------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NETMAP_DEV "/dev/netmap" struct nmgen { void *pkts; size_t plen; struct pollfd fds; struct nmreq nmr; } ng; static void cleanup(void); const char lldp_ttl_big[] = "\ \x04\x7d\x7b\xa8\xf0\xb9\x00\xa0\x12\x22\x22\x22\x88\xcc\x02\x07\ \x04\x00\xa0\x12\x1b\x00\xa6\x04\x07\x03\x00\xa0\x12\x1b\x00\xa8\ \x06\x02\xff\xff\x10\x0c\x05\x01\x0a\x03\xd9\xd9\x02\x00\x00\x00\ \x02\x00\x10\x0c\x05\x01\x0b\x00\x00\x01\x02\x00\x00\x00\x03\x00\ \x10\x0c\x05\x01\x7f\x00\x00\x01\x02\x00\x00\x00\x01\x00\x10\x0e\ \x07\x06\x00\xa0\x12\x1b\x00\xa6\x02\x00\x00\x00\x00\x00\x08\x14\ \x50\x68\x79\x73\x69\x63\x61\x6c\x20\x49\x6e\x74\x65\x72\x66\x61\ \x63\x65\x20\x32\x0c\x44\x4e\x4f\x4b\x49\x41\x20\x45\x53\x42\x32\ \x36\x20\x73\x6f\x66\x74\x77\x61\x72\x65\x20\x76\x65\x72\x73\x69\ \x6f\x6e\x20\x34\x2e\x34\x2e\x30\x20\x62\x75\x69\x6c\x64\x20\x30\ \x33\x20\x20\x20\x4e\x6f\x76\x20\x32\x39\x20\x32\x30\x30\x36\x20\ \x2d\x20\x31\x37\x3a\x30\x39\x3a\x30\x34\x0e\x04\x00\x12\x00\x12\ \x00\x00"; int main(int argc, char **argv, char **envp) { int i; char *buf; struct netmap_if *nifp; struct netmap_ring *ring; bzero(&ng, sizeof(struct nmgen)); ng.fds.fd = -1; if (argc != 2){ printf ("Usage: %s \n", argv[0]); exit(0); } if (atexit(cleanup) != 0) err(1, "Failed to register cleanup routine"); if ((ng.fds.fd = open(NETMAP_DEV, O_RDWR)) == -1) err(1, "open(NETMAP_DEV) failed"); bzero(&(ng.nmr), sizeof(ng.nmr)); strlcpy(ng.nmr.nr_name, argv[1], sizeof(ng.nmr.nr_name)); ng.nmr.nr_version = NETMAP_API; if ((ioctl(ng.fds.fd , NIOCGINFO, &(ng.nmr))) == -1) err(1, "Failed to bind to interface %s", argv[1]); ng.plen = ng.nmr.nr_memsize; if ((ng.pkts = mmap(NULL, ng.nmr.nr_memsize, PROT_READ | PROT_WRITE, MAP_SHARED, ng.fds.fd, 0)) == MAP_FAILED) err(1, "Failed to alloc memory"); if ((ioctl(ng.fds.fd , NIOCREGIF, &(ng.nmr))) == -1) err(1, "Failed to bind to interface %s", argv[1]); nifp = NETMAP_IF(ng.pkts, ng.nmr.nr_offset); ring = NETMAP_TXRING(nifp, 0); ng.fds.events = POLLOUT | POLLWRNORM | POLLWRBAND; printf("Available buffers in ring %d\n", ring->avail); ng.plen = ring->avail; for (;;) { for ( ; ring->avail > 0 ; ring->avail--) { i = ring->cur; buf = NETMAP_BUF(ring, ring->slot[i].buf_idx); memcpy(buf, lldp_ttl_big, sizeof(lldp_ttl_big)); ring->slot[i].len = sizeof(lldp_ttl_big); buf[ETHER_ADDR_LEN - 1] = i; buf[2 * ETHER_ADDR_LEN - 1] = i; ring->cur = NETMAP_RING_NEXT(ring, i); } ring->flags = NR_TIMESTAMP | NR_FORWARD; if (poll(&(ng.fds), 1, 2000 /*INFTIM*/) == -1) err(1, "Poll error"); if (ioctl(ng.fds.fd, NIOCTXSYNC, NULL) == -1) errx(1, "ioctl(NIOCTXSYNC) failed"); } exit(0); } static void cleanup(void) { if (ng.pkts != NULL) munmap(ng.pkts, ng.plen); if (ng.fds.fd != -1) close(ng.fds.fd); }