Contiki 2.6

tcpdump.c

00001 /*
00002  * Copyright (c) 2005, Swedish Institute of Computer Science
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * This file is part of the Contiki operating system.
00030  *
00031  * @(#)$Id: tcpdump.c,v 1.3 2010/10/19 18:29:04 adamdunkels Exp $
00032  */
00033 
00034 #include "contiki-net.h"
00035 
00036 #include <string.h>
00037 #include <stdio.h>
00038 
00039  struct ip_hdr {
00040   /* IP header. */
00041    uint8_t vhl,
00042     tos,
00043      len[2],
00044      ipid[2],
00045      ipoffset[2],
00046      ttl,
00047      proto;
00048    uint16_t ipchksum;
00049    uint8_t srcipaddr[4],
00050      destipaddr[4];
00051  };
00052 
00053 #define TCP_FIN 0x01
00054 #define TCP_SYN 0x02
00055 #define TCP_RST 0x04
00056 #define TCP_PSH 0x08
00057 #define TCP_ACK 0x10
00058 #define TCP_URG 0x20
00059 #define TCP_CTL 0x3f
00060 
00061 struct tcpip_hdr {
00062   /* IP header. */
00063    uint8_t vhl,
00064     tos,
00065      len[2],
00066      ipid[2],
00067      ipoffset[2],
00068      ttl,
00069      proto;
00070    uint16_t ipchksum;
00071    uint8_t srcipaddr[4],
00072      destipaddr[4];
00073   /* TCP header. */
00074   uint16_t srcport,
00075     destport;
00076   uint8_t seqno[4],
00077     ackno[4],
00078     tcpoffset,
00079     flags,
00080     wnd[2];
00081   uint16_t tcpchksum;
00082   uint8_t urgp[2];
00083   uint8_t optdata[4];
00084 };
00085 
00086 #define ICMP_ECHO_REPLY 0
00087 #define ICMP_ECHO       8
00088 
00089 struct icmpip_hdr {
00090   /* IP header. */
00091    uint8_t vhl,
00092     tos,
00093      len[2],
00094      ipid[2],
00095      ipoffset[2],
00096      ttl,
00097      proto;
00098   uint16_t ipchksum;
00099   uint8_t srcipaddr[4],
00100     destipaddr[4];
00101   /* The ICMP and IP headers. */
00102   /* ICMP (echo) header. */
00103   uint8_t type, icode;
00104   uint16_t icmpchksum;
00105   uint16_t id, seqno;
00106 };
00107 
00108 
00109 /* The UDP and IP headers. */
00110 struct udpip_hdr {
00111   /* IP header. */
00112    uint8_t vhl,
00113     tos,
00114      len[2],
00115      ipid[2],
00116      ipoffset[2],
00117      ttl,
00118      proto;
00119    uint16_t ipchksum;
00120   uint8_t srcipaddr[4],
00121     destipaddr[4];
00122   
00123   /* UDP header. */
00124   uint16_t srcport,
00125     destport;
00126   uint16_t udplen;
00127   uint16_t udpchksum;
00128 };
00129 
00130 #define ETHBUF    ((struct eth_hdr *)&packet[0])
00131 #define IPBUF     ((struct ip_hdr *)&packet[0])
00132 #define UDPBUF  ((struct udpip_hdr *)&packet[0])
00133 #define ICMPBUF ((struct icmpip_hdr *)&packet[0])
00134 #define TCPBUF  ((struct tcpip_hdr *)&packet[0])
00135 
00136 
00137 /*---------------------------------------------------------------------------*/
00138 static void
00139 tcpflags(unsigned char flags, char *flagsstr)
00140 {
00141   if(flags & TCP_FIN) {
00142     *flagsstr++ = 'F';
00143   }
00144   if(flags & TCP_SYN) {
00145     *flagsstr++ = 'S';
00146   }
00147   if(flags & TCP_RST) {
00148     *flagsstr++ = 'R';
00149   }
00150   if(flags & TCP_ACK) {
00151     *flagsstr++ = 'A';
00152   }
00153   if(flags & TCP_URG) {
00154     *flagsstr++ = 'U';
00155   }
00156 
00157   *flagsstr = 0;
00158 }
00159 /*---------------------------------------------------------------------------*/
00160 static char * CC_FASTCALL
00161 n(uint16_t num, char *ptr)
00162 {
00163   uint16_t d;
00164   uint8_t a, f;
00165 
00166   if(num == 0) {
00167     *ptr = '0';
00168     return ptr + 1;
00169   } else {
00170     f = 0;
00171     for(d = 10000; d >= 1; d /= 10) {
00172       a = (num / d) % 10;
00173       if(f == 1 || a > 0) {
00174         *ptr = a + '0';
00175         ++ptr;
00176         f = 1;
00177       }
00178     }
00179   }
00180   return ptr;
00181 }
00182 /*---------------------------------------------------------------------------*/
00183 static char * CC_FASTCALL
00184 d(char *ptr)
00185 {
00186   *ptr = '.';
00187   return ptr + 1;
00188 }
00189 /*---------------------------------------------------------------------------*/
00190 static char * CC_FASTCALL
00191 s(char *str, char *ptr)
00192 {
00193   strcpy(ptr, str);
00194   return ptr + strlen(str);
00195 }
00196 /*---------------------------------------------------------------------------*/
00197 int
00198 tcpdump_format(uint8_t *packet, uint16_t packetlen,
00199                char *buf, uint16_t buflen)
00200 {
00201   char flags[8];
00202   if(IPBUF->proto == UIP_PROTO_ICMP) {
00203     if(ICMPBUF->type == ICMP_ECHO) {
00204       return s(" ping",
00205              n(IPBUF->destipaddr[3], d(
00206              n(IPBUF->destipaddr[2], d(
00207              n(IPBUF->destipaddr[1], d(
00208              n(IPBUF->destipaddr[0],
00209              s(" ",
00210              n(IPBUF->srcipaddr[3], d(
00211              n(IPBUF->srcipaddr[2], d(
00212              n(IPBUF->srcipaddr[1], d(
00213              n(IPBUF->srcipaddr[0],
00214              buf)))))))))))))))) - buf;
00215              
00216       /*      return sprintf(buf, "%d.%d.%d.%d %d.%d.%d.%d ping",
00217                      IPBUF->srcipaddr[0], IPBUF->srcipaddr[1],
00218                      IPBUF->srcipaddr[2], IPBUF->srcipaddr[3],
00219                      IPBUF->destipaddr[0], IPBUF->destipaddr[1],
00220                      IPBUF->destipaddr[2], IPBUF->destipaddr[3]);*/
00221     } else if(ICMPBUF->type == ICMP_ECHO_REPLY) {
00222       return s(" pong",
00223              n(IPBUF->destipaddr[3], d(
00224              n(IPBUF->destipaddr[2], d(
00225              n(IPBUF->destipaddr[1], d(
00226              n(IPBUF->destipaddr[0],
00227              s(" ",
00228              n(IPBUF->srcipaddr[3], d(
00229              n(IPBUF->srcipaddr[2], d(
00230              n(IPBUF->srcipaddr[1], d(
00231              n(IPBUF->srcipaddr[0],
00232              buf)))))))))))))))) - buf;
00233       /*      return sprintf(buf, "%d.%d.%d.%d %d.%d.%d.%d pong",
00234                      IPBUF->srcipaddr[0], IPBUF->srcipaddr[1],
00235                      IPBUF->srcipaddr[2], IPBUF->srcipaddr[3],
00236                      IPBUF->destipaddr[0], IPBUF->destipaddr[1],
00237                      IPBUF->destipaddr[2], IPBUF->destipaddr[3]);*/
00238     }
00239   } else if(IPBUF->proto == UIP_PROTO_UDP) {
00240       return s(" UDP",
00241              n(uip_htons(UDPBUF->destport), d(
00242              n(IPBUF->destipaddr[3], d(
00243              n(IPBUF->destipaddr[2], d(
00244              n(IPBUF->destipaddr[1], d(
00245              n(IPBUF->destipaddr[0],
00246              s(" ",
00247              n(uip_htons(UDPBUF->srcport), d(
00248              n(IPBUF->srcipaddr[3], d(
00249              n(IPBUF->srcipaddr[2], d(
00250              n(IPBUF->srcipaddr[1], d(
00251              n(IPBUF->srcipaddr[0],
00252              buf)))))))))))))))))))) - buf;
00253       /*    return sprintf(buf, "%d.%d.%d.%d.%d %d.%d.%d.%d.%d UDP",
00254                    IPBUF->srcipaddr[0], IPBUF->srcipaddr[1],
00255                    IPBUF->srcipaddr[2], IPBUF->srcipaddr[3],
00256                    uip_htons(UDPBUF->srcport),
00257                    IPBUF->destipaddr[0], IPBUF->destipaddr[1],
00258                    IPBUF->destipaddr[2], IPBUF->destipaddr[3],
00259                    uip_htons(UDPBUF->destport));*/
00260   } else if(IPBUF->proto == UIP_PROTO_TCP) {
00261     tcpflags(TCPBUF->flags, flags);
00262       return s(flags,
00263              s(" ",
00264              n(uip_htons(TCPBUF->destport), d(
00265              n(IPBUF->destipaddr[3], d(
00266              n(IPBUF->destipaddr[2], d(
00267              n(IPBUF->destipaddr[1], d(
00268              n(IPBUF->destipaddr[0],
00269              s(" ",
00270              n(uip_htons(TCPBUF->srcport), d(
00271              n(IPBUF->srcipaddr[3], d(
00272              n(IPBUF->srcipaddr[2], d(
00273              n(IPBUF->srcipaddr[1], d(
00274              n(IPBUF->srcipaddr[0],
00275              buf))))))))))))))))))))) - buf;
00276     /*    return sprintf(buf, "%d.%d.%d.%d.%d %d.%d.%d.%d.%d %s",
00277                    IPBUF->srcipaddr[0], IPBUF->srcipaddr[1],
00278                    IPBUF->srcipaddr[2], IPBUF->srcipaddr[3],
00279                    uip_htons(TCPBUF->srcport),
00280                    IPBUF->destipaddr[0], IPBUF->destipaddr[1],
00281                    IPBUF->destipaddr[2], IPBUF->destipaddr[3],
00282                    uip_htons(TCPBUF->destport),
00283                    flags);  */
00284   } else {
00285     strcpy(buf, "Unrecognized protocol");
00286   }
00287 
00288   return 0;
00289 }
00290 /*---------------------------------------------------------------------------*/