/****************************************************************************
** File: packet_manip.c
**
** Author: Mike Borella
**
** Comments: Packet manipulation routines
**
** $Id: packet_manip.c,v 1.16 2001/10/09 23:20:42 mborella Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Library General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*****************************************************************************/
#include "packet_manip.h"
#include "hexbuffer.h"
extern struct arg_t *my_args;
/*----------------------------------------------------------------------------
**
** get_packet_bytesgeneral()
**
** Non API function, this is a generalization of get_packet_bytes() and
** get_packet_bytestoend().
**
** Mode 0 is get_packet_bytes()
** Mode 1 is get_packet_bytestoend()
**
** NOTE: This is NOT a safe function. The caller MUST allocate enough memory
** in the destination array.
**
** Returns 0 if operation fails and no write occurs. Returns 1 otherwise.
**----------------------------------------------------------------------------
*/
inline int get_packet_bytesgeneral(u_int8_t *dst, packet_t *p, unsigned int n,
int mode)
{
/*
* First make sure that we can read the bytes without running off the end
* of the packet.
*/
switch(mode)
{
case 0:
if (p->current + n > p->apparent_end + 1)
return 0;
break;
case 1:
if (p->current + n > p->end + 1)
return 0;
break;
default:
error_message("unknown mode for get_packet_bytesgeneral()");
return 0;
}
/*
* Do the copy
*/
memcpy(dst, p->current, n);
hexbuffer_add(p->current, n);
/*
* Increment the current pointer
*/
p->current += n;
/*
* Return successfully
*/
return 1;
}
/*----------------------------------------------------------------------------
**
** get_packet_bytes()
**
** Grab a specified number of bytes from a packet and deposit them in an array.
**
** NOTE: This is NOT a safe function. The caller MUST allocate enough memory
** in the destination array.
**
** Returns 0 if operation fails and no write occurs. Returns 1 otherwise.
**----------------------------------------------------------------------------
*/
inline int get_packet_bytes(u_int8_t *dst, packet_t *p, unsigned int n)
{
return get_packet_bytesgeneral(dst, p, n, 0);
}
/*----------------------------------------------------------------------------
**
** get_packet_bytestoend()
**
** Grab a specified number of bytes from a packet and deposit them in an array.
** Get bytes all the way to the real end of the packet, not the apparent end.
**
** NOTE: This is NOT a safe function. The caller MUST allocate enough memory
** in the destination array.
**
** Returns 0 if operation fails and no write occurs. Returns 1 otherwise.
**----------------------------------------------------------------------------
*/
inline int get_packet_bytestoend(u_int8_t *dst, packet_t *p, unsigned int n)
{
return get_packet_bytesgeneral(dst, p, n, 1);
}
/*----------------------------------------------------------------------------
**
** get_packet_line()
**
** Get a \n terminated line of text from the packet.
**
** NOTE: This is NOT a safe function. The caller MUST allocate enough memory
** in the destination array.
**
** Returns 0 if operation fails and no write occurs.
** Returns number of bytes read otherwise.
**----------------------------------------------------------------------------
*/
inline int get_packet_line(u_int8_t *dst, u_int32_t max, packet_t *p)
{
u_int8_t * ptr;
int ret;
/*
* Find the next \n
*/
ptr = p->current;
while (ptr < p->apparent_end && (ptr - p->current) < max - 1)
{
if (*ptr == '\n')
break;
ptr++;
}
/*
* If we reached the end, then there's no line to read, fail.
*/
if (ptr >= p->apparent_end)
return 0;
/*
* Do the copy (NOTE, we do not copy the \n)
* We add a \0 in the appropriate place.
*/
memcpy(dst, p->current, ptr - p->current);
dst[ptr - p->current] = '\0';
hexbuffer_add(p->current, ptr - p->current);
/*
* Increment the current pointer past the \n
*/
ret = ptr - p->current;
p->current += ret + 1;
/*
* Return successfully the length of the text, not including the \n
*/
return ret;
}
/*----------------------------------------------------------------------------
**
** get_packet_string()
**
** Get a \0 terminated string of text from the packet.
**
** NOTE: This is NOT a safe function. The caller MUST allocate enough memory
** in the destination array.
**
** Returns 0 if operation fails and no write occurs.
** Returns number of bytes read otherwise.
**----------------------------------------------------------------------------
*/
inline int get_packet_string(u_int8_t *dst, u_int32_t max, packet_t *p)
{
u_int8_t * ptr;
int ret;
/*
* Find the next \0
*/
ptr = p->current;
while (ptr < p->apparent_end && (ptr - p->current) < max - 1)
{
if (*ptr == '\0')
break;
ptr++;
}
/*
* If we reached the end, then there's no line to read, fail.
*/
if (ptr >= p->apparent_end)
return 0;
/*
* Do the copy (NOTE, we do not copy the \0)
* We add a \0 in the appropriate place.
*/
memcpy(dst, p->current, ptr - p->current);
dst[ptr - p->current] = '\0';
hexbuffer_add(p->current, ptr - p->current);
/*
* Increment the current pointer past the \0
*/
ret = ptr - p->current;
p->current += ret + 1;
/*
* Return successfully the length of the text
*/
return ret;
}
/*----------------------------------------------------------------------------
**
** look_packet_bytes()
**
** Copy specified number of bytes from a packet and deposit them in an array.
** Unlike get_packet_bytes(), we will not increment the pointer.
**
** NOTE: This is NOT a safe function. The caller MUST allocate enough memory
** in the destination array.
**
** Returns 0 if operation fails and no write occurs. Returns 1 otherwise.
**----------------------------------------------------------------------------
*/
inline int look_packet_bytes(u_int8_t *dst, packet_t *p, unsigned int n)
{
/*
* First make sure that we can read the bytes without running off the end
* of the packet.
*/
if (p->current + n > p->apparent_end + 1)
return 0;
/*
* Do the copy
*/
memcpy(dst, p->current, n);
/*
* Return successfully
*/
return 1;
}
/*----------------------------------------------------------------------------
**
** skip_packet_bytes()
**
** Jump the pointer ahead the specified number of bytes
**
** Returns 0 if operation fails and no write occurs. Returns 1 otherwise.
**----------------------------------------------------------------------------
*/
inline int skip_packet_bytes(packet_t *p, unsigned int n)
{
/*
* First make sure that we can read the bytes without running off the end
* of the packet.
*/
if (p->current + n > p->apparent_end + 1)
return 0;
/*
* Increment the current pointer
*/
p->current += n;
hexbuffer_add(p->current, n);
/*
* Return successfully
*/
return 1;
}
/*----------------------------------------------------------------------------
**
** skip_packet_toapparentend()
**
** Jump the pointer ahead the apparent end of the packet. Useful for
** jumping a padding section, if one exists.
**
** Returns 0 if operation fails and no write occurs. Returns 1 otherwise.
**----------------------------------------------------------------------------
*/
inline int skip_packet_toapparentend(packet_t *p)
{
if (p->current > p->apparent_end)
return 0;
/*
* Set the current pointer
*/
p->current = p->apparent_end;
/*
* Return successfully
*/
return 1;
}
/*----------------------------------------------------------------------------
**
** get_packet_apparentbytesleft()
**
** Returns the # of apparent bytes left to read off of the packet.
**
**----------------------------------------------------------------------------
*/
inline u_int32_t get_packet_apparentbytesleft(packet_t *pkt)
{
u_int32_t len;
len = pkt->apparent_end - pkt->current;
if (len < 0)
return 0;
else
return len;
}
/*----------------------------------------------------------------------------
**
** get_packet_bytesleft()
**
** Returns the # of bytes left to read off of the packet.
**
**----------------------------------------------------------------------------
*/
inline u_int32_t get_packet_bytesleft(packet_t *pkt)
{
u_int32_t len;
len = pkt->end - pkt->current;
if (len < 0)
return 0;
else
return len;
}
/*----------------------------------------------------------------------------
**
** packet_haspadding()
**
** Returns 1 if there are bytes between the apparent end and the real end,
** 0 otherwise
**
**----------------------------------------------------------------------------
*/
inline int packet_haspadding(packet_t *pkt)
{
u_int32_t len;
len = pkt->end - pkt->apparent_end;
if (len <= 0)
return 0;
else
return 1;
}
/*----------------------------------------------------------------------------
**
** set_packet_mark()
**
** Mark the current byte of the packet
**
**----------------------------------------------------------------------------
*/
inline void set_packet_mark(packet_t *pkt)
{
pkt->mark = pkt->current;
}
/*----------------------------------------------------------------------------
**
** get_packet_markdistance()
**
** Get the distance between the current pointer and the mark
**
**----------------------------------------------------------------------------
*/
inline int32_t get_packet_markdistance(packet_t *pkt)
{
/*
* Sanity check the mark first
*/
if (pkt->mark < pkt->contents || pkt->mark > pkt->apparent_end)
return -1;
return pkt->current - pkt->mark;
}
/*----------------------------------------------------------------------------
**
** set_packet_apparentend()
**
** Set the apparent end of the packet to be the given number of bytes beyond
** the current pointer.
**
**----------------------------------------------------------------------------
*/
inline void set_packet_apparentend(packet_t * pkt, int n)
{
/* make sure we're not running off the packet */
if (pkt->current + n >= pkt->apparent_end)
return;
pkt->apparent_end = pkt->current + n;
}
syntax highlighted by Code2HTML, v. 0.9.1