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
capture_init(void)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
capture_prepare(struct capture * cap)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
capture_close(struct capture * cap)48 void capture_close(struct capture *cap)
49 {
50 pcap_dump_close(cap->dumper);
51
52 pcap_close(cap->pcap);
53 }
54
capture_binding(struct mctp_pktbuf * pkt,bool outgoing,void * user)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
capture_socket(pcap_dumper_t * dumper,const void * buf,size_t len,bool outgoing,int eid)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