#include "utils/mctp-capture.h" #include #include #include #if HAVE_PCAP #include #include #include "libmctp-alloc.h" #ifndef ETH_P_MCTP #define ETH_P_MCTP 0xfa #endif #endif int capture_init(void) { char errbuf[PCAP_ERRBUF_SIZE]; int rc; if ((rc = pcap_init(PCAP_CHAR_ENC_UTF_8, errbuf)) == -1) { fprintf(stderr, "pcap_init: %s\n", errbuf); return -1; } return 0; } int capture_prepare(struct capture *cap) { if (!(cap->pcap = pcap_open_dead(CAPTURE_LINKTYPE_LINUX_SLL2, UINT16_MAX))) { fprintf(stderr, "pcap_open_dead: failed\n"); return -1; } if (!(cap->dumper = pcap_dump_open(cap->pcap, cap->path))) { fprintf(stderr, "pcap_dump_open: failed\n"); return -1; } return 0; } void capture_close(struct capture *cap) { pcap_dump_close(cap->dumper); pcap_close(cap->pcap); } void capture_binding(struct mctp_pktbuf *pkt, bool outgoing, void *user) { pcap_dumper_t *dumper = user; struct pcap_pkthdr hdr; int rc; uint8_t *pktbuf = NULL; size_t size; if ((rc = gettimeofday(&hdr.ts, NULL)) == -1) return; /* Write sll2 header */ size = sizeof(struct sll2_header) + mctp_pktbuf_size(pkt); pktbuf = __mctp_alloc(size); if (!pktbuf) return; struct sll2_header *sll2 = (struct sll2_header *)pktbuf; sll2->sll2_protocol = htons(ETH_P_MCTP); if (outgoing) sll2->sll2_pkttype = LINUX_SLL_OUTGOING; else sll2->sll2_pkttype = LINUX_SLL_HOST; sll2->sll2_reserved_mbz = 0x0; sll2->sll2_if_index = 0x0; sll2->sll2_hatype = 0x0; sll2->sll2_halen = 0x0; memset(sll2->sll2_addr, 0, SLL_ADDRLEN); memcpy(pktbuf + sizeof(struct sll2_header), mctp_pktbuf_hdr(pkt), mctp_pktbuf_size(pkt)); hdr.caplen = size; hdr.len = size; pcap_dump((u_char *)dumper, &hdr, (const u_char *)pktbuf); __mctp_free(pktbuf); } void capture_socket(pcap_dumper_t *dumper, const void *buf, size_t len, bool outgoing, int eid) { struct pcap_pkthdr hdr; int rc; uint8_t *pktbuf = NULL; size_t size; if ((rc = gettimeofday(&hdr.ts, NULL)) == -1) return; /* Write sll2 header */ size = sizeof(struct sll2_header) + sizeof(struct mctp_hdr) + len; pktbuf = __mctp_alloc(size); if (!pktbuf) return; struct sll2_header *sll2 = (struct sll2_header *)pktbuf; sll2->sll2_protocol = htons(ETH_P_MCTP); if (outgoing) sll2->sll2_pkttype = LINUX_SLL_OUTGOING; else sll2->sll2_pkttype = LINUX_SLL_HOST; sll2->sll2_reserved_mbz = 0x0; sll2->sll2_if_index = 0x0; sll2->sll2_hatype = 0x0; sll2->sll2_halen = 0x0; memset(sll2->sll2_addr, 0, SLL_ADDRLEN); /* Write fake mctp header */ struct mctp_hdr *mctp = (struct mctp_hdr *)(pktbuf + sizeof(struct sll2_header)); mctp->ver = 1; mctp->flags_seq_tag = 0xc0; //set SOM and EOM if (outgoing) { mctp->dest = eid; mctp->src = 0; } else { mctp->dest = 0; mctp->src = eid; } /* Ignore the eid at start of buf */ memcpy(pktbuf + sizeof(struct sll2_header) + sizeof(struct mctp_hdr), (const uint8_t *)buf + 1, len - 1); hdr.caplen = size; hdr.len = size; pcap_dump((u_char *)dumper, &hdr, (const u_char *)pktbuf); __mctp_free(pktbuf); }