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