1 #include "utils/mctp-capture.h" 2 3 #include <stdio.h> 4 #include <sys/time.h> 5 #include <string.h> 6 7 #if HAVE_PCAP 8 #include <pcap/sll.h> 9 #include <linux/if_ether.h> 10 #include "libmctp-alloc.h" 11 12 #ifndef ETH_P_MCTP 13 #define ETH_P_MCTP 0xfa 14 #endif 15 16 #endif 17 18 int capture_init(void) 19 { 20 char errbuf[PCAP_ERRBUF_SIZE]; 21 int rc; 22 23 if ((rc = pcap_init(PCAP_CHAR_ENC_UTF_8, errbuf)) == -1) { 24 fprintf(stderr, "pcap_init: %s\n", errbuf); 25 return -1; 26 } 27 28 return 0; 29 } 30 31 int capture_prepare(struct capture *cap) 32 { 33 if (!(cap->pcap = pcap_open_dead(CAPTURE_LINKTYPE_LINUX_SLL2, 34 UINT16_MAX))) { 35 fprintf(stderr, "pcap_open_dead: failed\n"); 36 return -1; 37 } 38 if (!(cap->dumper = pcap_dump_open(cap->pcap, cap->path))) { 39 fprintf(stderr, "pcap_dump_open: failed\n"); 40 return -1; 41 } 42 43 return 0; 44 } 45 46 void capture_close(struct capture *cap) 47 { 48 pcap_dump_close(cap->dumper); 49 50 pcap_close(cap->pcap); 51 } 52 53 void capture_binding(struct mctp_pktbuf *pkt, bool outgoing, void *user) 54 { 55 pcap_dumper_t *dumper = user; 56 struct pcap_pkthdr hdr; 57 int rc; 58 uint8_t *pktbuf = NULL; 59 size_t size; 60 61 if ((rc = gettimeofday(&hdr.ts, NULL)) == -1) 62 return; 63 64 /* Write sll2 header */ 65 size = sizeof(struct sll2_header) + mctp_pktbuf_size(pkt); 66 pktbuf = __mctp_alloc(size); 67 if (!pktbuf) 68 return; 69 70 struct sll2_header *sll2 = (struct sll2_header *)pktbuf; 71 sll2->sll2_protocol = htons(ETH_P_MCTP); 72 if (outgoing) 73 sll2->sll2_pkttype = LINUX_SLL_OUTGOING; 74 else 75 sll2->sll2_pkttype = LINUX_SLL_HOST; 76 sll2->sll2_reserved_mbz = 0x0; 77 sll2->sll2_if_index = 0x0; 78 sll2->sll2_hatype = 0x0; 79 sll2->sll2_halen = 0x0; 80 memset(sll2->sll2_addr, 0, SLL_ADDRLEN); 81 82 memcpy(pktbuf + sizeof(struct sll2_header), mctp_pktbuf_hdr(pkt), 83 mctp_pktbuf_size(pkt)); 84 85 hdr.caplen = size; 86 hdr.len = size; 87 88 pcap_dump((u_char *)dumper, &hdr, (const u_char *)pktbuf); 89 __mctp_free(pktbuf); 90 } 91 92 void capture_socket(pcap_dumper_t *dumper, const void *buf, size_t len, 93 bool outgoing, int eid) 94 { 95 struct pcap_pkthdr hdr; 96 int rc; 97 uint8_t *pktbuf = NULL; 98 size_t size; 99 100 if ((rc = gettimeofday(&hdr.ts, NULL)) == -1) 101 return; 102 103 /* Write sll2 header */ 104 size = sizeof(struct sll2_header) + sizeof(struct mctp_hdr) + len; 105 pktbuf = __mctp_alloc(size); 106 if (!pktbuf) 107 return; 108 109 struct sll2_header *sll2 = (struct sll2_header *)pktbuf; 110 sll2->sll2_protocol = htons(ETH_P_MCTP); 111 if (outgoing) 112 sll2->sll2_pkttype = LINUX_SLL_OUTGOING; 113 else 114 sll2->sll2_pkttype = LINUX_SLL_HOST; 115 sll2->sll2_reserved_mbz = 0x0; 116 sll2->sll2_if_index = 0x0; 117 sll2->sll2_hatype = 0x0; 118 sll2->sll2_halen = 0x0; 119 memset(sll2->sll2_addr, 0, SLL_ADDRLEN); 120 121 /* Write fake mctp header */ 122 struct mctp_hdr *mctp = 123 (struct mctp_hdr *)(pktbuf + sizeof(struct sll2_header)); 124 mctp->ver = 1; 125 mctp->flags_seq_tag = 0xc0; //set SOM and EOM 126 if (outgoing) { 127 mctp->dest = eid; 128 mctp->src = 0; 129 } else { 130 mctp->dest = 0; 131 mctp->src = eid; 132 } 133 134 /* Ignore the eid at start of buf */ 135 memcpy(pktbuf + sizeof(struct sll2_header) + sizeof(struct mctp_hdr), 136 (const uint8_t *)buf + 1, len - 1); 137 138 hdr.caplen = size; 139 hdr.len = size; 140 141 pcap_dump((u_char *)dumper, &hdr, (const u_char *)pktbuf); 142 __mctp_free(pktbuf); 143 } 144