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