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