]>
Commit | Line | Data |
---|---|---|
89c4ed63 A |
1 | /* |
2 | Copyright (c) 2000 | |
3 | International Computer Science Institute | |
4 | All rights reserved. | |
5 | ||
6 | This file may contain software code originally developed for the | |
7 | Sting project. The Sting software carries the following copyright: | |
8 | ||
9 | Copyright (c) 1998, 1999 | |
10 | Stefan Savage and the University of Washington. | |
11 | All rights reserved. | |
12 | ||
13 | Redistribution and use in source and binary forms, with or without | |
14 | modification, are permitted provided that the following conditions | |
15 | are met: | |
16 | 1. Redistributions of source code must retain the above copyright | |
17 | notice, this list of conditions and the following disclaimer. | |
18 | 2. Redistributions in binary form must reproduce the above copyright | |
19 | notice, this list of conditions and the following disclaimer in the | |
20 | documentation and/or other materials provided with the distribution. | |
21 | 3. All advertising materials mentioning features or use of this software | |
22 | must display the following acknowledgment: | |
23 | This product includes software developed by ACIRI, the AT&T | |
24 | Center for Internet Research at ICSI (the International Computer | |
25 | Science Institute). This product may also include software developed | |
26 | by Stefan Savage at the University of Washington. | |
27 | 4. The names of ACIRI, ICSI, Stefan Savage and University of Washington | |
28 | may not be used to endorse or promote products derived from this software | |
29 | without specific prior written permission. | |
30 | ||
31 | THIS SOFTWARE IS PROVIDED BY ICSI AND CONTRIBUTORS ``AS IS'' AND | |
32 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
33 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
34 | ARE DISCLAIMED. IN NO EVENT SHALL ICSI OR CONTRIBUTORS BE LIABLE | |
35 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
36 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
37 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
38 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
39 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
40 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
41 | SUCH DAMAGE. | |
42 | */ | |
43 | #include <sys/types.h> | |
44 | #include <sys/param.h> | |
45 | #include <sys/time.h> | |
46 | #include <string.h> | |
47 | #include <stdlib.h> | |
48 | #include <stdio.h> | |
49 | #include "gmt2local.h" | |
50 | #include "pcap.h" | |
51 | #include "inet.h" | |
52 | #include "capture.h" | |
53 | ||
54 | /* set snaplen to max etherenet packet size */ | |
55 | #define DEFAULT_SNAPLEN 1500 | |
56 | ||
57 | pcap_t *pc; /* pcap device */ | |
58 | int datalinkOffset; /* offset of ip packet from datalink packet */ | |
755a8d69 | 59 | int captureDebug = 1; |
89c4ed63 A |
60 | unsigned int thisTimeZone; |
61 | ||
62 | void CaptureInit(u_int32_t sourceIP, u_int16_t sourcePort, | |
63 | u_int32_t targetIP, u_int16_t targetPort, char *dev) | |
64 | { | |
65 | ||
66 | char *device = NULL; | |
67 | char errbuf[PCAP_ERRBUF_SIZE]; | |
68 | int snaplen = DEFAULT_SNAPLEN; | |
69 | int promisc = 1; | |
70 | int timeout = 10; /* timeout in 1 second (10 ms) */ | |
71 | char filtercmds[255]; | |
72 | bpf_u_int32 netmask = 0; | |
73 | struct bpf_program filter; | |
74 | char source[18]; | |
75 | char target[18]; | |
76 | int i; | |
77 | ||
78 | /* Get local time zone for interpreting timestamps */ | |
79 | /* XXX - does this belong here? */ | |
80 | thisTimeZone = gmt2local(0); | |
81 | ||
82 | if (dev != NULL) { | |
83 | device = dev; | |
84 | } else { | |
85 | device = pcap_lookupdev(errbuf); | |
86 | if (device == NULL) { | |
87 | fprintf(stderr, "Can't find capture device: %s\n", errbuf); | |
88 | exit(-1); | |
89 | } | |
90 | } | |
91 | ||
92 | if (captureDebug) { | |
93 | printf("Device name is %s\n", device); | |
94 | } | |
95 | pc = pcap_open_live(device, snaplen, promisc, timeout, errbuf); | |
96 | if (pc == NULL) { | |
97 | fprintf(stderr,"Can't open capture device %s: %s\n",device, errbuf); | |
98 | exit(-1); | |
99 | } | |
100 | ||
101 | /* XXX why do we need to do this? */ | |
102 | i = pcap_snapshot(pc); | |
103 | if (snaplen < i) { | |
104 | fprintf(stderr, "Warning: snaplen raised to %d from %d", | |
105 | snaplen, i); | |
106 | } | |
107 | ||
108 | if ((i = pcap_datalink(pc)) < 0) { | |
109 | fprintf(stderr,"Unable to determine datalink type for %s: %s\n", | |
110 | device, errbuf); | |
111 | exit(-1); | |
112 | } | |
113 | ||
114 | switch(i) { | |
115 | ||
116 | case DLT_EN10MB: datalinkOffset = 14; break; | |
117 | case DLT_IEEE802: datalinkOffset = 22; break; | |
118 | case DLT_NULL: datalinkOffset = 4; break; | |
119 | case DLT_SLIP: | |
120 | case DLT_PPP: datalinkOffset = 24; break; | |
121 | case DLT_RAW: datalinkOffset = 0; break; | |
122 | default: | |
123 | fprintf(stderr,"Unknown datalink type %d\n",i); | |
124 | exit(-1); | |
125 | break; | |
126 | ||
127 | } | |
128 | ||
129 | if (InetAddress(sourceIP) < 0) { | |
130 | fprintf(stderr, "Invalid source IP address (%d)\n", sourceIP); | |
131 | exit(-1); | |
132 | } | |
133 | ||
134 | strncpy(source, InetAddress(sourceIP), sizeof(source) - 1); | |
135 | strncpy(target, InetAddress(targetIP), sizeof(target) - 1); | |
136 | ||
137 | /* Setup initial filter */ | |
138 | sprintf(filtercmds, | |
fa34b6f5 A |
139 | "(host %s && host %s && port %d) || icmp\n", |
140 | source, target, targetPort); | |
89c4ed63 A |
141 | |
142 | if (captureDebug) { | |
143 | printf("datalinkOffset = %d\n", datalinkOffset); | |
144 | printf("filter = %s\n", filtercmds); | |
145 | } | |
146 | if (pcap_compile(pc, &filter, filtercmds, 1, netmask) < 0) { | |
147 | printf("Error: %s", pcap_geterr(pc)); | |
148 | exit(-1); | |
149 | } | |
150 | ||
151 | if (pcap_setfilter(pc, &filter) < 0) { | |
152 | fprintf(stderr, "Can't set filter: %s",pcap_geterr(pc)); | |
153 | exit(-1); | |
154 | } | |
155 | ||
156 | if (captureDebug) { | |
157 | printf("Listening on %s...\n", device); | |
158 | } | |
159 | ||
160 | } | |
161 | ||
162 | char *CaptureGetPacket(struct pcap_pkthdr *pi) | |
163 | { | |
164 | ||
165 | const u_char *p; | |
166 | ||
167 | p = pcap_next(pc, (struct pcap_pkthdr *)pi); | |
168 | ||
169 | if (p != NULL) { | |
170 | p += datalinkOffset; | |
171 | } | |
172 | ||
173 | pi->ts.tv_sec = (pi->ts.tv_sec + thisTimeZone) % 86400; | |
174 | ||
175 | return (char *)p; | |
176 | ||
177 | } | |
178 | ||
179 | ||
180 | void CaptureEnd() | |
181 | { | |
182 | struct pcap_stat stat; | |
183 | ||
184 | if (pcap_stats(pc, &stat) < 0) { | |
185 | (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pc)); | |
186 | } | |
187 | else { | |
188 | (void)fprintf(stderr, "%d packets received by filter\n", stat.ps_recv); | |
189 | (void)fprintf(stderr, "%d packets dropped by kernel\n", stat.ps_drop); | |
190 | } | |
191 | ||
192 | pcap_close(pc); | |
193 | } | |
194 |