/* -*- mode: c; c-file-style: "openbsd" -*- */ /* * Copyright (c) 2015 Vincent Bernat * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include #include "common.h" int dump = -1; char *filename = NULL; struct pkts_t pkts; char macaddress[ETHER_ADDR_LEN] = { 0x5e, 0x10, 0x8e, 0xe7, 0x84, 0xad }; struct lldpd_hardware hardware; struct lldpd_chassis chassis; int pcap_send(struct lldpd *cfg, struct lldpd_hardware *hardware, char *buffer, size_t size) { struct pcaprec_hdr hdr; struct packet *pkt; int n; /* Write pcap record header */ hdr.ts_sec = time(NULL); hdr.ts_usec = 0; hdr.incl_len = hdr.orig_len = size; n = write(dump, &hdr, sizeof(hdr)); if (n == 1) { fail("unable to write pcap record header to %s", filename); return -1; } /* Write data */ n = write(dump, buffer, size); if (n == -1) { fail("unable to write pcap data to %s", filename); return -1; } /* Append to list of packets */ pkt = (struct packet *)malloc(size + sizeof(TAILQ_HEAD(, packet)) + sizeof(int)); if (!pkt) { fail("unable to allocate packet"); return -1; } memcpy(pkt->data, buffer, size); pkt->size = size; TAILQ_INSERT_TAIL(&pkts, pkt, next); return 0; } struct lldpd_ops pcap_ops = { .send = pcap_send, .recv = NULL, /* Won't be used */ .cleanup = NULL, /* Won't be used */ }; void pcap_setup(void) { static int serial = 0; struct pcap_hdr hdr; int n; /* Prepare packet buffer */ TAILQ_INIT(&pkts); /* Open a new dump file */ n = asprintf(&filename, "%s_%04d.pcap", filenameprefix, serial++); if (n == -1) { fail("unable to compute filename"); return; } dump = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dump == -1) { fail("unable to open %s", filename); return; } /* Write a PCAP header */ hdr.magic_number = 0xa1b2c3d4; hdr.version_major = 2; hdr.version_minor = 4; hdr.thiszone = 0; hdr.sigfigs = 0; hdr.snaplen = 65535; hdr.network = 1; n = write(dump, &hdr, sizeof(hdr)); if (n == -1) { fail("unable to write pcap header to %s", filename); return; } /* Prepare hardware */ memset(&hardware, 0, sizeof(struct lldpd_hardware)); TAILQ_INIT(&hardware.h_rports); #ifdef ENABLE_DOT1 TAILQ_INIT(&hardware.h_lport.p_vlans); TAILQ_INIT(&hardware.h_lport.p_ppvids); TAILQ_INIT(&hardware.h_lport.p_pids); #endif hardware.h_mtu = 1500; hardware.h_ifindex = 4; strlcpy(hardware.h_ifname, "test", sizeof(hardware.h_ifname)); memcpy(hardware.h_lladdr, macaddress, ETHER_ADDR_LEN); hardware.h_ops = &pcap_ops; /* Prepare chassis */ memset(&chassis, 0, sizeof(struct lldpd_chassis)); hardware.h_lport.p_chassis = &chassis; } void pcap_teardown() { struct packet *npkt, *pkt; for (pkt = TAILQ_FIRST(&pkts); pkt != NULL; pkt = npkt) { npkt = TAILQ_NEXT(pkt, next); TAILQ_REMOVE(&pkts, pkt, next); free(pkt); } if (dump != -1) { close(dump); dump = -1; } if (filename) { free(filename); filename = NULL; } } /* Disable leak detection sanitizer */ int __lsan_is_turned_off(void); int __lsan_is_turned_off(void) { return 1; }