Contiki 2.5
tcpdump.c
1 /*
2  * Copyright (c) 2005, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * @(#)$Id: tcpdump.c,v 1.3 2010/10/19 18:29:04 adamdunkels Exp $
32  */
33 
34 #include "contiki-net.h"
35 
36 #include <string.h>
37 #include <stdio.h>
38 
39  struct ip_hdr {
40  /* IP header. */
41  u8_t vhl,
42  tos,
43  len[2],
44  ipid[2],
45  ipoffset[2],
46  ttl,
47  proto;
48  u16_t ipchksum;
49  u8_t srcipaddr[4],
50  destipaddr[4];
51  };
52 
53 #define TCP_FIN 0x01
54 #define TCP_SYN 0x02
55 #define TCP_RST 0x04
56 #define TCP_PSH 0x08
57 #define TCP_ACK 0x10
58 #define TCP_URG 0x20
59 #define TCP_CTL 0x3f
60 
61 struct tcpip_hdr {
62  /* IP header. */
63  u8_t vhl,
64  tos,
65  len[2],
66  ipid[2],
67  ipoffset[2],
68  ttl,
69  proto;
70  u16_t ipchksum;
71  u8_t srcipaddr[4],
72  destipaddr[4];
73  /* TCP header. */
74  u16_t srcport,
75  destport;
76  u8_t seqno[4],
77  ackno[4],
78  tcpoffset,
79  flags,
80  wnd[2];
81  u16_t tcpchksum;
82  u8_t urgp[2];
83  u8_t optdata[4];
84 };
85 
86 #define ICMP_ECHO_REPLY 0
87 #define ICMP_ECHO 8
88 
89 struct icmpip_hdr {
90  /* IP header. */
91  u8_t vhl,
92  tos,
93  len[2],
94  ipid[2],
95  ipoffset[2],
96  ttl,
97  proto;
98  u16_t ipchksum;
99  u8_t srcipaddr[4],
100  destipaddr[4];
101  /* The ICMP and IP headers. */
102  /* ICMP (echo) header. */
103  u8_t type, icode;
104  u16_t icmpchksum;
105  u16_t id, seqno;
106 };
107 
108 
109 /* The UDP and IP headers. */
110 struct udpip_hdr {
111  /* IP header. */
112  u8_t vhl,
113  tos,
114  len[2],
115  ipid[2],
116  ipoffset[2],
117  ttl,
118  proto;
119  u16_t ipchksum;
120  u8_t srcipaddr[4],
121  destipaddr[4];
122 
123  /* UDP header. */
124  u16_t srcport,
125  destport;
126  u16_t udplen;
127  u16_t udpchksum;
128 };
129 
130 #define ETHBUF ((struct eth_hdr *)&packet[0])
131 #define IPBUF ((struct ip_hdr *)&packet[0])
132 #define UDPBUF ((struct udpip_hdr *)&packet[0])
133 #define ICMPBUF ((struct icmpip_hdr *)&packet[0])
134 #define TCPBUF ((struct tcpip_hdr *)&packet[0])
135 
136 
137 /*---------------------------------------------------------------------------*/
138 static void
139 tcpflags(unsigned char flags, char *flagsstr)
140 {
141  if(flags & TCP_FIN) {
142  *flagsstr++ = 'F';
143  }
144  if(flags & TCP_SYN) {
145  *flagsstr++ = 'S';
146  }
147  if(flags & TCP_RST) {
148  *flagsstr++ = 'R';
149  }
150  if(flags & TCP_ACK) {
151  *flagsstr++ = 'A';
152  }
153  if(flags & TCP_URG) {
154  *flagsstr++ = 'U';
155  }
156 
157  *flagsstr = 0;
158 }
159 /*---------------------------------------------------------------------------*/
160 static char * CC_FASTCALL
161 n(u16_t num, char *ptr)
162 {
163  u16_t d;
164  u8_t a, f;
165 
166  if(num == 0) {
167  *ptr = '0';
168  return ptr + 1;
169  } else {
170  f = 0;
171  for(d = 10000; d >= 1; d /= 10) {
172  a = (num / d) % 10;
173  if(f == 1 || a > 0) {
174  *ptr = a + '0';
175  ++ptr;
176  f = 1;
177  }
178  }
179  }
180  return ptr;
181 }
182 /*---------------------------------------------------------------------------*/
183 static char * CC_FASTCALL
184 d(char *ptr)
185 {
186  *ptr = '.';
187  return ptr + 1;
188 }
189 /*---------------------------------------------------------------------------*/
190 static char * CC_FASTCALL
191 s(char *str, char *ptr)
192 {
193  strcpy(ptr, str);
194  return ptr + strlen(str);
195 }
196 /*---------------------------------------------------------------------------*/
197 int
198 tcpdump_format(u8_t *packet, u16_t packetlen,
199  char *buf, u16_t buflen)
200 {
201  char flags[8];
202  if(IPBUF->proto == UIP_PROTO_ICMP) {
203  if(ICMPBUF->type == ICMP_ECHO) {
204  return s(" ping",
205  n(IPBUF->destipaddr[3], d(
206  n(IPBUF->destipaddr[2], d(
207  n(IPBUF->destipaddr[1], d(
208  n(IPBUF->destipaddr[0],
209  s(" ",
210  n(IPBUF->srcipaddr[3], d(
211  n(IPBUF->srcipaddr[2], d(
212  n(IPBUF->srcipaddr[1], d(
213  n(IPBUF->srcipaddr[0],
214  buf)))))))))))))))) - buf;
215 
216  /* return sprintf(buf, "%d.%d.%d.%d %d.%d.%d.%d ping",
217  IPBUF->srcipaddr[0], IPBUF->srcipaddr[1],
218  IPBUF->srcipaddr[2], IPBUF->srcipaddr[3],
219  IPBUF->destipaddr[0], IPBUF->destipaddr[1],
220  IPBUF->destipaddr[2], IPBUF->destipaddr[3]);*/
221  } else if(ICMPBUF->type == ICMP_ECHO_REPLY) {
222  return s(" pong",
223  n(IPBUF->destipaddr[3], d(
224  n(IPBUF->destipaddr[2], d(
225  n(IPBUF->destipaddr[1], d(
226  n(IPBUF->destipaddr[0],
227  s(" ",
228  n(IPBUF->srcipaddr[3], d(
229  n(IPBUF->srcipaddr[2], d(
230  n(IPBUF->srcipaddr[1], d(
231  n(IPBUF->srcipaddr[0],
232  buf)))))))))))))))) - buf;
233  /* return sprintf(buf, "%d.%d.%d.%d %d.%d.%d.%d pong",
234  IPBUF->srcipaddr[0], IPBUF->srcipaddr[1],
235  IPBUF->srcipaddr[2], IPBUF->srcipaddr[3],
236  IPBUF->destipaddr[0], IPBUF->destipaddr[1],
237  IPBUF->destipaddr[2], IPBUF->destipaddr[3]);*/
238  }
239  } else if(IPBUF->proto == UIP_PROTO_UDP) {
240  return s(" UDP",
241  n(uip_htons(UDPBUF->destport), d(
242  n(IPBUF->destipaddr[3], d(
243  n(IPBUF->destipaddr[2], d(
244  n(IPBUF->destipaddr[1], d(
245  n(IPBUF->destipaddr[0],
246  s(" ",
247  n(uip_htons(UDPBUF->srcport), d(
248  n(IPBUF->srcipaddr[3], d(
249  n(IPBUF->srcipaddr[2], d(
250  n(IPBUF->srcipaddr[1], d(
251  n(IPBUF->srcipaddr[0],
252  buf)))))))))))))))))))) - buf;
253  /* return sprintf(buf, "%d.%d.%d.%d.%d %d.%d.%d.%d.%d UDP",
254  IPBUF->srcipaddr[0], IPBUF->srcipaddr[1],
255  IPBUF->srcipaddr[2], IPBUF->srcipaddr[3],
256  uip_htons(UDPBUF->srcport),
257  IPBUF->destipaddr[0], IPBUF->destipaddr[1],
258  IPBUF->destipaddr[2], IPBUF->destipaddr[3],
259  uip_htons(UDPBUF->destport));*/
260  } else if(IPBUF->proto == UIP_PROTO_TCP) {
261  tcpflags(TCPBUF->flags, flags);
262  return s(flags,
263  s(" ",
264  n(uip_htons(TCPBUF->destport), d(
265  n(IPBUF->destipaddr[3], d(
266  n(IPBUF->destipaddr[2], d(
267  n(IPBUF->destipaddr[1], d(
268  n(IPBUF->destipaddr[0],
269  s(" ",
270  n(uip_htons(TCPBUF->srcport), d(
271  n(IPBUF->srcipaddr[3], d(
272  n(IPBUF->srcipaddr[2], d(
273  n(IPBUF->srcipaddr[1], d(
274  n(IPBUF->srcipaddr[0],
275  buf))))))))))))))))))))) - buf;
276  /* return sprintf(buf, "%d.%d.%d.%d.%d %d.%d.%d.%d.%d %s",
277  IPBUF->srcipaddr[0], IPBUF->srcipaddr[1],
278  IPBUF->srcipaddr[2], IPBUF->srcipaddr[3],
279  uip_htons(TCPBUF->srcport),
280  IPBUF->destipaddr[0], IPBUF->destipaddr[1],
281  IPBUF->destipaddr[2], IPBUF->destipaddr[3],
282  uip_htons(TCPBUF->destport),
283  flags); */
284  } else {
285  strcpy(buf, "Unrecognized protocol");
286  }
287 
288  return 0;
289 }
290 /*---------------------------------------------------------------------------*/