Initial import
[sliver-openvswitch.git] / datapath / tests / ofp_pcap.c
1 /* A cheap knock-off of the pcap library to remove that dependency. */
2
3 #include <stdlib.h>
4 #include <string.h>
5 #include <arpa/inet.h>
6 #include "ofp_pcap.h"
7
8 int
9 ofp_pcap_open(struct ofp_pcap *p, const char *fname, char *errbuf)
10 {
11         FILE *fp;
12         struct pcap_file_header hdr;
13         size_t amt_read;
14
15         fp = fopen(fname, "r");
16
17         memset((char *)p, 0, sizeof(*p));
18
19         amt_read = fread((char *)&hdr, 1, sizeof(hdr), fp);
20         if (amt_read != sizeof(hdr)) {
21                 snprintf(errbuf, OFP_PCAP_ERRBUF_SIZE, "error reading dump file");
22                 goto error;
23         }
24
25         if (hdr.magic != TCPDUMP_MAGIC) {
26                 hdr.magic         = SWAPLONG(hdr.magic);
27                 hdr.version_major = SWAPSHORT(hdr.version_major);
28                 hdr.version_minor = SWAPSHORT(hdr.version_minor);
29                 hdr.thiszone      = SWAPLONG(hdr.thiszone);
30                 hdr.sigfigs       = SWAPLONG(hdr.sigfigs);
31                 hdr.snaplen       = SWAPLONG(hdr.snaplen);
32                 hdr.linktype      = SWAPLONG(hdr.linktype);
33
34                 p->swapped = 1;
35         }
36
37         p->fp = fp;
38         p->errbuf = errbuf;
39         p->bufsize = hdr.snaplen+sizeof(struct pcap_pkthdr);
40         p->buf = malloc(p->bufsize);
41         if (!p->buf) {
42                 snprintf(errbuf, OFP_PCAP_ERRBUF_SIZE, "error allocating buffer");
43                 goto error;
44         }
45
46         if (hdr.version_major < OFP_PCAP_VERSION_MAJOR) {
47                 snprintf(errbuf, OFP_PCAP_ERRBUF_SIZE, "archaic file format");
48                 goto error;
49         }
50
51         return 0;
52
53 error:
54         if (p->buf)
55                 free(p->buf);
56         return 1;
57 }
58
59 char *
60 ofp_pcap_next(struct ofp_pcap *p, struct pcap_pkthdr *hdr)
61 {
62         size_t amt_read;
63
64         amt_read = fread(hdr, 1, sizeof(*hdr), p->fp);
65         if (amt_read != sizeof(*hdr)) {
66                 snprintf(p->errbuf, OFP_PCAP_ERRBUF_SIZE, "error reading dump file");
67                 return NULL;
68         }
69
70         if (p->swapped) {
71                 hdr->caplen = SWAPLONG(hdr->caplen);
72                 hdr->len = SWAPLONG(hdr->len);
73                 hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec);
74                 hdr->ts.tv_usec = SWAPLONG(hdr->ts.tv_usec);
75         }
76
77         if (hdr->caplen > p->bufsize) {
78                 snprintf(p->errbuf, OFP_PCAP_ERRBUF_SIZE, "error reading dump file");
79                 return NULL;
80         }
81
82         amt_read = fread((char *)p->buf, 1, hdr->caplen, p->fp);
83         if (amt_read != hdr->caplen){
84                 snprintf(p->errbuf, OFP_PCAP_ERRBUF_SIZE, "error reading dump file");
85                 return NULL;
86         }
87
88         return p->buf;
89 }
90
91 void
92 ofp_pcap_close(struct ofp_pcap *p)
93 {
94         fclose(p->fp);
95         free(p->buf);
96 }
97