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 int rc; 34 35 if (!(cap->pcap = pcap_open_dead(CAPTURE_LINKTYPE_LINUX_SLL2, 36 UINT16_MAX))) { 37 fprintf(stderr, "pcap_open_dead: failed\n"); 38 return -1; 39 } 40 if (!(cap->dumper = pcap_dump_open(cap->pcap, cap->path))) { 41 fprintf(stderr, "pcap_dump_open: failed\n"); 42 return -1; 43 } 44 45 return 0; 46 } 47 48 void capture_close(struct capture *cap) 49 { 50 pcap_dump_close(cap->dumper); 51 52 pcap_close(cap->pcap); 53 } 54 55 void capture_binding(struct mctp_pktbuf *pkt, bool outgoing, void *user) 56 { 57 pcap_dumper_t *dumper = user; 58 struct pcap_pkthdr hdr; 59 int rc; 60 uint8_t *pktbuf = NULL; 61 size_t size; 62 63 if ((rc = gettimeofday(&hdr.ts, NULL)) == -1) 64 return; 65 66 /* Write sll2 header */ 67 size = sizeof(struct sll2_header) + mctp_pktbuf_size(pkt); 68 pktbuf = __mctp_alloc(size); 69 if (!pktbuf) 70 return; 71 72 struct sll2_header *sll2 = (struct sll2_header *)pktbuf; 73 sll2->sll2_protocol = htons(ETH_P_MCTP); 74 if (outgoing) 75 sll2->sll2_pkttype = LINUX_SLL_OUTGOING; 76 else 77 sll2->sll2_pkttype = LINUX_SLL_HOST; 78 sll2->sll2_reserved_mbz = 0x0; 79 sll2->sll2_if_index = 0x0; 80 sll2->sll2_hatype = 0x0; 81 sll2->sll2_halen = 0x0; 82 memset(sll2->sll2_addr, 0, SLL_ADDRLEN); 83 84 memcpy(pktbuf + sizeof(struct sll2_header), mctp_pktbuf_hdr(pkt), 85 mctp_pktbuf_size(pkt)); 86 87 hdr.caplen = size; 88 hdr.len = size; 89 90 pcap_dump((u_char *)dumper, &hdr, (const u_char *)pktbuf); 91 __mctp_free(pktbuf); 92 } 93 94 void capture_socket(pcap_dumper_t *dumper, const void *buf, size_t len, 95 bool outgoing, int eid) 96 { 97 struct pcap_pkthdr hdr; 98 int rc; 99 uint8_t *pktbuf = NULL; 100 size_t size; 101 102 if ((rc = gettimeofday(&hdr.ts, NULL)) == -1) 103 return; 104 105 /* Write sll2 header */ 106 size = sizeof(struct sll2_header) + sizeof(struct mctp_hdr) + len; 107 pktbuf = __mctp_alloc(size); 108 if (!pktbuf) 109 return; 110 111 struct sll2_header *sll2 = (struct sll2_header *)pktbuf; 112 sll2->sll2_protocol = htons(ETH_P_MCTP); 113 if (outgoing) 114 sll2->sll2_pkttype = LINUX_SLL_OUTGOING; 115 else 116 sll2->sll2_pkttype = LINUX_SLL_HOST; 117 sll2->sll2_reserved_mbz = 0x0; 118 sll2->sll2_if_index = 0x0; 119 sll2->sll2_hatype = 0x0; 120 sll2->sll2_halen = 0x0; 121 memset(sll2->sll2_addr, 0, SLL_ADDRLEN); 122 123 /* Write fake mctp header */ 124 struct mctp_hdr *mctp = 125 (struct mctp_hdr *)(pktbuf + sizeof(struct sll2_header)); 126 mctp->ver = 1; 127 mctp->flags_seq_tag = 0xc0; //set SOM and EOM 128 if (outgoing) { 129 mctp->dest = eid; 130 mctp->src = 0; 131 } else { 132 mctp->dest = 0; 133 mctp->src = eid; 134 } 135 136 /* Ignore the eid at start of buf */ 137 memcpy(pktbuf + sizeof(struct sll2_header) + sizeof(struct mctp_hdr), 138 buf + 1, len - 1); 139 140 hdr.caplen = size; 141 hdr.len = size; 142 143 pcap_dump((u_char *)dumper, &hdr, (const u_char *)pktbuf); 144 __mctp_free(pktbuf); 145 } 146