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