embedded IPsec source code documentation


dumpdev.c

Go to the documentation of this file.
00001 /*
00002  * embedded IPsec
00003  * Copyright (c) 2003 Niklaus Schild and Christian Scheurer, HTI Biel/Bienne
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without modification,
00007  * are permitted provided that the following conditions are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright notice,
00010  *    this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright notice,
00012  *    this list of conditions and the following disclaimer in the documentation
00013  *    and/or other materials provided with the distribution.
00014  * 3. The name of the author may not be used to endorse or promote products
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00018  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00020  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00021  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00022  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00025  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00026  * OF SUCH DAMAGE.
00027  *
00028  */
00060 #include "lwip/mem.h"
00061 #include "netif/etharp.h"
00062 #include "netif/dumpdev.h"
00063 
00064 #include "ipsec/debug.h"
00065 #include "ipsec/util.h"
00066 
00067 #define DUMPDEV_NAME0 'd'       
00068 #define DUMPDEV_NAME1 'p'       
00075 #define DUMPDEV_IGNORE_RESPONSE
00076 
00082 //#define DUMPDEV_USE_PING_DATA
00083 
00089 #define DUMPDEV_USE_HTTPGET_DATA
00090 
00091 /* NS: made some problems
00092 #ifdef DUMPDEV_USE_PING_DATA && DUMPDEV_USE_HTTPGET_DATA
00093 #error "Please use only one set of dumped packets! (combination of DUMPDEV_USE_PING_DATA and DUMPDEV_USE_HTTPGET_DATA is not tested)"
00094 #endif
00095 */
00096 
00097 #ifdef DUMPDEV_USE_PING_DATA
00098 #include "testing/functional/ipsec-lwip-integration/dumpdev-pingdata.h" 
00099 #endif
00100 
00101 #ifdef DUMPDEV_USE_HTTPGET_DATA
00102 #include "testing/functional/ipsec-lwip-integration/dumpdev-httpgetdata.h"      
00103 #endif
00104 
00105 
00106 unsigned char dumpdev_pingpacket[74] =  
00107 {
00108     0x00, 0xE0, 0x29, 0x25, 0x60, 0x6C, 0x00, 0xE0, 0x29, 0x15, 0x1C, 0x41, 0x08, 0x00, 0x45, 0x00,
00109     0x00, 0x3C, 0x07, 0xF5, 0x00, 0x00, 0x80, 0x01, 0xAF, 0x78, 0xC0, 0xA8, 0x01, 0x02, 0xC0, 0xA8,
00110     0x01, 0x01, 0x08, 0x00, 0x40, 0x5C, 0x05, 0x00, 0x08, 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
00111     0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
00112     0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
00113 } ;  
00116 unsigned char dumpdev_ESP_packet[114] =
00117 {
00118     0x00, 0xA0, 0x24, 0x15, 0x3E, 0x12, 0x00, 0xE0, 0x29, 0x25, 0x60, 0x6C, 0x08, 0x00, 0x45, 0x00,
00119     0x00, 0x64, 0x79, 0x28, 0x00, 0x00, 0x40, 0x32, 0x7D, 0xC4, 0xC0, 0xA8, 0x01, 0x28, 0xC0, 0xA8,
00120     0x01, 0x03, 0x00, 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x01, 0xA7, 0x36, 0xBA, 0x27, 0x8D, 0x39,
00121     0xC5, 0x09, 0x49, 0x26, 0x53, 0x04, 0x07, 0xC9, 0x4D, 0xBB, 0x16, 0x59, 0x0E, 0x4E, 0x0B, 0x35,
00122     0xBD, 0x56, 0x0A, 0x84, 0x26, 0x8E, 0x24, 0x8D, 0xB7, 0xAE, 0x8C, 0x59, 0x3F, 0x0C, 0x40, 0x22,
00123     0x2B, 0x82, 0xA3, 0xC8, 0x3D, 0xDB, 0x0B, 0xA9, 0xD7, 0x81, 0x1A, 0x52, 0xC3, 0x26, 0xDB, 0x19,
00124     0xCB, 0xFF, 0x67, 0xA3, 0xA0, 0x04, 0x94, 0x8E, 0x36, 0xE4, 0xBF, 0xDF, 0x61, 0xBA, 0xCB, 0xB5,
00125     0xBA, 0xE9,
00126 } ;             
00150 void ipsec_debug_dumppbufs(char *prefix, struct pbuf *data) 
00151 {
00152         unsigned char *pbuf_pos_ptr = 0;
00153         unsigned char *tmp_ptr = 0;
00154     struct pbuf *q;
00155         int bytecount = 0;              // number of bytes which have already been dumped
00156         int i;
00157 
00158         if(data == NULL) {
00159                 printf("%sCan't dump pbuf ==> data == NULL\n", prefix); 
00160                 return;
00161         }
00162 
00163         printf("%sDumping pbuf (total length is %d bytes)\n", prefix, data->tot_len); 
00164         if(data->tot_len == 0) {
00165                 printf(" => nothing to dump\n");
00166                 return;
00167         }
00168 
00169     // q traverses through linked list of pbuf's
00170     // for(q = data; q != NULL; q = q->next)
00171         q = data;
00172         if((q != NULL) && (q->payload != NULL))
00173     {
00174                 // dump all pbufs
00175         pbuf_pos_ptr = (unsigned char *)q->payload;
00176                 for(i = 0; i < q->len; i ++)
00177                 {
00178                         if((bytecount % 16) == 0) printf("%s%08Lx:", prefix, pbuf_pos_ptr);
00179                         printf(" %02X", *pbuf_pos_ptr);
00180                         if((bytecount % 16) == 15) printf("\n");
00181                         pbuf_pos_ptr++;
00182                         bytecount++;
00183                 }
00184     }
00185 
00186         if((bytecount % 16) != 0) printf(" \n");
00187 }
00188 
00189 
00198 void dumpdev_service(struct netif *netif)
00199 {
00200         dumpdev_input(netif);
00201 }
00202 
00203 
00215 void dumpdev_input(struct netif *netif)
00216 {
00217         struct dumpdev_stats *dumpdev_stats = netif->state;
00218         struct eth_hdr *ethhdr = NULL;
00219         struct pbuf *p = NULL, *q = NULL;
00220         unsigned char *ptr = NULL;
00221         unsigned char *input_ptr = NULL;
00222         u16_t len = 0;
00223         u16_t i;
00224 
00225         IPSEC_LOG_MSG("dumpdev_input", ("*** start of dumpdev_input() ***") );
00226 
00231         len = sizeof(dumpdev_ESP_packet);
00232         input_ptr = dumpdev_ESP_packet;
00233 
00234 
00235 #ifdef DUMPDEV_USE_HTTPGET_DATA
00236         if(httpget_sequence[httpget_sequence_pos].packet_type == INBOUND)
00237         {
00238                 len             = httpget_sequence[httpget_sequence_pos].size;
00239                 input_ptr       = httpget_sequence[httpget_sequence_pos].payload;
00240         }
00241         httpget_sequence_pos = (httpget_sequence_pos + 1) % HTTPGET_SEQUENCE_LENGTH;
00242 #endif
00243 
00244 
00245 #ifdef DUMPDEV_USE_PING_DATA
00246         if(ping_sequence[ping_sequence_pos].packet_type == INBOUND)
00247         {
00248                 len             = ping_sequence[ping_sequence_pos].size;
00249                 input_ptr       = ping_sequence[ping_sequence_pos].payload;
00250         }
00251         ping_sequence_pos = (ping_sequence_pos + 1) % PING_SEQUENCE_LENGTH;
00252 #endif
00253 
00254         /* if there are some data ready, receive them and put them in a new pubf */
00255         if(len > 0)
00256     {
00257                 /* allocate a pbuf memory of size 'len' */
00258         p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
00259                 if(p != NULL)
00260                 {
00261                         /* copy payload */
00263                 ptr = p->payload;
00264                 for (i = 0; i < p->len; i++)
00265                         {
00266                                 ptr[i] = input_ptr[i];
00267                         }
00268                 }
00269                 else {
00270                         IPSEC_LOG_ERR("dumpdev_input", IPSEC_STATUS_DATA_SIZE_ERROR, ("failed to allocate memory for incoming packet"));
00271                     return;
00272                 }
00273         }
00274         else {
00275                 IPSEC_LOG_DBG("dumpdev_input", IPSEC_STATUS_DATA_SIZE_ERROR, ("no data to read"));
00276                 return;
00277         }
00278 
00279         if(p != NULL)
00280         {
00281                 IPSEC_LOG_MSG("dumpdev_input", ("receiving data:") );
00282                 ipsec_debug_dumppbufs("                                        INBOUND : ", p);
00283         }
00284 
00285 
00286         ethhdr = p->payload;            /* get MAC address (start of Ethernet frame) */
00287 
00288         switch(htons(ethhdr->type)) {
00289                 case ETHTYPE_IP:                /* IP packet */
00290                                 q = etharp_ip_input(netif, p);  /* update ARP table */
00291                                 pbuf_header(p, -14);                    /* remove Ethernet header */
00292                                 IPSEC_LOG_MSG("dumpdev_input", ("passing new packet higher layers") );
00293                                 netif->input(p, netif);                 /* pass packet to higher network layers */
00294                         break;
00295                 case ETHTYPE_ARP:               /* ARP packet */
00296                                 /* pass p to ARP module, get ARP reply or ARP queued packet */
00297                                 q = etharp_arp_input(netif, (struct eth_addr *)&netif->hwaddr, p);
00298                         break;
00299                 default:                                /* drop unknown packets */
00300                                 IPSEC_LOG_MSG("dumpdev_input", ("unknown packet -> drop") );
00301                                 pbuf_free(p);
00302                                 p = NULL;
00303                                 q = NULL;
00304                         break;
00305         }
00306 
00307         /* send out the ARP reply or ARP queued packet */
00308         if (q != NULL)
00309         {
00310                 /* q pbuf has been succesfully sent? */
00311                 if (dumpdev_output(netif, q, -1) == IPSEC_STATUS_SUCCESS)       
00312                 {
00313                         pbuf_free(q);
00314                         q = NULL;
00315                 }
00316                 else {
00317                         /* TODO re-queue packet in the ARP cache here (?) */
00318                         pbuf_free(q);
00319                         q = NULL;
00320                 }
00321         }
00322         IPSEC_LOG_MSG("dumpdev_input", ("*** end of dumpdev_input() ***") );
00323 }
00324 
00325 
00341 err_t dumpdev_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
00342 {
00343         IPSEC_LOG_MSG("dumpdev_output", ("*** start of dumpdev_output() ***") );
00344 
00345         p = etharp_output(netif, ipaddr, p);
00346 
00347     /* network hardware address obtained? */
00348         if (p != NULL)
00349         {
00350                 IPSEC_LOG_MSG("dumpdev_output", ("sending data:") );
00351                 ipsec_debug_dumppbufs("                                        OUTBOUND: ", p);
00352                 ((struct dumpdev_stats *)netif->state)->sentbytes += p->tot_len;
00353         }
00354         IPSEC_LOG_MSG("dumpdev_output", ("*** end of dumpdev_output() ***") );
00355         return ERR_OK;
00356 }
00357 
00358 
00368 err_t dumpdev_netlink_output(struct netif *netif, struct pbuf *p)
00369 {
00370         void *dummy;                    // dummy variable to avoid compiler warnings
00371         dummy = netif;
00372         dummy = (void*) p;
00373         IPSEC_LOG_MSG("dempdev_netlink_output()", ("simulate writing netlink stuff (not implemented, just returning ERR_OK)") );
00374         return ERR_OK;
00375 }
00376 
00377 
00389 err_t dumpdev_init(struct netif *netif)
00390 {
00391         struct dumpdev_stats *dumpdev_stats;
00392 
00393         dumpdev_stats = mem_malloc(sizeof(struct dumpdev_stats));
00394         if (dumpdev_stats == NULL)
00395         {
00396                 LWIP_DEBUGF(DUMPDEV_DEBUG, ("dumpdev_input: out of memory for dumpdev_stats\n"));
00397                 return ERR_MEM;
00398         }
00399 
00400         /* set the name of this interface */
00401         netif->name[0] = DUMPDEV_NAME0;
00402         netif->name[1] = DUMPDEV_NAME1;
00403 
00404         /* use the same output function for all operations */
00405         netif->output = (void*)dumpdev_output;  /* usually called if the IP module wants to send data */
00406         netif->linkoutput = (void*)dumpdev_netlink_output; /* usually called if the ARP module wants to send data "as-is" */
00407 
00408         dumpdev_stats->sentbytes = 0;                   /* reset statistic */
00409         netif->state = dumpdev_stats;                   /* assign statistic */
00410         netif->mtu = 1500;                                              /* set MTU */
00411         netif->flags = NETIF_FLAG_LINK_UP | NETIF_FLAG_BROADCAST;       /* device is always connected and supports broadcasts */
00412         netif->hwaddr_len = 6;                                  /* set hardware address (MAC address) */
00413         netif->hwaddr[0] = 0x00;
00414         netif->hwaddr[1] = 0xe0;
00415         netif->hwaddr[2] = 0x29;
00416         netif->hwaddr[3] = 0x25;
00417         netif->hwaddr[4] = 0x60;
00418         netif->hwaddr[5] = 0x6c;
00419 
00420         return IPSEC_STATUS_SUCCESS;
00421 }
00422 
00423 

Copyright 2003 by Christian Scheurer and Niklaus Schild