1 /****************************************************************************
2 ** File: datalink.c
3 **
4 ** Author: Mike Borella
5 **
6 ** Comments: Generic datalink module
7 **
8 ** $Id: datalink.c,v 1.26 2007/06/25 10:44:49 farooq-i-azam Exp $
9 **
10 ** This program is free software; you can redistribute it and/or modify
11 ** it under the terms of the GNU General Public License as published by
12 ** the Free Software Foundation; either version 2 of the License, or
13 ** (at your option) any later version.
14 **
15 ** This program is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ** GNU Library General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with this program; if not, write to the Free Software
22 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 **
24 *****************************************************************************/
25
26 #include "global.h"
27 #include "error.h"
28 #include "datalink.h"
29 #include "ethernet.h"
30 #include "loopback.h"
31 #include "slip.h"
32 #include "raw.h"
33 #include "ppp.h"
34 #include "padding.h"
35 #include "payload.h"
36 #include "stats.h"
37 #include "dynports.h"
38
39 extern struct arg_t * my_args;
40 extern int packet_displayed;
41 extern int start_of_packet;
42
43 /* Map for datalink types */
44 strmap_t datalink_type_map[] =
45 {
46 { DATALINK_TYPE_ETHERNET, "ethernet" },
47 { DATALINK_TYPE_8023, "802.3" },
48 { DATALINK_TYPE_TOKENBUS, "token bus" },
49 { DATALINK_TYPE_TOKENRING, "token ring" },
50 { DATALINK_TYPE_METRONET, "metro net" },
51 { DATALINK_TYPE_HDLC, "HDLC" },
52 { DATALINK_TYPE_CHARSYNCH, "character synchronous" },
53 { DATALINK_TYPE_IBMC2C, "IBM channel-to-channel" },
54 { DATALINK_TYPE_FDDI, "FDDI" },
55 { DATALINK_TYPE_NULL, "null" },
56 { DATALINK_TYPE_SLIP, "SLIP" },
57 { DATALINK_TYPE_PPP, "PPP" },
58 { DATALINK_TYPE_RAWIP, "raw ip" },
59 { 0, ""}
60 };
61
62 /*----------------------------------------------------------------------------
63 **
64 ** datalink_pcap()
65 **
66 ** Libpcap specific wrapper for the generic datalink function
67 **
68 **----------------------------------------------------------------------------
69 */
70
datalink_pcap(u_char * user,const struct pcap_pkthdr * h,u_char * pkt)71 void datalink_pcap(u_char * user, const struct pcap_pkthdr * h, u_char * pkt)
72 {
73 int linktype = -1;
74 u_int32_t * link;
75 struct timeval tv;
76
77 /* Translate the link type */
78 link = (u_int32_t *) user;
79 switch(*link)
80 {
81 case DLT_NULL:
82 linktype = DATALINK_TYPE_NULL;
83 break;
84
85 case DLT_EN10MB:
86 linktype = DATALINK_TYPE_ETHERNET;
87 break;
88
89 case DLT_SLIP:
90 linktype = DATALINK_TYPE_SLIP;
91 break;
92
93 case DLT_PPP:
94 linktype = DATALINK_TYPE_PPP;
95 break;
96
97 #ifdef DLT_RAW /* Not supported in some arch or older pcap versions */
98 case DLT_RAW:
99 linktype = DATALINK_TYPE_RAWIP;
100 break;
101 #endif
102 default:
103 error_fatal("\ncannot handle data link type %d", link);
104 }
105
106 /*
107 * Copy the timestamp our own timeval struct to avoid compilation
108 * errors with older versions of libpcap.
109 */
110
111 tv.tv_sec = h->ts.tv_sec;
112 tv.tv_usec = h->ts.tv_usec;
113
114 /* Call the generic datalink function */
115 datalink(linktype, tv, h->caplen, h->len, pkt);
116 }
117
118 /*----------------------------------------------------------------------------
119 **
120 ** datalink()
121 **
122 **----------------------------------------------------------------------------
123 */
124
datalink(int linktype,struct timeval ts,u_int32_t captured_length,u_int32_t media_length,u_int8_t * pkt)125 void datalink(int linktype, struct timeval ts, u_int32_t captured_length,
126 u_int32_t media_length, u_int8_t * pkt)
127 {
128 packet_t packet;
129 static int count = 1; /* count of the number of packets */
130
131 /*
132 * For minimal mode. We haven't displayed part of a packet yet...
133 * Set the start of packet flag so that we can display a nicer separator
134 */
135
136 packet_displayed = 0;
137 start_of_packet = 1;
138
139 /*
140 * Reset the stats counted flag and unpause the counting if paused.
141 * This avoids the double-counting of encapsulated headers.
142 */
143
144 stats_reset();
145 stats_unpause();
146
147 /*
148 * Set up packet into data structure
149 */
150
151 packet.contents = my_malloc(captured_length);
152 memcpy(packet.contents, pkt, captured_length);
153 packet.current = &packet.contents[0];
154 packet.end = &packet.contents[0] + captured_length;
155 packet.apparent_end = packet.end;
156 packet.media_length = media_length;
157
158 /*
159 * Print time stamp is human readable format.
160 */
161
162 snprintf(packet.timestamp, PACKET_TIMESTAMP_LEN, "%s",
163 ctime ( ( const time_t * ) &ts.tv_sec ) );
164
165 /*
166 * If we're in minimal mode, start off with the count number
167 * and the optional packet timestamp
168 */
169
170 if (my_args->m)
171 {
172 display_minimal((u_int8_t *) &count, 4, DISP_DEC);
173 display_minimal_string(" ");
174 count ++;
175
176 if (!my_args->T)
177 {
178 display_minimal_string(packet.timestamp);
179 display_minimal_string(" ");
180 }
181 }
182
183 /*
184 * Delete any remaining hex buffer contents
185 */
186
187 hexbuffer_kill();
188
189 /*
190 * Determine what to do next
191 */
192
193 switch(linktype)
194 {
195 case DATALINK_TYPE_NULL:
196 dump_loopback(&packet);
197 break;
198
199 case DATALINK_TYPE_ETHERNET:
200 dump_ethernet(&packet);
201 break;
202
203 case DATALINK_TYPE_SLIP:
204 dump_slip(&packet);
205 break;
206
207 case DATALINK_TYPE_PPP:
208 dump_ppp(&packet);
209 break;
210
211 case DATALINK_TYPE_RAWIP:
212 dump_raw(&packet);
213 break;
214
215 default:
216 error_fatal("\ncannot handle data link type %d", linktype);
217 }
218
219 /*
220 * Make sure we set the layer back to a null value in case one of
221 * the layers was suppressed.
222 */
223
224 set_layer(LAYER_NONE);
225
226 /*
227 * Both payload and padding shouldn't be displayed in minimal mode
228 */
229 if (!my_args->m)
230 {
231 /*
232 * If there is any remaining data and the user wants to see it, dump it
233 * out now
234 */
235
236 if (my_args->p && get_packet_apparentbytesleft(&packet))
237 dump_payload(&packet);
238
239 /*
240 * If there is a padding and the user wants to see it, dump it out now
241 */
242
243 if (my_args->d && packet_haspadding(&packet))
244 dump_padding(&packet);
245 }
246
247 /*
248 * For minimal mode, finish with a carriage return
249 */
250
251 if (my_args->m && packet_displayed)
252 {
253 display_minimal_cr();
254 display_minimal_cr();
255 }
256
257 /*
258 * Time out stale dynamic port mappings
259 */
260
261 dynports_timeout();
262
263 /*
264 * Deallocate memory
265 */
266
267 my_free(packet.contents);
268
269 }
270