Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

byte_extract.c

Go to the documentation of this file.
00001 /* $Id$ */
00002 /*
00003 ** Copyright (C) 2003 Sourcefire, Inc.
00004 **               Chris Green <cmg@sourcefire.com>
00005 **
00006 ** This program is free software; you can redistribute it and/or modify
00007 ** it under the terms of the GNU General Public License as published by
00008 ** the Free Software Foundation; either version 2 of the License, or
00009 ** (at your option) any later version.
00010 **
00011 ** This program is distributed in the hope that it will be useful,
00012 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 ** GNU General Public License for more details.
00015 **
00016 ** You should have received a copy of the GNU General Public License
00017 ** along with this program; if not, write to the Free Software
00018 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019 **
00020 **
00021 */
00022 
00023 #include <sys/types.h>
00024 #include <stdlib.h>
00025 #include <ctype.h>
00026 #ifdef HAVE_STRINGS_H
00027 #include <strings.h>
00028 #endif
00029 #include <errno.h>
00030 
00031 #include "bounds.h"
00032 #include "byte_extract.h"
00033 #include "debug.h"
00034 
00035 #define TEXTLEN  (PARSELEN + 1)
00036  
00037 /** 
00038  * Grab a binary representation of data from a buffer
00039  *
00040  * This method will read either a big or little endian value in binary
00041  * data from the packet and return an u_int32_t value. 
00042  * 
00043  * @param endianess value to read the byte as
00044  * @param bytes_to_grab how many bytes should we grab from the packet
00045  * @param data pointer to where to grab the data from
00046  * @param start pointer to start range of buffer
00047  * @param end pointer to end range of buffer
00048  * @param value pointer to store data in
00049  *
00050  * @returns 0 on success, otherwise failure
00051  */
00052 int byte_extract(int endianess, int bytes_to_grab, u_int8_t *ptr,
00053                  u_int8_t *start, u_int8_t *end,
00054                  u_int32_t *value)
00055 {
00056     if(endianess != LITTLE && endianess != BIG)
00057     {
00058         /* we only support 2 byte formats */
00059         return -2;
00060     }
00061 
00062     /* make sure the data to grab stays in bounds */
00063     if(!inBounds(start,end,ptr + (bytes_to_grab - 1)))
00064     {
00065         return -3;
00066     }
00067     
00068     if(!inBounds(start,end,ptr))
00069     {
00070         return -3;
00071     }        
00072 
00073     /*
00074      * We only support grabbing 1, 2, or 4 bytes of binary data.
00075      */
00076     switch(bytes_to_grab)
00077     {
00078     case 1:
00079         *value =  (*ptr) & 0xFF;
00080         break;
00081     case 2:
00082         if(endianess == LITTLE)
00083         {
00084             *value = (*ptr) & 0xFF;
00085             *value |= (*(ptr + 1) & 0xFF) << 8;
00086         }
00087         else
00088         {
00089             *value = ((*ptr) & 0xFF) << 8;
00090             *value |= (*(ptr + 1)) & 0xFF;
00091         }
00092         break;
00093     case 4:
00094         if(endianess == LITTLE)
00095         {
00096             *value = (*ptr) & 0xFF;
00097             *value |= ((*(ptr + 1)) & 0xFF) << 8;
00098             *value |= ((*(ptr + 2)) & 0xFF) << 16;
00099             *value |= ((*(ptr + 3)) & 0xFF) << 24;
00100         }
00101         else
00102         {
00103             *value =  ((*ptr) & 0xFF)       << 24;
00104             *value |= ((*(ptr + 1)) & 0xFF) << 16;
00105             *value |= ((*(ptr + 2)) & 0xFF) << 8;
00106             *value |= (*(ptr + 3)) & 0xFF;
00107         }
00108         break;
00109     default:
00110         /* unknown type */
00111         return -1;
00112     }
00113 
00114     return 0;
00115 }
00116 
00117 /** 
00118  * Grab a string representation of data from a buffer
00119  * 
00120  * @param base base representation for data: -> man stroul()
00121  * @param bytes_to_grab how many bytes should we grab from the packet
00122  * @param data pointer to where to grab the data from
00123  * @param start pointer to start range of buffer
00124  * @param end pointer to end range of buffer
00125  * @param value pointer to store data in
00126  *
00127  * @returns 0 on success, otherwise failure
00128  */
00129 int string_extract(int bytes_to_grab, int base, u_int8_t *ptr,
00130                    u_int8_t *start, u_int8_t *end,
00131                    u_int32_t *value)
00132 {
00133     char byte_array[TEXTLEN];
00134     char *parse_helper;
00135     int x; /* counter */
00136 
00137     if(bytes_to_grab > (TEXTLEN - 1) || bytes_to_grab <= 0)
00138     {
00139         return -1;
00140     }
00141 
00142     /* make sure the data to grab stays in bounds */
00143     if(!inBounds(start,end,ptr + (bytes_to_grab - 1)))
00144     {
00145         return -3;
00146     }
00147     
00148     if(!inBounds(start,end,ptr))
00149     {
00150         return -3;
00151     }        
00152 
00153     for(x=0;x<bytes_to_grab; x++)
00154     {
00155         byte_array[x] = *(ptr+x);
00156     }
00157 
00158     byte_array[bytes_to_grab] = '\0';
00159     
00160     *value = strtoul(byte_array, &parse_helper, base);
00161     
00162     if(byte_array == parse_helper)
00163     {
00164         return -1;
00165     }
00166 
00167 #ifdef TEST_BYTE_EXTRACT    
00168     printf("[----]\n");
00169     for(x=0;(x<=TEXTLEN) && (byte_array[x] != '\0');x++)
00170         printf("%c", byte_array[x]);
00171     printf("\n");
00172             
00173     printf("converted value: 0x%08X (%u) %s\n", *value, *value, (char *) byte_array);
00174 #endif /* TEST_BYTE_EXTRACT */    
00175     return 0;
00176 }
00177 
00178 
00179 #ifdef TEST_BYTE_EXTRACT
00180 #include <stdio.h>
00181 
00182 void test_extract(void)
00183 {
00184     int i;
00185     u_int32_t ret;
00186     
00187     u_int8_t value1[2];    
00188     u_int8_t value2[2];
00189     u_int8_t value3[4];
00190 
00191     value1[0] = 0;
00192     value1[1] = 0xff;
00193 
00194     value2[0] = 0xff;
00195     value2[1] = 0x01;
00196 
00197     value3[0] = 0xff;
00198     value3[1] = 0xff;
00199     value3[2] = 0x00;
00200     value3[3] = 0x00;
00201 
00202     if(byte_extract(BIG, 2, value1, value1, value1 + 2, &ret))
00203     {
00204         printf("test 1 failed\n");
00205     }
00206     else
00207     {
00208         printf("test 1: value: %x %u\n", ret, ret);
00209     }
00210 
00211     if(byte_extract(LITTLE, 2, value1, value1, value1 + 2, &ret))
00212     {
00213         printf("test 2 failed\n");
00214     }
00215     else
00216     {
00217         printf("test 2: value: %x %u\n", ret, ret);
00218     }
00219 
00220     
00221     if(byte_extract(LITTLE, 2, value1 + 2, value1, value1 + 2, &ret))
00222     {
00223         printf("test 3 failed correctly\n");
00224     }
00225     else
00226     {
00227         printf("test 3: value: %x %u\n", ret, ret);
00228     }
00229 
00230 
00231     if(byte_extract(BIG, 2, value2, value2, value2 + 2, &ret))
00232     {
00233         printf("test 1 failed\n");
00234     }
00235     else
00236     {
00237         printf("test 1: value: %x %u\n", ret, ret);
00238     }
00239 
00240     if(byte_extract(LITTLE, 2, value2, value2, value2 + 2, &ret))
00241     {
00242         printf("test 2 failed\n");
00243     }
00244     else
00245     {
00246         printf("test 2: value: %x %u\n", ret, ret);
00247     }
00248 
00249     
00250     if(byte_extract(LITTLE, 2, value2 + 2, value2, value2 + 2, &ret))
00251     {
00252         printf("test 3 failed correctly\n");
00253     }
00254     else
00255     {
00256         printf("test 3: value: %x %u\n", ret, ret);
00257     }
00258 
00259 
00260     if(byte_extract(BIG, 4, value3, value3, value3 + 4, &ret))
00261     {
00262         printf("test 1 failed\n");
00263     }
00264     else
00265     {
00266         printf("test 1: value: %x %u\n", ret, ret);
00267     }
00268 
00269     if(byte_extract(LITTLE, 4, value3, value3, value3 + 4, &ret))
00270     {
00271         printf("test 2 failed\n");
00272     }
00273     else
00274     {
00275         printf("test 2: value: %x %u\n", ret, ret);
00276     }
00277 
00278     
00279     if(byte_extract(LITTLE, 4, value3 + 2, value3, value3 + 4, &ret))
00280     {
00281         printf("test 3 failed correctly\n");
00282     }
00283     else
00284     {
00285         printf("test 3: value: %x %u\n", ret, ret);
00286     }
00287 
00288     printf("-----------------------------\n");
00289 
00290     for(i=0;i<10;i++)
00291     {
00292         if(byte_extract(LITTLE, 4, value3 + i, value3, value3 + 4, &ret))
00293         {
00294             printf("[loop] %d failed correctly\n", i);
00295         }
00296         else
00297         {         
00298             printf("[loop] value: %x %x\n", ret, *(u_int32_t *) &value3);
00299         }
00300     }
00301 }
00302 
00303 void test_string()
00304 {
00305     char *stringdata = "21212312412";
00306     int datalen = strlen(stringdata);
00307     u_int32_t ret;
00308     
00309     if(string_extract(4, 10, stringdata,  stringdata, stringdata + datalen,  &ret))
00310     {
00311         printf("TS1: Failed\n");
00312     }
00313     else
00314     {
00315         printf("TS1: value %x %u\n", ret, ret);
00316     }
00317 
00318     if(string_extract(10, 10, stringdata,  stringdata, stringdata + datalen,  &ret))
00319     {
00320         printf("TS2: Failed\n");
00321     }
00322     else
00323     {
00324         printf("TS2: value %x %u\n", ret, ret);
00325     }
00326 
00327     if(string_extract(9, 10, stringdata,  stringdata, stringdata + datalen,  &ret))
00328     {
00329         printf("TS3: Failed\n");
00330     }
00331     else
00332     {
00333         printf("TS3: value %x %u\n", ret, ret);
00334     }
00335 
00336     
00337     if(string_extract(19, 10, stringdata,  stringdata, stringdata + datalen,  &ret))
00338     {
00339         printf("TS4: Failed Normally\n");
00340     }
00341     else
00342     {
00343         printf("TS4: value %x %u\n", ret, ret);
00344     }
00345 
00346 }
00347 
00348 int main(void)
00349 {
00350     test_extract();
00351     test_string();
00352     return 0;
00353 }
00354 
00355 #endif /* TEST_BYTE_EXTRACT */

Generated on Sun May 14 14:51:12 2006 by  doxygen 1.4.2