copy from intranet.

This commit is contained in:
lijia
2019-07-10 17:54:02 +08:00
commit f36a4fca25
353 changed files with 130721 additions and 0 deletions

472
src/MESA_list.c Normal file
View File

@@ -0,0 +1,472 @@
#include <linux/types.h>
#include <linux/stddef.h>
#include <assert.h>
#include "MESA_list.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*************************** <20>ڲ<EFBFBD>ʵ<EFBFBD>ֽӿ<D6BD> ********************************/
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
static void INIT_LIST_HEAD(struct list_index *head)
{
head->nextele = head;
head->preele = head;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_index *new_list,
struct list_index *prev,
struct list_index *next)
{
next->preele = new_list;
new_list->nextele = next;
new_list->preele = prev;
prev->nextele = new_list;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
* lijia comment: list_add()<29><><EFBFBD>½ڵ<C2BD><DAB5><EFBFBD><EFBFBD><EFBFBD>head<61><64>head->next֮<74><D6AE>.
*/
void list_add(struct list_index *new_list, struct list_index *head)
{
__list_add(new_list, head, head->nextele);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
* lijia comment: list_add_tail()<29><><EFBFBD>½ڵ<C2BD><DAB5><EFBFBD><EFBFBD><EFBFBD>head<61><64>head->prev֮<76><D6AE>.
*/
void list_add_tail(struct list_index *new_list, struct list_index *head)
{
__list_add(new_list, head->preele, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_index * prev, struct list_index * next)
{
next->preele = prev;
prev->nextele = next;
}
static inline void __list_del_entry(struct list_index *entry)
{
__list_del(entry->preele, entry->nextele);
entry->nextele = NULL;
entry->preele = NULL;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static void list_del(struct list_index *entry)
{
__list_del(entry->preele, entry->nextele);
entry->nextele = NULL;
entry->preele = NULL;
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static void list_move(struct list_index *list, struct list_index *head)
{
__list_del_entry(list);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static void list_move_tail(struct list_index *list, struct list_index *head)
{
__list_del_entry(list);
list_add_tail(list, head);
}
#if 0
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static int list_empty(const struct list_index *head)
{
return head->nextele == head;
}
#endif
/**
* list_empty_careful - tests whether a list is empty and not being modified
* @head: the list to test
*
* Description:
* tests whether a list is empty _and_ checks that no other CPU might be
* in the process of modifying either member (next or prev)
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*/
static int list_empty_careful(const struct list_index *head)
{
MESA_queue_head_t *next = head->nextele;
return (next == head) && (next == head->preele);
}
static inline void list_count_init(void **list_count)
{
long *p_c = (long *)list_count;
*p_c = 0;
}
static inline void list_count_inc(void **list_count)
{
long *p_c = (long *)list_count;
long c = *p_c;
*p_c = c + 1;
}
static inline void list_count_dec(void **list_count)
{
long *p_c = (long *)list_count;
long c = *p_c;
*p_c = c - 1;
}
#if MESA_LIST_CHECK != 0
/*Function:Check the intergrity of the list,to dectect memory mess.
*Input: Queue Head,data check call back function
*Output: return a number below zero,if the queue got a problem,else return 0;
*Author:zhengchao@iie.ac.cn at 20100913
*/
#if 0
static int MESA_q_list_check(const MESA_queue_head_t *qhead_obj,int(*quiddity_check)(const void *))
{
MESA_list_index_t *p=NULL, *head=NULL;
// int linked_ele_number=0;
int ret=0;
// return 0;
if(qhead_obj->listcount==0)
{
if(qhead_obj->head!=NULL||qhead_obj->head!=NULL)
{
ret=-1;
}
goto exit;
}
if(qhead_obj->head==NULL||qhead_obj->tail==NULL)
{
ret=-2;
goto exit;
}
if(qhead_obj->listcount>1){
if(qhead_obj->head->preele!=NULL||qhead_obj->head->nextele==NULL)
{
ret=-3;
goto exit;
}
if(qhead_obj->tail->preele==NULL||qhead_obj->tail->nextele!=NULL)
{
ret=-4;
goto exit;
}
head = p = qhead_obj->head;
p = p->nextele;
while(p != head)
{
if(p == NULL) break;
if(p == head){
ret = -5; /* has a cycle */
goto exit;
}
p = p->nextele;
}
}
/*
pre=qhead_obj->head;
p=pre->nextele;
while(p!=NULL){
linked_ele_number++;
//Is the declared size equal to element linked number;
if(linked_ele_number > qhead_obj->listcount)
{
ret=-5;
goto exit;
}
//Is element's preele pointer equal to its preele
if(pre!=p->preele)
{
ret=-6;
goto exit;
}
if(quiddity_check!=NULL){
if(0>quiddity_check(p->quiddity))
{
ret =-7;
goto exit;
}
}
pre=p;
p=p->nextele;
}
//Is the last element equal to tail
if(pre!=qhead_obj->tail)
{
ret=-8;
goto exit;
}
if(linked_ele_number !=qhead_obj->listcount-1)
{
ret=-9;
goto exit;
}
*/
exit:
if(ret<0)
{
return ret;
}
else
{
return 1;
}
}
#endif
#if 2==MESA_LIST_CHECK
/*Simple check,not raversal*/
static int MESA_q_is_item_in_list(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj){
// MESA_list_index_t* pre=lindex_obj->preele;
// MESA_list_index_t*next=lindex_obj->nextele;
MESA_list_index_t*p=NULL;
int i, num;
if(list_empty_careful(qhead_obj)){
return 0;
}
p = qhead_obj->nextele;
num = MESA_get_list_count(qhead_obj);
i = 0;
while((p != qhead_obj) && (i <= num))
{
if(p == lindex_obj)
{
return 1;
}
p=p->nextele;
i++;
}
return 0;
}
#endif
/*every MESA_list_index_t leaves list,its pre and next will be set NULL
* In Configuration Transmiiter project, not null element will consider in list,
* pre and next is NULL only if there's one element in list only*/
static int MESA_q_is_item_in_list_quick(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
//empty list
if(list_empty_careful(qhead_obj)){
return 0;
}
//have more element
if(lindex_obj->nextele==NULL || lindex_obj->preele==NULL){
return 0;
}
if(lindex_obj->nextele->preele != lindex_obj){
return 0;
}
if(lindex_obj->preele->nextele != lindex_obj){
return 0;
}
return 1;
}
#endif
/*************************** <20>ⲿ<EFBFBD><E2B2BF><EFBFBD>ýӿ<C3BD> ********************************/
/*
<20><>һ<EFBFBD><D2BB>ʹ<EFBFBD><CAB9>MESA_listģ<74><C4A3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô˳<C3B4>ʼ<EFBFBD><CABC>ģ<EFBFBD><C4A3>.
*/
int MESA_list_init(MESA_queue_head_t *head)
{
INIT_LIST_HEAD(head);
list_count_init(&head->quiddity);
return 0;
}
/* <20><>Ϊheadʹ<64><CAB9>ʱ, "quiddity"<22><>Ϊһ<CEAA><D2BB>long<6E>ͱ<EFBFBD><CDB1><EFBFBD>,<2C><><EFBFBD>ڴ洢<DAB4><E6B4A2><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
long MESA_get_list_count(const MESA_queue_head_t *head)
{
return (long)head->quiddity;
}
MESA_list_index_t *MESA_q_read_head(const MESA_queue_head_t *qhead_obj)
{
if(list_empty_careful(qhead_obj)){
return NULL;
}
return qhead_obj->nextele;
}
MESA_list_index_t *MESA_q_get_head(MESA_queue_head_t *qhead_obj)
{
MESA_list_index_t *out;
if(list_empty_careful(qhead_obj)){
return NULL;
}
out = qhead_obj->nextele;
list_del(out);
list_count_dec(&qhead_obj->quiddity);
return out;
}
MESA_list_index_t *MESA_q_get_tail(MESA_queue_head_t *qhead_obj)
{
MESA_list_index_t *out;
if(list_empty_careful(qhead_obj)){
return NULL;
}
out = qhead_obj->preele;
list_del(out);
list_count_dec(&qhead_obj->quiddity);
return out;
}
MESA_list_index_t *MESA_q_join_tail(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
list_add_tail(lindex_obj, qhead_obj);
list_count_inc(&qhead_obj->quiddity);
return lindex_obj;
}
MESA_list_index_t *MESA_q_join_head(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
list_add(lindex_obj, qhead_obj);
list_count_inc(&qhead_obj->quiddity);
return lindex_obj;
}
MESA_list_index_t *MESA_q_leave_list(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
#if 1==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list_quick(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#elif 2==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#endif
list_del(lindex_obj);
list_count_dec(&qhead_obj->quiddity);
return lindex_obj;
}
MESA_list_index_t *MESA_q_move_head(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
#if 1==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list_quick(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#elif 2==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#endif
list_move(lindex_obj, qhead_obj);
return lindex_obj;
}
MESA_list_index_t *MESA_q_move_tail(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
#if 1==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list_quick(qhead_obj,lindex_obj)){
//return NULL;
assert(0); //critical
}
#elif 2==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#endif
list_move_tail(lindex_obj, qhead_obj);
return lindex_obj;
}
#ifdef __cplusplus
}
#endif

68
src/MESA_list.h Normal file
View File

@@ -0,0 +1,68 @@
#ifndef _MESA_LIST_NEW_H_
#define _MESA_LIST_NEW_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define MESA_LIST_CHECK (1) /* 0:no check; 1:quick check; 2:careful check */
typedef struct list_index {
struct list_index *nextele;
struct list_index *preele;
unsigned char *quiddity;
int pktlen;
}MESA_list_index_t;
typedef struct list_index MESA_queue_head_t;
/* MESA_fixed_queue implement */
typedef struct fixed_qelem{
void *data;
long datalen;
}MESA_fixed_qelem_t;
typedef struct list_index MESA_fixed_q_t;
/*
<20><>һ<EFBFBD><D2BB>ʹ<EFBFBD><CAB9>MESA_fixed_qģ<71><C4A3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô˳<C3B4>ʼ<EFBFBD><CABC>ģ<EFBFBD><C4A3>!!!
*/
int MESA_fixed_q_init(MESA_fixed_q_t *head, long total_elem_num, long max_elem_len);
void MESA_fixed_q_destroy(MESA_fixed_q_t *__head);
long MESA_fixed_q_count(const MESA_fixed_q_t *head);
MESA_fixed_qelem_t *MESA_fixed_q_read_head(MESA_fixed_q_t *head);
MESA_fixed_qelem_t *MESA_fixed_q_get_head(MESA_fixed_q_t *head);
/* In MESA_fixed_queue module, the memory of "data" can not be allocated by malloc, stack memory is alright! */
MESA_fixed_qelem_t *MESA_fixed_q_join_tail(MESA_fixed_q_t *head, void *data, long datalen);
/*
<20><>һ<EFBFBD><D2BB>ʹ<EFBFBD><CAB9>MESA_listģ<74><C4A3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô˳<C3B4>ʼ<EFBFBD><CABC>ģ<EFBFBD><C4A3>!!!
*/
int MESA_list_init(MESA_queue_head_t *head);
long MESA_get_list_count(const MESA_queue_head_t *head);
MESA_list_index_t *MESA_q_read_head(const MESA_queue_head_t *qhead_obj);
MESA_list_index_t *MESA_q_get_head(MESA_queue_head_t *qhead_obj);
MESA_list_index_t *MESA_q_get_tail(MESA_queue_head_t *qhead_obj);
MESA_list_index_t *MESA_q_join_tail(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_join_head(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_leave_list(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_move_head(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_move_tail(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
#if 0 /* do do, <20><>δʵ<CEB4><CAB5> */
MESA_list_index_t *MESA_q_join_list_n(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lobj_next, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_join_list_p(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lobj_pre, MESA_list_index_t *lindex_obj);
#endif
#ifdef __cplusplus
}
#endif
#endif

122
src/Makefile.am Normal file
View File

@@ -0,0 +1,122 @@
# $Id: Makefile.am 1632 2007-02-03 18:46:16Z aturner $
if COMPILE_FRAGROUTE
LIBFRAGROUTE = ./fragroute/libfragroute.a @LDNETLIB@
FRAGROUTE_DIR = fragroute
else
LIBFRAGROUTE =
FRAGROUTE_DIR =
endif
SUBDIRS = common tcpedit $(FRAGROUTE_DIR)
if SYSTEM_STRLCPY
LIBSTRL =
else
LIBSTRL = ../lib/libstrl.a
endif
manpages: tcpprep.1 tcprewrite.1 tcpreplay.1 tcpbridge.1 tcpreplay-edit.1
autoopts: tcpreplay_opts.c tcprewrite_opts.c tcpbridge_opts.c manpages \
tcpreplay_edit_opts.c
# Get AutoOpts search path
opts_list=-L tcpedit
tcpprep.1: tcpprep_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) --base-name tcpprep tcpprep_opts.def
tcprewrite.1: tcprewrite_opts.def tcpedit/tcpedit_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) --base-name tcprewrite tcprewrite_opts.def
tcpreplay-edit.1: tcpreplay_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) -DTCPREPLAY_EDIT --base-name tcpreplay-edit tcpreplay_opts.def
tcpreplay.1: tcpreplay_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) --base-name tcpreplay tcpreplay_opts.def
tcpbridge.1: tcpbridge_opts.def tcpedit/tcpedit_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) --base-name tcpbridge tcpbridge_opts.def
man_MANS = tcpreplay.1 tcpprep.1 tcprewrite.1 tcpreplay-edit.1
EXTRA_DIST = tcpreplay.1 tcpprep.1 tcprewrite.1 tcpbridge.1 tcpreplay-edit.1
bin_PROGRAMS = tcpreplay tcpprep tcprewrite tcpreplay-edit
if COMPILE_TCPBRIDGE
bin_PROGRAMS += tcpbridge
man_MANS += tcpbridge.1
endif
tcpreplay_edit_CFLAGS = $(LIBOPTS_CFLAGS) -I.. $(LNAV_CFLAGS) @LDNETINC@ -DTCPREPLAY -DTCPREPLAY_EDIT -DHAVE_CACHEFILE_SUPPORT
tcpreplay_edit_LDADD = ./tcpedit/libtcpedit.a ./common/libcommon.a ./suppport_lib/libMESA_prof_load.a $(LIBSTRL) @LPCAPLIB@ @LDNETLIB@ $(LIBOPTS_LDADD)
tcpreplay_edit_SOURCES = tcpreplay_edit_opts.c send_packets.c signal_handler.c tcpreplay.c sleep.c
tcpreplay_edit_OBJECTS: tcpreplay_opts.h
tcpreplay_edit_opts.h: tcpreplay_edit_opts.c
tcpreplay_edit_opts.c: tcpreplay_opts.def
@AUTOGEN@ $(opts_list) -DTCPREPLAY_EDIT -b tcpreplay_edit_opts \
tcpreplay_opts.def
tcpreplay_CFLAGS = $(LIBOPTS_CFLAGS) -I.. $(LNAV_CFLAGS) @LDNETINC@ -DTCPREPLAY
tcpreplay_SOURCES = tcpreplay_opts.c send_packets.c signal_handler.c tcpreplay.c sleep.c
tcpreplay_LDADD = ./common/libcommon.a ./suppport_lib/libMESA_prof_load.a $(LIBSTRL) @LPCAPLIB@ @LDNETLIB@ $(LIBOPTS_LDADD)
tcpreplay_OBJECTS: tcpreplay_opts.h
tcpreplay_opts.h: tcpreplay_opts.c
tcpreplay_opts.c: tcpreplay_opts.def
@AUTOGEN@ $(opts_list) tcpreplay_opts.def
if ENABLE_OSX_FRAMEWORKS
tcpreplay_LDFLAGS = -framework CoreServices -framework Carbon
tcpreplay_edit_LDFLAGS = -framework CoreServices -framework Carbon
endif
tcprewrite_CFLAGS = $(LIBOPTS_CFLAGS) -I.. @LDNETINC@ $(LNAV_CFLAGS) -DTCPREWRITE -DHAVE_CACHEFILE_SUPPORT
tcprewrite_LDADD = ./tcpedit/libtcpedit.a ./common/libcommon.a ./suppport_lib/libMESA_prof_load.a \
$(LIBSTRL) @LPCAPLIB@ $(LIBOPTS_LDADD) @DMALLOC_LIB@ \
$(LIBFRAGROUTE)
tcprewrite_SOURCES = tcprewrite_opts.c tcprewrite.c
tcprewrite_OBJECTS: tcprewrite_opts.h
tcprewrite_opts.h: tcprewrite_opts.c
tcprewrite_opts.c: tcprewrite_opts.def tcpedit/tcpedit_opts.def
@AUTOGEN@ $(opts_list) tcprewrite_opts.def
tcpprep_CFLAGS = $(LIBOPTS_CFLAGS) -I.. $(LNAV_CFLAGS) @LDNETINC@ -DTCPPREP
tcpprep_LDADD = ./common/libcommon.a suppport_lib/libMESA_prof_load.a \
$(LIBSTRL) @LPCAPLIB@ $(LIBOPTS_LDADD) @DMALLOC_LIB@
tcpprep_SOURCES = tcpprep_opts.c tcpprep.c tree.c
tcpprep_OBJECTS: tcpprep_opts.h
tcpprep_opts.h: tcpprep_opts.c
tcpprep_opts.c: tcpprep_opts.def
@AUTOGEN@ tcpprep_opts.def
tcpbridge_CFLAGS = $(LIBOPTS_CFLAGS) -I.. $(LNAV_CFLAGS) @LDNETINC@ -DTCPBRIDGE
tcpbridge_LDADD = ./tcpedit/libtcpedit.a ./common/libcommon.a suppport_lib/libMESA_prof_load.a \
$(LIBSTRL) @LPCAPLIB@ @LDNETLIB@ $(LIBOPTS_LDADD) @DMALLOC_LIB@
if ENABLE_OSX_FRAMEWORKS
tcpbridge_LDFLAGS = -framework CoreServices -framework Carbon
endif
tcpbridge_SOURCES = tcpbridge_opts.c tcpbridge.c bridge.c send_packets.c sleep.c
tcpbridge_OBJECTS: tcpbridge_opts.h
tcpbridge_opts.h: tcpbridge_opts.c
tcpbridge_opts.c: tcpbridge_opts.def tcpedit/tcpedit_opts.def
@AUTOGEN@ $(opts_list) tcpbridge_opts.def
noinst_HEADERS = tcpreplay.h tcpprep.h bridge.h defines.h tree.h \
send_packets.h signal_handler.h common.h tcpreplay_opts.h \
tcpreplay_edit_opts.h tcprewrite.h tcprewrite_opts.h tcpprep_opts.h \
tcpprep_opts.def tcprewrite_opts.def tcpreplay_opts.def \
tcpbridge_opts.def tcpbridge.h tcpbridge_opts.h tcpr.h sleep.h
MOSTLYCLEANFILES = *~ *.o
MAINTAINERCLEANFILES = Makefile.in tcpreplay_opts.h tcpreplay_opts.c \
tcprewrite_opts.c tcprewrite_opts.h tcpprep_opts.c \
tcpprep_opts.h tcpprep.1 tcpreplay.1 tcprewrite.1 \
tcpbridge.1 tcpbridge_opts.h tcpbridge_opts.c \
tcpreplay_edit_opts.c tcpreplay_edit_opts.h \
tcpreplay-edit.1

1258
src/Makefile.in Normal file

File diff suppressed because it is too large Load Diff

518
src/bridge.c Normal file
View File

@@ -0,0 +1,518 @@
/* $Id: bridge.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <sys/time.h>
#include <signal.h>
#include <string.h>
#include <netinet/in.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
#ifdef HAVE_BPF
#include <sys/select.h> /* necessary for using select() for BPF devices */
#endif
#include "tcpbridge.h"
#include "bridge.h"
#include "send_packets.h"
#include "tcpedit/tcpedit.h"
extern tcpbridge_opt_t options;
extern struct timeval begin, end;
extern COUNTER bytes_sent, failed, pkts_sent;
extern volatile int didsig;
#ifdef DEBUG
extern int debug;
#endif
static int live_callback(struct live_data_t *,
struct pcap_pkthdr *, const u_char *);
/**
* First, prep our RB Tree which tracks where each (source)
* MAC really lives so we don't create really nasty network
* storms.
*/
static struct macsrc_t *new_node(void);
RB_HEAD(macsrc_tree, macsrc_t) macsrc_root;
static int
rbmacsrc_comp(struct macsrc_t *a, struct macsrc_t *b)
{
return (memcmp(a->key, b->key, ETHER_ADDR_LEN));
}
RB_PROTOTYPE(macsrc_tree, macsrc_t, node, rbmacsrc_comp)
RB_GENERATE(macsrc_tree, macsrc_t, node, rbmacsrc_comp)
/**
* redblack init
*/
void
rbinit(void)
{
RB_INIT(&macsrc_root);
}
/**
* create a new node... Malloc's memory
*/
struct macsrc_t *
new_node(void)
{
struct macsrc_t *node;
node = (struct macsrc_t *)safe_malloc(sizeof(struct macsrc_t));
memset(node, '\0', sizeof(struct macsrc_t));
return (node);
}
/**
* main loop for bridging in only one direction
* optimized to not use poll(), but rather libpcap's builtin pcap_loop()
*/
static void
do_bridge_unidirectional(tcpbridge_opt_t *options, tcpedit_t *tcpedit)
{
struct live_data_t livedata;
int retcode;
assert(options);
assert(tcpedit);
livedata.tcpedit = tcpedit;
livedata.source = PCAP_INT1;
livedata.pcap = options->pcap1;
livedata.options = options;
if ((retcode = pcap_loop(options->pcap1, options->limit_send,
(pcap_handler)live_callback, (u_char *) &livedata)) < 0) {
warnx("Error in pcap_loop(): %s", pcap_geterr(options->pcap1));
}
}
#ifndef HAVE_BPF
/**
* main loop for bridging in both directions. Since we dealing with two handles
* we need to poll() on them which isn't the most efficent.
*
* Note that this function is only used on systems which do not have a BPF
* device because poll() behaves poorly with /dev/bpf
*/
static void
do_bridge_bidirectional(tcpbridge_opt_t *options, tcpedit_t *tcpedit)
{
struct pollfd polls[2]; /* one for left & right pcap */
int pollresult, pollcount, timeout;
struct live_data_t livedata;
assert(options);
assert(tcpedit);
livedata.tcpedit = tcpedit;
livedata.options = options;
/*
* loop until ctrl-C or we've sent enough packets
* note that if -L wasn't specified, limit_send is
* set to 0 so this will loop infinately
*/
while ((options->limit_send == 0) || (options->limit_send > pkts_sent)) {
if (didsig)
break;
dbgx(3, "limit_send: " COUNTER_SPEC " \t pkts_sent: " COUNTER_SPEC,
options->limit_send, pkts_sent);
/* reset the result codes */
polls[PCAP_INT1].revents = 0;
polls[PCAP_INT1].events = POLLIN;
polls[PCAP_INT1].fd = pcap_fileno(options->pcap1);
polls[PCAP_INT2].revents = 0;
polls[PCAP_INT2].events = POLLIN;
polls[PCAP_INT2].fd = pcap_fileno(options->pcap2);
timeout = options->poll_timeout;
pollcount = 2;
/* poll for a packet on the two interfaces */
pollresult = poll(polls, pollcount, timeout);
/* poll has returned, process the result */
if (pollresult > 0) {
dbgx(3, "pollresult: %d", pollresult);
/* success, got one or more packets */
if (polls[PCAP_INT1].revents > 0) {
dbg(5, "Processing first interface");
livedata.source = PCAP_INT1;
livedata.pcap = options->pcap1;
pcap_dispatch(options->pcap1, -1, (pcap_handler) live_callback,
(u_char *) &livedata);
}
/* check the other interface?? */
if (polls[PCAP_INT2].revents > 0) {
dbg(5, "Processing second interface");
livedata.source = PCAP_INT2;
livedata.pcap = options->pcap2;
pcap_dispatch(options->pcap2, -1, (pcap_handler) live_callback,
(u_char *) &livedata);
}
}
else if (pollresult == 0) {
dbg(3, "poll timeout exceeded...");
/* do something here? */
}
else {
/* poll error, probably a Ctrl-C */
warnx("poll() error: %s", strerror(errno));
}
/* go back to the top of the loop */
}
} /* do_bridge_bidirectional() */
#elif defined HAVE_BPF && defined HAVE_PCAP_SETNONBLOCK
/**
* main loop for bridging in both directions with BPF. We'll be using
* select() because that works better on older *BSD and OSX
*
* See this for details behind this maddness:
* http://article.gmane.org/gmane.network.tcpdump.devel/3581
*/
static void
do_bridge_bidirectional(tcpbridge_opt_t *options, tcpedit_t *tcpedit)
{
fd_set readfds, writefds, errorfds;
struct live_data_t livedata;
int fd, nfds, ret;
struct timeval timeout = { 0, 100 }; /* default to 100ms timeout */
char ebuf[PCAP_ERRBUF_SIZE];
assert(options);
assert(tcpedit);
livedata.tcpedit = tcpedit;
livedata.options = options;
/*
* loop until ctrl-C or we've sent enough packets
* note that if -L wasn't specified, limit_send is
* set to 0 so this will loop infinately
*/
while ((options->limit_send == 0) || (options->limit_send > pkts_sent)) {
if (didsig)
break;
dbgx(3, "limit_send: " COUNTER_SPEC " \t pkts_sent: " COUNTER_SPEC,
options->limit_send, pkts_sent);
/* reset the result codes */
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&errorfds);
/* set for reading */
#ifdef HAVE_PCAP_GET_SELECTABLE_FD
fd = pcap_get_selectable_fd(options->pcap1);
#else
fd = pcap_fileno(options->pcap1);
#endif
if ((pcap_setnonblock(options->pcap1, 1, ebuf)) < 0)
errx(1, "Unable to set %s into nonblocking mode: %s", options->intf1, ebuf);
FD_SET(fd, &readfds);
#ifdef HAVE_PCAP_GET_SELECTABLE_FD
fd = pcap_get_selectable_fd(options->pcap2);
#else
fd = pcap_fileno(options->pcap2);
#endif
if ((pcap_setnonblock(options->pcap2, 1, ebuf)) < 0)
errx(1, "Unable to set %s into nonblocking mode: %s", options->intf2, ebuf);
FD_SET(fd, &readfds);
nfds = 2;
/* wait for a packet on the two interfaces */
ret = select(nfds, &readfds, &writefds, &errorfds, &timeout);
/*
* There is a problem with OS X and certian *BSD's when using
* select() on a character device like /dev/bpf. Hence we always
* must attempt to read off each fd after the timeout. This is why
* we put the fd's in nonblocking mode above!
*/
dbg(5, "Processing first interface");
livedata.source = PCAP_INT1;
livedata.pcap = options->pcap1;
pcap_dispatch(options->pcap1, -1, (pcap_handler) live_callback,
(u_char *) &livedata);
dbg(5, "Processing second interface");
livedata.source = PCAP_INT2;
livedata.pcap = options->pcap2;
pcap_dispatch(options->pcap2, -1, (pcap_handler) live_callback,
(u_char *) &livedata);
/* go back to the top of the loop */
}
}
#else
#error "Your system needs a libpcap with pcap_setnonblock(). Please upgrade libpcap."
#endif
/**
* Main entry point to bridging. Does some initial setup and then calls the
* correct loop (unidirectional or bidirectional)
*/
void
do_bridge(tcpbridge_opt_t *options, tcpedit_t *tcpedit)
{
/* do we apply a bpf filter? */
if (options->bpf.filter != NULL) {
/* compile filter */
dbgx(2, "Try to compile pcap bpf filter: %s", options->bpf.filter);
if (pcap_compile(options->pcap1, &options->bpf.program, options->bpf.filter, options->bpf.optimize, 0) != 0) {
errx(-1, "Error compiling BPF filter: %s", pcap_geterr(options->pcap1));
}
/* apply filter */
pcap_setfilter(options->pcap1, &options->bpf.program);
/* same for other interface if applicable */
if (options->unidir == 0) {
/* compile filter */
dbgx(2, "Try to compile pcap bpf filter: %s", options->bpf.filter);
if (pcap_compile(options->pcap2, &options->bpf.program, options->bpf.filter, options->bpf.optimize, 0) != 0) {
errx(-1, "Error compiling BPF filter: %s", pcap_geterr(options->pcap2));
}
/* apply filter */
pcap_setfilter(options->pcap2, &options->bpf.program);
}
}
/* register signals */
didsig = 0;
(void)signal(SIGINT, catcher);
if (options->unidir == 1) {
do_bridge_unidirectional(options, tcpedit);
} else {
do_bridge_bidirectional(options, tcpedit);
}
packet_stats(&begin, &end, bytes_sent, pkts_sent, failed);
}
/**
* This is the callback we use with pcap_dispatch to process
* each packet recieved by libpcap on the two interfaces.
* Need to return > 0 to denote success
*/
static int
live_callback(struct live_data_t *livedata, struct pcap_pkthdr *pkthdr,
const u_char * nextpkt)
{
ipv4_hdr_t *ip_hdr = NULL;
ipv6_hdr_t *ip6_hdr = NULL;
pcap_t *send = NULL;
static u_char *pktdata = NULL; /* full packet buffer */
int cache_mode, retcode;
static unsigned long packetnum = 0;
struct macsrc_t *node, finder; /* rb tree nodes */
#ifdef DEBUG
u_char dstmac[ETHER_ADDR_LEN];
#endif
u_int16_t l2proto;
packetnum++;
dbgx(2, "packet %lu caplen %d", packetnum, pkthdr->caplen);
/* only malloc the first time */
if (pktdata == NULL) {
/* create packet buffers */
pktdata = (u_char *)safe_malloc(MAXPACKET);
} else {
/* zero out the old packet info */
memset(pktdata, '\0', MAXPACKET);
}
/* copy the packet to our buffer */
memcpy(pktdata, nextpkt, pkthdr->caplen);
#ifdef ENABLE_VERBOSE
/* decode packet? */
if (livedata->options->verbose)
tcpdump_print(livedata->options->tcpdump, pkthdr, nextpkt);
#endif
/* lookup our source MAC in the tree */
memcpy(&finder.key, &pktdata[ETHER_ADDR_LEN], ETHER_ADDR_LEN);
#ifdef DEBUG
memcpy(&dstmac, pktdata, ETHER_ADDR_LEN);
dbgx(1, "SRC MAC: " MAC_FORMAT "\tDST MAC: " MAC_FORMAT,
MAC_STR(finder.key), MAC_STR(dstmac));
#endif
/* first, is this a packet sent locally? If so, ignore it */
if ((memcmp(livedata->options->intf1_mac, &finder.key, ETHER_ADDR_LEN)) == 0) {
dbgx(1, "Packet matches the MAC of %s, skipping.", livedata->options->intf1);
return (1);
}
else if ((memcmp(livedata->options->intf2_mac, &finder.key, ETHER_ADDR_LEN)) == 0) {
dbgx(1, "Packet matches the MAC of %s, skipping.", livedata->options->intf2);
return (1);
}
node = RB_FIND(macsrc_tree, &macsrc_root, &finder);
/* if we can't find the node, build a new one */
if (node == NULL) {
dbg(1, "Unable to find MAC in the tree");
node = new_node();
node->source = livedata->source;
memcpy(&node->key, &finder.key, ETHER_ADDR_LEN);
RB_INSERT(macsrc_tree, &macsrc_root, node);
}
/* otherwise compare sources */
else if (node->source != livedata->source) {
dbg(1, "Found the dest MAC in the tree and it doesn't match this source NIC... skipping packet");
/*
* IMPORTANT!!!
* Never send a packet out the same interface we sourced it on!
*/
return (1);
}
/* what is our cache mode? */
cache_mode = livedata->source == PCAP_INT1 ? TCPR_DIR_C2S : TCPR_DIR_S2C;
l2proto = tcpedit_l3proto(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);
dbgx(2, "Packet protocol: %04hx", l2proto);
/* should we skip this packet based on CIDR match? */
if (l2proto == ETHERTYPE_IP) {
dbg(3, "Packet is IPv4");
ip_hdr = (ipv4_hdr_t *)tcpedit_l3data(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);
/* look for include or exclude CIDR match */
if (livedata->options->xX.cidr != NULL) {
if (!process_xX_by_cidr_ipv4(livedata->options->xX.mode, livedata->options->xX.cidr, ip_hdr)) {
dbg(2, "Skipping IPv4 packet due to CIDR match");
return (1);
}
}
}
else if (l2proto == ETHERTYPE_IP6) {
dbg(3, "Packet is IPv6");
ip6_hdr = (ipv6_hdr_t *)tcpedit_l3data(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);
/* look for include or exclude CIDR match */
if (livedata->options->xX.cidr != NULL) {
if (!process_xX_by_cidr_ipv6(livedata->options->xX.mode, livedata->options->xX.cidr, ip6_hdr)) {
dbg(2, "Skipping IPv6 packet due to CIDR match");
return (1);
}
}
}
if ((retcode = tcpedit_packet(livedata->tcpedit, &pkthdr, &pktdata, cache_mode)) < 0) {
if (retcode == TCPEDIT_SOFT_ERROR) {
return 1;
} else { /* TCPEDIT_ERROR */
return -1;
}
}
/*
* send packets out the OTHER interface
* and update the dst mac if necessary
*/
switch(node->source) {
case PCAP_INT1:
dbgx(2, "Packet source was %s... sending out on %s", livedata->options->intf1,
livedata->options->intf2);
send = livedata->options->pcap2;
break;
case PCAP_INT2:
dbgx(2, "Packet source was %s... sending out on %s", livedata->options->intf2,
livedata->options->intf1);
send = livedata->options->pcap1;
break;
default:
errx(-1, "wtf? our node->source != PCAP_INT1 and != PCAP_INT2: %c",
node->source);
}
/*
* write packet out on the network
*/
if (pcap_sendpacket(send, pktdata, pkthdr->caplen) < 0)
errx(-1, "Unable to send packet out %s: %s",
send == livedata->options->pcap1 ? livedata->options->intf1 : livedata->options->intf2, pcap_geterr(send));
bytes_sent += pkthdr->caplen;
pkts_sent++;
dbgx(1, "Sent packet " COUNTER_SPEC, pkts_sent);
return (1);
} /* live_callback() */

81
src/bridge.h Normal file
View File

@@ -0,0 +1,81 @@
/* $Id: bridge.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __BRIDGE_H__
#define __BRIDGE_H__
#include "config.h"
#include "lib/tree.h"
#include "tcpedit/tcpedit.h"
/*
* RBTree node object for tracking which side of tcpreplay where
* each source MAC address lives
*/
struct macsrc_t {
RB_ENTRY(macsrc_t) node;
u_char key[ETHER_ADDR_LEN];
u_char source; /* interface device name we first saw the source MAC */
sendpacket_t *sp; /* sendpacket handle to send packets out */
};
/* pri and secondary pcap interfaces */
#define PCAP_INT1 0
#define PCAP_INT2 1
/* our custom pcap_dispatch handler user struct */
struct live_data_t {
u_int32_t linktype;
int l2enabled;
int l2len;
u_char source;
char *l2data;
pcap_t *pcap;
tcpedit_t *tcpedit;
tcpbridge_opt_t *options;
};
void rbinit(void);
void do_bridge(tcpbridge_opt_t *, tcpedit_t *);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

28
src/common.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef __COMMON_H__
#define __COMMON_H__
#include <assert.h>
#include "config.h"
#include "common/pcap_dlt.h"
#include "common/cache.h"
#include "common/cidr.h"
#include "common/err.h"
#include "common/get.h"
#include "common/fakepcap.h"
#include "common/fakepcapnav.h"
#include "common/fakepoll.h"
#include "common/list.h"
#include "common/mac.h"
#include "common/services.h"
#include "common/utils.h"
#include "common/xX.h"
#include "common/rdtsc.h"
#include "common/tcpdump.h"
#include "common/timer.h"
#include "common/abort.h"
#include "common/sendpacket.h"
#include "common/interface.h"
const char *svn_version(void); /* svn_version.c */
#endif

34
src/common/Makefile.am Normal file
View File

@@ -0,0 +1,34 @@
# $Id: Makefile.am 1621 2006-11-09 07:01:37Z aturner $
noinst_LIBRARIES = libcommon.a
BUILT_SOURCES = svn_version.c
svn_version.c:
$(ECHO) -n 'const char SVN_Version[] = "' > svn_version.c
svnversion -n ../.. >> svn_version.c
$(ECHO) '";' >> svn_version.c
$(ECHO) 'const char *svn_version(void) {' >> svn_version.c
$(ECHO) ' return SVN_Version;' >> svn_version.c
$(ECHO) '}' >> svn_version.c
libcommon_a_SOURCES = cidr.c err.c list.c cache.c services.c get.c \
fakepcap.c fakepcapnav.c fakepoll.c xX.c utils.c \
timer.c svn_version.c abort.c sendpacket.c \
dlt_names.c mac.c interface.c rdtsc.c
if ENABLE_TCPDUMP
libcommon_a_SOURCES += tcpdump.c
endif
AM_CFLAGS = -I.. -I../.. $(LNAV_CFLAGS) @LDNETINC@
libcommon_a_LIBADD = ../../lib/libstrl.a
noinst_HEADERS = cidr.h err.h list.h cache.h services.h get.h \
fakepcap.h fakepcapnav.h fakepoll.h xX.h utils.h \
tcpdump.h timer.h abort.h pcap_dlt.h sendpacket.h \
dlt_names.h mac.h interface.h rdtsc.h
MOSTLYCLEANFILES = *~
MAINTAINERCLEANFILES = Makefile.in svn_version.c

559
src/common/Makefile.in Normal file
View File

@@ -0,0 +1,559 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
@ENABLE_TCPDUMP_TRUE@am__append_1 = tcpdump.c
subdir = src/common
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/libopts/m4/libopts.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LIBRARIES = $(noinst_LIBRARIES)
ARFLAGS = cru
libcommon_a_AR = $(AR) $(ARFLAGS)
libcommon_a_DEPENDENCIES = ../../lib/libstrl.a
am__libcommon_a_SOURCES_DIST = cidr.c err.c list.c cache.c services.c \
get.c fakepcap.c fakepcapnav.c fakepoll.c xX.c utils.c timer.c \
svn_version.c abort.c sendpacket.c dlt_names.c mac.c \
interface.c rdtsc.c tcpdump.c
@ENABLE_TCPDUMP_TRUE@am__objects_1 = tcpdump.$(OBJEXT)
am_libcommon_a_OBJECTS = cidr.$(OBJEXT) err.$(OBJEXT) list.$(OBJEXT) \
cache.$(OBJEXT) services.$(OBJEXT) get.$(OBJEXT) \
fakepcap.$(OBJEXT) fakepcapnav.$(OBJEXT) fakepoll.$(OBJEXT) \
xX.$(OBJEXT) utils.$(OBJEXT) timer.$(OBJEXT) \
svn_version.$(OBJEXT) abort.$(OBJEXT) sendpacket.$(OBJEXT) \
dlt_names.$(OBJEXT) mac.$(OBJEXT) interface.$(OBJEXT) \
rdtsc.$(OBJEXT) $(am__objects_1)
libcommon_a_OBJECTS = $(am_libcommon_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libcommon_a_SOURCES)
DIST_SOURCES = $(am__libcommon_a_SOURCES_DIST)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOGEN = @AUTOGEN@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CUT = @CUT@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DMALLOC_LIB = @DMALLOC_LIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GROFF = @GROFF@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDNETINC = @LDNETINC@
LDNETLIB = @LDNETLIB@
LIBOBJS = @LIBOBJS@
LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
LIBOPTS_DIR = @LIBOPTS_DIR@
LIBOPTS_LDADD = @LIBOPTS_LDADD@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LNAVLIB = @LNAVLIB@
LNAV_CFLAGS = @LNAV_CFLAGS@
LN_S = @LN_S@
LPCAPINC = @LPCAPINC@
LPCAPLIB = @LPCAPLIB@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCAP_BPF_H_FILE = @PCAP_BPF_H_FILE@
PRINTF = @PRINTF@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TCPREPLAY_RELEASE = @TCPREPLAY_RELEASE@
TCPREPLAY_VERSION = @TCPREPLAY_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
debug_flag = @debug_flag@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
nic1 = @nic1@
nic2 = @nic2@
oldincludedir = @oldincludedir@
pcncfg = @pcncfg@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
tcpdump_path = @tcpdump_path@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
# $Id: Makefile.am 1621 2006-11-09 07:01:37Z aturner $
noinst_LIBRARIES = libcommon.a
BUILT_SOURCES = svn_version.c
libcommon_a_SOURCES = cidr.c err.c list.c cache.c services.c get.c \
fakepcap.c fakepcapnav.c fakepoll.c xX.c utils.c timer.c \
svn_version.c abort.c sendpacket.c dlt_names.c mac.c \
interface.c rdtsc.c $(am__append_1)
AM_CFLAGS = -I.. -I../.. $(LNAV_CFLAGS) @LDNETINC@
libcommon_a_LIBADD = ../../lib/libstrl.a
noinst_HEADERS = cidr.h err.h list.h cache.h services.h get.h \
fakepcap.h fakepcapnav.h fakepoll.h xX.h utils.h \
tcpdump.h timer.h abort.h pcap_dlt.h sendpacket.h \
dlt_names.h mac.h interface.h rdtsc.h
MOSTLYCLEANFILES = *~
MAINTAINERCLEANFILES = Makefile.in svn_version.c
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/common/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu src/common/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES)
-rm -f libcommon.a
$(libcommon_a_AR) libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD)
$(RANLIB) libcommon.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abort.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cidr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlt_names.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/err.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fakepcap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fakepcapnav.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fakepoll.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdtsc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendpacket.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/services.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/svn_version.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcpdump.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xX.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: all check install install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am
svn_version.c:
$(ECHO) -n 'const char SVN_Version[] = "' > svn_version.c
svnversion -n ../.. >> svn_version.c
$(ECHO) '";' >> svn_version.c
$(ECHO) 'const char *svn_version(void) {' >> svn_version.c
$(ECHO) ' return SVN_Version;' >> svn_version.c
$(ECHO) '}' >> svn_version.c
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

92
src/common/abort.c Normal file
View File

@@ -0,0 +1,92 @@
/* $Id: abort.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2005-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <signal.h>
#include <stdlib.h>
extern volatile int didsig;
extern COUNTER bytes_sent, pkts_sent, failed;
extern struct timeval begin, end;
#ifdef DEBUG
extern int debug;
#endif
/**
* we've got a race condition, this is our workaround
*/
void
catcher(int signo)
{
/* stdio in signal handlers causes a race condition, instead set a flag */
if (signo == SIGINT)
didsig = 1;
}
/**
* when we're sending only one packet at a time via <ENTER>
* then there's no race and we can quit now
* also called when didsig is set
*/
void
break_now(int signo)
{
if (signo == SIGINT || didsig) {
printf("\n");
/*
#ifdef ENABLE_VERBOSE
if (tcpdump.pid)
if (kill(tcpdump.pid, SIGTERM) != 0)
kill(tcpdump.pid, SIGKILL);
#endif
*/
packet_stats(&begin, &end, bytes_sent, pkts_sent, failed);
exit(1);
}
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

49
src/common/abort.h Normal file
View File

@@ -0,0 +1,49 @@
/* $Id: abort.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2005-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ABORT_H__
#define __ABORT_H__
void catcher(int signo);
void break_now(int signo);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

379
src/common/cache.c Normal file
View File

@@ -0,0 +1,379 @@
/* $Id: cache.c 2424 2010-03-16 05:33:03Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#ifdef DEBUG
extern int debug;
#endif
static tcpr_cache_t *new_cache(void);
/**
* Takes a single char and returns a ptr to a string representation of the
* 8 bits that make up that char. Use BIT_STR() to print it out
*/
#ifdef DEBUG
static char *
byte2bits(char byte, char *bitstring) {
int i = 1, j = 7;
for (i = 1; i <= 255; i = i << 1) {
if (byte & i)
bitstring[j] = '\061';
j--;
}
return bitstring;
}
#endif
/**
* simple function to read in a cache file created with tcpprep this let's us
* be really damn fast in picking an interface to send the packet out returns
* number of cache entries read
*
* now also checks for the cache magic and version
*/
COUNTER
read_cache(char **cachedata, const char *cachefile, char **comment)
{
int cachefd;
tcpr_cache_file_hdr_t header;
ssize_t read_size = 0;
COUNTER cache_size = 0;
/* open the file or abort */
if ((cachefd = open(cachefile, O_RDONLY)) == -1)
errx(-1, "unable to open %s:%s", cachefile, strerror(errno));
/* read the cache header and determine compatibility */
if ((read_size = read(cachefd, &header, sizeof(header))) < 0)
errx(-1, "unable to read from %s:%s,", cachefile, strerror(errno));
if (read_size < (ssize_t)sizeof(header))
errx(-1, "Cache file %s doesn't contain a full header", cachefile);
/* verify our magic: tcpprep\0 */
if (memcmp(header.magic, CACHEMAGIC, sizeof(CACHEMAGIC)) != 0)
errx(-1, "Unable to process %s: not a tcpprep cache file", cachefile);
/* verify version */
if (atoi(header.version) != atoi(CACHEVERSION))
errx(-1, "Unable to process %s: cache file version missmatch",
cachefile);
/* read the comment */
header.comment_len = ntohs(header.comment_len);
*comment = (char *)safe_malloc(header.comment_len + 1);
dbgx(1, "Comment length: %d", header.comment_len);
if ((read_size = read(cachefd, *comment, header.comment_len))
!= header.comment_len)
errx(-1, "Unable to read %d bytes of data for the comment (%zu) %s",
header.comment_len, read_size,
read_size == -1 ? strerror(read_size) : "");
dbgx(1, "Cache file comment: %s", *comment);
/* malloc our cache block */
header.num_packets = ntohll(header.num_packets);
header.packets_per_byte = ntohs(header.packets_per_byte);
cache_size = header.num_packets / header.packets_per_byte;
/* deal with any remainder, becuase above divsion is integer */
if (header.num_packets % header.packets_per_byte)
cache_size ++;
dbgx(1, "Cache file contains %llu packets in %llu bytes",
header.num_packets, cache_size);
dbgx(1, "Cache uses %d packets per byte", header.packets_per_byte);
*cachedata = (char *)safe_malloc(cache_size);
/* read in the cache */
if ((COUNTER)(read_size = read(cachefd, *cachedata, cache_size))
!= cache_size)
errx(-1, "Cache data length (%ld bytes) doesn't match "
"cache header (" COUNTER_SPEC " bytes)", read_size, cache_size);
dbgx(1, "Loaded in %llu packets from cache.", header.num_packets);
close(cachefd);
return (header.num_packets);
}
/**
* writes out the cache file header, comment and then the
* contents of *cachedata to out_file and then returns the number
* of cache entries written
*/
COUNTER
write_cache(tcpr_cache_t * cachedata, const int out_file, COUNTER numpackets,
char *comment)
{
tcpr_cache_t *mycache = NULL;
tcpr_cache_file_hdr_t *cache_header = NULL;
u_int32_t chars, last = 0;
COUNTER packets = 0;
ssize_t written = 0;
assert(cachedata);
assert(out_file);
/* write a header to our file */
cache_header = (tcpr_cache_file_hdr_t *)
safe_malloc(sizeof(tcpr_cache_file_hdr_t));
strncpy(cache_header->magic, CACHEMAGIC, strlen(CACHEMAGIC));
strncpy(cache_header->version, CACHEVERSION, strlen(CACHEVERSION));
cache_header->packets_per_byte = htons(CACHE_PACKETS_PER_BYTE);
cache_header->num_packets = htonll((u_int64_t)numpackets);
/* we can't strlen(NULL) so ... */
if (comment != NULL) {
cache_header->comment_len = htons((u_int16_t)strlen(comment));
} else {
cache_header->comment_len = 0;
}
written = write(out_file, cache_header, sizeof(tcpr_cache_file_hdr_t));
dbgx(1, "Wrote %zu bytes of cache file header", written);
if (written != sizeof(tcpr_cache_file_hdr_t))
errx(-1, "Only wrote %zu of %zu bytes of the cache file header!\n%s",
written, sizeof(tcpr_cache_file_hdr_t),
written == -1 ? strerror(errno) : "");
/* don't write comment if there is none */
if (comment != NULL) {
written = write(out_file, comment, strlen(comment));
dbgx(1, "Wrote %zu bytes of comment", written);
if (written != (ssize_t)strlen(comment))
errx(-1, "Only wrote %zu of %zu bytes of the comment!\n%s",
written, strlen(comment),
written == -1 ? strerror(errno) : "");
}
mycache = cachedata;
while (!last) {
/* increment total packets */
packets += mycache->packets;
/* calculate how many chars to write */
chars = mycache->packets / CACHE_PACKETS_PER_BYTE;
if (mycache->packets % CACHE_PACKETS_PER_BYTE) {
chars++;
dbgx(1, "Bumping up to the next byte: %d %% %d", mycache->packets,
CACHE_PACKETS_PER_BYTE);
}
/* write to file, and verify it wrote properly */
written = write(out_file, mycache->data, chars);
dbgx(1, "Wrote %zu bytes of cache data", written);
if (written != (ssize_t)chars)
errx(-1, "Only wrote %zu of %i bytes to cache file!", written, chars);
/*
* if that was the last, stop processing, otherwise wash,
* rinse, repeat
*/
if (mycache->next != NULL) {
mycache = mycache->next;
}
else {
last = 1;
}
}
/* return number of packets written */
return (packets);
}
/**
* mallocs a new CACHE struct all pre-set to sane defaults
*/
static tcpr_cache_t *
new_cache(void)
{
tcpr_cache_t *newcache;
/* malloc mem */
newcache = (tcpr_cache_t *)safe_malloc(sizeof(tcpr_cache_t));
return (newcache);
}
/**
* adds the cache data for a packet to the given cachedata
*/
tcpr_dir_t
add_cache(tcpr_cache_t ** cachedata, const int send, const tcpr_dir_t interface)
{
static tcpr_cache_t *lastcache = NULL;
u_char *byte = NULL;
u_int32_t bit;
tcpr_dir_t result = TCPR_DIR_ERROR;
COUNTER index;
#ifdef DEBUG
char bitstring[9] = EIGHT_ZEROS;
#endif
assert(cachedata);
/* first run? malloc our first entry, set bit count to 0 */
if (*cachedata == NULL) {
*cachedata = new_cache();
lastcache = *cachedata;
}
else {
/* check to see if this is the last bit in this struct */
if ((lastcache->packets + 1) > (CACHEDATASIZE * CACHE_PACKETS_PER_BYTE)) {
/*
* if so, we have to malloc a new one and set bit to 0
*/
dbg(1, "Adding to cachedata linked list");
lastcache->next = new_cache();
lastcache = lastcache->next;
}
}
/* always increment our bit count */
lastcache->packets++;
dbgx(1, "Cache array packet %d", lastcache->packets);
/* send packet ? */
if (send == SEND) {
index = (lastcache->packets - 1) / (COUNTER)CACHE_PACKETS_PER_BYTE;
bit = (((lastcache->packets - 1) % (COUNTER)CACHE_PACKETS_PER_BYTE) *
(COUNTER)CACHE_BITS_PER_PACKET) + 1;
dbgx(3, "Bit: %d", bit);
byte = (u_char *) & lastcache->data[index];
*byte += (u_char) (1 << bit);
dbgx(2, "set send bit: byte " COUNTER_SPEC " = 0x%x", index, *byte);
/* if true, set low order bit. else, do squat */
if (interface == TCPR_DIR_C2S) {
*byte += (u_char)(1 << (bit - 1));
dbgx(2, "set interface bit: byte " COUNTER_SPEC " = 0x%x", index, *byte);
result = TCPR_DIR_C2S;
}
else {
dbgx(2, "don't set interface bit: byte " COUNTER_SPEC " = 0x%x", index, *byte);
result = TCPR_DIR_S2C;
}
#ifdef DEBUG
/*
* only build the byte string when not in debug mode since
* the calculation is a bit expensive
*/
dbgx(3, "Current cache byte: %c%c%c%c%c%c%c%c",
BIT_STR(byte2bits(*byte, bitstring)));
#endif
}
else {
dbg(1, "not setting send bit");
result = TCPR_DIR_NOSEND;
}
return result;
}
/**
* returns the action for a given packet based on the CACHE
*/
tcpr_dir_t
check_cache(char *cachedata, COUNTER packetid)
{
COUNTER index = 0;
u_int32_t bit;
assert(cachedata);
if (packetid == 0)
err(-1, "packetid must be > 0");
index = (packetid - 1) / (COUNTER)CACHE_PACKETS_PER_BYTE;
bit = (u_int32_t)(((packetid - 1) % (COUNTER)CACHE_PACKETS_PER_BYTE) *
(COUNTER)CACHE_BITS_PER_PACKET) + 1;
#ifdef DEBUG
dbgx(3, "Index: " COUNTER_SPEC "\tBit: %d\tByte: %hhu\tMask: %hhu", index, bit,
cachedata[index], (cachedata[index] & (char)(1 << bit)));
#endif
if (!(cachedata[index] & (char)(1 << bit))) {
return TCPR_DIR_NOSEND;
}
/* go back a bit to get the interface */
bit--;
if (cachedata[index] & (char)(1 << bit)) {
return TCPR_DIR_C2S;
}
else {
return TCPR_DIR_S2C;
}
return TCPR_DIR_ERROR;
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

125
src/common/cache.h Normal file
View File

@@ -0,0 +1,125 @@
/* $Id: cache.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CACHE_H__
#define __CACHE_H__
#define CACHEMAGIC "tcpprep"
#define CACHEVERSION "04"
#define CACHEDATASIZE 255
#define CACHE_PACKETS_PER_BYTE 4 /* number of packets / byte */
#define CACHE_BITS_PER_PACKET 2 /* number of bits / packet */
#define SEND 1
#define DONT_SEND 0
/*
* CACHEVERSION History:
* 01 - Inital release. 1 bit of data/packet (primary or secondary nic)
* 02 - 2 bits of data/packet (drop/send & primary or secondary nic)
* 03 - Write integers in network-byte order
* 04 - Increase num_packets from 32 to 64 bit integer
*/
struct tcpr_cache_s {
char data[CACHEDATASIZE];
unsigned int packets; /* number of packets tracked in data */
struct tcpr_cache_s *next;
};
typedef struct tcpr_cache_s tcpr_cache_t;
/*
* Each byte in cache_type.data represents CACHE_PACKETS_PER_BYTE (4) number of packets
* Each packet has CACHE_BITS_PER_PACKETS (2) bits of data.
* High Bit: 1 = send, 0 = don't send
* Low Bit: 1 = primary interface, 0 = secondary interface
*/
/*
* cache_file_header Data structure defining a file as a tcpprep cache file
* and it's version
*
* If you need to enhance this struct, do so AFTER the version field and be sure
* to increment CACHEVERSION
*/
struct tcpr_cache_file_hdr_s {
char magic[8];
char version[4];
/* begin version 2 features */
/* version 3 puts everything in network-byte order */
/* version 4 makes num_packets a 64 bit int */
u_int64_t num_packets; /* total # of packets in file */
u_int16_t packets_per_byte;
u_int16_t comment_len; /* how long is the user comment? */
} __attribute__((__packed__));
typedef struct tcpr_cache_file_hdr_s tcpr_cache_file_hdr_t;
enum tcpr_dir_e {
TCPR_DIR_ERROR = -1,
TCPR_DIR_NOSEND = 0,
TCPR_DIR_C2S = 1, /* aka PRIMARY */
TCPR_DIR_S2C = 2 /* aka SECONDARY */
};
typedef enum tcpr_dir_e tcpr_dir_t;
COUNTER write_cache(tcpr_cache_t *, const int, COUNTER, char *);
tcpr_dir_t add_cache(tcpr_cache_t **, const int, const tcpr_dir_t);
COUNTER read_cache(char **, const char *, char **);
tcpr_dir_t check_cache(char *, COUNTER);
/* return values for check_cache
#define CACHE_ERROR -1
#define CACHE_NOSEND 0 // NULL
#define CACHE_PRIMARY 1
#define CACHE_SECONDARY 2
*/
/* macro to change a bitstring to 8 bits */
#define BIT_STR(x) x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]
/* string of 8 zeros */
#define EIGHT_ZEROS "\060\060\060\060\060\060\060\060"
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

708
src/common/cidr.c Normal file
View File

@@ -0,0 +1,708 @@
/* $Id: cidr.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include "lib/strlcpy.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* required for inet_aton() */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef DEBUG
extern int debug;
#endif
static tcpr_cidr_t *cidr2cidr(char *);
/**
* prints to the given fd all the entries in mycidr
*/
void
print_cidr(tcpr_cidr_t * mycidr)
{
tcpr_cidr_t *cidr_ptr;
fprintf(stderr, "Cidr List: ");
cidr_ptr = mycidr;
while (cidr_ptr != NULL) {
/* print it */
fprintf(stderr, "%s/%d, ", get_cidr2name(cidr_ptr, RESOLVE),
cidr_ptr->masklen);
/* go to the next */
if (cidr_ptr->next != NULL) {
cidr_ptr = cidr_ptr->next;
}
else {
break;
}
}
fprintf(stderr, "\n");
}
/**
* deletes all entries in a cidr and destroys the datastructure
*/
void
destroy_cidr(tcpr_cidr_t * cidr)
{
if (cidr != NULL)
if (cidr->next != NULL)
destroy_cidr(cidr->next);
safe_free(cidr);
return;
}
/**
* adds a new tcpr_cidr_t entry to cidrdata
*/
void
add_cidr(tcpr_cidr_t ** cidrdata, tcpr_cidr_t ** newcidr)
{
tcpr_cidr_t *cidr_ptr;
dbg(1, "Running new_cidr()");
if (*cidrdata == NULL) {
*cidrdata = *newcidr;
} else {
cidr_ptr = *cidrdata;
while (cidr_ptr->next != NULL)
cidr_ptr = cidr_ptr->next;
cidr_ptr->next = *newcidr;
}
}
/**
* takes in an IP and masklen, and returns a string in
* cidr format: x.x.x.x/y. This malloc's memory.
*/
u_char *
ip2cidr(const unsigned long ip, const int masklen)
{
u_char *network;
char mask[3];
network = (u_char *)safe_malloc(20);
strlcpy((char *)network, (char *)get_addr2name4(ip, RESOLVE),
sizeof(network));
strcat((char *)network, "/");
if (masklen < 10) {
snprintf(mask, 1, "%d", masklen);
strncat((char *)network, mask, 1);
} else {
snprintf(mask, 2, "%d", masklen);
strncat((char *)network, mask, 2);
}
return (network);
}
/**
* Mallocs and sets to sane defaults a tcpr_cidr_t structure
*/
tcpr_cidr_t *
new_cidr(void)
{
tcpr_cidr_t *newcidr;
newcidr = (tcpr_cidr_t *)safe_malloc(sizeof(tcpr_cidr_t));
memset(newcidr, '\0', sizeof(tcpr_cidr_t));
newcidr->masklen = 99;
newcidr->next = NULL;
return (newcidr);
}
/**
* Creates a new tcpr_cidrmap_t structure. Malloc's memory
*/
tcpr_cidrmap_t *
new_cidr_map(void)
{
tcpr_cidrmap_t *new;
new = (tcpr_cidrmap_t *)safe_malloc(sizeof(tcpr_cidrmap_t));
memset(new, '\0', sizeof(tcpr_cidrmap_t));
new->next = NULL;
return (new);
}
/**
* Converts a single cidr (string) in the form of x.x.x.x/y into a
* tcpr_cidr_t structure. Will malloc the tcpr_cidr_t structure.
*/
static tcpr_cidr_t *
cidr2cidr(char *cidr)
{
int count = 0;
unsigned int octets[4]; /* used in sscanf */
tcpr_cidr_t *newcidr;
char networkip[16], tempoctet[4], ebuf[EBUF_SIZE];
int family;
char* p;
assert(cidr);
assert(strlen(cidr) <= EBUF_SIZE);
newcidr = new_cidr();
for (p = cidr; *p; ++p) {
if (*p == '#') {
*p = ':';
} else if (*p == ']') {
*p = 0;
break;
}
}
/*
* scan it, and make sure it scanned correctly, also copy over the
* masklen
*/
count = sscanf(cidr, "%u.%u.%u.%u/%d", &octets[0], &octets[1],
&octets[2], &octets[3], &newcidr->masklen);
if (count == 4) {
newcidr->masklen = 32;
family = AF_INET;
} else if (count == 5) {
family = AF_INET;
} else {
p = strstr(cidr, "/");
if (p) {
*p = 0;
++p;
count = sscanf(p, "%d", &newcidr->masklen);
} else {
newcidr->masklen = 128;
}
if (newcidr->masklen < 0 || newcidr->masklen > 128)
goto error;
/* skip past the opening [ */
if (*cidr == '[')
cidr ++;
if (get_name2addr6(cidr, RESOLVE, &newcidr->u.network6) > 0) {
family = AF_INET6;
} else {
goto error;
}
}
if (family == AF_INET) {
/* masklen better be 0 =< masklen <= 32 */
if (newcidr->masklen > 32)
goto error;
/* copy in the ip address */
memset(networkip, '\0', 16);
for (count = 0; count < 4; count++) {
if (octets[count] > 255)
goto error;
snprintf(tempoctet, sizeof(octets[count]), "%d", octets[count]);
strcat(networkip, tempoctet);
/* we don't want a '.' at the end of the last octet */
if (count < 3)
strcat(networkip, ".");
}
/* copy over the network address and return */
#ifdef HAVE_INET_ATON
inet_aton(networkip, (struct in_addr *)&newcidr->u.network);
#elif HAVE_INET_ADDR
newcidr->network = inet_addr(networkip);
#endif
} else if (family == AF_INET6) {
/* Everything's done */
} else {
goto error;
}
newcidr->family = family;
return (newcidr);
/* we only get here on error parsing input */
error:
memset(ebuf, '\0', EBUF_SIZE);
strcpy(ebuf, "Unable to parse as a vaild CIDR: ");
strlcat(ebuf, cidr, EBUF_SIZE);
errx(-1, "%s", ebuf);
return NULL;
}
static void
mask_cidr6(char **cidrin, char* delim)
{
char *p;
if (**cidrin == '[' && *delim == ':') {
++*cidrin;
/* make strtok happy */
for (p = *cidrin; *p && *p != ']'; ++p) {
if (*p == ':') {
*p = '#';
}
}
}
}
/**
* parses a list of tcpr_cidr_t's input from the user which should be in the form
* of x.x.x.x/y,x.x.x.x/y...
* returns 1 for success, or fails to return on failure (exit 1)
* since we use strtok to process cidr, it gets zeroed out.
*/
int
parse_cidr(tcpr_cidr_t ** cidrdata, char *cidrin, char *delim)
{
tcpr_cidr_t *cidr_ptr; /* ptr to current cidr record */
char *network = NULL;
char *token = NULL;
mask_cidr6(&cidrin, delim);
/* first itteration of input using strtok */
network = strtok_r(cidrin, delim, &token);
*cidrdata = cidr2cidr(network);
cidr_ptr = *cidrdata;
/* do the same with the rest of the input */
while (1) {
if (token)
mask_cidr6(&token, delim);
network = strtok_r(NULL, delim, &token);
/* if that was the last CIDR, then kickout */
if (network == NULL)
break;
/* next record */
cidr_ptr->next = cidr2cidr(network);
cidr_ptr = cidr_ptr->next;
}
return 1;
}
/**
* parses a pair of IP addresses: <IP1>:<IP2> and processes it like:
* -N 0.0.0.0/0:<IP1> -N 0.0.0.0/0:<IP2>
* returns 1 for success or returns 0 on failure
* since we use strtok to process optarg, it gets zeroed out
*/
int
parse_endpoints(tcpr_cidrmap_t ** cidrmap1, tcpr_cidrmap_t ** cidrmap2, const char *optarg)
{
#define NEWMAP_LEN (INET6_ADDRSTRLEN * 2)
char *map = NULL, newmap[NEWMAP_LEN];
char *token = NULL;
char *string;
char *p;
string = safe_strdup(optarg);
if (*string == '[') {
/* ipv6 mode */
memset(newmap, '\0', NEWMAP_LEN);
p = strstr(string, "]:[");
if (!p)
return 0;
*p = 0;
strlcpy(newmap, "[::/0]:", NEWMAP_LEN);
strlcat(newmap, string, NEWMAP_LEN);
strlcat(newmap, "]", NEWMAP_LEN);
if (! parse_cidr_map(cidrmap1, newmap))
return 0;
/* do again with the second IP */
memset(newmap, '\0', NEWMAP_LEN);
strlcpy(newmap, "[::/0]:", NEWMAP_LEN);
strlcat(newmap, p + 2, NEWMAP_LEN);
if (! parse_cidr_map(cidrmap2, newmap))
return 0;
} else {
/* ipv4 mode */
memset(newmap, '\0', NEWMAP_LEN);
map = strtok_r(string, ":", &token);
strlcpy(newmap, "0.0.0.0/0:", NEWMAP_LEN);
strlcat(newmap, map, NEWMAP_LEN);
if (! parse_cidr_map(cidrmap1, newmap))
return 0;
/* do again with the second IP */
memset(newmap, '\0', NEWMAP_LEN);
map = strtok_r(NULL, ":", &token);
strlcpy(newmap, "0.0.0.0/0:", NEWMAP_LEN);
strlcat(newmap, map, NEWMAP_LEN);
if (! parse_cidr_map(cidrmap2, newmap))
return 0;
}
safe_free(string);
return 1; /* success */
}
/**
* parses a list of tcpr_cidrmap_t's input from the user which should be in the form
* of x.x.x.x/y:x.x.x.x/y,...
* IPv6 syntax: [addr/y]:[addr/y],...
* returns 1 for success, or returns 0 on failure
* since we use strtok to process optarg, it gets zeroed out.
*/
int
parse_cidr_map(tcpr_cidrmap_t **cidrmap, const char *optarg)
{
tcpr_cidr_t *cidr = NULL;
char *map = NULL;
char *token = NULL, *string = NULL;
tcpr_cidrmap_t *ptr;
string = safe_strdup(optarg);
/* first iteration */
map = strtok_r(string, ",", &token);
if (! parse_cidr(&cidr, map, ":"))
return 0;
/* must return a linked list of two */
if (cidr->next == NULL)
return 0;
/* copy over */
*cidrmap = new_cidr_map();
ptr = *cidrmap;
ptr->from = cidr;
ptr->to = cidr->next;
ptr->from->next = NULL;
/* do the same with the reset of the input */
while(1) {
map = strtok_r(NULL, ",", &token);
if (map == NULL)
break;
if (! parse_cidr(&cidr, map, ":"))
return 0;
/* must return a linked list of two */
if (cidr->next == NULL)
return 0;
/* copy over */
ptr->next = new_cidr_map();
ptr = ptr->next;
ptr->from = cidr;
ptr->to = cidr->next;
ptr->from->next = NULL;
}
safe_free(string);
return 1; /* success */
}
/**
* checks to see if the ip address is in the cidr
* returns 1 for true, 0 for false
*/
int
ip_in_cidr(const tcpr_cidr_t * mycidr, const unsigned long ip)
{
unsigned long ipaddr = 0, network = 0, mask = 0;
int ret = 0;
#ifdef DEBUG
char netstr[20];
#endif
if (mycidr->family != AF_INET)
return 0;
/* always return 1 if 0.0.0.0/0 */
if (mycidr->masklen == 0 && mycidr->u.network == 0)
return 1;
mask = ~0; /* turn on all the bits */
/* shift over by the correct number of bits */
mask = mask << (32 - mycidr->masklen);
/* apply the mask to the network and ip */
ipaddr = ntohl(ip) & mask;
network = htonl(mycidr->u.network) & mask;
#ifdef DEBUG
/* copy this for debug purposes, since it's not re-entrant */
strlcpy(netstr, get_addr2name4(htonl(mycidr->u.network), RESOLVE), 20);
#endif
/* if they're the same, then ip is in network */
if (network == ipaddr) {
#ifdef DEBUG
dbgx(1, "The ip %s is inside of %s/%d",
get_addr2name4(ip, RESOLVE), netstr, mycidr->masklen);
#endif
ret = 1;
} else {
#ifdef DEBUG
dbgx(1, "The ip %s is not inside of %s/%d",
get_addr2name4(ip, RESOLVE), netstr, mycidr->masklen);
#endif
ret = 0;
}
return ret;
}
static int
ip6_addr_is_unspec(const struct tcpr_in6_addr *addr)
{
return addr->tcpr_s6_addr32[0] == 0 && addr->tcpr_s6_addr32[1] == 0 &&
addr->tcpr_s6_addr32[2] == 0 && addr->tcpr_s6_addr32[3] == 0;
}
int
ip6_in_cidr(const tcpr_cidr_t * mycidr, const struct tcpr_in6_addr *addr)
{
int ret = 0;
#ifdef DEBUG
char netstr[INET6_ADDRSTRLEN];
#endif
int i, j, k;
if (mycidr->family != AF_INET6)
return 0;
/* always return 1 if ::/0 */
if (mycidr->masklen == 0 && ip6_addr_is_unspec(addr))
return 1;
j = mycidr->masklen / 8;
for (i = 0; i < j; i++) {
if (addr->tcpr_s6_addr[i] != mycidr->u.network6.tcpr_s6_addr[i]) {
ret = 0;
goto out;
}
}
if ((k = mycidr->masklen % 8) == 0) {
ret = 1;
goto out;
}
k = ~0 << (8 - k);
i = addr->tcpr_s6_addr[j] & k;
j = mycidr->u.network6.tcpr_s6_addr[j] & k;
ret = i == j;
out:
#ifdef DEBUG
/* copy this for debug purposes, since it's not re-entrant */
strlcpy(netstr, get_addr2name6(&mycidr->u.network6, RESOLVE), INET6_ADDRSTRLEN);
#endif
/* if they're the same, then ip is in network */
if (ret) {
#ifdef DEBUG
dbgx(1, "The ip %s is inside of %s/%d",
get_addr2name6(addr, RESOLVE), netstr, mycidr->masklen);
#endif
} else {
#ifdef DEBUG
dbgx(1, "The ip %s is not inside of %s/%d",
get_addr2name6(addr, RESOLVE), netstr, mycidr->masklen);
#endif
}
return ret;
}
/**
* iterates over cidrdata to find if a given ip matches
* returns 1 for true, 0 for false
*/
int
check_ip_cidr(tcpr_cidr_t * cidrdata, const unsigned long ip)
{
tcpr_cidr_t *mycidr;
/* if we have no cidrdata, of course it isn't in there
* this actually should happen occasionally, so don't put an assert here
*/
if (cidrdata == NULL)
return 1;
mycidr = cidrdata;
/* loop through cidr */
while (1) {
/* if match, return 1 */
if (ip_in_cidr(mycidr, ip)) {
dbgx(3, "Found %s in cidr", get_addr2name4(ip, RESOLVE));
return 1;
}
/* check for next record */
if (mycidr->next != NULL) {
mycidr = mycidr->next;
} else {
break;
}
}
/* if we get here, no match */
dbgx(3, "Didn't find %s in cidr", get_addr2name4(ip, RESOLVE));
return 0;
}
int
check_ip6_cidr(tcpr_cidr_t * cidrdata, const struct tcpr_in6_addr *addr)
{
tcpr_cidr_t *mycidr;
/* if we have no cidrdata, of course it isn't in there
* this actually should happen occasionally, so don't put an assert here
*/
if (cidrdata == NULL) {
return 1;
}
mycidr = cidrdata;
/* loop through cidr */
while (1) {
/* if match, return 1 */
if (ip6_in_cidr(mycidr, addr)) {
dbgx(3, "Found %s in cidr", get_addr2name6(addr, RESOLVE));
return 1;
}
/* check for next record */
if (mycidr->next != NULL) {
mycidr = mycidr->next;
} else {
break;
}
}
/* if we get here, no match */
dbgx(3, "Didn't find %s in cidr", get_addr2name6(addr, RESOLVE));
return 0;
}
/**
* cidr2ip takes a tcpr_cidr_t and a delimiter
* and returns a string which lists all the IP addresses in the cidr
* deliminated by the given char
*/
char *
cidr2iplist(tcpr_cidr_t * cidr, char delim)
{
char *list = NULL;
char ipaddr[16];
u_int32_t size, addr, first, last, numips;
struct in_addr in;
/*
* 16 bytes per IP + delim
* # of IP's = 2^(32-masklen)
*/
numips = 2;
for (int i = 2; i <= (32 - cidr->masklen); i++)
numips *= 2;
size = 16 * numips;
list = (char *)safe_malloc(size);
memset(list, 0, size);
/* first and last should not include network or broadcast */
first = ntohl(cidr->u.network) + 1;
last = first + numips - 3;
dbgx(1, "First: %u\t\tLast: %u", first, last);
/* loop through all but the last one */
for (addr = first; addr < last; addr++) {
in.s_addr = htonl(addr);
snprintf(ipaddr, 17, "%s%c", inet_ntoa(in), delim);
dbgx(2, "%s", ipaddr);
strlcat(list, ipaddr, size);
}
/* last is a special case, end in \0 */
in.s_addr = htonl(addr);
snprintf(ipaddr, 16, "%s", inet_ntoa(in));
strlcat(list, ipaddr, size);
return list;
}

83
src/common/cidr.h Normal file
View File

@@ -0,0 +1,83 @@
/* $Id: cidr.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "cache.h"
#ifndef __CIDR_H__
#define __CIDR_H__
struct tcpr_cidr_s {
int family; /* AF_INET or AF_INET6 */
union {
u_int32_t network;
struct tcpr_in6_addr network6;
} u;
int masklen;
struct tcpr_cidr_s *next;
};
typedef struct tcpr_cidr_s tcpr_cidr_t;
struct tcpr_cidrmap_s {
tcpr_cidr_t *from;
tcpr_cidr_t *to;
struct tcpr_cidrmap_s *next;
};
typedef struct tcpr_cidrmap_s tcpr_cidrmap_t;
int ip_in_cidr(const tcpr_cidr_t *, const unsigned long);
int check_ip_cidr(tcpr_cidr_t *, const unsigned long);
int check_ip6_cidr(tcpr_cidr_t *, const struct tcpr_in6_addr *addr);
int parse_cidr(tcpr_cidr_t **, char *, char *delim);
int parse_cidr_map(tcpr_cidrmap_t **, const char *);
int parse_endpoints(tcpr_cidrmap_t **, tcpr_cidrmap_t **, const char *);
u_char *ip2cidr(const unsigned long, const int);
void add_cidr(tcpr_cidr_t **, tcpr_cidr_t **);
tcpr_cidr_t *new_cidr(void);
tcpr_cidrmap_t *new_cidr_map(void);
void destroy_cidr(tcpr_cidr_t *);
void print_cidr(tcpr_cidr_t *);
char *cidr2iplist(tcpr_cidr_t *, char);
int ip6_in_cidr(const tcpr_cidr_t * mycidr, const struct tcpr_in6_addr *addr);
int check_ip6_cidr(tcpr_cidr_t *, const struct tcpr_in6_addr *addr);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

511
src/common/dlt_names.c Normal file
View File

@@ -0,0 +1,511 @@
/* $Id: dlt_names.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2006-2010 Aaron Turner
* All rights reserved.
*
* This file is generated by scripts/dlt2name.pl which converts your pcap-bpf.h
* header file which comes with libpcap into a header file
* which translates DLT values to their string names as well as a list of all
* of the available DLT types.
*
* Hence DO NOT EDIT THIS FILE!
* If your DLT type is not listed here, edit the %known hash in
* scripts/dlt2name.pl
*
* This file contains data which was taken from libpcap's pcap-bpf.h.
* The copyright/license is included below:
*/
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.34.2.6 2005/08/13 22:29:47 hannes Exp $ (LBL)
*/
#include <stdlib.h>
/* DLT to descriptions */
char *dlt2desc[] = {
"BSD loopback encapsulation",
"Ethernet (10Mb)",
"Experimental Ethernet (3Mb)",
"Amateur Radio AX.25",
"Proteon ProNET Token Ring",
"Chaos",
"IEEE 802 Networks",
"ARCNET, with BSD-style header",
"Serial Line IP",
"Point-to-point Protocol",
"FDDI",
"LLC-encapsulated ATM",
"raw IP",
"BSD/OS Serial Line IP",
"BSD/OS Point-to-point Protocol",
"BSD/OS Serial Line IP",
"BSD/OS Point-to-point Protocol",
"",
"",
"Linux Classical-IP over ATM",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"PPP over serial with HDLC encapsulation",
"PPP over Ethernet",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Cisco HDLC",
"IEEE 802.11 wireless",
"Unknown",
"BSD/OS Frame Relay",
"OpenBSD Loopback",
"",
"Unknown",
"Unknown",
"Unknown",
"Linux Cooked Sockets",
"Apple LocalTalk",
"Acorn Econet",
"OpenBSD IPFilter",
"OpenBSD PF Log/SuSE 6.3 LANE 802.3",
"Cisco IOS",
"802.11 Prism Header",
"802.11 Aironet Header",
"Siemens HiPath HDLC",
"IP over Fibre Channel",
"Solaris+SunATM",
"RapidIO",
"PCI Express",
"Xilinx Aurora link layer",
"802.11 plus radiotap radio header",
"Tazmen Sniffer Protocol",
"ARCNET",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"pseudo-header with various info, followed by MTP2",
"MTP2, without pseudo-header",
"MTP3, without pseudo-header or MTP2",
"SCCP, without pseudo-header or MTP2 or MTP3",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"802.11 plus AVS radio header",
"",
"",
"",
"",
"",
"GPRS LLC",
"GPF-T (ITU-T G.7041/Y.1303)",
"GPF-F (ITU-T G.7041/Y.1303)",
"",
"",
"",
"Ethernet",
"Packet-over-SONET",
"",
"",
"",
"",
NULL
};
/* DLT to names */
char *dlt2name[] = {
"DLT_NULL",
"DLT_EN10MB",
"DLT_EN3MB",
"DLT_AX25",
"DLT_PRONET",
"DLT_CHAOS",
"DLT_IEEE802",
"DLT_ARCNET",
"DLT_SLIP",
"DLT_PPP",
"DLT_FDDI",
"DLT_ATM_RFC1483",
"DLT_RAW",
"DLT_ENC",
"DLT_PPP_BSDOS",
"DLT_SLIP_BSDOS",
"DLT_PPP_BSDOS",
"DLT_OLD_PFLOG",
"DLT_PFSYNC",
"DLT_ATM_CLIP",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"DLT_REDBACK_SMARTEDGE",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"DLT_PPP_SERIAL",
"DLT_PPP_ETHER",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"DLT_SYMANTEC_FIREWALL",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"DLT_C_HDLC",
"DLT_IEEE802_11",
"Unknown",
"DLT_FRELAY",
"DLT_LOOP",
"DLT_ENC",
"Unknown",
"Unknown",
"Unknown",
"DLT_LINUX_SLL",
"DLT_LTALK",
"DLT_ECONET",
"DLT_IPFILTER",
"DLT_PFLOG",
"DLT_CISCO_IOS",
"DLT_PRISM_HEADER",
"DLT_AIRONET_HEADER",
"DLT_HHDLC",
"DLT_IP_OVER_FC",
"DLT_SUNATM",
"DLT_RIO",
"DLT_PCI_EXP",
"DLT_AURORA",
"DLT_IEEE802_11_RADIO",
"DLT_TZSP",
"DLT_ARCNET_LINUX",
"DLT_JUNIPER_MLPPP",
"DLT_JUNIPER_MLFR",
"DLT_JUNIPER_ES",
"DLT_JUNIPER_GGSN",
"DLT_JUNIPER_MFR",
"DLT_JUNIPER_ATM2",
"DLT_JUNIPER_SERVICES",
"DLT_JUNIPER_ATM1",
"DLT_APPLE_IP_OVER_IEEE1394",
"DLT_MTP2_WITH_PHDR",
"DLT_MTP2",
"DLT_MTP3",
"DLT_SCCP",
"DLT_DOCSIS",
"DLT_LINUX_IRDA",
"DLT_IBM_SP",
"DLT_IBM_SN",
"DLT_USER0",
"DLT_USER1",
"DLT_USER2",
"DLT_USER3",
"DLT_USER4",
"DLT_USER5",
"DLT_USER6",
"DLT_USER7",
"DLT_USER8",
"DLT_USER9",
"DLT_USER10",
"DLT_USER11",
"DLT_USER12",
"DLT_USER13",
"DLT_USER14",
"DLT_USER15",
"DLT_IEEE802_11_RADIO_AVS",
"DLT_JUNIPER_MONITOR",
"DLT_BACNET_MS_TP",
"DLT_PPP_PPPD",
"DLT_JUNIPER_PPPOE",
"DLT_JUNIPER_PPPOE_ATM",
"DLT_GPRS_LLC",
"DLT_GPF_T",
"DLT_GPF_F",
"DLT_GCOM_T1E1",
"DLT_GCOM_SERIAL",
"DLT_JUNIPER_PIC_PEER",
"DLT_ERF_ETH",
"DLT_ERF_POS",
"DLT_LINUX_LAPD",
"DLT_JUNIPER_ETHER",
"DLT_JUNIPER_PPP",
"DLT_JUNIPER_FRELAY",
"DLT_JUNIPER_CHDLC",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
NULL
};

461
src/common/dlt_names.h Normal file
View File

@@ -0,0 +1,461 @@
/* $Id: dlt_names.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2006-2010 Aaron Turner
* All rights reserved.
*
* This file is generated by scripts/dlt2name.pl which converts your pcap-bpf.h
* header file which comes with libpcap into a header file
* which translates DLT values to their string names as well as a list of all
* of the available DLT types.
*
* Hence DO NOT EDIT THIS FILE!
* If your DLT type is not listed here, edit the %known hash in
* scripts/dlt2name.pl
*
* This file contains data which was taken from libpcap's pcap-bpf.h.
* The copyright/license is included below:
*/
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.34.2.6 2005/08/13 22:29:47 hannes Exp $ (LBL)
*/
/* include all the DLT types form pcap-bpf.h */
extern const char *dlt2desc[];
extern const char *dlt2name[];
#define DLT2DESC_LEN 181
#define DLT2NAME_LEN 181
#ifndef DLT_NULL
#define DLT_NULL 0
#endif
#ifndef DLT_EN10MB
#define DLT_EN10MB 1
#endif
#ifndef DLT_EN3MB
#define DLT_EN3MB 2
#endif
#ifndef DLT_AX25
#define DLT_AX25 3
#endif
#ifndef DLT_PRONET
#define DLT_PRONET 4
#endif
#ifndef DLT_CHAOS
#define DLT_CHAOS 5
#endif
#ifndef DLT_IEEE802
#define DLT_IEEE802 6
#endif
#ifndef DLT_ARCNET
#define DLT_ARCNET 7
#endif
#ifndef DLT_SLIP
#define DLT_SLIP 8
#endif
#ifndef DLT_PPP
#define DLT_PPP 9
#endif
#ifndef DLT_FDDI
#define DLT_FDDI 10
#endif
#ifndef DLT_ATM_RFC1483
#define DLT_ATM_RFC1483 11
#endif
#ifndef DLT_RAW
#define DLT_RAW 12
#endif
#ifndef DLT_ENC
#define DLT_ENC 13
#endif
#ifndef DLT_PPP_BSDOS
#define DLT_PPP_BSDOS 14
#endif
#ifndef DLT_SLIP_BSDOS
#define DLT_SLIP_BSDOS 15
#endif
#ifndef DLT_PPP_BSDOS
#define DLT_PPP_BSDOS 16
#endif
#ifndef DLT_OLD_PFLOG
#define DLT_OLD_PFLOG 17
#endif
#ifndef DLT_PFSYNC
#define DLT_PFSYNC 18
#endif
#ifndef DLT_ATM_CLIP
#define DLT_ATM_CLIP 19
#endif
#ifndef DLT_REDBACK_SMARTEDGE
#define DLT_REDBACK_SMARTEDGE 32
#endif
#ifndef DLT_PPP_SERIAL
#define DLT_PPP_SERIAL 50
#endif
#ifndef DLT_PPP_ETHER
#define DLT_PPP_ETHER 51
#endif
#ifndef DLT_SYMANTEC_FIREWALL
#define DLT_SYMANTEC_FIREWALL 99
#endif
#ifndef DLT_C_HDLC
#define DLT_C_HDLC 104
#endif
#ifndef DLT_IEEE802_11
#define DLT_IEEE802_11 105
#endif
#ifndef DLT_FRELAY
#define DLT_FRELAY 107
#endif
#ifndef DLT_LOOP
#define DLT_LOOP 108
#endif
#ifndef DLT_ENC
#define DLT_ENC 109
#endif
#ifndef DLT_LINUX_SLL
#define DLT_LINUX_SLL 113
#endif
#ifndef DLT_LTALK
#define DLT_LTALK 114
#endif
#ifndef DLT_ECONET
#define DLT_ECONET 115
#endif
#ifndef DLT_IPFILTER
#define DLT_IPFILTER 116
#endif
#ifndef DLT_PFLOG
#define DLT_PFLOG 117
#endif
#ifndef DLT_CISCO_IOS
#define DLT_CISCO_IOS 118
#endif
#ifndef DLT_PRISM_HEADER
#define DLT_PRISM_HEADER 119
#endif
#ifndef DLT_AIRONET_HEADER
#define DLT_AIRONET_HEADER 120
#endif
#ifndef DLT_HHDLC
#define DLT_HHDLC 121
#endif
#ifndef DLT_IP_OVER_FC
#define DLT_IP_OVER_FC 122
#endif
#ifndef DLT_SUNATM
#define DLT_SUNATM 123
#endif
#ifndef DLT_RIO
#define DLT_RIO 124
#endif
#ifndef DLT_PCI_EXP
#define DLT_PCI_EXP 125
#endif
#ifndef DLT_AURORA
#define DLT_AURORA 126
#endif
#ifndef DLT_IEEE802_11_RADIO
#define DLT_IEEE802_11_RADIO 127
#endif
#ifndef DLT_TZSP
#define DLT_TZSP 128
#endif
#ifndef DLT_ARCNET_LINUX
#define DLT_ARCNET_LINUX 129
#endif
#ifndef DLT_JUNIPER_MLPPP
#define DLT_JUNIPER_MLPPP 130
#endif
#ifndef DLT_JUNIPER_MLFR
#define DLT_JUNIPER_MLFR 131
#endif
#ifndef DLT_JUNIPER_ES
#define DLT_JUNIPER_ES 132
#endif
#ifndef DLT_JUNIPER_GGSN
#define DLT_JUNIPER_GGSN 133
#endif
#ifndef DLT_JUNIPER_MFR
#define DLT_JUNIPER_MFR 134
#endif
#ifndef DLT_JUNIPER_ATM2
#define DLT_JUNIPER_ATM2 135
#endif
#ifndef DLT_JUNIPER_SERVICES
#define DLT_JUNIPER_SERVICES 136
#endif
#ifndef DLT_JUNIPER_ATM1
#define DLT_JUNIPER_ATM1 137
#endif
#ifndef DLT_APPLE_IP_OVER_IEEE1394
#define DLT_APPLE_IP_OVER_IEEE1394 138
#endif
#ifndef DLT_MTP2_WITH_PHDR
#define DLT_MTP2_WITH_PHDR 139
#endif
#ifndef DLT_MTP2
#define DLT_MTP2 140
#endif
#ifndef DLT_MTP3
#define DLT_MTP3 141
#endif
#ifndef DLT_SCCP
#define DLT_SCCP 142
#endif
#ifndef DLT_DOCSIS
#define DLT_DOCSIS 143
#endif
#ifndef DLT_LINUX_IRDA
#define DLT_LINUX_IRDA 144
#endif
#ifndef DLT_IBM_SP
#define DLT_IBM_SP 145
#endif
#ifndef DLT_IBM_SN
#define DLT_IBM_SN 146
#endif
#ifndef DLT_USER0
#define DLT_USER0 147
#endif
#ifndef DLT_USER1
#define DLT_USER1 148
#endif
#ifndef DLT_USER2
#define DLT_USER2 149
#endif
#ifndef DLT_USER3
#define DLT_USER3 150
#endif
#ifndef DLT_USER4
#define DLT_USER4 151
#endif
#ifndef DLT_USER5
#define DLT_USER5 152
#endif
#ifndef DLT_USER6
#define DLT_USER6 153
#endif
#ifndef DLT_USER7
#define DLT_USER7 154
#endif
#ifndef DLT_USER8
#define DLT_USER8 155
#endif
#ifndef DLT_USER9
#define DLT_USER9 156
#endif
#ifndef DLT_USER10
#define DLT_USER10 157
#endif
#ifndef DLT_USER11
#define DLT_USER11 158
#endif
#ifndef DLT_USER12
#define DLT_USER12 159
#endif
#ifndef DLT_USER13
#define DLT_USER13 160
#endif
#ifndef DLT_USER14
#define DLT_USER14 161
#endif
#ifndef DLT_USER15
#define DLT_USER15 162
#endif
#ifndef DLT_IEEE802_11_RADIO_AVS
#define DLT_IEEE802_11_RADIO_AVS 163
#endif
#ifndef DLT_JUNIPER_MONITOR
#define DLT_JUNIPER_MONITOR 164
#endif
#ifndef DLT_BACNET_MS_TP
#define DLT_BACNET_MS_TP 165
#endif
#ifndef DLT_PPP_PPPD
#define DLT_PPP_PPPD 166
#endif
#ifndef DLT_JUNIPER_PPPOE
#define DLT_JUNIPER_PPPOE 167
#endif
#ifndef DLT_JUNIPER_PPPOE_ATM
#define DLT_JUNIPER_PPPOE_ATM 168
#endif
#ifndef DLT_GPRS_LLC
#define DLT_GPRS_LLC 169
#endif
#ifndef DLT_GPF_T
#define DLT_GPF_T 170
#endif
#ifndef DLT_GPF_F
#define DLT_GPF_F 171
#endif
#ifndef DLT_GCOM_T1E1
#define DLT_GCOM_T1E1 172
#endif
#ifndef DLT_GCOM_SERIAL
#define DLT_GCOM_SERIAL 173
#endif
#ifndef DLT_JUNIPER_PIC_PEER
#define DLT_JUNIPER_PIC_PEER 174
#endif
#ifndef DLT_ERF_ETH
#define DLT_ERF_ETH 175
#endif
#ifndef DLT_ERF_POS
#define DLT_ERF_POS 176
#endif
#ifndef DLT_LINUX_LAPD
#define DLT_LINUX_LAPD 177
#endif
#ifndef DLT_JUNIPER_ETHER
#define DLT_JUNIPER_ETHER 178
#endif
#ifndef DLT_JUNIPER_PPP
#define DLT_JUNIPER_PPP 179
#endif
#ifndef DLT_JUNIPER_FRELAY
#define DLT_JUNIPER_FRELAY 180
#endif
#ifndef DLT_JUNIPER_CHDLC
#define DLT_JUNIPER_CHDLC 181
#endif

157
src/common/err.c Normal file
View File

@@ -0,0 +1,157 @@
/* $Id: err.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* err.c
*
* Adapted from OpenBSD libc *err* *warn* code.
*
* Copyright (c) 2001-2010 Aaron Turner.
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#ifdef DEBUG
extern int debug;
#endif
/**
* writes a notice message to stderr. Always forces a newline
*/
void
notice(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (fmt != NULL)
(void)vfprintf(stderr, fmt, ap);
(void)fprintf(stderr, "\n");
va_end(ap);
fflush(NULL);
}
/**
* Inner call to dbgx() which prints the function, line & function along
* with the message to stderr. Always forces a newline.
*
* You don't actually want to call this! use dbgx() instead!
*/
#ifdef DEBUG
void
_our_verbose_dbgx(int dbg_level, const char *fmt, const char *function,
const int line, const char *file, ...)
{
va_list ap;
if (debug < dbg_level)
return;
fprintf(stderr, "DEBUG%d in %s:%s() line %d: ", dbg_level, file,
function, line);
va_start(ap, file);
if (fmt != NULL)
(void)vfprintf(stderr, fmt, ap);
(void)fprintf(stderr, "\n");
va_end(ap);
fflush(NULL);
}
#endif
/**
* Inner call to errx() which when in DEBUG mode, prints the function, line & file
* along with the actual error message to stderr. Alawys forces a newline
*/
#ifdef DEBUG
void
_our_verbose_errx(int eval, const char *fmt, const char *function, const int line, const char *file, ...) {
#else
void
_our_verbose_errx(int eval, const char *fmt, ...) {
#endif
va_list ap;
#ifdef DEBUG
fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n", file, function, line);
va_start(ap, file);
#else
fprintf(stderr, "\nFatal Error: ");
va_start(ap, fmt);
#endif
if (fmt != NULL)
(void)vfprintf(stderr, fmt, ap);
(void)fprintf(stderr, "\n");
va_end(ap);
exit(eval);
}
/**
* Inner call to warnx() which when in DEBUG mode, prints the function, line & file
* along with the actual warning to stderr. Alawys forces a newline
*/
#ifdef DEBUG
void
_our_verbose_warnx(const char *fmt, const char *function, const int line, const char *file, ...) {
#else
void
_our_verbose_warnx(const char *fmt, ...) {
#endif
va_list ap;
#ifdef DEBUG
fprintf(stderr, "Warning in %s:%s() line %d:\n", file, function, line);
va_start(ap, file);
#else
fprintf(stderr, "Warning: ");
va_start(ap, fmt);
#endif
if (fmt != NULL)
(void)vfprintf(stderr, fmt, ap);
(void)fprintf(stderr, "\n");
va_end(ap);
}

128
src/common/err.h Normal file
View File

@@ -0,0 +1,128 @@
/* $Id: err.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* err.h
*
* Adapted from OpenBSD libc *err* *warn* code.
*
* Copyright (c) 2001-2010 Aaron Turner.
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)err.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _ERR_H_
#define _ERR_H_
#include <stdlib.h>
#ifdef DEBUG
extern int debug;
#endif
/*
* We define five functions for reporting errors, warnings and debug messages:
* err() - Fatal error. Pass exit code followed by static string
* errx() - Fatal error. Pass exit code, format string, one or more variables
* warn() - Warning. Pass static string
* warnx() - Warning. Pass format string, one or more variables
* dbg() - Debug. Debug level to trigger, static string
* dbgx() - Debug. Debug level to trigger, format string, one or more variables
* notice() - Informational only via stderr, format string, one or more variables
*/
/* gcc accepts __FUNCTION__, but C99 says use __func__. Necessary for SunPro compiler */
#if !defined(__GNUC__) && !defined(__FUNCTION__)
# define __FUNCTION__ __func__
#endif
void notice(const char *fmt, ...);
#ifdef DEBUG /* then err, errx, warn, warnx print file, func, line */
#define dbg(x, y) do { \
if (debug >= x) \
fprintf(stderr, "DEBUG%d in %s:%s() line %d: %s\n", x, __FILE__, __FUNCTION__, __LINE__, y); \
} while(0)
#define dbgx(x, y, ...) do { \
if (debug >= x) { \
fprintf(stderr, "DEBUG%d in %s:%s() line %d: " y "\n", x, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__); \
} \
} while(0)
#define warn(x) fprintf(stderr, "Warning in %s:%s() line %d:\n%s\n", __FILE__, __FUNCTION__, __LINE__, x)
#define warnx(x, ...) fprintf(stderr, "Warning in %s:%s() line %d:\n" x "\n", __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#define err(x, y) do { \
fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n%s\n", __FILE__, __FUNCTION__, __LINE__, y); \
fflush(NULL); \
exit(x); \
} while (0)
#define errx(x, y, ...) do {\
fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n " y "\n", __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__); \
fflush(NULL); \
exit(x); \
} while (0)
#else /* no detailed DEBUG info */
/* dbg() and dbgx() become no-ops for non-DEBUG builds */
#define dbg(x, y) { }
#define dbgx(x, y, ...) { }
#define warn(x) fprintf(stderr, "Warning: %s\n", x)
#define warnx(x, ...) fprintf(stderr, "Warning: " x "\n", __VA_ARGS__)
#define err(x, y) do {\
fprintf(stderr, "\nFatal Error:\n%s\n", y); \
fflush(NULL); \
exit(x); \
} while(0)
#define errx(x, y, ...) do {\
fprintf(stderr, "\nFatal Error: " y "\n", __VA_ARGS__); \
fflush(NULL); \
exit(x); \
} while (0)
#endif /* DEBUG */
#endif /* !_ERR_H_ */

86
src/common/fakepcap.c Normal file
View File

@@ -0,0 +1,86 @@
/* $Id: fakepcap.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2004-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This file impliments missing libpcap functions which only exist in really
* recent versions of libpcap. We assume the user has at least 0.6, so anything
* after that needs to be re-implimented here unless we want to start
* requiring a newer version
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdlib.h>
#ifndef HAVE_DLT_VAL_TO_DESC
/**
* replacement for libpcap's pcap_datalink_val_to_description()
* which doesn't exist in all versions
*/
const char *
pcap_datalink_val_to_description(int dlt)
{
if (dlt > DLT2DESC_LEN)
return "Unknown";
return dlt2desc[dlt];
}
/**
* replacement for libpcap's pcap_datalink_val_to_name()
* which doesn't exist in all versions
*/
const char *
pcap_datalink_val_to_name(int dlt)
{
if (dlt > DLT2NAME_LEN)
return "Unknown";
return dlt2name[dlt];
}
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

70
src/common/fakepcap.h Normal file
View File

@@ -0,0 +1,70 @@
/* $Id: fakepcap.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2004-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FAKEPCAP_H_
#define _FAKEPCAP_H_
#include "config.h"
/*
* libpcap <= 0.5 don't have some DLT types. Add them here
*/
#ifndef HAVE_DLT_LINUX_SLL
#define DLT_LINUX_SLL 113
#endif
#ifndef HAVE_DLT_C_HDLC
#define DLT_C_HDLC 104
#endif
/*
* libpcap < 0.8 don't have pcap_datalink_val_to_description()
* and pcap_datalink_val_to_name()
*/
#ifndef HAVE_DLT_VAL_TO_DESC
const char *pcap_datalink_val_to_description(int dlt);
const char *pcap_datalink_val_to_name(int dlt);
#endif
#endif /* end of _FAKEPCAP_H_ */
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

108
src/common/fakepcapnav.c Normal file
View File

@@ -0,0 +1,108 @@
/* $Id: fakepcapnav.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* This file impliments a fake, non-functioning version of the libpcapnav
* API based on libpcap. It's solely here for people who don't have
* libpcapnav installed on their system, and to keep the code maintainable.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdlib.h>
#ifndef HAVE_PCAPNAV
/**
* pcapnav_init does nothing!
*/
void
pcapnav_init(void)
{
return;
}
/**
* pcapnav_open_offline opens a pcap file,
* and creates the struct for our use
*/
pcapnav_t *
pcapnav_open_offline(const char *filename)
{
pcapnav_t *pcapnav;
char errbuf[PCAP_ERRBUF_SIZE];
pcapnav = (pcapnav_t *) malloc(sizeof(pcapnav_t));
if (pcapnav == NULL) {
err(-1, "malloc() error: unable to malloc pcapnav_t");
}
pcapnav->pcap = pcap_open_offline(filename, errbuf);
if (pcapnav->pcap == NULL) {
errx(-1, "Error opening pcap file %s: %s", filename, errbuf);
}
return (pcapnav);
}
/**
* closes our pcap file and free's the pcapnav
*/
void
pcapnav_close(pcapnav_t * pcapnav)
{
pcap_close(pcapnav->pcap);
safe_free(pcapnav);
}
/**
* returns the pcap_t data struct
*/
pcap_t *
pcapnav_pcap(pcapnav_t * pcapnav)
{
return (pcapnav->pcap);
}
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

69
src/common/fakepcapnav.h Normal file
View File

@@ -0,0 +1,69 @@
/* $Id: fakepcapnav.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_PCAPNAV
#include <pcapnav.h>
#define _FAKEPCAPNAV_H_
#endif
#ifndef _FAKEPCAPNAV_H_
#define _FAKEPCAPNAV_H_
#include "config.h"
#include "defines.h"
#ifndef HAVE_PCAPNAV
typedef struct pcapnav pcapnav_t;
struct pcapnav {
pcap_t *pcap;
};
void pcapnav_init(void);
pcapnav_t *pcapnav_open_offline(const char *);
void pcapnav_close(pcapnav_t *);
pcap_t *pcapnav_pcap(pcapnav_t *);
#endif
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

148
src/common/fakepoll.c Normal file
View File

@@ -0,0 +1,148 @@
/* $Id: fakepoll.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* fakepoll.c
*
* On systems where 'poll' doesn't exist, fake it with 'select'.
*
* Copyright (c) 2001-2003, Nick Mathewson <nickm@freehaven.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
/* prevents ISO C error */
static void FAKEPOLL(int stop)
{
if (! stop)
FAKEPOLL(1);
return;
}
#ifdef USE_FAKE_POLL
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#if _MSC_VER > 1300
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(_MSC_VER)
#include <winsock.h>
#endif
/* by default, windows handles only 64 fd's */
#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
#define FD_SETSIZE MAXCONNECTIONS
#endif
#include "util.h"
/**
* custom version of poll() using select() in the backend
* only used if you don't actually have poll on your system.
*/
int
poll(struct pollfd *ufds, unsigned int nfds, int timeout)
{
int idx, maxfd, fd;
int r;
#ifdef MS_WINDOWS
int any_fds_set = 0;
#endif
fd_set readfds, writefds, exceptfds;
#ifdef USING_FAKE_TIMEVAL
#undef timeval
#undef tv_sec
#undef tv_usec
#endif
struct timeval _timeout;
_timeout.tv_sec = timeout / 1000;
_timeout.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
maxfd = -1;
for (idx = 0; idx < nfds; ++idx) {
ufds[idx].revents = 0;
fd = ufds[idx].fd;
if (fd > maxfd) {
maxfd = fd;
#ifdef MS_WINDOWS
any_fds_set = 1;
#endif
}
if (ufds[idx].events & POLLIN)
FD_SET(fd, &readfds);
if (ufds[idx].events & POLLOUT)
FD_SET(fd, &writefds);
FD_SET(fd, &exceptfds);
}
#ifdef MS_WINDOWS
if (!any_fds_set) {
Sleep(timeout);
return 0;
}
#endif
r = select(maxfd + 1, &readfds, &writefds, &exceptfds,
timeout == -1 ? NULL : &_timeout);
if (r <= 0)
return r;
r = 0;
for (idx = 0; idx < nfds; ++idx) {
fd = ufds[idx].fd;
if (FD_ISSET(fd, &readfds))
ufds[idx].revents |= POLLIN;
if (FD_ISSET(fd, &writefds))
ufds[idx].revents |= POLLOUT;
if (FD_ISSET(fd, &exceptfds))
ufds[idx].revents |= POLLERR;
if (ufds[idx].revents)
++r;
}
return r;
}
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

86
src/common/fakepoll.h Normal file
View File

@@ -0,0 +1,86 @@
/* $Id: fakepoll.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* fakepoll.h
*
* On systems where 'poll' doesn't exist, fake it with 'select'.
*
* Copyright (c) 2001-2003, Nick Mathewson <nickm@freehaven.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* don't warn on OS X that poll is emulated */
#define POLL_NO_WARN
#define SYS_POLL_NO_WARN
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#define __FAKEPOLL_H
#elif HAVE_POLL_H
#include <poll.h>
#define __FAKEPOLL_H
#endif
#ifndef __FAKEPOLL_H
#define __FAKEPOLL_H
#include "config.h"
#ifndef HAVE_POLL_H
#ifndef HAVE_SYS_POLL_H
#define USE_FAKE_POLL
struct pollfd {
int fd;
short events;
short revents;
};
#define POLLIN 0x0001
#define POLLPRI 0x0002
#define POLLOUT 0x0004
#define POLLERR 0x0008
#define POLLHUP 0x0010
#define POLLNVAL 0x0020
int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
#endif
#endif
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

633
src/common/get.c Normal file
View File

@@ -0,0 +1,633 @@
/* $Id: get.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include "../../lib/sll.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#ifdef DEBUG
extern int debug;
#endif
#if defined HAVE_PCAP_VERSION && ! defined HAVE_WIN32
extern const char pcap_version[];
#endif
/**
* Depending on what version of libpcap/WinPcap there are different ways to get the
* version of the libpcap/WinPcap library. This presents a unified way to get that
* information.
*/
const char *
get_pcap_version(void)
{
#if defined HAVE_WINPCAP
static char ourver[255];
char *last, *version;
/* WinPcap returns a string like:
* WinPcap version 4.0 (packet.dll version 4.0.0.755), based on libpcap version 0.9.5
*/
version = safe_strdup(pcap_lib_version());
strtok_r(version, " ", &last);
strtok_r(NULL, " ", &last);
strlcpy(ourver, strtok_r(NULL, " ", &last), 255);
safe_free(version);
return ourver;
#elif defined HAVE_PCAP_VERSION
return pcap_version;
#else
return pcap_lib_version();
#endif
}
/**
* returns the L2 protocol (IP, ARP, etc)
* or 0 for error
*/
u_int16_t
get_l2protocol(const u_char *pktdata, const int datalen, const int datalink)
{
eth_hdr_t *eth_hdr;
vlan_hdr_t *vlan_hdr;
hdlc_hdr_t *hdlc_hdr;
sll_hdr_t *sll_hdr;
u_int16_t ether_type;
assert(pktdata);
assert(datalen);
switch (datalink) {
case DLT_RAW:
return ETHERTYPE_IP;
break;
case DLT_EN10MB:
eth_hdr = (eth_hdr_t *)pktdata;
ether_type = ntohs(eth_hdr->ether_type);
switch (ether_type) {
case ETHERTYPE_VLAN: /* 802.1q */
vlan_hdr = (vlan_hdr_t *)pktdata;
return ntohs(vlan_hdr->vlan_len);
default:
return ether_type; /* yes, return it in host byte order */
}
break;
case DLT_C_HDLC:
hdlc_hdr = (hdlc_hdr_t *)pktdata;
return hdlc_hdr->protocol;
break;
case DLT_LINUX_SLL:
sll_hdr = (sll_hdr_t *)pktdata;
return sll_hdr->sll_protocol;
break;
default:
errx(-1, "Unable to process unsupported DLT type: %s (0x%x)",
pcap_datalink_val_to_description(datalink), datalink);
}
return 0;
}
/**
* returns the length in number of bytes of the L2 header, or -1 on error
*/
int
get_l2len(const u_char *pktdata, const int datalen, const int datalink)
{
eth_hdr_t *eth_hdr;
assert(pktdata);
assert(datalen);
switch (datalink) {
case DLT_RAW:
/* pktdata IS the ip header! */
return 0;
break;
case DLT_EN10MB:
eth_hdr = (struct tcpr_ethernet_hdr *)pktdata;
switch (ntohs(eth_hdr->ether_type)) {
case ETHERTYPE_VLAN:
return 18;
break;
default:
return 14;
break;
}
break;
case DLT_C_HDLC:
return CISCO_HDLC_LEN;
break;
case DLT_LINUX_SLL:
return SLL_HDR_LEN;
break;
default:
errx(-1, "Unable to process unsupported DLT type: %s (0x%x)",
pcap_datalink_val_to_description(datalink), datalink);
break;
}
return -1; /* we shouldn't get here */
}
/**
* returns a ptr to the ip header + data or NULL if it's not IP
* we may use an extra buffer for the ip header (and above)
* on stricly aligned systems where the layer 2 header doesn't
* fall on a 4 byte boundry (like a standard ethernet header)
*
* Note: you can cast the result as an ip_hdr_t, but you'll be able
* to access data above the header minus any stripped L2 data
*/
const u_char *
get_ipv4(const u_char *pktdata, int datalen, int datalink, u_char **newbuff)
{
const u_char *ip_hdr = NULL;
int l2_len = 0;
u_int16_t proto;
assert(pktdata);
assert(datalen);
assert(*newbuff);
l2_len = get_l2len(pktdata, datalen, datalink);
/* sanity... datalen must be > l2_len + IP header len*/
if (l2_len + TCPR_IPV4_H > datalen) {
dbg(1, "get_ipv4(): Layer 2 len > total packet len, hence no IP header");
return NULL;
}
proto = get_l2protocol(pktdata, datalen, datalink);
if (proto != ETHERTYPE_IP)
return NULL;
#ifdef FORCE_ALIGN
/*
* copy layer 3 and up to our temp packet buffer
* for now on, we have to edit the packetbuff because
* just before we send the packet, we copy the packetbuff
* back onto the pkt.data + l2len buffer
* we do all this work to prevent byte alignment issues
*/
if (l2_len % 4) {
ip_hdr = *newbuff;
memcpy(ip_hdr, (pktdata + l2_len), (datalen - l2_len));
} else {
/* we don't have to do a memcpy if l2_len lands on a boundry */
ip_hdr = (pktdata + l2_len);
}
#else
/*
* on non-strict byte align systems, don't need to memcpy(),
* just point to l2len bytes into the existing buffer
*/
ip_hdr = (pktdata + l2_len);
#endif
return ip_hdr;
}
const u_char *
get_ipv6(const u_char *pktdata, int datalen, int datalink, u_char **newbuff)
{
const u_char *ip6_hdr = NULL;
int l2_len = 0;
u_int16_t proto;
assert(pktdata);
assert(datalen);
assert(*newbuff);
l2_len = get_l2len(pktdata, datalen, datalink);
/* sanity... datalen must be > l2_len + IP header len*/
if (l2_len + TCPR_IPV6_H > datalen) {
dbg(1, "get_ipv6(): Layer 2 len > total packet len, hence no IPv6 header");
return NULL;
}
proto = get_l2protocol(pktdata, datalen, datalink);
if (proto != ETHERTYPE_IP6)
return NULL;
#ifdef FORCE_ALIGN
/*
* copy layer 3 and up to our temp packet buffer
* for now on, we have to edit the packetbuff because
* just before we send the packet, we copy the packetbuff
* back onto the pkt.data + l2len buffer
* we do all this work to prevent byte alignment issues
*/
if (l2_len % 4) {
ip6_hdr = *newbuff;
memcpy(ip6_hdr, (pktdata + l2_len), (datalen - l2_len));
} else {
/* we don't have to do a memcpy if l2_len lands on a boundry */
ip6_hdr = (pktdata + l2_len);
}
#else
/*
* on non-strict byte align systems, don't need to memcpy(),
* just point to l2len bytes into the existing buffer
*/
ip6_hdr = (pktdata + l2_len);
#endif
return ip6_hdr;
}
/**
* returns a pointer to the layer 4 header which is just beyond the IPv4 header
*/
void *
get_layer4_v4(const ipv4_hdr_t *ip_hdr)
{
void *ptr;
assert(ip_hdr);
ptr = (u_int32_t *) ip_hdr + ip_hdr->ip_hl;
return ((void *)ptr);
}
/**
* returns a pointer to the layer 4 header which is just beyond the IPv6 header
* and any exension headers or NULL when there is none as in the case of
* v6 Frag or ESP header. Function is recursive.
*/
void *
get_layer4_v6(const ipv6_hdr_t *ip6_hdr)
{
struct tcpr_ipv6_ext_hdr_base *next, *exthdr;
u_int8_t proto;
assert(ip6_hdr);
/* jump to the end of the IPv6 header */
next = (struct tcpr_ipv6_ext_hdr_base *)((u_char *)ip6_hdr + TCPR_IPV6_H);
proto = ip6_hdr->ip_nh;
while (TRUE) {
dbgx(3, "Processing proto: 0x%hx", proto);
switch (proto) {
/* recurse due to v6-in-v6, need to recast next as an IPv6 Header */
case TCPR_IPV6_NH_IPV6:
dbg(3, "recursing due to v6-in-v6");
return get_layer4_v6((ipv6_hdr_t *)next);
break;
/* loop again */
case TCPR_IPV6_NH_AH:
case TCPR_IPV6_NH_ROUTING:
case TCPR_IPV6_NH_DESTOPTS:
case TCPR_IPV6_NH_HBH:
dbgx(3, "Going deeper due to extension header 0x%02X", proto);
exthdr = get_ipv6_next(next);
proto = exthdr->ip_nh;
next = exthdr;
break;
/*
* Can't handle. Unparsable IPv6 fragment/encrypted data
*/
case TCPR_IPV6_NH_FRAGMENT:
case TCPR_IPV6_NH_ESP:
return NULL;
break;
/*
* no further processing, either TCP, UDP, ICMP, etc...
*/
default:
if (proto != ip6_hdr->ip_nh) {
dbgx(3, "Returning byte offset of this ext header: %u", IPV6_EXTLEN_TO_BYTES(next->ip_len));
return (void *)((u_char *)next + IPV6_EXTLEN_TO_BYTES(next->ip_len));
} else {
dbgx(3, "%s", "Returning end of IPv6 Header");
return next;
}
break;
} /* switch */
} /* while */
}
/**
* returns the next payload or header of the current extention header
* returns NULL for none/ESP.
*/
void *
get_ipv6_next(struct tcpr_ipv6_ext_hdr_base *exthdr)
{
int len = 0;
assert(exthdr);
dbgx(3, "Jumping to next IPv6 header. Processing 0x%02x", exthdr->ip_nh);
switch (exthdr->ip_nh) {
/* no further processing */
case TCPR_IPV6_NH_NO_NEXT:
case TCPR_IPV6_NH_ESP:
dbg(3, "No-Next or ESP... can't go any further...");
return NULL;
break;
/*
* fragment header is fixed size
* FIXME: Frag header has further ext headers (has a ip_nh field)
* but I don't support it because there's never a full L4 + payload beyond.
*/
case TCPR_IPV6_NH_FRAGMENT:
dbg(3, "Looks like were a fragment header. Returning some frag'd data.");
return (void *)((u_char *)exthdr + sizeof(struct tcpr_ipv6_frag_hdr));
break;
/* all the rest require us to go deeper using the ip_len field */
case TCPR_IPV6_NH_IPV6:
case TCPR_IPV6_NH_ROUTING:
case TCPR_IPV6_NH_DESTOPTS:
case TCPR_IPV6_NH_HBH:
case TCPR_IPV6_NH_AH:
len = IPV6_EXTLEN_TO_BYTES(exthdr->ip_len);
dbgx(3, "Looks like we're an ext header (0x%hhx). Jumping %u bytes to the next", exthdr->ip_nh, len);
return (void *)((u_char *)exthdr + len);
break;
default:
dbg(3, "Must not be a v6 extension header... returning self");
return (void *)exthdr;
break;
}
}
/**
* returns the protocol of the actual layer4 header by processing through
* the extension headers
*/
u_int8_t
get_ipv6_l4proto(const ipv6_hdr_t *ip6_hdr)
{
u_char *ptr = (u_char *)ip6_hdr + TCPR_IPV6_H; /* jump to the end of the IPv6 header */
u_int8_t proto;
struct tcpr_ipv6_ext_hdr_base *exthdr = NULL;
proto = ip6_hdr->ip_nh;
assert(ip6_hdr);
while (TRUE) {
dbgx(3, "Processing next proto 0x%02X", proto);
switch (proto) {
/* no further processing for IPV6 types with nothing beyond them */
case TCPR_IPV6_NH_FRAGMENT:
case TCPR_IPV6_NH_ESP:
dbg(3, "No-Next or ESP... can't go any further...");
return proto;
break;
/* recurse */
case TCPR_IPV6_NH_IPV6:
dbg(3, "Recursing due to v6 in v6");
return get_ipv6_l4proto((ipv6_hdr_t *)ptr);
break;
/* loop again */
case TCPR_IPV6_NH_AH:
case TCPR_IPV6_NH_ROUTING:
case TCPR_IPV6_NH_DESTOPTS:
case TCPR_IPV6_NH_HBH:
dbgx(3, "Jumping to next extension header (0x%hhx)", proto);
exthdr = get_ipv6_next((struct tcpr_ipv6_ext_hdr_base *)ptr);
proto = exthdr->ip_nh;
ptr = (u_char *)exthdr;
break;
/* should be TCP, UDP or the like */
default:
dbgx(3, "Selecting next L4 Proto as: 0x%02x", proto);
return proto;
}
}
}
/**
* get_name2addr4()
* stolen from LIBNET since I didn't want to have to deal with
* passing a libnet_t around. Returns 0xFFFFFFFF (255.255.255.255)
* on error
*/
u_int32_t
get_name2addr4(const char *hostname, u_int8_t dnslookup)
{
struct in_addr addr;
#if ! defined HAVE_INET_ATON && defined HAVE_INET_ADDR
struct hostent *host_ent;
#endif
u_int32_t m;
u_int val;
int i;
if (dnslookup == DNS_RESOLVE) {
#ifdef HAVE_INET_ATON
if (inet_aton(hostname, &addr) != 1) {
return(0xffffffff);
}
#elif defined HAVE_INET_ADDR
if ((addr.s_addr = inet_addr(hostname)) == INADDR_NONE) {
if (!(host_ent = gethostbyname(hostname))) {
warnx("unable to resolve %s: %s", hostname, strerror(errno));
/* XXX - this is actually 255.255.255.255 */
return (0xffffffff);
}
/* was: host_ent->h_length); */
memcpy(&addr.s_addr, host_ent->h_addr, sizeof(addr.s_addr));
}
#else
warn("Unable to support get_name2addr4 w/ resolve");
/* call ourselves recursively once w/o resolving the hostname */
return get_name2addr4(hostname, DNS_DONT_RESOLVE);
#endif
/* return in network byte order */
return (addr.s_addr);
} else {
/*
* We only want dots 'n decimals.
*/
if (!isdigit(hostname[0])) {
warnx("Expected dotted-quad notation (%s) when DNS lookups are disabled", hostname);
/* XXX - this is actually 255.255.255.255 */
return (-1);
}
m = 0;
for (i = 0; i < 4; i++) {
m <<= 8;
if (*hostname) {
val = 0;
while (*hostname && *hostname != '.') {
val *= 10;
val += *hostname - '0';
if (val > 255) {
dbgx(4, "value %d > 255 for dotted quad", val);
/* XXX - this is actually 255.255.255.255 */
return (-1);
}
hostname++;
}
m |= val;
if (*hostname) {
hostname++;
}
}
}
/* host byte order */
return (ntohl(m));
}
}
int
get_name2addr6(const char *hostname, u_int8_t dnslookup, struct tcpr_in6_addr *addr)
{
(void)dnslookup;
#ifdef HAVE_INET_PTON
return inet_pton(AF_INET6, hostname, addr);
#else
#error "Unable to support get_name2addr6."
#endif
return -1;
}
/**
* Generic wrapper around inet_ntop() and inet_ntoa() depending on whichever
* is available on your system
*/
const char *
get_addr2name4(const u_int32_t ip, u_int8_t dnslookup)
{
struct in_addr addr;
static char *new_string = NULL;
if (new_string == NULL)
new_string = (char *)safe_malloc(255);
new_string[0] = '\0';
addr.s_addr = ip;
#ifdef HAVE_INET_NTOP
if (inet_ntop(AF_INET, &addr, new_string, 255) == NULL) {
warnx("Unable to convert 0x%x to a string", ip);
strlcpy(new_string, "", sizeof(new_string));
}
return new_string;
#elif defined HAVE_INET_NTOA
return inet_ntoa(&addr);
#else
#error "Unable to support get_addr2name4."
#endif
if (dnslookup != DNS_DONT_RESOLVE) {
warn("Sorry, we don't support name resolution.");
}
return new_string;
}
const char *
get_addr2name6(const struct tcpr_in6_addr *addr, u_int8_t dnslookup)
{
static char *new_string = NULL;
if (new_string == NULL)
new_string = (char *)safe_malloc(255);
new_string[0] = '\0';
#ifdef HAVE_INET_NTOP
if (inet_ntop(AF_INET6, addr, new_string, 255) == NULL) {
warn("Unable to convert addr to a string");
strlcpy(new_string, "", sizeof(new_string));
}
return new_string;
#else
#error "Unable to support get_addr2name6."
#endif
if (dnslookup != DNS_DONT_RESOLVE) {
warn("Sorry, we don't support name resolution.");
}
return new_string;
}
const char *
get_cidr2name(const tcpr_cidr_t *cidr_ptr, u_int8_t dnslookup)
{
if (cidr_ptr->family == AF_INET) {
return get_addr2name4(cidr_ptr->u.network, dnslookup);
} else if (cidr_ptr->family == AF_INET6) {
return get_addr2name6(&cidr_ptr->u.network6, dnslookup);
} else {
return NULL;
}
}

75
src/common/get.h Normal file
View File

@@ -0,0 +1,75 @@
/* $Id: get.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GET_H__
#define __GET_H__
#include "config.h"
#include "defines.h"
#include "common.h"
int get_l2len(const u_char *pktdata, const int datalen, const int datalink);
u_int16_t get_l2protocol(const u_char *pktdata, const int datalen, const int datalink);
void *get_layer4_v4(const ipv4_hdr_t *ip_hdr);
void *get_layer4_v6(const ipv6_hdr_t *ip_hdr);
u_int8_t get_ipv6_l4proto(const ipv6_hdr_t *ip6_hdr);
void *get_ipv6_next(struct tcpr_ipv6_ext_hdr_base *exthdr);
const u_char *get_ipv4(const u_char *pktdata, int datalen, int datalink, u_char **newbuff);
const u_char *get_ipv6(const u_char *pktdata, int datalen, int datalink, u_char **newbuff);
u_int32_t get_name2addr4(const char *hostname, u_int8_t dnslookup);
const char *get_addr2name4(const u_int32_t ip, u_int8_t dnslookup);
const char *get_addr2name6(const struct tcpr_in6_addr *addr, u_int8_t dnslookup);
const char *get_pcap_version(void);
int get_name2addr6(const char *hostname, u_int8_t dnslookup, struct tcpr_in6_addr *addr);
const char *get_cidr2name(const tcpr_cidr_t *cidr_ptr, u_int8_t dnslookup);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

158
src/common/interface.c Normal file
View File

@@ -0,0 +1,158 @@
/* $Id: interface.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2007-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include "config.h"
#include "defines.h"
#include "common.h"
#include "interface.h"
/**
* Method takes a user specified device name and returns
* the canonical name for that device. This allows me to
* create named interface aliases on platforms like Windows
* which use horrifically long interface names
*
* Returns NULL on error
*
* On success, it *may* malloc() memory equal to the length of *alias.
*/
char *
get_interface(interface_list_t *list, const char *alias)
{
interface_list_t *ptr;
char *name;
assert(alias);
if (list != NULL) {
ptr = list;
do {
/* check both the alias & name fields */
if (strcmp(alias, ptr->alias) == 0)
return(ptr->name);
if (strcmp(alias, ptr->name) == 0)
return(ptr->name);
ptr = ptr->next;
} while (ptr != NULL);
} else {
name = (char *)safe_malloc(strlen(alias) + 1);
strlcpy(name, alias, sizeof(name));
return(name);
}
return(NULL);
}
/**
* Get all available interfaces as an interface_list *
*/
interface_list_t *
get_interface_list(void)
{
interface_list_t *list_head, *list_ptr;
char ebuf[PCAP_ERRBUF_SIZE];
pcap_if_t *pcap_if, *pcap_if_ptr;
int i = 0;
#ifndef HAVE_WIN32
/* Unix just has a warning about being root */
if (geteuid() != 0)
warn("May need to run as root to get complete list.");
#endif
if (pcap_findalldevs(&pcap_if, ebuf) < 0)
errx(-1, "Error: %s", ebuf);
pcap_if_ptr = pcap_if;
list_head = (interface_list_t *)safe_malloc(sizeof(interface_list_t));
list_ptr = list_head;
while (pcap_if_ptr != NULL) {
if (i > 0) {
list_ptr->next = (interface_list_t *)safe_malloc(sizeof(interface_list_t));
list_ptr = list_ptr->next;
}
strlcpy(list_ptr->name, pcap_if_ptr->name, sizeof(list_ptr->name));
/* description is usually null under Unix */
if (pcap_if_ptr->description != NULL)
strlcpy(list_ptr->description, pcap_if_ptr->description, sizeof(list_ptr->description));
sprintf(list_ptr->alias, "%%%d", i++);
list_ptr->flags = pcap_if_ptr->flags;
pcap_if_ptr = pcap_if_ptr->next;
}
pcap_freealldevs(pcap_if);
return(list_head);
}
/**
* Prints all the available interfaces found by get_interface_list()
*/
void
list_interfaces(interface_list_t *list)
{
interface_list_t *ptr;
if (list == NULL) {
printf("No network interfaces available");
return;
}
printf("Available network interfaces:\n");
#ifdef HAVE_WIN32 /* Win32 has alias/name/description */
printf("Alias\tName\tDescription\n");
#endif
ptr = list;
do {
if (! ptr->flags & PCAP_IF_LOOPBACK) {
#ifdef HAVE_WIN32
printf("%s\t%s\n\t%s\n", ptr->alias, ptr->name, ptr->description);
#else
printf("%s\n", ptr->name);
#endif
}
ptr = ptr->next;
} while (ptr != NULL);
}

53
src/common/interface.h Normal file
View File

@@ -0,0 +1,53 @@
/* $Id: interface.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2007-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _INTERFACE_H_
#define _INTERFACE_H_
struct interface_list_s {
char name[255];
char alias[255];
char description[255];
u_int32_t flags;
struct interface_list_s *next;
};
typedef struct interface_list_s interface_list_t;
#define INTERFACE_LIST_SIZE (80 * 80) /* 80 cols * 80 rows */
char *get_interface(interface_list_t *, const char *);
interface_list_t *get_interface_list(void);
void list_interfaces(interface_list_t *);
#endif

218
src/common/list.c Normal file
View File

@@ -0,0 +1,218 @@
/* $Id: list.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* A generic method to parse a list of integers which are
* delimited by commas and dashes to indicate individual
* numbers and ranges
* Provides both a way to process the list and determine
* if an integer exists in the list.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#include <errno.h>
/**
* Creates a new tcpr_list entry. Malloc's memory.
*/
tcpr_list_t *
new_list()
{
tcpr_list_t *newlist;
newlist = (tcpr_list_t *)safe_malloc(sizeof(tcpr_list_t));
return (newlist);
}
/**
* Processes a string (ourstr) containing the list in human readable
* format and places the data in **list and finally returns 1 for
* success, 0 for fail.
*/
int
parse_list(tcpr_list_t ** listdata, char *ourstr)
{
tcpr_list_t *listcur, *list_ptr;
char *this = NULL;
char *first, *second;
int rcode;
regex_t preg;
char ebuf[EBUF_SIZE];
char regex[] = "^[0-9]+(-[0-9]+)?$";
char *token = NULL;
/* compile the regex first */
if ((rcode = regcomp(&preg, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
regerror(rcode, &preg, ebuf, sizeof(ebuf));
errx(-1, "Unable to compile regex (%s): %s", regex, ebuf);
}
/* first iteration */
this = strtok_r(ourstr, ",", &token);
first = this;
second = NULL;
/* regex test */
if (regexec(&preg, this, 0, NULL, 0) != 0) {
warnx("Unable to parse: %s", this);
return 0;
}
*listdata = new_list();
list_ptr = *listdata;
listcur = list_ptr;
for (u_int i = 0; i < strlen(this); i++) {
if (this[i] == '-') {
this[i] = '\0';
second = &this[i + 1];
}
}
list_ptr->min = strtoull(first, NULL, 0);
if (second != NULL) {
list_ptr->max = strtoull(second, NULL, 0);
}
else {
list_ptr->max = list_ptr->min;
}
while (1) {
this = strtok_r(NULL, ",", &token);
if (this == NULL)
break;
first = this;
second = NULL;
/* regex test */
if (regexec(&preg, this, 0, NULL, 0) != 0) {
warnx("Unable to parse: %s", this);
return 0;
}
listcur->next = new_list();
listcur = listcur->next;
for (u_int i = 0; i < strlen(this); i++) {
if (this[i] == '-') {
this[i] = '\0';
second = &this[i + 1];
}
}
listcur->min = strtoull(first, NULL, 0);
if (second != NULL) {
listcur->max = strtoull(second, NULL, 0);
}
else {
listcur->max = listcur->min;
}
}
return 1;
}
/**
* Checks to see if the given integer exists in the LIST.
*/
tcpr_dir_t
check_list(tcpr_list_t * list, COUNTER value)
{
tcpr_list_t *current;
current = list;
do {
if ((current->min != 0) && (current->max != 0)) {
if ((value >= current->min) && (value <= current->max))
return TCPR_DIR_C2S;
}
else if (current->min == 0) {
if (value <= current->max)
return TCPR_DIR_C2S;
}
else if (current->max == 0) {
if (value >= current->min)
return TCPR_DIR_C2S;
}
if (current->next != NULL) {
current = current->next;
}
else {
current = NULL;
}
} while (current != NULL);
return TCPR_DIR_S2C;
}
/**
* Free's all the memory associated with the given LIST
*/
void
free_list(tcpr_list_t * list)
{
/* recursively go down the list */
if (list->next != NULL)
free_list(list->next);
safe_free(list);
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

58
src/common/list.h Normal file
View File

@@ -0,0 +1,58 @@
/* $Id: list.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LIST_H__
#define __LIST_H__
struct list_s {
COUNTER max;
COUNTER min;
struct list_s *next;
};
typedef struct list_s tcpr_list_t;
int parse_list(tcpr_list_t **, char *);
int check_list(tcpr_list_t *, COUNTER);
void free_list(tcpr_list_t *);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

167
src/common/mac.c Normal file
View File

@@ -0,0 +1,167 @@
/* $Id: mac.c 2423 2010-03-13 07:09:49Z aturner $ */
/* Copyright 2004-2010 Aaron Turner
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include "mac.h"
/**
* converts a string representation of a MAC address, based on
* non-portable ether_aton()
*/
void
mac2hex(const char *mac, u_char *dst, int len)
{
int i;
long l;
char *pp;
if (len < 6)
return;
while (isspace(*mac))
mac++;
/* expect 6 hex octets separated by ':' or space/NUL if last octet */
for (i = 0; i < 6; i++) {
l = strtol(mac, &pp, 16);
if (pp == mac || l > 0xFF || l < 0)
return;
if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
return;
dst[i] = (u_char) l;
mac = pp + 1;
}
}
/**
* converts a string representation of TWO MAC addresses, which
* are comma deliminated into two hex values. Either *first or *second
* can be NULL if there is nothing before or after the comma.
* returns:
* 1 = first mac
* 2 = second mac
* 3 = both mac's
* 0 = none
*/
int
dualmac2hex(const char *dualmac, u_char *first, u_char *second, int len)
{
char *tok, *temp, *string;
int ret = 0;
string = safe_strdup(dualmac);
/* if we've only got a comma, then return NULL's */
if (len <= 1) {
second = first = NULL;
return 0;
}
temp = strtok_r(string, ",", &tok);
if (strlen(temp)) {
mac2hex(temp, first, len);
ret = 1;
}
temp = strtok_r(NULL, ",", &tok);
/* temp is null if no comma */
if (temp != NULL) {
if (strlen(temp)) {
mac2hex(temp, second, len);
ret += 2;
}
}
return ret;
}
/**
* Figures out if a MAC is listed in a comma delimited
* string of MAC addresses.
* returns TCPR_DIR_C2S if listed
* returns TCPR_DIR_S2C if not listed
*/
tcpr_dir_t
macinstring(const char *macstring, const u_char *mac)
{
char *tok, *tempstr, *ourstring;
u_char tempmac[6];
int len = 6, ret = TCPR_DIR_S2C;
ourstring = safe_strdup(macstring);
tempstr = strtok_r(ourstring, ",", &tok);
if (strlen(tempstr)) {
mac2hex(tempstr, tempmac, len);
if (memcmp(mac, tempmac, len) == 0) {
dbgx(3, "Packet matches: " MAC_FORMAT " sending out primary.\n", MAC_STR(tempmac));
ret = TCPR_DIR_C2S;
goto EXIT_MACINSTRING;
}
} else {
goto EXIT_MACINSTRING;
}
while ((tempstr = strtok_r(NULL, ",", &tok)) != NULL) {
mac2hex(tempstr, tempmac, len);
if (memcmp(mac, tempmac, len) == 0) {
ret = TCPR_DIR_C2S;
dbgx(3, "Packet matches: " MAC_FORMAT " sending out primary.\n", MAC_STR(tempmac));
goto EXIT_MACINSTRING;
}
}
EXIT_MACINSTRING:
safe_free(ourstring);
#ifdef DEBUG
if (ret == TCPR_DIR_S2C)
dbg(3, "Packet doesn't match any MAC addresses sending out secondary.\n");
#endif
return ret;
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

50
src/common/mac.h Normal file
View File

@@ -0,0 +1,50 @@
/* $Id: mac.h 2423 2010-03-13 07:09:49Z aturner $ */
/* Copyright 2004-2010 Aaron Turner
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MAC_H__
#define __MAC_H__
void mac2hex(const char *mac, u_char *dst, int len);
int dualmac2hex(const char *dualmac, u_char *first, u_char *second, int len);
tcpr_dir_t macinstring(const char *macstring, const u_char *mac);
#endif /* __MAC_H__ */
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

52
src/common/pcap_dlt.h Normal file
View File

@@ -0,0 +1,52 @@
/* $Id: pcap_dlt.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2004-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PCAP_DLT_H_
#define _PCAP_DLT_H_
/*
* Cisco HDLC. Used by Dag interfaces for SONET
* and possibly others
*/
#define CISCO_HDLC_LEN 4
struct hdlc_hdr_s {
u_int16_t address;
u_int16_t protocol;
};
typedef struct hdlc_hdr_s hdlc_hdr_t;
#endif /* _PCAP_DLT_H_ */

79
src/common/rdtsc.c Normal file
View File

@@ -0,0 +1,79 @@
/* $Id:$ */
/*
* Copyright (c) 2008-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
/*
* returns the # of clicks/usec
*/
u_int64_t
rdtsc_calibrate(u_int32_t mhz)
{
static u_int64_t x = 0;
u_int64_t v = 0;
struct timeval start, end, diff;
u_int64_t x1, x2;
u_int16_t n;
if (x != 0) {
return x;
} else if (mhz > 0 && x == 0) {
x = (u_int64_t)mhz;
notice("Using user specification of %llu Mhz", x);
} else {
/* haven't calculated clicks/usec yet */
for (n=0; n<16; ++n) {
gettimeofday(&start, 0);
x1 = rdtsc();
usleep(100000);
x2 = rdtsc();
gettimeofday(&end, 0);
timersub(&end, &start, &diff);
v = (x2 - x1)/(diff.tv_sec * 1000000 + diff.tv_usec);
x = x ? (x + v)/2 : v;
}
notice("Using guessimate of %llu Mhz", x);
}
return x;
}

125
src/common/rdtsc.h Normal file
View File

@@ -0,0 +1,125 @@
/* $Id:$ */
/*
* Copyright (c) 2008-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Read TimeStamp Counter (RDTSC)
* http://www-unix.mcs.anl.gov/~kazutomo/rdtsc.html
* I'm not really sure what the license is, but I'll assume Kazutomo Yoshii is
* cool with me using it since he published it on his website.
* Should also check out: http://www.fftw.org/cycle.h
*/
#ifndef __RDTSC_H__
#define __RDTSC_H__
u_int64_t rdtsc_calibrate(u_int32_t mhz);
#if defined(__i386__)
#define HAVE_RDTSC 1
static inline u_int64_t
rdtsc(void)
{
u_int64_t x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
#elif defined(__x86_64__)
#define HAVE_RDTSC 1
static inline u_int64_t
rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (u_int64_t)lo)|( ((u_int64_t)hi)<<32 );
}
#elif defined(__powerpc__)
#define HAVE_RDTSC 1
static inline u_int64_t
rdtsc(void)
{
u_int64_t result=0;
u_int32_t upper, lower,tmp;
__asm__ volatile(
"0: \n"
"\tmftbu %0 \n"
"\tmftb %1 \n"
"\tmftbu %2 \n"
"\tcmpw %2,%0 \n"
"\tbne 0b \n"
: "=r"(upper),"=r"(lower),"=r"(tmp)
);
result = upper;
result = result<<32;
result = result|lower;
return(result);
}
#else
/* do not HAVE_RDTSC for your platform */
#endif
/* only define rdtsc_sleep() if we have rdtsc() */
#ifdef HAVE_RDTSC
/*
* sleeps for sleep time, using the rdtsc counter for accuracy
* you need to call rdtsc_calibrate() BEFORE this or you'll sleep for
* an additional .1 sec the very first time you call it.
*/
static inline void
rdtsc_sleep(const struct timespec sleep)
{
u_int64_t sleep_until;
u_int64_t now = 0;
static u_int64_t clicks_per_usec = 0;
sleep_until = rdtsc();
clicks_per_usec = clicks_per_usec > 0 ? clicks_per_usec : rdtsc_calibrate(0);
sleep_until += clicks_per_usec * TIMESPEC_TO_MICROSEC(&sleep);
while (now < sleep_until)
now = rdtsc();
}
#endif
#endif /* __RDTSC_H__ */

960
src/common/sendpacket.c Normal file
View File

@@ -0,0 +1,960 @@
/* $Id: sendpacket.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2006-2010 Aaron Turner.
* Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
* Copyright (c) 2000 Torsten Landschoff <torsten@debian.org>
* Sebastian Krahmer <krahmer@cs.uni-potsdam.de>
* Copyright (c) 1993, 1994, 1995, 1996, 1998
* The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* 4. All advertising materials mentioning features or use of this software
* display the following acknowledgement:
* ``This product includes software developed by the University of
* California, Lawrence Berkeley Laboratory and its contributors.''
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* sendpacket.[ch] is my attempt to write a universal packet injection
* API for BPF, libpcap, libdnet, and Linux's PF_PACKET. I got sick
* and tired dealing with libnet bugs and its lack of active maintenence,
* but unfortunately, libpcap frame injection support is relatively new
* and not everyone uses Linux, so I decided to support all four as
* best as possible. If your platform/OS/hardware supports an additional
* injection method, then by all means add it here (and send me a patch).
*
* Anyways, long story short, for now the order of preference is:
* 1. PF_PACKET
* 2. BPF
* 3. libdnet
* 4. pcap_inject()
* 5. pcap_sendpacket()
*
* Right now, one big problem with the pcap_* methods is that libpcap
* doesn't provide a reliable method of getting the MAC address of
* an interface (required for tcpbridge).
* You can use PF_PACKET or BPF to get that, but if your system suports
* those, might as well inject directly without going through another
* level of indirection.
*
* Please note that some of this code was copied from Libnet 1.1.3
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include "sendpacket.h"
#ifdef FORCE_INJECT_LIBDNET
#undef HAVE_PF_PACKET
#undef HAVE_PCAP_INJECT
#undef HAVE_PCAP_SENDPACKET
#undef HAVE_BPF
#endif
#ifdef FORCE_INJECT_BPF
#undef HAVE_LIBDNET
#undef HAVE_PCAP_INJECT
#undef HAVE_PCAP_SENDPACKET
#undef HAVE_PF_PACKET
#endif
#ifdef FORCE_INJECT_PCAP_INJECT
#undef HAVE_LIBDNET
#undef HAVE_PCAP_SENDPACKET
#undef HAVE_BPF
#undef HAVE_PF_PACKET
#endif
#ifdef FORCE_INJECT_PCAP_SENDPACKET
#undef HAVE_LIBDNET
#undef HAVE_PCAP_INJECT
#undef HAVE_BPF
#undef HAVE_PF_PACKET
#endif
#if (defined HAVE_WINPCAP && defined HAVE_PCAP_INJECT)
#undef HAVE_PCAP_INJECT /* configure returns true for some odd reason */
#endif
#if !defined HAVE_PCAP_INJECT && !defined HAVE_PCAP_SENDPACKET && !defined HAVE_LIBDNET && !defined HAVE_PF_PACKET && !defined HAVE_BPF
#error You need pcap_inject() or pcap_sendpacket() from libpcap, libdnet, Linux's PF_PACKET or *BSD's BPF
#endif
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_PF_PACKET
#undef INJECT_METHOD
#define INJECT_METHOD "PF_PACKET send()"
#include <fcntl.h>
#include <sys/utsname.h>
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <net/if_arp.h>
#include <netpacket/packet.h>
#ifndef __GLIBC__
typedef int socklen_t;
#endif
static sendpacket_t *sendpacket_open_pf(const char *, char *);
static struct tcpr_ether_addr *sendpacket_get_hwaddr_pf(sendpacket_t *);
static int get_iface_index(int fd, const int8_t *device, char *);
#endif /* HAVE_PF_PACKET */
#if defined HAVE_BPF && ! defined INJECT_METHOD
#undef INJECT_METHOD
#define INJECT_METHOD "bpf send()"
#include <net/bpf.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/uio.h>
#include <net/if_dl.h> // used for get_hwaddr_bpf()
static sendpacket_t *sendpacket_open_bpf(const char *, char *) _U_;
static struct tcpr_ether_addr *sendpacket_get_hwaddr_bpf(sendpacket_t *) _U_;
#endif /* HAVE_BPF */
#if defined HAVE_LIBDNET && ! defined INJECT_METHOD
#undef INJECT_METHOD
#define INJECT_METHOD "libdnet eth_send()"
/* need to undef these which are pulled in via defines.h, prior to importing dnet.h */
#undef icmp_id
#undef icmp_seq
#undef icmp_data
#undef icmp_mask
#include <dnet.h>
static sendpacket_t *sendpacket_open_libdnet(const char *, char *) _U_;
static struct tcpr_ether_addr *sendpacket_get_hwaddr_libdnet(sendpacket_t *) _U_;
#endif /* HAVE_LIBDNET */
#if (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) && ! defined INJECT_METHOD
static sendpacket_t *sendpacket_open_pcap(const char *, char *) _U_;
static struct tcpr_ether_addr *sendpacket_get_hwaddr_pcap(sendpacket_t *) _U_;
#endif /* HAVE_PCAP_INJECT || HAVE_PACKET_SENDPACKET */
#if defined HAVE_PCAP_INJECT && ! defined INJECT_METHOD
#undef INJECT_METHOD
#define INJECT_METHOD "pcap_inject()"
#elif defined HAVE_PCAP_SENDPACKET && ! defined INJECT_METHOD
#undef INJECT_METHOD
#define INJECT_METHOD "pcap_sendpacket()"
#endif
static void sendpacket_seterr(sendpacket_t *sp, const char *fmt, ...);
/* You need to define didsig in your main .c file. Set to 1 if CTRL-C was pressed */
extern volatile int didsig;
/**
* returns number of bytes sent on success or -1 on error
* Note: it is theoretically possible to get a return code >0 and < len
* which for most people would be considered an error (the packet wasn't fully sent)
* so you may want to test for recode != len too.
*
* Most socket API's have two interesting errors: ENOBUFS & EAGAIN. ENOBUFS
* is usually due to the kernel buffers being full. EAGAIN happens when you
* try to send traffic faster then the PHY allows.
*/
int
sendpacket(sendpacket_t *sp, const u_char *data, size_t len)
{
int retcode;
assert(sp);
assert(data);
if (len <= 0)
return -1;
TRY_SEND_AGAIN:
sp->attempt ++;
#if defined HAVE_PF_PACKET
retcode = (int)send(sp->handle.fd, (void *)data, len, 0);
/* out of buffers, or hit max PHY speed, silently retry */
if (retcode < 0 && !didsig) {
switch (errno) {
case EAGAIN:
sp->retry_eagain ++;
goto TRY_SEND_AGAIN;
break;
case ENOBUFS:
sp->retry_enobufs ++;
goto TRY_SEND_AGAIN;
break;
default:
sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)",
INJECT_METHOD, sp->sent + sp->failed + 1, strerror(errno), errno);
}
}
#elif defined HAVE_BPF
retcode = write(sp->handle.fd, (void *)data, len);
/* out of buffers, or hit max PHY speed, silently retry */
if (retcode < 0 && !didsig) {
switch (errno) {
case EAGAIN:
sp->retry_eagain ++;
goto TRY_SEND_AGAIN;
break;
case ENOBUFS:
sp->retry_enobufs ++;
goto TRY_SEND_AGAIN;
break;
default:
sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)",
INJECT_METHOD, sp->sent + sp->failed + 1, strerror(errno), errno);
}
}
#elif defined HAVE_LIBDNET
retcode = eth_send(sp->handle.ldnet, (void*)data, (size_t)len);
/* out of buffers, or hit max PHY speed, silently retry */
if (retcode < 0 && !didsig) {
switch (errno) {
case EAGAIN:
sp->retry_eagain ++;
goto TRY_SEND_AGAIN;
break;
case ENOBUFS:
sp->retry_enobufs ++;
goto TRY_SEND_AGAIN;
break;
default:
sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)",
INJECT_METHOD, sp->sent + sp->failed + 1, strerror(errno), errno);
}
}
#elif defined HAVE_PCAP_INJECT
/*
* pcap methods don't seem to support ENOBUFS, so we just straight fail
* is there a better way???
*/
retcode = pcap_inject(sp->handle.pcap, (void*)data, len);
/* out of buffers, or hit max PHY speed, silently retry */
if (retcode < 0 && !didsig) {
switch (errno) {
case EAGAIN:
sp->retry_eagain ++;
goto TRY_SEND_AGAIN;
break;
case ENOBUFS:
sp->retry_enobufs ++;
goto TRY_SEND_AGAIN;
break;
default:
sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)",
INJECT_METHOD, sp->sent + sp->failed + 1, pcap_geterr(sp->handle.pcap), errno);
}
}
#elif defined HAVE_PCAP_SENDPACKET
retcode = pcap_sendpacket(sp->handle.pcap, data, (int)len);
/* out of buffers, or hit max PHY speed, silently retry */
if (retcode < 0 && !didsig) {
switch (errno) {
case EAGAIN:
sp->retry_eagain ++;
goto TRY_SEND_AGAIN;
break;
case ENOBUFS:
sp->retry_enobufs ++;
goto TRY_SEND_AGAIN;
break;
default:
sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)",
INJECT_METHOD, sp->sent + sp->failed + 1, pcap_geterr(sp->handle.pcap), errno);
}
}
/*
* pcap_sendpacket returns 0 on success, not the packet length!
* hence, we have to fix retcode to be more standard on success
*/
if (retcode == 0)
retcode = len;
#endif
if (retcode < 0) {
sp->failed ++;
} else if (retcode != (int)len) {
sendpacket_seterr(sp, "Only able to write %d bytes out of %u bytes total",
retcode, len);
} else {
sp->bytes_sent += len;
sp->sent ++;
}
return retcode;
}
/**
* Open the given network device name and returns a sendpacket_t struct
* pass the error buffer (in case there's a problem) and the direction
* that this interface represents
*/
sendpacket_t *
sendpacket_open(const char *device, char *errbuf, tcpr_dir_t direction)
{
sendpacket_t *sp;
assert(device);
assert(errbuf);
#if defined HAVE_PF_PACKET
sp = sendpacket_open_pf(device, errbuf);
#elif defined HAVE_BPF
sp = sendpacket_open_bpf(device, errbuf);
#elif defined HAVE_LIBDNET
sp = sendpacket_open_libdnet(device, errbuf);
#elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET)
sp = sendpacket_open_pcap(device, errbuf);
#endif
if (sp != NULL) {
sp->open = 1;
sp->cache_dir = direction;
}
return sp;
}
/**
* Get packet stats for the given sendpacket_t
*/
char *
sendpacket_getstat(sendpacket_t *sp)
{
static char buf[1024];
assert(sp);
memset(buf, 0, sizeof(buf));
sprintf(buf, "Statistics for network device: %s\n"
"\tAttempted packets: " COUNTER_SPEC "\n"
"\tSuccessful packets: " COUNTER_SPEC "\n"
"\tFailed packets: " COUNTER_SPEC "\n"
"\tRetried packets (ENOBUFS): " COUNTER_SPEC "\n"
"\tRetried packets (EAGAIN): " COUNTER_SPEC "\n",
sp->device, sp->attempt, sp->sent, sp->failed, sp->retry_enobufs, sp->retry_eagain);
return(buf);
}
/**
* close the given sendpacket
*/
int
sendpacket_close(sendpacket_t *sp)
{
assert(sp);
switch(sp->handle_type) {
case SP_TYPE_BPF:
#if (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET)
close(sp->handle.fd);
#endif
break;
case SP_TYPE_PF_PACKET:
#ifdef HAVE_PF_PACKET
close(sp->handle.fd);
#endif
break;
case SP_TYPE_LIBPCAP:
#ifdef HAVE_LIBPCAP
pcap_close(sp->handle.pcap);
#endif
break;
case SP_TYPE_LIBDNET:
#ifdef HAVE_LIBDNET
eth_close(sp->handle.ldnet);
#endif
break;
case SP_TYPE_LIBNET:
err(-1, "Libnet is no longer supported!");
break;
}
safe_free(sp);
return 0;
}
/**
* returns the Layer 2 address of the interface current
* open. on error, return NULL
*/
struct tcpr_ether_addr *
sendpacket_get_hwaddr(sendpacket_t *sp)
{
struct tcpr_ether_addr *addr;
assert(sp);
/* if we already have our MAC address stored, just return it */
if (memcmp(&sp->ether, "\x00\x00\x00\x00\x00\x00", ETHER_ADDR_LEN) != 0)
return &sp->ether;
#if defined HAVE_PF_PACKET
addr = sendpacket_get_hwaddr_pf(sp);
#elif defined HAVE_BPF
addr = sendpacket_get_hwaddr_bpf(sp);
#elif defined HAVE_LIBDNET
addr = sendpacket_get_hwaddr_libdnet(sp);
#elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET)
addr = sendpacket_get_hwaddr_pcap(sp);
#endif
return addr;
}
/**
* returns the error string
*/
char *
sendpacket_geterr(sendpacket_t *sp)
{
assert(sp);
return sp->errbuf;
}
/**
* Set's the error string
*/
static void
sendpacket_seterr(sendpacket_t *sp, const char *fmt, ...)
{
va_list ap;
assert(sp);
va_start(ap, fmt);
if (fmt != NULL)
(void)vsnprintf(sp->errbuf, SENDPACKET_ERRBUF_SIZE, fmt, ap);
va_end(ap);
sp->errbuf[(SENDPACKET_ERRBUF_SIZE-1)] = '\0'; // be safe
}
#if defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET
/**
* Inner sendpacket_open() method for using libpcap
*/
static sendpacket_t *
sendpacket_open_pcap(const char *device, char *errbuf)
{
pcap_t *pcap;
sendpacket_t *sp;
#ifdef BIOCSHDRCMPLT
u_int spoof_eth_src = 1;
int fd;
#endif
assert(device);
assert(errbuf);
dbg(1, "sendpacket: using Libpcap");
/* open_pcap_live automatically fills out our errbuf for us */
if ((pcap = pcap_open_live(device, 0, 0, 0, errbuf)) == NULL)
return NULL;
sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
strlcpy(sp->device, device, sizeof(sp->device));
sp->handle.pcap = pcap;
#ifdef BIOCSHDRCMPLT
/*
* Only systems using BPF on the backend need this...
* other systems don't have ioctl and will get compile errors.
*/
fd = pcap_get_selectable_fd(pcap);
if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1)
errx(-1, "Unable to enable source MAC spoof support: %s", strerror(errno));
#endif
sp->handle_type = SP_TYPE_LIBPCAP;
return sp;
}
/**
* Get the hardware MAC address for the given interface using libpcap
*/
static struct tcpr_ether_addr *
sendpacket_get_hwaddr_pcap(sendpacket_t *sp)
{
assert(sp);
sendpacket_seterr(sp, "Error: sendpacket_get_hwaddr() not yet supported for pcap injection");
return NULL;
}
#endif /* HAVE_PCAP_INJECT || HAVE_PCAP_SENDPACKET */
#if defined HAVE_LIBDNET
/**
* Inner sendpacket_open() method for using libdnet
*/
static sendpacket_t *
sendpacket_open_libdnet(const char *device, char *errbuf)
{
eth_t *ldnet;
sendpacket_t *sp;
assert(device);
assert(errbuf);
dbg(1, "sendpacket: using Libdnet");
if ((ldnet = eth_open(device)) == NULL)
return NULL;
sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
strlcpy(sp->device, device, sizeof(sp->device));
sp->handle.ldnet = ldnet;
sp->handle_type = SP_TYPE_LIBDNET;
return sp;
}
/**
* Get the hardware MAC address for the given interface using libdnet
*/
static struct tcpr_ether_addr *
sendpacket_get_hwaddr_libdnet(sendpacket_t *sp)
{
struct tcpr_ether_addr *addr;
int ret;
assert(sp);
ret = eth_get(sp->handle.ldnet, (eth_addr_t *)addr);
if (addr == NULL || ret < 0) {
sendpacket_seterr(sp, "Error getting hwaddr via libdnet: %s", strerror(errno));
return NULL;
}
memcpy(&sp->ether, addr, sizeof(struct tcpr_ether_addr));
return(&sp->ether);
}
#endif /* HAVE_LIBDNET */
#if defined HAVE_PF_PACKET
/**
* Inner sendpacket_open() method for using Linux's PF_PACKET
*/
static sendpacket_t *
sendpacket_open_pf(const char *device, char *errbuf)
{
int mysocket;
sendpacket_t *sp;
struct ifreq ifr;
struct sockaddr_ll sa;
int n = 1, err;
socklen_t errlen = sizeof(err);
assert(device);
assert(errbuf);
dbg(1, "sendpacket: using PF_PACKET");
/* open our socket */
if ((mysocket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "socket: %s", strerror(errno));
return NULL;
}
/* get the interface id for the device */
if ((sa.sll_ifindex = get_iface_index(mysocket, device, errbuf)) < 0) {
close(mysocket);
return NULL;
}
/* bind socket to our interface id */
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(ETH_P_ALL);
if (bind(mysocket, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "bind error: %s", strerror(errno));
close(mysocket);
return NULL;
}
/* check for errors, network down, etc... */
if (getsockopt(mysocket, SOL_SOCKET, SO_ERROR, &err, &errlen) < 0) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "error opening %s: %s", device,
strerror(errno));
close(mysocket);
return NULL;
}
if (err > 0) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "error opening %s: %s", device,
strerror(err));
close(mysocket);
return NULL;
}
/* get hardware type for our interface */
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(mysocket, SIOCGIFHWADDR, &ifr) < 0) {
close(mysocket);
sendpacket_seterr(sp, "Error getting hardware type: %s", strerror(errno));
return NULL;
}
/* make sure it's not loopback (PF_PACKET doesn't support it) */
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
warnx("Unsupported physical layer type 0x%04x on %s. Maybe it works, maybe it wont."
" See tickets #123/318", ifr.ifr_hwaddr.sa_family, device);
#ifdef SO_BROADCAST
/*
* man 7 socket
*
* Set or get the broadcast flag. When enabled, datagram sockets
* receive packets sent to a broadcast address and they are allowed
* to send packets to a broadcast address. This option has no
* effect on stream-oriented sockets.
*/
if (setsockopt(mysocket, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n)) == -1) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE,
"SO_BROADCAST: %s\n", strerror(errno));
close(mysocket);
return NULL;
}
#endif /* SO_BROADCAST */
/* prep & return our sp handle */
sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
strlcpy(sp->device, device, sizeof(sp->device));
sp->handle.fd = mysocket;
sp->handle_type = SP_TYPE_PF_PACKET;
return sp;
}
/**
* get the interface index (necessary for sending packets w/ PF_PACKET)
*/
static int
get_iface_index(int fd, const int8_t *device, char *errbuf) {
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "ioctl: %s", strerror(errno));
return (-1);
}
return ifr.ifr_ifindex;
}
/**
* get's the hardware address via Linux's PF packet interface
*/
struct tcpr_ether_addr *
sendpacket_get_hwaddr_pf(sendpacket_t *sp)
{
struct ifreq ifr;
int fd;
assert(sp);
if (!sp->open) {
sendpacket_seterr(sp, "Unable to get hardware address on un-opened sendpacket handle");
return NULL;
}
/* create dummy socket for ioctl */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
sendpacket_seterr(sp, "Unable to open dummy socket for get_hwaddr: %s", strerror(errno));
return NULL;
}
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, sp->device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFHWADDR, (int8_t *)&ifr) < 0) {
close(fd);
sendpacket_seterr(sp, "Error getting hardware address: %s", strerror(errno));
return NULL;
}
memcpy(&sp->ether, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
close(fd);
return(&sp->ether);
}
#endif /* HAVE_PF_PACKET */
#if defined HAVE_BPF
/**
* Inner sendpacket_open() method for using BSD's BPF interface
*/
static sendpacket_t *
sendpacket_open_bpf(const char *device, char *errbuf)
{
sendpacket_t *sp;
char bpf_dev[10];
int dev, mysocket, link_offset, link_type;
struct ifreq ifr;
struct bpf_version bv;
u_int v;
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
u_int spoof_eth_src = 1;
#endif
assert(device);
assert(errbuf);
memset(&ifr, '\0', sizeof(struct ifreq));
dbg(1, "sendpacket: using BPF");
/* open socket */
mysocket = -1;
for (dev = 0; dev <= 9; dev ++) {
memset(bpf_dev, '\0', sizeof(bpf_dev));
snprintf(bpf_dev, sizeof(bpf_dev), "/dev/bpf%d", dev);
if ((mysocket = open(bpf_dev, O_RDWR, 0)) > 0) {
break;
}
}
/* error?? */
if (mysocket < 0) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE,
"Unable to open /dev/bpfX: %s", strerror(errno));
errbuf[SENDPACKET_ERRBUF_SIZE -1] = '\0';
return NULL;
}
/* get BPF version */
if (ioctl(mysocket, BIOCVERSION, (caddr_t)&bv) < 0) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to get bpf version: %s", strerror(errno));
return NULL;
}
if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor != BPF_MINOR_VERSION) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Kernel's bpf version is out of date.");
return NULL;
}
/* attach to device */
strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(mysocket, BIOCSETIF, (caddr_t)&ifr) < 0) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to bind %s to %s: %s",
bpf_dev, device, strerror(errno));
return NULL;
}
/* get datalink type */
if (ioctl(mysocket, BIOCGDLT, (caddr_t)&v) < 0) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Unable to get datalink type: %s",
strerror(errno));
return NULL;
}
/*
* NetBSD and FreeBSD BPF have an ioctl for enabling/disabling
* automatic filling of the link level source address.
*/
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
if (ioctl(mysocket, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
snprintf(errbuf, SENDPACKET_ERRBUF_SIZE,
"Unable to enable spoofing src MAC: %s", strerror(errno));
return NULL;
}
#endif
/* assign link type and offset */
switch (v) {
case DLT_SLIP:
link_offset = 0x10;
break;
case DLT_RAW:
link_offset = 0x0;
break;
case DLT_PPP:
link_offset = 0x04;
break;
case DLT_EN10MB:
default: /* default to Ethernet */
link_offset = 0xe;
break;
}
#if _BSDI_VERSION - 0 > 199510
switch (v) {
case DLT_SLIP:
v = DLT_SLIP_BSDOS;
link_offset = 0x10;
break;
case DLT_PPP:
v = DLT_PPP_BSDOS;
link_offset = 0x04;
break;
}
#endif
link_type = v;
/* allocate our sp handle, and return it */
sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
strlcpy(sp->device, device, sizeof(sp->device));
sp->handle.fd = mysocket;
//sp->link_type = link_type;
//sp->link_offset = link_offset;
sp->handle_type = SP_TYPE_BPF;
return sp;
}
/**
* Get the interface hardware MAC address when using BPF
*/
struct tcpr_ether_addr *
sendpacket_get_hwaddr_bpf(sendpacket_t *sp)
{
int mib[6];
size_t len;
int8_t *buf, *next, *end;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
assert(sp);
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
mib[5] = 0;
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) {
sendpacket_seterr(sp, "%s(): sysctl(): %s", __func__, strerror(errno));
return NULL;
}
buf = (int8_t *)safe_malloc(len);
if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) {
sendpacket_seterr(sp, "%s(): sysctl(): %s", __func__, strerror(errno));
safe_free(buf);
return NULL;
}
end = buf + len;
for (next = buf; next < end; next += ifm->ifm_msglen) {
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO) {
sdl = (struct sockaddr_dl *)(ifm + 1);
if (strncmp(&sdl->sdl_data[0], sp->device, sdl->sdl_len) == 0) {
memcpy(&sp->ether, LLADDR(sdl), ETHER_ADDR_LEN);
break;
}
}
}
safe_free(buf);
return(&sp->ether);
}
#endif /* HAVE_BPF */
/**
* Get the DLT type of the opened sendpacket
* Return -1 if we can't figure it out, else return the DLT_ value
*/
int
sendpacket_get_dlt(sendpacket_t *sp)
{
int dlt;
#if defined HAVE_BPF
int rcode;
if ((rcode = ioctl(sp->handle.fd, BIOCGDLT, &dlt)) < 0) {
warnx("Unable to get DLT value for BPF device (%s): %s", sp->device, strerror(errno));
return(-1);
}
#elif defined HAVE_PF_PACKET || defined HAVE_LIBDNET
/* use libpcap to get dlt */
pcap_t *pcap;
char errbuf[PCAP_ERRBUF_SIZE];
if ((pcap = pcap_open_live(sp->device, 65535, 0, 0, errbuf)) == NULL) {
warnx("Unable to get DLT value for %s: %s", sp->device, errbuf);
return(-1);
}
dlt = pcap_datalink(pcap);
pcap_close(pcap);
#elif defined HAVE_PCAP_SENDPACKET || defined HAVE_PCAP_INJECT
dlt = pcap_datalink(sp->handle.pcap);
#endif
return dlt;
}
const char *
sendpacket_get_method()
{
return INJECT_METHOD;
}

101
src/common/sendpacket.h Normal file
View File

@@ -0,0 +1,101 @@
/* $Id: sendpacket.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2006-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#ifdef HAVE_PF_PACKET
#include <netpacket/packet.h>
#endif
#ifdef HAVE_LIBDNET
/* need to undef these which are pulled in via defines.h, prior to importing dnet.h */
#undef icmp_id
#undef icmp_seq
#undef icmp_data
#undef icmp_mask
#include <dnet.h>
#endif
#ifndef _SENDPACKET_H_
#define _SENDPACKET_H_
enum sendpacket_type_t {
SP_TYPE_LIBNET,
SP_TYPE_LIBDNET,
SP_TYPE_LIBPCAP,
SP_TYPE_BPF,
SP_TYPE_PF_PACKET
};
union sendpacket_handle {
pcap_t *pcap;
int fd;
#ifdef HAVE_LIBDNET
eth_t *ldnet;
#endif
};
#define SENDPACKET_ERRBUF_SIZE 1024
struct sendpacket_s {
tcpr_dir_t cache_dir;
int open;
char device[20];
char errbuf[SENDPACKET_ERRBUF_SIZE];
COUNTER retry_enobufs;
COUNTER retry_eagain;
COUNTER failed;
COUNTER sent;
COUNTER bytes_sent;
COUNTER attempt;
enum sendpacket_type_t handle_type;
union sendpacket_handle handle;
struct tcpr_ether_addr ether;
#ifdef HAVE_PF_PACKET
struct sockaddr_ll sa;
#endif
};
typedef struct sendpacket_s sendpacket_t;
int sendpacket(sendpacket_t *, const u_char *, size_t);
int sendpacket_close(sendpacket_t *);
char *sendpacket_geterr(sendpacket_t *);
char *sendpacket_getstat(sendpacket_t *);
sendpacket_t *sendpacket_open(const char *, char *, tcpr_dir_t);
struct tcpr_ether_addr *sendpacket_get_hwaddr(sendpacket_t *);
int sendpacket_get_dlt(sendpacket_t *);
const char *sendpacket_get_method();
#endif /* _SENDPACKET_H_ */

116
src/common/services.c Normal file
View File

@@ -0,0 +1,116 @@
/* $Id: services.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2004-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <sys/types.h>
#include <regex.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
/**
* parses /etc/services so we know which ports are service ports
*/
void
parse_services(const char *file, tcpr_services_t *services)
{
FILE *service = NULL;
char service_line[MAXLINE], port[10], proto[10];
regex_t preg;
u_int16_t portc;
size_t nmatch = 3;
regmatch_t pmatch[3];
char regex[] = "([0-9]+)/(tcp|udp)"; /* matches the port as pmatch[1], service pmatch[2] */
dbgx(1, "Parsing %s", file);
memset(service_line, '\0', MAXLINE);
/* mark all ports not a service */
memset(services->tcp, '\0', NUM_PORTS);
memset(services->udp, '\0', NUM_PORTS);
if ((service = fopen(file, "r")) == NULL) {
errx(-1, "Unable to open service file: %s\n%s", file, strerror(errno));
}
/* compile our regexes */
if ((regcomp(&preg, regex, REG_ICASE|REG_EXTENDED)) != 0) {
errx(-1, "Unable to compile regex: %s", regex);
}
/* parse the entire file */
while ((fgets(service_line, MAXLINE, service)) != NULL) {
/* zero out our vars */
memset(port, '\0', 10);
memset(proto, '\0', 10);
portc = 0;
dbgx(4, "Procesing: %s", service_line);
/* look for format of 1234/tcp */
if ((regexec(&preg, service_line, nmatch, pmatch, 0)) == 0) { /* matches */
if (nmatch < 2) {
err(-1, "WTF? I matched the line, but I don't know where!");
}
/* strip out the port & proto from the line */
strncpy(port, &service_line[pmatch[1].rm_so], (pmatch[1].rm_eo - pmatch[1].rm_so));
strncpy(proto, &service_line[pmatch[2].rm_so], (pmatch[2].rm_eo - pmatch[2].rm_so));
/* convert port[] into an integer */
portc = (u_int16_t)atoi(port);
/* update appropriate service array with the server port */
if (strcmp(proto, "tcp") == 0) {
dbgx(3, "Setting TCP/%d as a server port", portc);
services->tcp[portc] = 1; /* mark it as a service port */
} else if (strcmp(proto, "udp") == 0) {
dbgx(3, "Setting UDP/%d as a server port", portc);
services->udp[portc] = 1;
} else {
warnx("Skipping unknown protocol service %s/%d", proto, portc);
}
}
}
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

50
src/common/services.h Normal file
View File

@@ -0,0 +1,50 @@
/* $Id: services.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SERVICES_H__
#define __SERVICES_H__
void parse_services(const char *file, tcpr_services_t *services);
/* max width of a line in /etc/services */
#define MAXLINE 1024
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

4
src/common/svn_version.c Normal file
View File

@@ -0,0 +1,4 @@
const char SVN_Version[] = "2450";
const char *svn_version(void) {
return SVN_Version;
}

387
src/common/tcpdump.c Normal file
View File

@@ -0,0 +1,387 @@
/* $Id: tcpdump.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This code allows us to use tcpdump to print packet decodes.
* Basically, we create a local AF_UNIX socketpair, fork a copy
* of ourselves, link 1/2 of the pair to STDIN of the child and
* replace the child with tcpdump. We then send a "pcap" file
* over the socket so that tcpdump can print it's decode to STDOUT.
*
* Idea and a lot of code stolen from Christain Kreibich's
* <christian@whoop.org> libnetdude 0.4 code. Any bugs are mine. :)
*
* This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include "tcpdump.h"
#include "lib/strlcpy.h"
#ifdef DEBUG
extern int debug;
#endif
char *options_vec[OPTIONS_VEC_SIZE];
static int tcpdump_fill_in_options(char *opt);
static int can_exec(const char *filename);
/**
* given a packet, print a decode of via tcpdump
*/
int
tcpdump_print(tcpdump_t *tcpdump, struct pcap_pkthdr *pkthdr, const u_char *data)
{
struct pollfd poller[1];
int result;
char decode[TCPDUMP_DECODE_LEN];
assert(tcpdump);
assert(pkthdr);
assert(data);
poller[0].fd = tcpdump->infd;
poller[0].events = POLLOUT;
poller[0].revents = 0;
/* wait until we can write to the tcpdump socket */
result = poll(poller, 1, TCPDUMP_POLL_TIMEOUT);
if (result < 0)
errx(-1, "Error during poll() to write to tcpdump\n%s", strerror(errno));
if (result == 0)
err(-1, "poll() timeout... tcpdump seems to be having a problem keeping up\n"
"Try increasing TCPDUMP_POLL_TIMEOUT");
/* result > 0 if we get here */
if (write(tcpdump->infd, (char *)pkthdr, sizeof(struct pcap_pkthdr))
!= sizeof(struct pcap_pkthdr))
errx(-1, "Error writing pcap file header to tcpdump\n%s", strerror(errno));
#ifdef DEBUG
if (debug >= 5) {
if (write(tcpdump->debugfd, (char *)pkthdr, sizeof(struct pcap_pkthdr))
!= sizeof(struct pcap_pkthdr))
errx(-1, "Error writing pcap file header to tcpdump debug\n%s", strerror(errno));
}
#endif
if (write(tcpdump->infd, data, pkthdr->caplen) != (ssize_t)pkthdr->caplen)
errx(-1, "Error writing packet data to tcpdump\n%s", strerror(errno));
#ifdef DEBUG
if (debug >= 5) {
if (write(tcpdump->debugfd, data, pkthdr->caplen) != (ssize_t)pkthdr->caplen)
errx(-1, "Error writing packet data to tcpdump debug\n%s", strerror(errno));
}
#endif
/* Wait for output from tcpdump */
poller[0].fd = tcpdump->outfd;
poller[0].events = POLLIN;
poller[0].revents = 0;
result = poll(poller, 1, TCPDUMP_POLL_TIMEOUT);
if (result < 0)
errx(-1, "Error during poll() to write to tcpdump\n%s", strerror(errno));
if (result == 0)
err(-1, "poll() timeout... tcpdump seems to be having a problem keeping up\n"
"Try increasing TCPDUMP_POLL_TIMEOUT");
/* result > 0 if we get here */
if (read(tcpdump->outfd, &decode, TCPDUMP_DECODE_LEN) < 0)
errx(-1, "Error reading tcpdump decode: %s", strerror(errno));
printf("%s", decode);
return TRUE;
}
/**
* init our tcpdump handle using the given pcap handle
* Basically, this starts up tcpdump as a child and communicates
* to it via a pair of sockets (stdout/stdin)
*/
int
tcpdump_open(tcpdump_t *tcpdump, pcap_t *pcap)
{
int infd[2], outfd[2];
FILE *writer;
assert(tcpdump);
assert(pcap);
if (tcpdump->pid != 0) {
warn("tcpdump process already running");
return FALSE;
}
/* is tcpdump executable? */
if (! can_exec(TCPDUMP_BINARY)) {
errx(-1, "Unable to execute tcpdump binary: %s", TCPDUMP_BINARY);
}
#ifdef DEBUG
strlcpy(tcpdump->debugfile, TCPDUMP_DEBUG, sizeof(tcpdump->debugfile));
if (debug >= 5) {
dbgx(5, "Opening tcpdump debug file: %s", tcpdump->debugfile);
if ((tcpdump->debugfd = open(tcpdump->debugfile, O_WRONLY|O_CREAT|O_TRUNC,
S_IREAD|S_IWRITE|S_IRGRP|S_IROTH)) == -1) {
errx(-1, "Error opening tcpdump debug file: %s\n%s", tcpdump->debugfile, strerror(errno));
}
}
#endif
/* copy over the args */
dbg(2, "Prepping tcpdump options...");
tcpdump_fill_in_options(tcpdump->args);
dbg(2, "Starting tcpdump...");
/* create our socket pair to send packet data to tcpdump via */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, infd) < 0)
errx(-1, "Unable to create stdin socket pair: %s", strerror(errno));
/* create our socket pair to read packet decode from tcpdump */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, outfd) < 0)
errx(-1, "Unable to create stdout socket pair: %s", strerror(errno));
if ((tcpdump->pid = fork() ) < 0)
errx(-1, "Fork failed: %s", strerror(errno));
dbgx(2, "tcpdump pid: %d", tcpdump->pid);
if (tcpdump->pid > 0) {
/* we're still in tcpreplay */
dbgx(2, "[parent] closing input fd %d", infd[1]);
close(infd[1]); /* close the tcpdump side */
dbgx(2, "[parent] closing output fd %d", outfd[1]);
close(outfd[1]);
tcpdump->infd = infd[0];
tcpdump->outfd = outfd[0];
/* send the pcap file header to tcpdump */
writer = fdopen(tcpdump->infd, "w");
if ((tcpdump->dumper = pcap_dump_fopen(pcap, writer)) == NULL) {
warnx("[parent] pcap_dump_fopen(): %s", pcap_geterr(pcap));
return FALSE;
}
pcap_dump_flush(tcpdump->dumper);
if (fcntl(tcpdump->infd, F_SETFL, O_NONBLOCK) < 0)
warnx("[parent] Unable to fcntl tcpreplay socket:\n%s", strerror(errno));
if (fcntl(tcpdump->outfd, F_SETFL, O_NONBLOCK) < 0)
warnx("[parent] Unable to fnctl stdout socket:\n%s", strerror(errno));
}
else {
dbg(2, "[child] started the kid");
/* we're in the child process */
dbgx(2, "[child] closing in fd %d", infd[0]);
dbgx(2, "[child] closing out fd %d", outfd[0]);
close(infd[0]); /* close the tcpreplay side */
close(outfd[0]);
/* copy our side of the socketpair to our stdin */
if (infd[1] != STDIN_FILENO) {
if (dup2(infd[1], STDIN_FILENO) != STDIN_FILENO)
errx(-1, "[child] Unable to copy socket to stdin: %s",
strerror(errno));
}
/* copy our side of the socketpair to our stdout */
if (outfd[1] != STDOUT_FILENO) {
if (dup2(outfd[1], STDOUT_FILENO) != STDOUT_FILENO)
errx(-1, "[child] Unable to copy socket to stdout: %s",
strerror(errno));
}
/* exec tcpdump */
dbg(2, "[child] Exec'ing tcpdump...");
if (execv(TCPDUMP_BINARY, options_vec) < 0)
errx(-1, "Unable to exec tcpdump: %s", strerror(errno));
}
return TRUE;
}
/**
* shutdown tcpdump
*/
void
tcpdump_close(tcpdump_t *tcpdump)
{
if (! tcpdump)
return;
if (tcpdump->pid <= 0)
return;
dbgx(2, "[parent] killing tcpdump pid: %d", tcpdump->pid);
kill(tcpdump->pid, SIGKILL);
close(tcpdump->infd);
close(tcpdump->outfd);
if (waitpid(tcpdump->pid, NULL, 0) != tcpdump->pid)
errx(-1, "[parent] Error in waitpid: %s", strerror(errno));
tcpdump->pid = 0;
tcpdump->infd = 0;
tcpdump->outfd = 0;
}
/**
* forcefully kill tcpdump
*/
void
tcpdump_kill(tcpdump_t *tcpdump)
{
if (tcpdump->pid) {
if (kill(tcpdump->pid, SIGTERM) != 0) {
kill(tcpdump->pid, SIGKILL);
}
}
tcpdump->infd = 0;
tcpdump->outfd = 0;
tcpdump->pid = 0;
}
/**
* copy the string of args (*opt) to the vector (**opt_vec)
* for a max of opt_len. Returns the number of options
* in the vector
*/
static int
tcpdump_fill_in_options(char *opt)
{
char options[256];
char *arg, *newarg;
int i = 1, arglen;
char *token = NULL;
/* zero out our options_vec for execv() */
memset(options_vec, '\0', OPTIONS_VEC_SIZE);
/* first arg should be the binary (by convention) */
options_vec[0] = TCPDUMP_BINARY;
/* prep args */
memset(options, '\0', 256);
if (opt != NULL) {
strlcat(options, opt, sizeof(options));
}
strlcat(options, TCPDUMP_ARGS, sizeof(options));
dbgx(2, "[child] Will execute: tcpdump %s", options);
/* process args */
/* process the first argument */
arg = strtok_r(options, OPT_DELIM, &token);
arglen = strlen(arg) + 2; /* -{arg}\0 */
newarg = (char *)safe_malloc(arglen);
strlcat(newarg, "-", arglen);
strlcat(newarg, arg, arglen);
options_vec[i++] = newarg;
/* process the remaining args
note that i < OPTIONS_VEC_SIZE - 1
because: a) we need to add '-' as an option to the end
b) because the array has to be null terminated
*/
while (((arg = strtok_r(NULL, OPT_DELIM, &token)) != NULL) &&
(i < OPTIONS_VEC_SIZE - 1)) {
arglen = strlen(arg) + 2;
newarg = (char *)safe_malloc(arglen);
strlcat(newarg, "-", arglen);
strlcat(newarg, arg, arglen);
options_vec[i++] = newarg;
}
/* tell -r to read from stdin */
options_vec[i] = "-";
return(i);
}
/**
* can we exec the given file?
*/
static int
can_exec(const char *filename)
{
struct stat st;
if (!filename || filename[0] == '\0')
return FALSE;
/* Stat the file to see if it's executable and
if the user may run it.
*/
if (lstat(filename, &st) < 0)
return FALSE;
if ((st.st_mode & S_IXUSR) ||
(st.st_mode & S_IXGRP) ||
(st.st_mode & S_IXOTH))
return TRUE;
return FALSE;
}

93
src/common/tcpdump.h Normal file
View File

@@ -0,0 +1,93 @@
/* $Id: tcpdump.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __TCPDUMP_H__
#define __TCPDUMP_H__
/* line buffer stdout, read from stdin */
#define TCPDUMP_ARGS " -n -l -r -"
/* max number of tcpdump options; must be a multiple of 4 */
#define OPTIONS_VEC_SIZE 32
/* how long to wait (in ms) to write to tcpdump */
#define TCPDUMP_POLL_TIMEOUT 500
/* delim to be used for strtok() to process tcpdump args */
#define OPT_DELIM " -"
/* output file of data passed to tcpdump when debug level 5 is enabled */
#define TCPDUMP_DEBUG "tcpdump.debug"
/* taken from libpcap's savefile.c */
#define TCPDUMP_MAGIC 0xa1b2c3d4
#define PATCHED_TCPDUMP_MAGIC 0xa1b2cd34
#define TCPDUMP_DECODE_LEN 65535
struct tcpdump_s {
char *filename;
char *args;
struct pcap_file_header pfh;
int pid;
int infd; /* fd to write to. 1/2 of the socketpair */
int outfd; /* fd to read from. */
pcap_dumper_t *dumper;
/* following vars are for figuring out exactly what we send to
* tcpdump. See TCPDUMP_DEBUG
*/
#ifdef DEBUG
int debugfd;
char debugfile[255];
#endif
};
typedef struct tcpdump_s tcpdump_t;
//int tcpdump_init(tcpdump_t *tcpdump);
int tcpdump_open(tcpdump_t *tcpdump, pcap_t *pcap);
//int tcpdump_open_live(tcpdump_t *tcpdump, pcap_t *pcap);
int tcpdump_print(tcpdump_t *tcpdump, struct pcap_pkthdr *pkthdr, const u_char *data);
void tcpdump_close(tcpdump_t *tcpdump);
void tcpdump_kill(tcpdump_t *tcpdump);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

81
src/common/timer.c Normal file
View File

@@ -0,0 +1,81 @@
/* $Id: timer.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include "timer.h"
#include <stdlib.h>
/* Miscellaneous timeval routines */
/**
* Divide tvp by div, storing the result in tvp
*/
void
timerdiv(struct timeval *tvp, float div)
{
double interval;
if (div == 0 || div == 1)
return;
interval = ((double)tvp->tv_sec * 1000000 + tvp->tv_usec) / (double)div;
tvp->tv_sec = interval / (int)1000000;
tvp->tv_usec = interval - (tvp->tv_sec * 1000000);
}
/* Divide tvs by div, storing the result in tvs */
void timesdiv(struct timespec *tvs, float div)
{
double interval;
if (div == 0 || div == 1)
return;
interval = ((double)tvs->tv_sec * 1000000000 + tvs->tv_nsec) / (double)div;
tvs->tv_sec = interval / (int)1000000000;
tvs->tv_nsec = interval - (tvs->tv_sec * 1000000000);
}
void
init_delta_time(delta_t *ctx)
{
#ifdef HAVE_ABSOLUTE_TIME
SetZero(*ctx);
#else
timerclear(ctx);
#endif
}

260
src/common/timer.h Normal file
View File

@@ -0,0 +1,260 @@
/* $Id: timer.h 2434 2010-03-28 21:04:52Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _TIMER_H_
#define _TIMER_H_
#include "config.h"
#include "defines.h"
#include "tcpreplay.h"
#include "common.h"
#include <time.h>
#include <sys/time.h>
#include <math.h>
#ifdef HAVE_ABSOLUTE_TIME
#include <CoreServices/CoreServices.h>
#endif
/* AbsoluteTime methods */
#ifndef NonZero
#define NonZero(x) ((x).hi | (x).lo)
#endif
#ifndef SetZero
#define SetZero(x) do { (x).hi = 0 ; (x).lo = 0; } while(0)
#endif
#ifndef CopyAbsolute
#define CopyAbsolute(x, y) do { (x).lo = (y).lo ; (x).hi = (y).hi; } while (0)
#endif
#ifndef AbsoluteCmp
#define AbsoluteCmp(left, right, cmp) \
(((left)->hi == (right)->hi) ? \
((left)->lo cmp (right)->lo) : \
((left)->hi cmp (right)->hi))
#endif
/*
* 1 sec = 1,0000 millisec (ms)
* 1 sec = 1,000,000 microsec (us)
* 1 sec = 1,000,000,000 nanosec (ns)
* 1 millisec = 1,000 microsec
* 1 microsec = 1,000 nanosec
*/
void timerdiv(struct timeval *tvp, float div);
void timesdiv(struct timespec *tvs, float div);
/* convert float time to struct timeval *tvp */
#ifndef float2timer
#define float2timer(time, tvp) \
do { \
(tvp)->tv_sec = time; \
(tvp)->tv_usec = (time - (tvp)->tv_sec) * 100000; \
} while (0)
#endif
/* timesec to float */
#ifndef timer2float
#define timer2float(tvp, time) \
do { \
time = (tvp)->tv_sec; \
time += (float)((tvp)->tv_usec / 10000) * 0.01; \
} while (0)
#endif
#ifndef TIMEVAL_TO_TIMESPEC
#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; }
#endif
#ifndef TIMESPEC_TO_TIMEVAL
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (ts)->tv_sec; \
(tv)->tv_usec = (ts)->tv_nsec / 1000; }
#endif
#ifndef ROUND_TIMESPEC_TO_MICROSEC
#define ROUND_TIMESPEC_TO_MICROSEC(ts) \
do { \
(ts)->tv_nsec = ((((ts)->tv_nsec / 1000) + ((ts)->tv_nsec % 1000 >= 500 ? 1 : 0)) * 1000); \
} while (0)
#endif
/* zero out a timer */
#ifndef timerclear
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif
/* zero out a timespec */
#ifndef timesclear
#define timesclear(tvs) (tvs)->tv_sec = (tvs)->tv_nsec = 0
#endif
/* is timer non-zero? */
#ifndef timerisset
#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#endif
/* is timespec non-zero? */
#ifndef timesisset
#define timesisset(tvs) ((tvs)->tv_sec || (tvs)->tv_nsec)
#endif
/* add tvp and uvp and store in vvp */
#ifndef timeradd
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#endif
/* subtract uvp from tvp and store in vvp */
#ifndef timersub
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
#endif
#ifndef timessub
#define timessub(tsp, usp, vsp) \
do { \
(vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
(vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
if ((vsp)->tv_nsec < 0) { \
(vsp)->tv_sec--; \
(vsp)->tv_nsec += 1000000000; \
} \
} while (0)
#endif
/* compare tvp and uvp using cmp */
#ifndef timercmp
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#ifndef timescmp
#define timescmp(tsp, usp, cmp) \
(((tsp)->tv_sec == (usp)->tv_sec) ? \
((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
((tsp)->tv_sec cmp (usp)->tv_sec))
#endif
/* multiply tvp by x and store in uvp */
#define timermul(tvp, uvp, x) \
do { \
(uvp)->tv_sec = (tvp)->tv_sec * x; \
(uvp)->tv_usec = (tvp)->tv_usec * x; \
while((uvp)->tv_usec > 1000000) { \
(uvp)->tv_sec++; \
(uvp)->tv_usec -= 1000000; \
} \
} while(0)
#ifdef HAVE_ABSOLUTE_TIME
typedef AbsoluteTime delta_t;
#else
typedef struct timeval delta_t;
#endif
/*
* starts a timer so we can figure out how much time has passed
* when we call get_delta_timer()
*/
static inline void
start_delta_time(delta_t *ctx)
{
#ifdef HAVE_ABSOLUTE_TIME
*ctx = UpTime();
#else
gettimeofday(ctx, NULL);
#endif
}
void init_delta_time(delta_t *ctx);
/*
* returns the amount of time that has passed since the
* last time you called start_delta_time()
*/
static inline void
get_delta_time(delta_t *ctx, struct timespec *ret)
{
/* OS X has absolute time */
#ifdef HAVE_ABSOLUTE_TIME
AbsoluteTime now, delta;
Nanoseconds nano;
now = UpTime();
if (! NonZero(*ctx)) {
timesclear(ret);
} else {
delta = SubAbsoluteFromAbsolute(now, *ctx);
nano = AbsoluteToNanoseconds(delta);
NANOSEC_TO_TIMESPEC(UnsignedWideToUInt64(nano) / 10, ret);
}
/* Everyone else just uses gettimeofday */
#else
struct timeval now, delta;
gettimeofday(&now, NULL);
if (!timerisset(ctx)) {
timesclear(ret);
} else {
timersub(&now, ctx, &delta);
TIMEVAL_TO_TIMESPEC(&delta, ret);
}
#endif
}
#endif /* _TIMER_H_ */

222
src/common/utils.c Normal file
View File

@@ -0,0 +1,222 @@
/* $Id: utils.c 2433 2010-03-28 20:57:36Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#ifdef DEBUG
extern int debug;
#endif
/**
* this is wrapped up in a #define safe_malloc
* This function, detects failures to malloc memory and zeros out the
* memory before returning
*/
void *
_our_safe_malloc(size_t len, const char *funcname, const int line, const char *file)
{
u_char *ptr;
if ((ptr = malloc(len)) == NULL) {
fprintf(stderr, "ERROR in %s:%s() line %d: Unable to malloc() %zu bytes", file, funcname, line, len);
exit(-1);
}
/* zero memory */
memset(ptr, 0, len);
/* wrapped inside an #ifdef for better performance */
dbgx(5, "Malloc'd %zu bytes in %s:%s() line %d", len, file, funcname, line);
return (void *)ptr;
}
/**
* this is wrapped up in a #define safe_realloc
* This function, detects failures to realloc memory and zeros
* out the NEW memory if len > current len. As always, remember
* to use it as:
* ptr = safe_realloc(ptr, size)
*/
void *
_our_safe_realloc(void *ptr, size_t len, const char *funcname, const int line, const char *file)
{
if ((ptr = realloc(ptr, len)) == NULL) {
fprintf(stderr, "ERROR: in %s:%s() line %d: Unable to remalloc() buffer to %zu bytes", file, funcname, line, len);
exit(-1);
}
dbgx(5, "Remalloc'd buffer to %zu bytes in %s:%s() line %d", len, file, funcname, line);
return ptr;
}
/**
* this is wrapped up in a #define safe_strdup
* This function, detects failures to realloc memory
*/
char *
_our_safe_strdup(const char *str, const char *funcname, const int line, const char *file)
{
char *newstr;
if ((newstr = (char *)malloc(strlen(str) + 1)) == NULL) {
fprintf(stderr, "ERROR in %s:%s() line %d: Unable to strdup() %zu bytes\n", file, funcname, line, strlen(str));
exit(-1);
}
memcpy(newstr, str, strlen(str) + 1);
return newstr;
}
/**
* calls free and sets to NULL.
*/
void
_our_safe_free(void *ptr, const char *funcname, const int line, const char *file)
{
if (ptr == NULL) {
fprintf(stderr, "ERROR in %s:%s() line %d: Unable to call free on a NULL ptr", file, funcname, line);
exit(-1);
}
free(ptr);
ptr = NULL;
}
/**
* Print various packet statistics
*/
void
packet_stats(struct timeval *begin, struct timeval *end,
COUNTER bytes_sent, COUNTER pkts_sent, COUNTER failed)
{
float bytes_sec = 0.0, mb_sec = 0.0, pkts_sec = 0.0;
double frac_sec;
struct timeval diff;
timersub(end, begin, &diff);
timer2float(&diff, frac_sec);
if (timerisset(&diff)) {
if (bytes_sent){
bytes_sec = bytes_sent / frac_sec;
mb_sec = (bytes_sec * 8) / (1024 * 1024);
}
if (pkts_sent)
pkts_sec = pkts_sent / frac_sec;
}
printf("Actual: " COUNTER_SPEC " packets (" COUNTER_SPEC " bytes) sent in %.02f seconds.",
pkts_sent, bytes_sent, frac_sec);
printf("\t\tRated: %.1f bps, %.2f Mbps, %.2f pps\n",
bytes_sec, mb_sec, pkts_sec);
if (failed)
printf(COUNTER_SPEC " write attempts failed from full buffers and were repeated\n",
failed);
}
/**
* reads a hexstring in the format of xx,xx,xx,xx spits it back into *hex
* up to hexlen bytes. Returns actual number of bytes returned. On error
* it just calls errx() since all errors are fatal.
*/
int
read_hexstring(const char *l2string, u_char *hex, const int hexlen)
{
int numbytes = 0;
unsigned int value;
char *l2byte;
u_char databyte;
char *token = NULL;
char *string;
string = safe_strdup(l2string);
if (hexlen <= 0)
err(-1, "Hex buffer must be > 0");
memset(hex, '\0', hexlen);
/* data is hex, comma seperated, byte by byte */
/* get the first byte */
l2byte = strtok_r(string, ",", &token);
sscanf(l2byte, "%x", &value);
if (value > 0xff)
errx(-1, "Invalid hex string byte: %s", l2byte);
databyte = (u_char) value;
memcpy(&hex[numbytes], &databyte, 1);
/* get remaining bytes */
while ((l2byte = strtok_r(NULL, ",", &token)) != NULL) {
numbytes++;
if (numbytes + 1 > hexlen) {
warn("Hex buffer too small for data- skipping data");
return (++numbytes);
}
sscanf(l2byte, "%x", &value);
if (value > 0xff)
errx(-1, "Invalid hex string byte: %s", l2byte);
databyte = (u_char) value;
memcpy(&hex[numbytes], &databyte, 1);
}
numbytes++;
safe_free(string);
dbgx(1, "Read %d bytes of hex data", numbytes);
return (numbytes);
}
#ifdef USE_CUSTOM_INET_ATON
int
inet_aton(const char *name, struct in_addr *addr)
{
in_addr_t a = inet_addr (name);
addr->s_addr = a;
return a != (in_addr_t)-1;
}
#endif

75
src/common/utils.h Normal file
View File

@@ -0,0 +1,75 @@
/* $Id: utils.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _UTILS_H_
#define _UTILS_H_
#include "config.h"
#include "defines.h"
#include "common.h"
int read_hexstring(const char *l2string, u_char *hex, const int hexlen);
void packet_stats(struct timeval *begin, struct timeval *end,
COUNTER bytes_sent, COUNTER pkts_sent, COUNTER failed);
/* our "safe" implimentations of functions which allocate memory */
#define safe_malloc(x) _our_safe_malloc(x, __FUNCTION__, __LINE__, __FILE__)
void *_our_safe_malloc(size_t len, const char *, const int, const char *);
#define safe_realloc(x, y) _our_safe_realloc(x, y, __FUNCTION__, __LINE__, __FILE__)
void *_our_safe_realloc(void *ptr, size_t len, const char *, const int, const char *);
#define safe_strdup(x) _our_safe_strdup(x, __FUNCTION__, __LINE__, __FILE__)
char *_our_safe_strdup(const char *str, const char *, const int, const char *);
#define safe_free(x) _our_safe_free(x, __FUNCTION__, __LINE__, __FILE__)
void _our_safe_free(void *ptr, const char *, const int, const char *);
#define MAX_ARGS 128
#ifndef HAVE_INET_ATON
#define HAVE_INET_ATON
#define USE_CUSTOM_INET_ATON
int inet_aton(const char *name, struct in_addr *addr);
#endif
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

249
src/common/xX.c Normal file
View File

@@ -0,0 +1,249 @@
/* $Id: xX.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* xX stands for "include or exclude" which is used with the
* -x and -X flags
*
* Functions for use to process args for or check data against in
* tcpreplay/do_packets and tcpprep.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdlib.h>
/**
* returns the include_exclude_mode on success placing the CIDR or LIST in mybuf
* but on failure, returns xXError
*/
int
parse_xX_str(tcpr_xX_t *xX, char *str, tcpr_bpf_t *bpf)
{
int out = 0;
dbgx(1, "Parsing string: %s", str);
dbgx(1, "Switching on: %c", str[0]);
switch (str[0]) {
case 'B': /* both ip's */
str = str + 2;
out = xXBoth;
if (!parse_cidr(&(xX->cidr), str, ","))
return xXError;
break;
case 'D': /* dst ip */
str = str + 2;
out = xXDest;
if (!parse_cidr(&(xX->cidr), str, ","))
return xXError;
break;
case 'E': /* either ip */
str = str + 2;
out = xXEither;
if (!parse_cidr(&(xX->cidr), str, ","))
return xXError;
break;
case 'F': /* bpf filter */
str = str + 2;
out = xXBPF;
bpf->filter = safe_strdup(str);
/*
* note: it's temping to compile the BPF here, but we don't
* yet know what the link type is for the file, so we have
* to compile the BPF once we open the pcap file
*/
break;
case 'P': /* packet id */
str = str + 2;
out = xXPacket;
if (!parse_list(&(xX->list), str))
return xXError;
break;
case 'S': /* source ip */
str = str + 2;
out = xXSource;
if (!parse_cidr(&(xX->cidr), str, ","))
return xXError;
break;
default:
errx(-1, "Invalid -%c option: %c", xX->mode, *str);
break;
}
if (xX->mode == 'X') { /* run in exclude mode */
out += xXExclude;
if (bpf->filter != NULL)
err(-1, "Using a BPF filter with -X doesn't work.\n"
"Try using -xF:\"not <filter>\" instead");
}
xX->mode = out;
return xX->mode;
}
/**
* compare the source/destination IP address according to the mode
* and return 1 if we should send the packet or 0 if not
*/
int
process_xX_by_cidr_ipv4(int mode, tcpr_cidr_t * cidr, ipv4_hdr_t * ip_hdr)
{
if (mode & xXExclude) {
/* Exclude mode */
switch (mode ^ xXExclude) {
case xXSource:
/* note: check_ip_cidr() returns TCPR_DIR_C2S for true, TCPR_DIR_S2C for false
* and NOT true/false or 1/0, etc!
*/
return check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ? DONT_SEND : SEND;
break;
case xXDest:
return check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) ? DONT_SEND : SEND;
case xXBoth:
return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) &&
check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ) ? DONT_SEND : SEND;
break;
case xXEither:
return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) ||
check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ) ? DONT_SEND : SEND;
break;
}
}
else {
/* Include Mode */
switch (mode) {
case xXSource:
return check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ? SEND : DONT_SEND;
break;
case xXDest:
return check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) ? SEND : DONT_SEND;
break;
case xXBoth:
return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) &&
check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ) ? SEND : DONT_SEND;
break;
case xXEither:
return (check_ip_cidr(cidr, ip_hdr->ip_dst.s_addr) ||
check_ip_cidr(cidr, ip_hdr->ip_src.s_addr) ) ? SEND : DONT_SEND;
break;
}
}
/* total failure */
if (mode &xXExclude) {
warn("Unable to determine action in CIDR filter mode. Default: Don't Send.");
return DONT_SEND;
} else {
warn("Unable to determine action in CIDR filter mode. Default: Send.");
return SEND;
}
}
int
process_xX_by_cidr_ipv6(int mode, tcpr_cidr_t * cidr, ipv6_hdr_t * ip6_hdr)
{
if (mode & xXExclude) {
/* Exclude mode */
switch (mode ^ xXExclude) {
case xXSource:
/* note: check_ip_cidr() returns TCPR_DIR_C2S for true, TCPR_DIR_S2C for false
* and NOT true/false or 1/0, etc!
*/
return check_ip6_cidr(cidr, &ip6_hdr->ip_src) ? DONT_SEND : SEND;
break;
case xXDest:
return check_ip6_cidr(cidr, &ip6_hdr->ip_dst) ? DONT_SEND : SEND;
case xXBoth:
return (check_ip6_cidr(cidr, &ip6_hdr->ip_dst) &&
check_ip6_cidr(cidr, &ip6_hdr->ip_src) ) ? DONT_SEND : SEND;
break;
case xXEither:
return (check_ip6_cidr(cidr, &ip6_hdr->ip_dst) ||
check_ip6_cidr(cidr, &ip6_hdr->ip_src) ) ? DONT_SEND : SEND;
break;
}
}
else {
/* Include Mode */
switch (mode) {
case xXSource:
return check_ip6_cidr(cidr, &ip6_hdr->ip_src) ? SEND : DONT_SEND;
break;
case xXDest:
return check_ip6_cidr(cidr, &ip6_hdr->ip_dst) ? SEND : DONT_SEND;
break;
case xXBoth:
return (check_ip6_cidr(cidr, &ip6_hdr->ip_dst) &&
check_ip6_cidr(cidr, &ip6_hdr->ip_src) ) ? SEND : DONT_SEND;
break;
case xXEither:
return (check_ip6_cidr(cidr, &ip6_hdr->ip_dst) ||
check_ip6_cidr(cidr, &ip6_hdr->ip_src) ) ? SEND : DONT_SEND;
break;
}
}
/* total failure */
if (mode &xXExclude) {
warn("Unable to determine action in CIDR filter mode. Default: Don't Send.");
return DONT_SEND;
} else {
warn("Unable to determine action in CIDR filter mode. Default: Send.");
return SEND;
}
}

66
src/common/xX.h Normal file
View File

@@ -0,0 +1,66 @@
/* $Id: xX.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __xX_H__
#define __xX_H__
/*
* Functions for processing args/data generated by -x and -X
*/
int parse_xX_str(tcpr_xX_t *xX, char *str, tcpr_bpf_t *bpf);
int process_xX_by_cidr_ipv4(int, tcpr_cidr_t *, ipv4_hdr_t *);
int process_xX_by_cidr_ipv6(int, tcpr_cidr_t *, ipv6_hdr_t *);
/*
* Include/Exclude (xXmode) values
*/
#define xXError 0
#define xXSource 1
#define xXDest 2
#define xXBoth 4
#define xXEither 8
#define xXPacket 16
#define xXBPF 32
#define xXExclude 128 /* if exclude mode, add 128 to above value */
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

547
src/config.h.in Normal file
View File

@@ -0,0 +1,547 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* What version of autogen is installed on this system */
#undef AUTOGEN_VERSION
/* Enable debuging code and support for the -d option */
#undef DEBUG
/* Enable dmalloc function arg checking */
#undef DMALLOC_FUNC_CHECK
/* Enable Electric Fence memory debugger */
#undef EFENCE
/* Use 64bit packet counters */
#undef ENABLE_64BITS
/* Enable dmalloc */
#undef ENABLE_DMALLOC
/* Enable dynamically linking libs */
#undef ENABLE_DYNAMIC_LINK
/* Enable fragroute module */
#undef ENABLE_FRAGROUTE
/* Enable use of pcap_findalldevs() */
#undef ENABLE_PCAP_FINDALLDEVS
/* Compile tcpbridge */
#undef ENABLE_TCPBRIDGE
/* Do we have tcpdump and pcap_dump_fopen()? */
#undef ENABLE_VERBOSE
/* fopen(3) accepts a 'b' in the mode flag */
#undef FOPEN_BINARY_FLAG
/* fopen(3) accepts a 't' in the mode flag */
#undef FOPEN_TEXT_FLAG
/* Are we strictly aligned? */
#undef FORCE_ALIGN
/* Force using BPF for sending packet */
#undef FORCE_INJECT_BPF
/* Force using libdnet for sending packets */
#undef FORCE_INJECT_LIBDNET
/* Force using libpcap's pcap_inject() for sending packets */
#undef FORCE_INJECT_PCAP_INJECT
/* Force using libpcap's pcap_sendpacket() for sending packets */
#undef FORCE_INJECT_PCAP_SENDPACKET
/* Force using Linux's PF_PACKET for sending packets */
#undef FORCE_INJECT_PF
/* Enable GNU Profiler */
#undef GPROF
/* Have OS X UpTime()/AbsoluteTime high-precision timing */
#undef HAVE_ABSOLUTE_TIME
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Do we have BPF device support? */
#undef HAVE_BPF
/* Define to 1 if you have the `canonicalize_file_name' function. */
#undef HAVE_CANONICALIZE_FILE_NAME
/* Define to 1 if you have the `ctime' function. */
#undef HAVE_CTIME
/* Building Apple/Darwin */
#undef HAVE_DARWIN
/* Define this if /dev/zero is readable device */
#undef HAVE_DEV_ZERO
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Does pcap.h include a header with DLT_C_HDLC? */
#undef HAVE_DLT_C_HDLC
/* Does pcap.h include a header with DLT_LINUX_SLL? */
#undef HAVE_DLT_LINUX_SLL
/* Does libpcap have pcap_datalink_val_to_description? */
#undef HAVE_DLT_VAL_TO_DESC
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Do we have inet_addr? */
#undef HAVE_INET_ADDR
/* Do we have inet_aton? */
#undef HAVE_INET_ATON
/* Do we have inet_ntop? */
#undef HAVE_INET_NTOP
/* Do we have inet_pton? */
#undef HAVE_INET_PTON
/* Define to 1 if the system has the type `int16_t'. */
#undef HAVE_INT16_T
/* Define to 1 if the system has the type `int32_t'. */
#undef HAVE_INT32_T
/* Define to 1 if the system has the type `int8_t'. */
#undef HAVE_INT8_T
/* Define to 1 if the system has the type `intptr_t'. */
#undef HAVE_INTPTR_T
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Do we have libdnet? */
#undef HAVE_LIBDNET
/* Define to 1 if you have the `gen' library (-lgen). */
#undef HAVE_LIBGEN
/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define to 1 if you have the `rt' library (-lrt). */
#undef HAVE_LIBRT
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <net/route.h> header file. */
#undef HAVE_NET_ROUTE_H
/* Define to 1 if you have the `ntohll' function. */
#undef HAVE_NTOHLL
/* Define this if pathfind(3) works */
#undef HAVE_PATHFIND
/* Do we have libpcapnav? */
#undef HAVE_PCAPNAV
/* Does libpcap have pcap_breakloop? */
#undef HAVE_PCAP_BREAKLOOP
/* Does libpcap have pcap_dump_fopen? */
#undef HAVE_PCAP_DUMP_FOPEN
/* Does libpcap have pcap_get_selectable_fd? */
#undef HAVE_PCAP_GET_SELECTABLE_FD
/* Does libpcap have pcap_inject? */
#undef HAVE_PCAP_INJECT
/* Does libpcap have pcap_sendpacket? */
#undef HAVE_PCAP_SENDPACKET
/* Does libpcap have pcap_setnonblock? */
#undef HAVE_PCAP_SETNONBLOCK
/* Does libpcap have pcap_snapshot? */
#undef HAVE_PCAP_SNAPSHOT
/* Does libpcap have pcap_version[] */
#undef HAVE_PCAP_VERSION
/* Do we have Linux PF_PACKET socket support? */
#undef HAVE_PF_PACKET
/* Define to 1 if the system has the type `pid_t'. */
#undef HAVE_PID_T
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the <poll.h> header file. */
#undef HAVE_POLL_H
/* Define this if we have a functional realpath(3C) */
#undef HAVE_REALPATH
/* Define to 1 if you have the `regcomp' function. */
#undef HAVE_REGCOMP
/* Define to 1 if you have the <runetype.h> header file. */
#undef HAVE_RUNETYPE_H
/* Define to 1 if you have the <setjmp.h> header file. */
#undef HAVE_SETJMP_H
/* Define to 1 if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
/* Define to 1 if the system has the type `size_t'. */
#undef HAVE_SIZE_T
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define this if strftime() works */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strncpy' function. */
#undef HAVE_STRNCPY
/* Define to 1 if you have the `strrchr' function. */
#undef HAVE_STRRCHR
/* Define to 1 if you have the `strsignal' function. */
#undef HAVE_STRSIGNAL
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if you have the `strtoull' function. */
#undef HAVE_STRTOULL
/* Define to 1 if `tv_sec' is a member of `struct timeval'. */
#undef HAVE_STRUCT_TIMEVAL_TV_SEC
/* Define to 1 if you have the <sysexits.h> header file. */
#undef HAVE_SYSEXITS_H
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_DIR_H
/* Define to 1 if you have the <sys/limits.h> header file. */
#undef HAVE_SYS_LIMITS_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_NDIR_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/poll.h> header file. */
#undef HAVE_SYS_POLL_H
/* Define to 1 if you have the <sys/procset.h> header file. */
#undef HAVE_SYS_PROCSET_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/stropts.h> header file. */
#undef HAVE_SYS_STROPTS_H
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#undef HAVE_SYS_SYSCTL_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Do we have tcpdump? */
#undef HAVE_TCPDUMP
/* Define to 1 if the system has the type `uint16_t'. */
#undef HAVE_UINT16_T
/* Define to 1 if the system has the type `uint32_t'. */
#undef HAVE_UINT32_T
/* Define to 1 if the system has the type `uint8_t'. */
#undef HAVE_UINT8_T
/* Define to 1 if the system has the type `uintptr_t'. */
#undef HAVE_UINTPTR_T
/* Define to 1 if the system has the type `uint_t'. */
#undef HAVE_UINT_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
/* Define to 1 if you have the <values.h> header file. */
#undef HAVE_VALUES_H
/* Define to 1 if you have the <varargs.h> header file. */
#undef HAVE_VARARGS_H
/* Define to 1 if you have the `vprintf' function. */
#undef HAVE_VPRINTF
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
/* Define to 1 if the system has the type `wchar_t'. */
#undef HAVE_WCHAR_T
/* Windows/Cygwin */
#undef HAVE_WIN32
/* Do we have WinPcap? */
#undef HAVE_WINPCAP
/* Define to 1 if the system has the type `wint_t'. */
#undef HAVE_WINT_T
/* What is the path (if any) to the libpcap bpf header file? */
#undef INCLUDE_PCAP_BPF_HEADER
/* Version of libdnet */
#undef LIBDNET_VERSION
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
*/
#undef MAJOR_IN_MKDEV
/* Define to 1 if `major', `minor', and `makedev' are declared in
<sysmacros.h>. */
#undef MAJOR_IN_SYSMACROS
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Define this if optional arguments are disallowed */
#undef NO_OPTIONAL_OPT_ARGS
/* This is our package name */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* libpcapnav's version? */
#undef PCAPNAV_VERSION
/* name of regex header file */
#undef REGEX_HEADER
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* The size of `char*', as computed by sizeof. */
#undef SIZEOF_CHARP
/* The size of `int', as computed by sizeof. */
#undef SIZEOF_INT
/* The size of `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of `short', as computed by sizeof. */
#undef SIZEOF_SHORT
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* The tcpdump binary initially used */
#undef TCPDUMP_BINARY
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* What is our version? */
#undef VERSION
/* Define if using the dmalloc debugging malloc package */
#undef WITH_DMALLOC
/* Define this if a working libregex can be found */
#undef WITH_LIBREGEX
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#undef _LARGEFILE_SOURCE
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define to `uint16_t' if <sys/types.h> does not define. */
#undef u_int16_t
/* Define to `uint32_t' if <sys/types.h> does not define. */
#undef u_int32_t
/* Define to `uint64_t' if <sys/types.h> does not define. */
#undef u_int64_t
/* Define to `uint8_t' if <sys/types.h> does not define. */
#undef u_int8_t

285
src/defines.h.in Normal file
View File

@@ -0,0 +1,285 @@
#ifndef __DEFINES_H__
#define __DEFINES_H__
#include "config.h"
#include "tcpr.h"
/* should packet counters be 32 or 64 bit? --enable-64bit */
#ifdef ENABLE_64BITS
#define COUNTER unsigned long long
#define COUNTER_SPEC "%llu"
#else
#define COUNTER unsigned long
#define COUNTER_SPEC "%lu"
#endif
#ifdef HAVE_BPF
#include <net/bpf.h>
#define PCAP_DONT_INCLUDE_PCAP_BPF_H 1
#endif
#if defined INCLUDE_PCAP_BPF_H_FILE && !defined PCAP_DONT_INCLUDE_PCAP_BPF_H
#include "@PCAP_BPF_H_FILE@"
#define PCAP_DONT_INCLUDE_PCAP_BPF_H 1 /* don't re-include it in pcap.h */
#endif
#include "@LPCAPINC@"
#include "lib/strlcpy.h"
#include "common/list.h"
#include "common/cidr.h"
/*
* net/bpf.h doesn't include DLT types, but pcap-bpf.h does.
* Unfortunately, pcap-bpf.h also includes things in net/bpf.h
* while also missing some key things (wow, that sucks)
* The result is that I stole the DLT types from pcap-bpf.h and
* put them in here.
*/
#include "common/dlt_names.h"
#ifdef HAVE_LIBNET
#include "@LNETINC@"
#endif
typedef struct tcpr_ipv4_hdr ipv4_hdr_t;
typedef struct tcpr_ipv6_hdr ipv6_hdr_t;
typedef struct tcpr_tcp_hdr tcp_hdr_t;
typedef struct tcpr_udp_hdr udp_hdr_t;
typedef struct tcpr_icmpv4_hdr icmpv4_hdr_t;
typedef struct tcpr_icmpv6_hdr icmpv6_hdr_t;
typedef struct tcpr_ethernet_hdr eth_hdr_t;
typedef struct tcpr_802_1q_hdr vlan_hdr_t;
typedef struct sll_header sll_hdr_t;
typedef struct tcpr_arp_hdr arp_hdr_t;
typedef struct tcpr_dnsv4_hdr dnsv4_hdr_t;
/* our custom typdefs/structs */
typedef u_char tcpr_macaddr_t[TCPR_ETH_H];
struct tcpr_bpf_s {
char *filter;
int optimize;
struct bpf_program program;
};
typedef struct tcpr_bpf_s tcpr_bpf_t;
struct tcpr_xX_s {
#define xX_MODE_INCLUDE 'x'
#define xX_MODE_EXCLUDE 'X'
int mode;
tcpr_list_t *list;
tcpr_cidr_t *cidr;
#define xX_TYPE_LIST 1
#define xX_TYPE_CIDR 2
int type;
};
typedef struct tcpr_xX_s tcpr_xX_t;
/* number of ports 0-65535 */
#define NUM_PORTS 65536
struct tcpr_services_s {
char tcp[NUM_PORTS];
char udp[NUM_PORTS];
};
typedef struct tcpr_services_s tcpr_services_t;
struct tcpr_speed_s {
/* speed modifiers */
int mode;
#define SPEED_MULTIPLIER 1
#define SPEED_MBPSRATE 2
#define SPEED_PACKETRATE 3
#define SPEED_TOPSPEED 4
#define SPEED_ONEATATIME 5
float speed;
int pps_multi;
};
typedef struct tcpr_speed_s tcpr_speed_t;
#define MAX_FILES 1024 /* Max number of files we can pass to tcpreplay */
#define DEFAULT_MTU 1500 /* Max Transmission Unit of standard ethernet
* don't forget *frames* are MTU + L2 header! */
#define MAXPACKET 65535 /* was 16436 linux loopback, but maybe something is bigger then
linux loopback */
#define MAX_SNAPLEN 65535 /* tell libpcap to capture the entire packet */
#define DNS_RESOLVE 1
#define DNS_DONT_RESOLVE 0
#define RESOLVE 0 /* disable dns lookups */
#define BPF_OPTIMIZE 1 /* default is to optimize bpf program */
#define PCAP_TIMEOUT 100 /* 100ms pcap_open_live timeout */
/* HP-UX already defines TRUE/FALSE */
#ifndef TRUE
enum bool_t {
FALSE = 0,
TRUE
};
#endif
#define EBUF_SIZE 1024 /* size of our error buffers */
#define MAC_SIZE 7 /* size of the mac[] buffer */
enum pad_t {
PAD_PACKET,
TRUNC_PACKET
};
#define DNS_QUERY_FLAG 0x8000
enum direction_t {
DIR_UNKNOWN = -1,
DIR_CLIENT = 0,
DIR_SERVER = 1,
DIR_ANY = 2
};
enum tcpprep_mode {
ERROR_MODE, /* Some kind of error has occurred */
CIDR_MODE, /* single pass, CIDR netblock */
REGEX_MODE, /* single pass, regex */
PORT_MODE, /* single pass, use src/dst ports to split */
MAC_MODE, /* single pass, use src mac to split */
FIRST_MODE, /* single pass, use first seen to split */
AUTO_MODE, /* first pass through in auto mode */
ROUTER_MODE, /* second pass through in router mode */
BRIDGE_MODE, /* second pass through in bridge mode */
SERVER_MODE, /* second pass through in server (router) mode */
CLIENT_MODE /* second pass through in client (router) mode */
};
#define BROADCAST_MAC "\xFF\xFF\xFF\xFF\xFF\xFF"
/* MAC macros for printf */
#define MAC_FORMAT "%02X:%02X:%02X:%02X:%02X:%02X"
#define MAC_STR(x) x[0], x[1], x[2], x[3], x[4], x[5]
/* struct timeval print structs */
#ifdef HAVE_DARWIN
/* Darwin defines usec as an __int32_t, not unsigned long. */
#define TIMEVAL_FORMAT "%lus %dusec"
#else
#define TIMEVAL_FORMAT "%lus %luusec"
#endif
#define TIMESPEC_FORMAT "%lus %lunsec"
/* force a word or half-word swap on both Big and Little endian systems */
#ifndef SWAPLONG
#define SWAPLONG(y) \
((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
#endif
#ifndef SWAPSHORT
#define SWAPSHORT(y) \
( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
#endif
/* converts a 64bit int to network byte order */
#ifndef HAVE_NTOHLL
#ifdef WORDS_BIGENDIAN
#define ntohll(x) (x)
#define htonll(x) (x)
#else
/* stolen from http://www.codeproject.com/cpp/endianness.asp */
#define ntohll(x) (((u_int64_t)(ntohl((int)((x << 32) >> 32))) << 32) | \
(unsigned int)ntohl(((int)(x >> 32))))
#define htonll(x) ntohll(x)
#endif /* WORDS_BIGENDIAN */
#endif
#define DEBUG_INFO 1 /* informational only, lessthan 1 line per packet */
#define DEBUG_BASIC 2 /* limited debugging, one line per packet */
#define DEBUG_DETAIL 3 /* more detailed, a few lines per packet */
#define DEBUG_MORE 4 /* even more detail */
#define DEBUG_CODE 5 /* examines code & values, many lines per packet */
/* Win32 doesn't know about PF_INET6 */
#ifndef PF_INET6
#ifdef AF_INET6
#define PF_INET6 AF_INET6
#else
#define PF_INET6 30 /* stolen from OS/X */
#endif
#endif
/* convert IPv6 Extention Header Len value to bytes */
#define IPV6_EXTLEN_TO_BYTES(x) ((x * 4) + 8)
#ifndef HAVE_UINT8_T
typedef u_int8_t uint8_t
typedef u_int16_t uint16_t
typedef u_int32_t uint32_t
#endif
/* Support for flexible arrays. */
#undef __flexarr
#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97))
/* GCC 2.97 supports C99 flexible array members. */
# define __flexarr []
#else
# ifdef __GNUC__
# define __flexarr [0]
# else
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define __flexarr []
# elif defined(_WIN32)
/* MS VC++ */
# define __flexarr []
# else
/* Some other non-C99 compiler. Approximate with [1]. */
# define __flexarr [1]
# endif
# endif
#endif
/* Time converters */
#define SEC_TO_MILLISEC(x) (x * 1000)
#define SEC_TO_MICROSEC(x) (x * 1000000)
#define SEC_TO_NANOSEC(x) ((u_int64_t)x * 1000000000)
#define MILLISEC_TO_SEC(x) (x / 1000)
#define MICROSEC_TO_SEC(x) (x / 1000000)
#define NANOSEC_TO_SEC(x) ((u_int64_t)x / 1000000000)
#define TIMEVAL_TO_MILLISEC(x) (((x)->tv_sec * 1000) + ((x)->tv_usec / 1000))
#define TIMEVAL_TO_MICROSEC(x) (((x)->tv_sec * 1000000) + (x)->tv_usec)
#define TIMEVAL_TO_NANOSEC(x) ((u_int64_t)((x)->tv_sec * 1000000000) + ((u_int64_t)(x)->tv_usec * 1000))
#define MILLISEC_TO_TIMEVAL(x, tv) \
do { \
(tv)->tv_sec = (x) / 1000; \
(tv)->tv_usec = (x * 1000) - ((tv)->tv_sec * 1000000); \
} while(0)
#define MICROSEC_TO_TIMEVAL(x, tv) \
do { \
(tv)->tv_sec = (x) / 1000000; \
(tv)->tv_usec = (x) - ((tv)->tv_sec * 1000000); \
} while(0)
#define NANOSEC_TO_TIMEVAL(x, tv) \
do { \
(tv)->tv_sec = (x) / 1000000000; \
(tv)->tv_usec = ((x) % 1000000000) / 1000); \
} while(0)
#define NANOSEC_TO_TIMESPEC(x, ts) \
do { \
(ts)->tv_sec = (x) / 1000000000; \
(ts)->tv_nsec = (x) % 1000000000; \
} while(0)
#define TIMESPEC_TO_MILLISEC(x) (((x)->tv_sec * 1000) + ((x)->tv_nsec / 1000000))
#define TIMESPEC_TO_MICROSEC(x) (((x)->tv_sec * 1000000) + (x)->tv_nsec / 1000)
#define TIMESPEC_TO_NANOSEC(x) ((u_int64_t)((x)->tv_sec * 1000000000) + ((u_int64_t)(x)->tv_nsec))
#endif /* DEFINES */

7
src/encap_sample.cfg Normal file
View File

@@ -0,0 +1,7 @@
[main]
vxlan_smac=74:86:7a:d0:12:fc
vxlan_dmac=00:01:6C:53:A9:94
vxlan_sip=10.0.6.222
vxlan_dip=10.0.6.59
vxlan_sport=50704
vxlan_dport=4789

29
src/fragroute/LICENSE Normal file
View File

@@ -0,0 +1,29 @@
Copyright (c) 2001, 2002 Dug Song <dugsong@monkey.org>
Copyright (c) 2008 Aaron Turner
All rights reserved, all wrongs reversed.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors and copyright holders may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

19
src/fragroute/Makefile.am Normal file
View File

@@ -0,0 +1,19 @@
noinst_LIBRARIES = libfragroute.a
libfragroute_a_SOURCES = fragroute.c bget.c mod.c pkt.c argv.c \
randutil.c mod_delay.c mod_drop.c mod_dup.c \
mod_echo.c mod_ip_chaff.c mod_ip_frag.c mod_ip_opt.c \
mod_ip_ttl.c mod_ip_tos.c mod_order.c mod_print.c \
mod_tcp_chaff.c mod_tcp_opt.c mod_tcp_seg.c \
iputil.c mod_ip6_opt.c mod_ip6_qos.c
libfragroute_a_CFLAGS = -I.. -I../.. @LDNETINC@
# libfragroute_a_LIBS = @LDNETLIB@
noinst_HEADERS = bget.h mod.h pkt.h randutil.h iputil.h fragroute.h argv.h \
LICENSE README
MOSTLYCLEANFILES = *~
MAINTAINERCLEANFILES = Makefiles.in

879
src/fragroute/Makefile.in Normal file
View File

@@ -0,0 +1,879 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = src/fragroute
DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/libopts/m4/libopts.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LIBRARIES = $(noinst_LIBRARIES)
ARFLAGS = cru
libfragroute_a_AR = $(AR) $(ARFLAGS)
libfragroute_a_LIBADD =
am_libfragroute_a_OBJECTS = libfragroute_a-fragroute.$(OBJEXT) \
libfragroute_a-bget.$(OBJEXT) libfragroute_a-mod.$(OBJEXT) \
libfragroute_a-pkt.$(OBJEXT) libfragroute_a-argv.$(OBJEXT) \
libfragroute_a-randutil.$(OBJEXT) \
libfragroute_a-mod_delay.$(OBJEXT) \
libfragroute_a-mod_drop.$(OBJEXT) \
libfragroute_a-mod_dup.$(OBJEXT) \
libfragroute_a-mod_echo.$(OBJEXT) \
libfragroute_a-mod_ip_chaff.$(OBJEXT) \
libfragroute_a-mod_ip_frag.$(OBJEXT) \
libfragroute_a-mod_ip_opt.$(OBJEXT) \
libfragroute_a-mod_ip_ttl.$(OBJEXT) \
libfragroute_a-mod_ip_tos.$(OBJEXT) \
libfragroute_a-mod_order.$(OBJEXT) \
libfragroute_a-mod_print.$(OBJEXT) \
libfragroute_a-mod_tcp_chaff.$(OBJEXT) \
libfragroute_a-mod_tcp_opt.$(OBJEXT) \
libfragroute_a-mod_tcp_seg.$(OBJEXT) \
libfragroute_a-iputil.$(OBJEXT) \
libfragroute_a-mod_ip6_opt.$(OBJEXT) \
libfragroute_a-mod_ip6_qos.$(OBJEXT)
libfragroute_a_OBJECTS = $(am_libfragroute_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libfragroute_a_SOURCES)
DIST_SOURCES = $(libfragroute_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOGEN = @AUTOGEN@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CUT = @CUT@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DMALLOC_LIB = @DMALLOC_LIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GROFF = @GROFF@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDNETINC = @LDNETINC@
LDNETLIB = @LDNETLIB@
LIBOBJS = @LIBOBJS@
LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
LIBOPTS_DIR = @LIBOPTS_DIR@
LIBOPTS_LDADD = @LIBOPTS_LDADD@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LNAVLIB = @LNAVLIB@
LNAV_CFLAGS = @LNAV_CFLAGS@
LN_S = @LN_S@
LPCAPINC = @LPCAPINC@
LPCAPLIB = @LPCAPLIB@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCAP_BPF_H_FILE = @PCAP_BPF_H_FILE@
PRINTF = @PRINTF@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TCPREPLAY_RELEASE = @TCPREPLAY_RELEASE@
TCPREPLAY_VERSION = @TCPREPLAY_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
debug_flag = @debug_flag@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
nic1 = @nic1@
nic2 = @nic2@
oldincludedir = @oldincludedir@
pcncfg = @pcncfg@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
tcpdump_path = @tcpdump_path@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LIBRARIES = libfragroute.a
libfragroute_a_SOURCES = fragroute.c bget.c mod.c pkt.c argv.c \
randutil.c mod_delay.c mod_drop.c mod_dup.c \
mod_echo.c mod_ip_chaff.c mod_ip_frag.c mod_ip_opt.c \
mod_ip_ttl.c mod_ip_tos.c mod_order.c mod_print.c \
mod_tcp_chaff.c mod_tcp_opt.c mod_tcp_seg.c \
iputil.c mod_ip6_opt.c mod_ip6_qos.c
libfragroute_a_CFLAGS = -I.. -I../.. @LDNETINC@
# libfragroute_a_LIBS = @LDNETLIB@
noinst_HEADERS = bget.h mod.h pkt.h randutil.h iputil.h fragroute.h argv.h \
LICENSE README
MOSTLYCLEANFILES = *~
MAINTAINERCLEANFILES = Makefiles.in
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/fragroute/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu src/fragroute/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libfragroute.a: $(libfragroute_a_OBJECTS) $(libfragroute_a_DEPENDENCIES)
-rm -f libfragroute.a
$(libfragroute_a_AR) libfragroute.a $(libfragroute_a_OBJECTS) $(libfragroute_a_LIBADD)
$(RANLIB) libfragroute.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-argv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-bget.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-fragroute.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-iputil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_delay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_drop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_dup.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_echo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_ip6_opt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_ip6_qos.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_ip_chaff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_ip_frag.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_ip_opt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_ip_tos.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_ip_ttl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_order.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_print.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_tcp_chaff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_tcp_opt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-mod_tcp_seg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-pkt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfragroute_a-randutil.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
libfragroute_a-fragroute.o: fragroute.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-fragroute.o -MD -MP -MF $(DEPDIR)/libfragroute_a-fragroute.Tpo -c -o libfragroute_a-fragroute.o `test -f 'fragroute.c' || echo '$(srcdir)/'`fragroute.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-fragroute.Tpo $(DEPDIR)/libfragroute_a-fragroute.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fragroute.c' object='libfragroute_a-fragroute.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-fragroute.o `test -f 'fragroute.c' || echo '$(srcdir)/'`fragroute.c
libfragroute_a-fragroute.obj: fragroute.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-fragroute.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-fragroute.Tpo -c -o libfragroute_a-fragroute.obj `if test -f 'fragroute.c'; then $(CYGPATH_W) 'fragroute.c'; else $(CYGPATH_W) '$(srcdir)/fragroute.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-fragroute.Tpo $(DEPDIR)/libfragroute_a-fragroute.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fragroute.c' object='libfragroute_a-fragroute.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-fragroute.obj `if test -f 'fragroute.c'; then $(CYGPATH_W) 'fragroute.c'; else $(CYGPATH_W) '$(srcdir)/fragroute.c'; fi`
libfragroute_a-bget.o: bget.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-bget.o -MD -MP -MF $(DEPDIR)/libfragroute_a-bget.Tpo -c -o libfragroute_a-bget.o `test -f 'bget.c' || echo '$(srcdir)/'`bget.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-bget.Tpo $(DEPDIR)/libfragroute_a-bget.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bget.c' object='libfragroute_a-bget.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-bget.o `test -f 'bget.c' || echo '$(srcdir)/'`bget.c
libfragroute_a-bget.obj: bget.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-bget.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-bget.Tpo -c -o libfragroute_a-bget.obj `if test -f 'bget.c'; then $(CYGPATH_W) 'bget.c'; else $(CYGPATH_W) '$(srcdir)/bget.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-bget.Tpo $(DEPDIR)/libfragroute_a-bget.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bget.c' object='libfragroute_a-bget.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-bget.obj `if test -f 'bget.c'; then $(CYGPATH_W) 'bget.c'; else $(CYGPATH_W) '$(srcdir)/bget.c'; fi`
libfragroute_a-mod.o: mod.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod.Tpo -c -o libfragroute_a-mod.o `test -f 'mod.c' || echo '$(srcdir)/'`mod.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod.Tpo $(DEPDIR)/libfragroute_a-mod.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod.c' object='libfragroute_a-mod.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod.o `test -f 'mod.c' || echo '$(srcdir)/'`mod.c
libfragroute_a-mod.obj: mod.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod.Tpo -c -o libfragroute_a-mod.obj `if test -f 'mod.c'; then $(CYGPATH_W) 'mod.c'; else $(CYGPATH_W) '$(srcdir)/mod.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod.Tpo $(DEPDIR)/libfragroute_a-mod.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod.c' object='libfragroute_a-mod.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod.obj `if test -f 'mod.c'; then $(CYGPATH_W) 'mod.c'; else $(CYGPATH_W) '$(srcdir)/mod.c'; fi`
libfragroute_a-pkt.o: pkt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-pkt.o -MD -MP -MF $(DEPDIR)/libfragroute_a-pkt.Tpo -c -o libfragroute_a-pkt.o `test -f 'pkt.c' || echo '$(srcdir)/'`pkt.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-pkt.Tpo $(DEPDIR)/libfragroute_a-pkt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pkt.c' object='libfragroute_a-pkt.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-pkt.o `test -f 'pkt.c' || echo '$(srcdir)/'`pkt.c
libfragroute_a-pkt.obj: pkt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-pkt.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-pkt.Tpo -c -o libfragroute_a-pkt.obj `if test -f 'pkt.c'; then $(CYGPATH_W) 'pkt.c'; else $(CYGPATH_W) '$(srcdir)/pkt.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-pkt.Tpo $(DEPDIR)/libfragroute_a-pkt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pkt.c' object='libfragroute_a-pkt.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-pkt.obj `if test -f 'pkt.c'; then $(CYGPATH_W) 'pkt.c'; else $(CYGPATH_W) '$(srcdir)/pkt.c'; fi`
libfragroute_a-argv.o: argv.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-argv.o -MD -MP -MF $(DEPDIR)/libfragroute_a-argv.Tpo -c -o libfragroute_a-argv.o `test -f 'argv.c' || echo '$(srcdir)/'`argv.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-argv.Tpo $(DEPDIR)/libfragroute_a-argv.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='argv.c' object='libfragroute_a-argv.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-argv.o `test -f 'argv.c' || echo '$(srcdir)/'`argv.c
libfragroute_a-argv.obj: argv.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-argv.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-argv.Tpo -c -o libfragroute_a-argv.obj `if test -f 'argv.c'; then $(CYGPATH_W) 'argv.c'; else $(CYGPATH_W) '$(srcdir)/argv.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-argv.Tpo $(DEPDIR)/libfragroute_a-argv.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='argv.c' object='libfragroute_a-argv.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-argv.obj `if test -f 'argv.c'; then $(CYGPATH_W) 'argv.c'; else $(CYGPATH_W) '$(srcdir)/argv.c'; fi`
libfragroute_a-randutil.o: randutil.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-randutil.o -MD -MP -MF $(DEPDIR)/libfragroute_a-randutil.Tpo -c -o libfragroute_a-randutil.o `test -f 'randutil.c' || echo '$(srcdir)/'`randutil.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-randutil.Tpo $(DEPDIR)/libfragroute_a-randutil.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='randutil.c' object='libfragroute_a-randutil.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-randutil.o `test -f 'randutil.c' || echo '$(srcdir)/'`randutil.c
libfragroute_a-randutil.obj: randutil.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-randutil.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-randutil.Tpo -c -o libfragroute_a-randutil.obj `if test -f 'randutil.c'; then $(CYGPATH_W) 'randutil.c'; else $(CYGPATH_W) '$(srcdir)/randutil.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-randutil.Tpo $(DEPDIR)/libfragroute_a-randutil.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='randutil.c' object='libfragroute_a-randutil.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-randutil.obj `if test -f 'randutil.c'; then $(CYGPATH_W) 'randutil.c'; else $(CYGPATH_W) '$(srcdir)/randutil.c'; fi`
libfragroute_a-mod_delay.o: mod_delay.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_delay.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_delay.Tpo -c -o libfragroute_a-mod_delay.o `test -f 'mod_delay.c' || echo '$(srcdir)/'`mod_delay.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_delay.Tpo $(DEPDIR)/libfragroute_a-mod_delay.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_delay.c' object='libfragroute_a-mod_delay.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_delay.o `test -f 'mod_delay.c' || echo '$(srcdir)/'`mod_delay.c
libfragroute_a-mod_delay.obj: mod_delay.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_delay.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_delay.Tpo -c -o libfragroute_a-mod_delay.obj `if test -f 'mod_delay.c'; then $(CYGPATH_W) 'mod_delay.c'; else $(CYGPATH_W) '$(srcdir)/mod_delay.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_delay.Tpo $(DEPDIR)/libfragroute_a-mod_delay.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_delay.c' object='libfragroute_a-mod_delay.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_delay.obj `if test -f 'mod_delay.c'; then $(CYGPATH_W) 'mod_delay.c'; else $(CYGPATH_W) '$(srcdir)/mod_delay.c'; fi`
libfragroute_a-mod_drop.o: mod_drop.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_drop.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_drop.Tpo -c -o libfragroute_a-mod_drop.o `test -f 'mod_drop.c' || echo '$(srcdir)/'`mod_drop.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_drop.Tpo $(DEPDIR)/libfragroute_a-mod_drop.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_drop.c' object='libfragroute_a-mod_drop.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_drop.o `test -f 'mod_drop.c' || echo '$(srcdir)/'`mod_drop.c
libfragroute_a-mod_drop.obj: mod_drop.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_drop.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_drop.Tpo -c -o libfragroute_a-mod_drop.obj `if test -f 'mod_drop.c'; then $(CYGPATH_W) 'mod_drop.c'; else $(CYGPATH_W) '$(srcdir)/mod_drop.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_drop.Tpo $(DEPDIR)/libfragroute_a-mod_drop.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_drop.c' object='libfragroute_a-mod_drop.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_drop.obj `if test -f 'mod_drop.c'; then $(CYGPATH_W) 'mod_drop.c'; else $(CYGPATH_W) '$(srcdir)/mod_drop.c'; fi`
libfragroute_a-mod_dup.o: mod_dup.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_dup.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_dup.Tpo -c -o libfragroute_a-mod_dup.o `test -f 'mod_dup.c' || echo '$(srcdir)/'`mod_dup.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_dup.Tpo $(DEPDIR)/libfragroute_a-mod_dup.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_dup.c' object='libfragroute_a-mod_dup.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_dup.o `test -f 'mod_dup.c' || echo '$(srcdir)/'`mod_dup.c
libfragroute_a-mod_dup.obj: mod_dup.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_dup.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_dup.Tpo -c -o libfragroute_a-mod_dup.obj `if test -f 'mod_dup.c'; then $(CYGPATH_W) 'mod_dup.c'; else $(CYGPATH_W) '$(srcdir)/mod_dup.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_dup.Tpo $(DEPDIR)/libfragroute_a-mod_dup.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_dup.c' object='libfragroute_a-mod_dup.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_dup.obj `if test -f 'mod_dup.c'; then $(CYGPATH_W) 'mod_dup.c'; else $(CYGPATH_W) '$(srcdir)/mod_dup.c'; fi`
libfragroute_a-mod_echo.o: mod_echo.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_echo.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_echo.Tpo -c -o libfragroute_a-mod_echo.o `test -f 'mod_echo.c' || echo '$(srcdir)/'`mod_echo.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_echo.Tpo $(DEPDIR)/libfragroute_a-mod_echo.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_echo.c' object='libfragroute_a-mod_echo.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_echo.o `test -f 'mod_echo.c' || echo '$(srcdir)/'`mod_echo.c
libfragroute_a-mod_echo.obj: mod_echo.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_echo.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_echo.Tpo -c -o libfragroute_a-mod_echo.obj `if test -f 'mod_echo.c'; then $(CYGPATH_W) 'mod_echo.c'; else $(CYGPATH_W) '$(srcdir)/mod_echo.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_echo.Tpo $(DEPDIR)/libfragroute_a-mod_echo.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_echo.c' object='libfragroute_a-mod_echo.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_echo.obj `if test -f 'mod_echo.c'; then $(CYGPATH_W) 'mod_echo.c'; else $(CYGPATH_W) '$(srcdir)/mod_echo.c'; fi`
libfragroute_a-mod_ip_chaff.o: mod_ip_chaff.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_chaff.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_chaff.Tpo -c -o libfragroute_a-mod_ip_chaff.o `test -f 'mod_ip_chaff.c' || echo '$(srcdir)/'`mod_ip_chaff.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_chaff.Tpo $(DEPDIR)/libfragroute_a-mod_ip_chaff.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_chaff.c' object='libfragroute_a-mod_ip_chaff.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_chaff.o `test -f 'mod_ip_chaff.c' || echo '$(srcdir)/'`mod_ip_chaff.c
libfragroute_a-mod_ip_chaff.obj: mod_ip_chaff.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_chaff.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_chaff.Tpo -c -o libfragroute_a-mod_ip_chaff.obj `if test -f 'mod_ip_chaff.c'; then $(CYGPATH_W) 'mod_ip_chaff.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_chaff.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_chaff.Tpo $(DEPDIR)/libfragroute_a-mod_ip_chaff.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_chaff.c' object='libfragroute_a-mod_ip_chaff.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_chaff.obj `if test -f 'mod_ip_chaff.c'; then $(CYGPATH_W) 'mod_ip_chaff.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_chaff.c'; fi`
libfragroute_a-mod_ip_frag.o: mod_ip_frag.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_frag.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_frag.Tpo -c -o libfragroute_a-mod_ip_frag.o `test -f 'mod_ip_frag.c' || echo '$(srcdir)/'`mod_ip_frag.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_frag.Tpo $(DEPDIR)/libfragroute_a-mod_ip_frag.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_frag.c' object='libfragroute_a-mod_ip_frag.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_frag.o `test -f 'mod_ip_frag.c' || echo '$(srcdir)/'`mod_ip_frag.c
libfragroute_a-mod_ip_frag.obj: mod_ip_frag.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_frag.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_frag.Tpo -c -o libfragroute_a-mod_ip_frag.obj `if test -f 'mod_ip_frag.c'; then $(CYGPATH_W) 'mod_ip_frag.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_frag.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_frag.Tpo $(DEPDIR)/libfragroute_a-mod_ip_frag.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_frag.c' object='libfragroute_a-mod_ip_frag.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_frag.obj `if test -f 'mod_ip_frag.c'; then $(CYGPATH_W) 'mod_ip_frag.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_frag.c'; fi`
libfragroute_a-mod_ip_opt.o: mod_ip_opt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_opt.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_opt.Tpo -c -o libfragroute_a-mod_ip_opt.o `test -f 'mod_ip_opt.c' || echo '$(srcdir)/'`mod_ip_opt.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_opt.Tpo $(DEPDIR)/libfragroute_a-mod_ip_opt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_opt.c' object='libfragroute_a-mod_ip_opt.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_opt.o `test -f 'mod_ip_opt.c' || echo '$(srcdir)/'`mod_ip_opt.c
libfragroute_a-mod_ip_opt.obj: mod_ip_opt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_opt.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_opt.Tpo -c -o libfragroute_a-mod_ip_opt.obj `if test -f 'mod_ip_opt.c'; then $(CYGPATH_W) 'mod_ip_opt.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_opt.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_opt.Tpo $(DEPDIR)/libfragroute_a-mod_ip_opt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_opt.c' object='libfragroute_a-mod_ip_opt.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_opt.obj `if test -f 'mod_ip_opt.c'; then $(CYGPATH_W) 'mod_ip_opt.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_opt.c'; fi`
libfragroute_a-mod_ip_ttl.o: mod_ip_ttl.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_ttl.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_ttl.Tpo -c -o libfragroute_a-mod_ip_ttl.o `test -f 'mod_ip_ttl.c' || echo '$(srcdir)/'`mod_ip_ttl.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_ttl.Tpo $(DEPDIR)/libfragroute_a-mod_ip_ttl.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_ttl.c' object='libfragroute_a-mod_ip_ttl.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_ttl.o `test -f 'mod_ip_ttl.c' || echo '$(srcdir)/'`mod_ip_ttl.c
libfragroute_a-mod_ip_ttl.obj: mod_ip_ttl.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_ttl.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_ttl.Tpo -c -o libfragroute_a-mod_ip_ttl.obj `if test -f 'mod_ip_ttl.c'; then $(CYGPATH_W) 'mod_ip_ttl.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_ttl.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_ttl.Tpo $(DEPDIR)/libfragroute_a-mod_ip_ttl.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_ttl.c' object='libfragroute_a-mod_ip_ttl.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_ttl.obj `if test -f 'mod_ip_ttl.c'; then $(CYGPATH_W) 'mod_ip_ttl.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_ttl.c'; fi`
libfragroute_a-mod_ip_tos.o: mod_ip_tos.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_tos.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_tos.Tpo -c -o libfragroute_a-mod_ip_tos.o `test -f 'mod_ip_tos.c' || echo '$(srcdir)/'`mod_ip_tos.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_tos.Tpo $(DEPDIR)/libfragroute_a-mod_ip_tos.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_tos.c' object='libfragroute_a-mod_ip_tos.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_tos.o `test -f 'mod_ip_tos.c' || echo '$(srcdir)/'`mod_ip_tos.c
libfragroute_a-mod_ip_tos.obj: mod_ip_tos.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip_tos.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip_tos.Tpo -c -o libfragroute_a-mod_ip_tos.obj `if test -f 'mod_ip_tos.c'; then $(CYGPATH_W) 'mod_ip_tos.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_tos.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip_tos.Tpo $(DEPDIR)/libfragroute_a-mod_ip_tos.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip_tos.c' object='libfragroute_a-mod_ip_tos.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip_tos.obj `if test -f 'mod_ip_tos.c'; then $(CYGPATH_W) 'mod_ip_tos.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip_tos.c'; fi`
libfragroute_a-mod_order.o: mod_order.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_order.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_order.Tpo -c -o libfragroute_a-mod_order.o `test -f 'mod_order.c' || echo '$(srcdir)/'`mod_order.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_order.Tpo $(DEPDIR)/libfragroute_a-mod_order.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_order.c' object='libfragroute_a-mod_order.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_order.o `test -f 'mod_order.c' || echo '$(srcdir)/'`mod_order.c
libfragroute_a-mod_order.obj: mod_order.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_order.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_order.Tpo -c -o libfragroute_a-mod_order.obj `if test -f 'mod_order.c'; then $(CYGPATH_W) 'mod_order.c'; else $(CYGPATH_W) '$(srcdir)/mod_order.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_order.Tpo $(DEPDIR)/libfragroute_a-mod_order.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_order.c' object='libfragroute_a-mod_order.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_order.obj `if test -f 'mod_order.c'; then $(CYGPATH_W) 'mod_order.c'; else $(CYGPATH_W) '$(srcdir)/mod_order.c'; fi`
libfragroute_a-mod_print.o: mod_print.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_print.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_print.Tpo -c -o libfragroute_a-mod_print.o `test -f 'mod_print.c' || echo '$(srcdir)/'`mod_print.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_print.Tpo $(DEPDIR)/libfragroute_a-mod_print.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_print.c' object='libfragroute_a-mod_print.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_print.o `test -f 'mod_print.c' || echo '$(srcdir)/'`mod_print.c
libfragroute_a-mod_print.obj: mod_print.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_print.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_print.Tpo -c -o libfragroute_a-mod_print.obj `if test -f 'mod_print.c'; then $(CYGPATH_W) 'mod_print.c'; else $(CYGPATH_W) '$(srcdir)/mod_print.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_print.Tpo $(DEPDIR)/libfragroute_a-mod_print.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_print.c' object='libfragroute_a-mod_print.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_print.obj `if test -f 'mod_print.c'; then $(CYGPATH_W) 'mod_print.c'; else $(CYGPATH_W) '$(srcdir)/mod_print.c'; fi`
libfragroute_a-mod_tcp_chaff.o: mod_tcp_chaff.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_tcp_chaff.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_tcp_chaff.Tpo -c -o libfragroute_a-mod_tcp_chaff.o `test -f 'mod_tcp_chaff.c' || echo '$(srcdir)/'`mod_tcp_chaff.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_tcp_chaff.Tpo $(DEPDIR)/libfragroute_a-mod_tcp_chaff.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_tcp_chaff.c' object='libfragroute_a-mod_tcp_chaff.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_tcp_chaff.o `test -f 'mod_tcp_chaff.c' || echo '$(srcdir)/'`mod_tcp_chaff.c
libfragroute_a-mod_tcp_chaff.obj: mod_tcp_chaff.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_tcp_chaff.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_tcp_chaff.Tpo -c -o libfragroute_a-mod_tcp_chaff.obj `if test -f 'mod_tcp_chaff.c'; then $(CYGPATH_W) 'mod_tcp_chaff.c'; else $(CYGPATH_W) '$(srcdir)/mod_tcp_chaff.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_tcp_chaff.Tpo $(DEPDIR)/libfragroute_a-mod_tcp_chaff.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_tcp_chaff.c' object='libfragroute_a-mod_tcp_chaff.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_tcp_chaff.obj `if test -f 'mod_tcp_chaff.c'; then $(CYGPATH_W) 'mod_tcp_chaff.c'; else $(CYGPATH_W) '$(srcdir)/mod_tcp_chaff.c'; fi`
libfragroute_a-mod_tcp_opt.o: mod_tcp_opt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_tcp_opt.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_tcp_opt.Tpo -c -o libfragroute_a-mod_tcp_opt.o `test -f 'mod_tcp_opt.c' || echo '$(srcdir)/'`mod_tcp_opt.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_tcp_opt.Tpo $(DEPDIR)/libfragroute_a-mod_tcp_opt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_tcp_opt.c' object='libfragroute_a-mod_tcp_opt.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_tcp_opt.o `test -f 'mod_tcp_opt.c' || echo '$(srcdir)/'`mod_tcp_opt.c
libfragroute_a-mod_tcp_opt.obj: mod_tcp_opt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_tcp_opt.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_tcp_opt.Tpo -c -o libfragroute_a-mod_tcp_opt.obj `if test -f 'mod_tcp_opt.c'; then $(CYGPATH_W) 'mod_tcp_opt.c'; else $(CYGPATH_W) '$(srcdir)/mod_tcp_opt.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_tcp_opt.Tpo $(DEPDIR)/libfragroute_a-mod_tcp_opt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_tcp_opt.c' object='libfragroute_a-mod_tcp_opt.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_tcp_opt.obj `if test -f 'mod_tcp_opt.c'; then $(CYGPATH_W) 'mod_tcp_opt.c'; else $(CYGPATH_W) '$(srcdir)/mod_tcp_opt.c'; fi`
libfragroute_a-mod_tcp_seg.o: mod_tcp_seg.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_tcp_seg.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_tcp_seg.Tpo -c -o libfragroute_a-mod_tcp_seg.o `test -f 'mod_tcp_seg.c' || echo '$(srcdir)/'`mod_tcp_seg.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_tcp_seg.Tpo $(DEPDIR)/libfragroute_a-mod_tcp_seg.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_tcp_seg.c' object='libfragroute_a-mod_tcp_seg.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_tcp_seg.o `test -f 'mod_tcp_seg.c' || echo '$(srcdir)/'`mod_tcp_seg.c
libfragroute_a-mod_tcp_seg.obj: mod_tcp_seg.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_tcp_seg.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_tcp_seg.Tpo -c -o libfragroute_a-mod_tcp_seg.obj `if test -f 'mod_tcp_seg.c'; then $(CYGPATH_W) 'mod_tcp_seg.c'; else $(CYGPATH_W) '$(srcdir)/mod_tcp_seg.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_tcp_seg.Tpo $(DEPDIR)/libfragroute_a-mod_tcp_seg.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_tcp_seg.c' object='libfragroute_a-mod_tcp_seg.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_tcp_seg.obj `if test -f 'mod_tcp_seg.c'; then $(CYGPATH_W) 'mod_tcp_seg.c'; else $(CYGPATH_W) '$(srcdir)/mod_tcp_seg.c'; fi`
libfragroute_a-iputil.o: iputil.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-iputil.o -MD -MP -MF $(DEPDIR)/libfragroute_a-iputil.Tpo -c -o libfragroute_a-iputil.o `test -f 'iputil.c' || echo '$(srcdir)/'`iputil.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-iputil.Tpo $(DEPDIR)/libfragroute_a-iputil.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iputil.c' object='libfragroute_a-iputil.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-iputil.o `test -f 'iputil.c' || echo '$(srcdir)/'`iputil.c
libfragroute_a-iputil.obj: iputil.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-iputil.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-iputil.Tpo -c -o libfragroute_a-iputil.obj `if test -f 'iputil.c'; then $(CYGPATH_W) 'iputil.c'; else $(CYGPATH_W) '$(srcdir)/iputil.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-iputil.Tpo $(DEPDIR)/libfragroute_a-iputil.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iputil.c' object='libfragroute_a-iputil.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-iputil.obj `if test -f 'iputil.c'; then $(CYGPATH_W) 'iputil.c'; else $(CYGPATH_W) '$(srcdir)/iputil.c'; fi`
libfragroute_a-mod_ip6_opt.o: mod_ip6_opt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip6_opt.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip6_opt.Tpo -c -o libfragroute_a-mod_ip6_opt.o `test -f 'mod_ip6_opt.c' || echo '$(srcdir)/'`mod_ip6_opt.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip6_opt.Tpo $(DEPDIR)/libfragroute_a-mod_ip6_opt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip6_opt.c' object='libfragroute_a-mod_ip6_opt.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip6_opt.o `test -f 'mod_ip6_opt.c' || echo '$(srcdir)/'`mod_ip6_opt.c
libfragroute_a-mod_ip6_opt.obj: mod_ip6_opt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip6_opt.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip6_opt.Tpo -c -o libfragroute_a-mod_ip6_opt.obj `if test -f 'mod_ip6_opt.c'; then $(CYGPATH_W) 'mod_ip6_opt.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip6_opt.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip6_opt.Tpo $(DEPDIR)/libfragroute_a-mod_ip6_opt.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip6_opt.c' object='libfragroute_a-mod_ip6_opt.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip6_opt.obj `if test -f 'mod_ip6_opt.c'; then $(CYGPATH_W) 'mod_ip6_opt.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip6_opt.c'; fi`
libfragroute_a-mod_ip6_qos.o: mod_ip6_qos.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip6_qos.o -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip6_qos.Tpo -c -o libfragroute_a-mod_ip6_qos.o `test -f 'mod_ip6_qos.c' || echo '$(srcdir)/'`mod_ip6_qos.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip6_qos.Tpo $(DEPDIR)/libfragroute_a-mod_ip6_qos.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip6_qos.c' object='libfragroute_a-mod_ip6_qos.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip6_qos.o `test -f 'mod_ip6_qos.c' || echo '$(srcdir)/'`mod_ip6_qos.c
libfragroute_a-mod_ip6_qos.obj: mod_ip6_qos.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -MT libfragroute_a-mod_ip6_qos.obj -MD -MP -MF $(DEPDIR)/libfragroute_a-mod_ip6_qos.Tpo -c -o libfragroute_a-mod_ip6_qos.obj `if test -f 'mod_ip6_qos.c'; then $(CYGPATH_W) 'mod_ip6_qos.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip6_qos.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfragroute_a-mod_ip6_qos.Tpo $(DEPDIR)/libfragroute_a-mod_ip6_qos.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mod_ip6_qos.c' object='libfragroute_a-mod_ip6_qos.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfragroute_a_CFLAGS) $(CFLAGS) -c -o libfragroute_a-mod_ip6_qos.obj `if test -f 'mod_ip6_qos.c'; then $(CYGPATH_W) 'mod_ip6_qos.c'; else $(CYGPATH_W) '$(srcdir)/mod_ip6_qos.c'; fi`
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

33
src/fragroute/README Normal file
View File

@@ -0,0 +1,33 @@
This code is heavily based on, even stolen from Dug Song's excellent fragroute
utility. I've taken a perfectly good application and converted it into a
packet editing library for my own needs. Any bugs are my fault. Any praises
really should go to Dug.
Please consider all files here under the original fragroute LICENSE, with the
added caveat that any changes are:
Copyright 2008, Aaron Turner
Notes:
Fragroute runs as a daemon which intercepts packets by modifying the host
operating systems routing table, redirecting packets destined to the target
IP over the loopback interface. Packets reaching the loopback interface
are then read using libpcap/BPF filter processed according to the fragroute
rule set and then resent out the configured interface.
libfragroute works differently. First, we do away with any changes to the
host routing table. Secondly, packets are not sent out any interface, but
are read back by the caller. The API should look something like this:
ctx = fragroute_init(mtu, <rules>); // init library
// process a packet
fragroute_process(ctx, char *pktbuff, int pktsize)
// read resulting fragments
while ((ret = fragroute_read(ctx, char **fragment)) > 0) {
// do something with fragment
} else {
// no more fragments
}

68
src/fragroute/argv.c Normal file
View File

@@ -0,0 +1,68 @@
/*
* argv.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: argv.c 2000 2008-04-27 06:17:35Z aturner $
*/
#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "argv.h"
int
argv_create(char *p, int argc, char *argv[])
{
int i;
for (i = 0; i < argc - 1; i++) {
while (*p != '\0' && isspace((int)*p))
*p++ = '\0';
if (*p == '\0')
break;
argv[i] = p;
while (*p != '\0' && !isspace((int)*p))
p++;
}
p[0] = '\0';
argv[i] = NULL;
return (i);
}
/* XXX - from tcpdump util.c. */
char *
argv_copy(char *argv[])
{
char **p, *buf, *src, *dst;
int len = 0;
p = argv;
if (*p == 0)
return (NULL);
while (*p)
len += strlen(*p++) + 1;
if ((buf = (char *)malloc(len)) == NULL)
return (NULL);
p = argv;
dst = buf;
while ((src = *p++) != NULL) {
while ((*dst++ = *src++) != '\0')
;
dst[-1] = ' ';
}
dst[-1] = '\0';
return (buf);
}

15
src/fragroute/argv.h Normal file
View File

@@ -0,0 +1,15 @@
/*
* argv.h
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: argv.h 2000 2008-04-27 06:17:35Z aturner $
*/
#ifndef ARGV_H
#define ARGV_H
int argv_create(char *p, int argc, char *argv[]);
char *argv_copy(char *argv[]);
#endif /* ARGV_H */

1592
src/fragroute/bget.c Normal file

File diff suppressed because it is too large Load Diff

30
src/fragroute/bget.h Normal file
View File

@@ -0,0 +1,30 @@
/*
Interface definitions for bget.c, the memory management package.
*/
#ifndef _
#ifdef PROTOTYPES
#define _(x) x /* If compiler knows prototypes */
#else
#define _(x) () /* It it doesn't */
#endif /* PROTOTYPES */
#endif
typedef long bufsize;
void bpool _((void *buffer, bufsize len));
void *bget _((bufsize size));
void *bgetz _((bufsize size));
void *bgetr _((void *buffer, bufsize newsize));
void brel _((void *buf));
void bectl _((int (*compact)(bufsize sizereq, int sequence),
void *(*acquire)(bufsize size),
void (*release)(void *buf), bufsize pool_incr));
void bstats _((bufsize *curalloc, bufsize *totfree, bufsize *maxfree,
long *nget, long *nrel));
void bstatse _((bufsize *pool_incr, long *npool, long *npget,
long *nprel, long *ndget, long *ndrel));
void bufdump _((void *buf));
void bpoold _((void *pool, int dumpalloc, int dumpfree));
int bpoolv _((void *pool));

144
src/fragroute/fragroute.c Normal file
View File

@@ -0,0 +1,144 @@
/*
* fragroute.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
* Copyright (c) 2007-2008 Aaron Turner.
* $Id: fragroute.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_LIBDNET
/* need to undef these which are pulled in via defines.h, prior to importing dnet.h */
#undef icmp_id
#undef icmp_seq
#undef icmp_data
#undef icmp_mask
#include <dnet.h>
#endif
#include "fragroute.h"
#include "pkt.h"
#include "mod.h"
// #include "tun.h"
void
fragroute_close(fragroute_t *ctx)
{
free(ctx->pktq);
free(ctx);
ctx = NULL;
}
int
fragroute_process(fragroute_t *ctx, void *buf, size_t len)
{
struct pkt *pkt;
assert(ctx);
assert(buf);
ctx->first_packet = 0;
/* save the l2 header of the original packet for later */
ctx->l2len = get_l2len(buf, len, ctx->dlt);
memcpy(ctx->l2header, buf, ctx->l2len);
if ((pkt = pkt_new()) == NULL) {
strcpy(ctx->errbuf, "unable to pkt_new()");
return -1;
}
if (len > PKT_BUF_LEN) {
sprintf(ctx->errbuf, "skipping oversized packet: %zu", len);
return -1;
}
memcpy(pkt->pkt_data, buf, len);
pkt->pkt_end = pkt->pkt_data + len;
pkt_decorate(pkt);
if (pkt->pkt_ip == NULL) {
strcpy(ctx->errbuf, "skipping non-IP packet");
return -1;
}
if (pkt->pkt_eth && htons(pkt->pkt_eth->eth_type) == ETH_TYPE_IP) {
ip_checksum(pkt->pkt_ip, len);
}
TAILQ_INIT(ctx->pktq);
TAILQ_INSERT_TAIL(ctx->pktq, pkt, pkt_next);
mod_apply(ctx->pktq);
return 0;
}
/*
* keep calling this after fragroute_process() to get all the fragments.
* Each call returns the fragment length which is stored in **packet.
* Returns 0 when no more fragments remain or -1 on error
*/
int
fragroute_getfragment(fragroute_t *ctx, char **packet)
{
static struct pkt *pkt = NULL;
static struct pkt *next = NULL;
char *pkt_data = *packet;
u_int32_t length;
if (ctx->first_packet != 0) {
pkt = next;
} else {
ctx->first_packet = 1;
pkt = TAILQ_FIRST(ctx->pktq);
}
if (pkt != TAILQ_END(&(ctx->pktq))) {
next = TAILQ_NEXT(pkt, pkt_next);
memcpy(pkt_data, pkt->pkt_data, pkt->pkt_end - pkt->pkt_data);
/* return the original L2 header */
memcpy(pkt_data, ctx->l2header, ctx->l2len);
length = pkt->pkt_end - pkt->pkt_data;
pkt = next;
return length;
}
return 0; // nothing
}
fragroute_t *
fragroute_init(const int mtu, const int dlt, const char *config, char *errbuf)
{
fragroute_t *ctx;
if (dlt != DLT_EN10MB) {
sprintf(errbuf, "Fragroute only supports DLT_EN10MB pcap files");
return NULL;
}
ctx = (fragroute_t *)safe_malloc(sizeof(fragroute_t));
ctx->pktq = (struct pktq *)safe_malloc(sizeof(struct pktq));
ctx->dlt = dlt;
pkt_init(128);
ctx->mtu = mtu;
/* parse the config */
if (mod_open(config, errbuf) < 0) {
fragroute_close(ctx);
return NULL;
}
return ctx;
}

69
src/fragroute/fragroute.h Normal file
View File

@@ -0,0 +1,69 @@
/* $Id: fragroute.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2007-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "pkt.h"
#ifndef __FRAGROUTE_H__
#define __FRAGROUTE_H__
#define FRAGROUTE_ERRBUF_LEN 1024
/* Fragroute context. */
struct fragroute_s {
struct addr src;
struct addr dst;
struct addr smac;
struct addr dmac;
int dlt;
int mtu;
int first_packet; /* have we called getfragment() yet after process()? */
int l2len;
u_char l2header[50];
// arp_t *arp;
// eth_t *eth;
// intf_t *intf;
// route_t *route;
// tun_t *tun;
char errbuf[FRAGROUTE_ERRBUF_LEN];
struct pktq *pktq; /* packet chain */
};
typedef struct fragroute_s fragroute_t;
int fragroute_process(fragroute_t *ctx, void *buf, size_t len);
int fragroute_getfragment(fragroute_t *ctx, char **packet);
fragroute_t * fragroute_init(const int mtu, const int dlt, const char *config, char *errbuf);
void fragroute_close(fragroute_t *ctx);
#endif /* __FRAGROUTE_H__ */

147
src/fragroute/iputil.c Normal file
View File

@@ -0,0 +1,147 @@
#include "config.h"
#include "defines.h"
#include "common.h"
#include "iputil.h"
#include <dnet.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
static ssize_t
inet_add_option_6(void *buf, size_t len, int proto, const void *optbuf, size_t optlen);
ssize_t
inet_add_option(uint16_t eth_type, void *buf, size_t len,
int proto, const void *optbuf, size_t optlen)
{
if (eth_type == ETH_TYPE_IP) {
return ip_add_option(buf, len, proto, optbuf, optlen);
} else if (eth_type == ETH_TYPE_IPV6) {
return inet_add_option_6(buf, len, proto, optbuf, optlen);
} else {
errno = EINVAL;
return -1;
}
}
/*
* IPv6 version of libdnet's ip_add_option():
*/
ssize_t
inet_add_option_6(void *buf, size_t len, int proto, const void *optbuf, size_t optlen)
{
struct ip6_hdr *ip6;
struct tcp_hdr *tcp = NULL;
u_char *p;
int hl, datalen, padlen;
if (proto != IP_PROTO_TCP) {
errno = EINVAL;
return (-1);
}
ip6 = (struct ip6_hdr *)buf;
p = (u_char *)buf + IP6_HDR_LEN;
tcp = (struct tcp_hdr *)p;
hl = tcp->th_off << 2;
p = (u_char *)tcp + hl;
datalen = ntohs(ip6->ip6_plen) + IP6_HDR_LEN - (p - (u_char *)buf);
/* Compute padding to next word boundary. */
if ((padlen = 4 - (optlen % 4)) == 4)
padlen = 0;
/* XXX - IP_HDR_LEN_MAX == TCP_HDR_LEN_MAX */
if (hl + optlen + padlen > IP_HDR_LEN_MAX ||
ntohs(ip6->ip6_plen) + IP6_HDR_LEN + optlen + padlen > len) {
errno = EINVAL;
return (-1);
}
/* Shift any existing data. */
if (datalen) {
memmove(p + optlen + padlen, p, datalen);
}
/* XXX - IP_OPT_NOP == TCP_OPT_NOP */
if (padlen) {
memset(p, IP_OPT_NOP, padlen);
p += padlen;
}
memmove(p, optbuf, optlen);
p += optlen;
optlen += padlen;
tcp->th_off = (p - (u_char *)tcp) >> 2;
ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) + optlen);
return (optlen);
}
void
inet_checksum(uint16_t eth_type, void *buf, size_t len)
{
if (eth_type == ETH_TYPE_IP) {
return ip_checksum(buf, len);
} else if (eth_type == ETH_TYPE_IPV6) {
return ip6_checksum(buf, len);
}
}
int
raw_ip_opt_parse(int argc, char *argv[], uint8_t *opt_type, uint8_t *opt_len,
uint8_t *buff, int buff_len)
{
int i, j;
if (sscanf(argv[0], "%hhx", opt_type) != 1) {
warn("invalid opt_type");
return -1;
}
if (sscanf(argv[1], "%hhx", opt_len) != 1) {
warn("invalid opt_len");
return -1;
}
j = 0;
for (i = 2; i < argc && j < buff_len; ++i, ++j) {
if (sscanf(argv[i], "%hhx", &buff[j]) != 1) {
warn("invalid opt_data");
return -1;
}
}
if (*opt_len != j + 2) {
warnx("invalid opt->len (%d) doesn't match data length (%d)",
*opt_len, j);
return -1;
}
return 0;
}
int
raw_ip6_opt_parse(int argc, char *argv[], uint8_t *proto, int *len,
uint8_t *buff, int buff_len)
{
int i, j;
if (sscanf(argv[0], "%hhx", proto) != 1) {
warn("invalid protocol");
return -1;
}
j = 0;
for (i = 1; i < argc && j < buff_len; ++i, ++j) {
if (sscanf(argv[i], "%hhx", &buff[j]) != 1) {
warn("invalid opt_data");
return -1;
}
}
*len = j;
if ((j + 2) % 8 != 0) {
warnx("(opt_len (%d) + 2) %% 8 != 0", j);
return -1;
}
return 0;
}

13
src/fragroute/iputil.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef IPUTIL_H
#define IPUTIL_H
ssize_t inet_add_option(uint16_t eth_type, void *buf, size_t len,
int proto, const void *optbuf, size_t optlen);
void inet_checksum(uint16_t eth_type, void *buf, size_t len);
int raw_ip_opt_parse(int argc, char *argv[], uint8_t *type, uint8_t *len,
uint8_t *buff, int buff_len);
int raw_ip6_opt_parse(int argc, char *argv[], uint8_t *proto, int *len,
uint8_t *buff, int buff_len);
#endif /* IPUTIL_H */

187
src/fragroute/mod.c Normal file
View File

@@ -0,0 +1,187 @@
/*
* mod.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
* Copyright (c) 2007-2010 Aaron Turner.
*
* $Id: mod.c 2423 2010-03-13 07:09:49Z aturner $
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "argv.h"
#include "mod.h"
#define MAX_ARGS 128 /* XXX */
struct rule {
struct mod *mod;
void *data;
TAILQ_ENTRY(rule) next;
};
/*
* XXX - new modules must be registered here.
*/
extern struct mod mod_delay;
extern struct mod mod_drop;
extern struct mod mod_dup;
extern struct mod mod_echo;
extern struct mod mod_ip_chaff;
extern struct mod mod_ip_frag;
extern struct mod mod_ip_opt;
extern struct mod mod_ip_ttl;
extern struct mod mod_ip_tos;
extern struct mod mod_ip6_qos;
extern struct mod mod_ip6_opt;
extern struct mod mod_order;
extern struct mod mod_print;
extern struct mod mod_tcp_chaff;
extern struct mod mod_tcp_opt;
extern struct mod mod_tcp_seg;
static struct mod *mods[] = {
&mod_delay,
&mod_drop,
&mod_dup,
&mod_echo,
&mod_ip_chaff,
&mod_ip_frag,
&mod_ip_opt,
&mod_ip_ttl,
&mod_ip_tos,
&mod_ip6_qos,
&mod_ip6_opt,
&mod_order,
&mod_print,
&mod_tcp_chaff,
&mod_tcp_opt,
&mod_tcp_seg,
NULL
};
static TAILQ_HEAD(head, rule) rules;
void
mod_usage(void)
{
struct mod **m;
for (m = mods; *m != NULL; m++) {
fprintf(stderr, " %s\n", (*m)->usage);
}
}
int
mod_open(const char *script, char *errbuf)
{
FILE *fp;
struct mod **m;
struct rule *rule;
char *argv[MAX_ARGS], buf[BUFSIZ];
int i, argc, ret = 0;
TAILQ_INIT(&rules);
/* open the config/script file */
if ((fp = fopen(script, "r")) == NULL) {
sprintf(errbuf, "couldn't open %s", script);
return (-1);
}
dbg(1, "opened config file...");
/* read the file, one line at a time... */
for (i = 1; fgets(buf, sizeof(buf), fp) != NULL; i++) {
/* skip comments & blank lines */
if (*buf == '#' || *buf == '\r' || *buf == '\n')
continue;
/* parse the line into an array */
if ((argc = argv_create(buf, MAX_ARGS, argv)) < 1) {
sprintf(errbuf, "couldn't parse arguments (line %d)", i);
ret = -1;
break;
}
dbgx(1, "argc = %d, %s, %s, %s", argc, argv[0], argv[1], argv[2]);
/* check first keyword against modules */
for (m = mods; *m != NULL; m++) {
if (strcasecmp((*m)->name, argv[0]) == 0) {
dbgx(1, "comparing %s to %s", argv[0], (*m)->name);
break;
}
}
/* do we have a match? */
if (*m == NULL) {
sprintf(errbuf, "unknown directive '%s' (line %d)", argv[0], i);
ret = -1;
break;
}
/* allocate memory for our rule */
if ((rule = calloc(1, sizeof(*rule))) == NULL) {
sprintf(errbuf, "calloc");
ret = -1;
break;
}
rule->mod = *m;
/* pass the remaining args to the rule */
if (rule->mod->open != NULL &&
(rule->data = rule->mod->open(argc, argv)) == NULL) {
sprintf(errbuf, "invalid argument to directive '%s' (line %d)",
rule->mod->name, i);
ret = -1;
break;
}
/* append the rule to the rule list */
TAILQ_INSERT_TAIL(&rules, rule, next);
}
/* close the file */
fclose(fp);
dbg(1, "close file...");
if (ret == 0) {
buf[0] = '\0';
TAILQ_FOREACH(rule, &rules, next) {
strlcat(buf, rule->mod->name, sizeof(buf));
strlcat(buf, " -> ", sizeof(buf));
}
buf[strlen(buf) - 4] = '\0';
sprintf(errbuf, "wtf: %s", buf);
// ret = -1;
}
return (ret);
}
void
mod_apply(struct pktq *pktq)
{
struct rule *rule;
TAILQ_FOREACH(rule, &rules, next) {
rule->mod->apply(rule->data, pktq);
}
}
void
mod_close(void)
{
struct rule *rule;
TAILQ_FOREACH_REVERSE(rule, &rules, next, head) {
if (rule->mod->close != NULL)
rule->data = rule->mod->close(rule->data);
TAILQ_REMOVE(&rules, rule, next);
free(rule);
}
}

27
src/fragroute/mod.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* mod.h
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod.h 2000 2008-04-27 06:17:35Z aturner $
*/
#ifndef MOD_H
#define MOD_H
#include "pkt.h"
struct mod {
char *name;
char *usage;
void *(*open)(int argc, char *argv[]);
int (*apply)(void *data, struct pktq *pktq);
void *(*close)(void *data);
};
void mod_usage(void);
int mod_open(const char *script, char *errbuf);
void mod_apply(struct pktq *pktq);
void mod_close(void);
#endif /* MOD_H */

97
src/fragroute/mod_delay.c Normal file
View File

@@ -0,0 +1,97 @@
/*
* mod_delay.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_delay.c 2000 2008-04-27 06:17:35Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pkt.h"
#include "mod.h"
#define DELAY_FIRST 1
#define DELAY_LAST 2
#define DELAY_RANDOM 3
struct delay_data {
rand_t *rnd;
int which;
struct timeval tv;
};
void *
delay_close(void *d)
{
struct delay_data *data = (struct delay_data *)d;
if (data != NULL) {
rand_close(data->rnd);
free(data);
}
return (NULL);
}
void *
delay_open(int argc, char *argv[])
{
struct delay_data *data;
uint64_t usec;
if (argc != 3)
return (NULL);
if ((data = malloc(sizeof(*data))) == NULL)
return (NULL);
data->rnd = rand_open();
if (strcasecmp(argv[1], "first") == 0)
data->which = DELAY_FIRST;
else if (strcasecmp(argv[1], "last") == 0)
data->which = DELAY_LAST;
else if (strcasecmp(argv[1], "random") == 0)
data->which = DELAY_RANDOM;
else
return (delay_close(data));
if ((usec = atoi(argv[2])) <= 0)
return (delay_close(data));
usec *= 1000;
data->tv.tv_sec = usec / 1000000;
data->tv.tv_usec = usec % 1000000;
return (data);
}
int
delay_apply(void *d, struct pktq *pktq)
{
struct delay_data *data = (struct delay_data *)d;
struct pkt *pkt;
if (data->which == DELAY_FIRST)
pkt = TAILQ_FIRST(pktq);
else if (data->which == DELAY_LAST)
pkt = TAILQ_LAST(pktq, pktq);
else
pkt = pktq_random(data->rnd, pktq);
memcpy(&pkt->pkt_ts, &data->tv, sizeof(pkt->pkt_ts));
return (0);
}
struct mod mod_delay = {
"delay", /* name */
"delay first|last|random <ms>", /* usage */
delay_open, /* open */
delay_apply, /* apply */
delay_close /* close */
};

97
src/fragroute/mod_drop.c Normal file
View File

@@ -0,0 +1,97 @@
/*
* mod_drop.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_drop.c 2000 2008-04-27 06:17:35Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pkt.h"
#include "mod.h"
#define DROP_FIRST 1
#define DROP_LAST 2
#define DROP_RANDOM 3
struct drop_data {
rand_t *rnd;
int which;
int percent;
};
void *
drop_close(void *d)
{
struct drop_data *data = (struct drop_data *)d;
if (data != NULL) {
rand_close(data->rnd);
free(data);
}
return (NULL);
}
void *
drop_open(int argc, char *argv[])
{
struct drop_data *data;
if (argc != 3)
return (NULL);
if ((data = calloc(1, sizeof(*data))) == NULL)
return (NULL);
data->rnd = rand_open();
if (strcasecmp(argv[1], "first") == 0)
data->which = DROP_FIRST;
else if (strcasecmp(argv[1], "last") == 0)
data->which = DROP_LAST;
else if (strcasecmp(argv[1], "random") == 0)
data->which = DROP_RANDOM;
else
return (drop_close(data));
if ((data->percent = atoi(argv[2])) <= 0 || data->percent > 100)
return (drop_close(data));
return (data);
}
int
drop_apply(void *d, struct pktq *pktq)
{
struct drop_data *data = (struct drop_data *)d;
struct pkt *pkt;
if (data->percent < 100 &&
(rand_uint16(data->rnd) % 100) > data->percent)
return (0);
if (data->which == DROP_FIRST)
pkt = TAILQ_FIRST(pktq);
else if (data->which == DROP_LAST)
pkt = TAILQ_LAST(pktq, pktq);
else
pkt = pktq_random(data->rnd, pktq);
TAILQ_REMOVE(pktq, pkt, pkt_next);
pkt_free(pkt);
return (0);
}
struct mod mod_drop = {
"drop", /* name */
"drop first|last|random <prob-%>", /* usage */
drop_open, /* open */
drop_apply, /* apply */
drop_close /* close */
};

100
src/fragroute/mod_dup.c Normal file
View File

@@ -0,0 +1,100 @@
/*
* mod_dup.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_dup.c 2000 2008-04-27 06:17:35Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pkt.h"
#include "mod.h"
#define DUP_FIRST 1
#define DUP_LAST 2
#define DUP_RANDOM 3
struct dup_data {
rand_t *rnd;
int which;
int percent;
};
void *
dup_close(void *d)
{
struct dup_data *data = (struct dup_data *)d;
if (data != NULL) {
rand_close(data->rnd);
free(data);
}
return (NULL);
}
void *
dup_open(int argc, char *argv[])
{
struct dup_data *data;
if (argc != 3)
return (NULL);
if ((data = malloc(sizeof(*data))) == NULL)
return (NULL);
data->rnd = rand_open();
if (strcasecmp(argv[1], "first") == 0)
data->which = DUP_FIRST;
else if (strcasecmp(argv[1], "last") == 0)
data->which = DUP_LAST;
else if (strcasecmp(argv[1], "random") == 0)
data->which = DUP_RANDOM;
else
return (dup_close(data));
if ((data->percent = atoi(argv[2])) <= 0 || data->percent > 100)
return (dup_close(data));
return (data);
}
int
dup_apply(void *d, struct pktq *pktq)
{
struct dup_data *data = (struct dup_data *)d;
struct pkt *pkt, *new;
if (data->percent < 100 &&
(rand_uint16(data->rnd) % 100) > data->percent)
return (0);
if ((new = pkt_new()) == NULL)
return (-1);
if (data->which == DUP_FIRST)
pkt = TAILQ_FIRST(pktq);
else if (data->which == DUP_LAST)
pkt = TAILQ_LAST(pktq, pktq);
else
pkt = pktq_random(data->rnd, pktq);
new = pkt_dup(pkt);
TAILQ_INSERT_AFTER(pktq, pkt, new, pkt_next);
return (0);
}
struct mod mod_dup = {
"dup", /* name */
"dup first|last|random <prob-%>", /* usage */
dup_open, /* open */
dup_apply, /* apply */
dup_close /* close */
};

57
src/fragroute/mod_echo.c Normal file
View File

@@ -0,0 +1,57 @@
/*
* mod_echo.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_echo.c 2000 2008-04-27 06:17:35Z aturner $
*/
#include "config.h"
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "argv.h"
#include "mod.h"
void *
echo_open(int argc, char *argv[])
{
char *p;
if (argc < 2)
return (NULL);
if ((p = argv_copy(argv + 1)) == NULL)
return (NULL);
return (p);
}
int
echo_apply(void *d, struct pktq *pktq)
{
char *p = (char *)d;
printf("%s\n", p);
return (0);
}
void *
echo_close(void *d)
{
if (d != NULL)
free(d);
return (NULL);
}
struct mod mod_echo = {
"echo", /* name */
"echo <string> ...", /* usage */
echo_open, /* open */
echo_apply, /* apply */
echo_close /* close */
};

196
src/fragroute/mod_ip6_opt.c Normal file
View File

@@ -0,0 +1,196 @@
/*
* mod_ip6_opt.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
*/
#include "config.h"
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pkt.h"
#include "mod.h"
#include "iputil.h"
#define MAX_ADDRS 32
#define OPT6_TYPE_ROUTE 1
#define OPT6_TYPE_RAW 2
struct ip6_opt_data_route
{
int segments;
struct addr addr[MAX_ADDRS];
};
struct ip6_opt_data_raw
{
int len;
uint8_t proto;
uint8_t data8[512];
};
struct ip6_opt_data
{
int type;
union
{
struct ip6_opt_data_route route;
struct ip6_opt_data_raw raw;
} u;
};
void *
ip6_opt_close(void *d)
{
if (d != NULL)
free(d);
return (NULL);
}
void *
ip6_opt_open(int argc, char *argv[])
{
struct ip6_opt_data *opt;
int i, j;
if (argc < 4)
return (NULL);
if ((opt = calloc(1, sizeof(*opt))) == NULL)
return (NULL);
if (strcasecmp(argv[1], "route") == 0) {
opt->type = OPT6_TYPE_ROUTE;
if ((opt->u.route.segments = atoi(argv[2])) < 1 ||
opt->u.route.segments > MAX_ADDRS) {
warnx("<segments> must be >= 1");
return (ip6_opt_close(opt));
}
i = 0;
j = 3;
if (opt->u.route.segments + 3 != argc) {
return (ip6_opt_close(opt));
}
for (; j < argc; i++, j++) {
if (addr_aton(argv[j], &opt->u.route.addr[i]) < 0 ||
opt->u.route.addr[i].addr_type != ADDR_TYPE_IP6) {
return (ip6_opt_close(opt));
}
}
} else if (strcasecmp(argv[1], "raw") == 0) {
opt->type = OPT6_TYPE_RAW;
if (raw_ip6_opt_parse(argc - 2, &argv[2],
&opt->u.raw.proto, &opt->u.raw.len,
&opt->u.raw.data8[2], sizeof(opt->u.raw.data8) - 2) != 0)
return (ip6_opt_close(opt));
opt->u.raw.len += 2;
opt->u.raw.data8[0] = 0;
opt->u.raw.data8[1] = opt->u.raw.len / 8;
} else {
return (ip6_opt_close(opt));
}
return (opt);
}
int
ip6_opt_apply(void *d, struct pktq *pktq)
{
struct ip6_opt_data *opt = (struct ip6_opt_data *)d;
struct __ip6_ext_data_routing* route;
struct ip6_ext_hdr* ext;
int offset, len;
struct pkt *pkt;
uint8_t nxt, iph_nxt;
uint8_t* p;
int i;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
if (eth_type != ETH_TYPE_IPV6) {
continue;
}
nxt = pkt->pkt_ip6->ip6_nxt;
ext = (struct ip6_ext_hdr*)(((u_char*)pkt->pkt_ip6) + IP6_HDR_LEN);
if (opt->type == OPT6_TYPE_ROUTE) {
offset = 8 + IP6_ADDR_LEN * opt->u.route.segments;
memmove(((u_char*)ext) + offset, ext, pkt->pkt_end - (u_char*)ext);
pkt->pkt_end += offset;
pkt->pkt_ip_data += offset;
len = (IP6_ADDR_LEN / 8) * opt->u.route.segments;
route = (struct __ip6_ext_data_routing*)ext;
ext->ext_data.routing.type = 0;
ext->ext_data.routing.segleft = opt->u.route.segments;
((uint32_t*)ext)[1] = 0; /* reserved */
iph_nxt = IP_PROTO_ROUTING;
p = (uint8_t*)(ext) + 8;
for (i = 0; i < opt->u.route.segments; ++i, p += IP6_ADDR_LEN) {
memcpy(p, opt->u.route.addr[i].addr_data8, IP6_ADDR_LEN);
}
} else if (opt->type == OPT6_TYPE_RAW) {
offset = opt->u.raw.len;
memmove(((u_char*)ext) + offset, ext, pkt->pkt_end - (u_char*)ext);
pkt->pkt_end += offset;
pkt->pkt_ip_data += offset;
iph_nxt = opt->u.raw.proto;
p = (uint8_t*)ext;
memcpy(p, opt->u.raw.data8, opt->u.raw.len);
#if 0
printf("len: %d, data %02x %02x %02x %02x %02x %02x %02x %02x\n",
opt->u.raw.len, opt->u.raw.data8[0], opt->u.raw.data8[1],
opt->u.raw.data8[2], opt->u.raw.data8[3],
opt->u.raw.data8[4], opt->u.raw.data8[5],
opt->u.raw.data8[6], opt->u.raw.data8[7]);
#endif
len = (opt->u.raw.len - 8) / 8;
} else {
continue;
}
ext->ext_nxt = nxt;
ext->ext_len = len;
pkt->pkt_ip6->ip6_nxt = iph_nxt;
pkt->pkt_ip6->ip6_plen = htons(htons(pkt->pkt_ip6->ip6_plen) + offset);
/* XXX: do we need it? */
pkt_decorate(pkt);
/* ip6_checksum(pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data); */
}
return (0);
}
struct mod mod_ip6_opt = {
"ip6_opt", /* name */
"ip6_opt [route <segments> <ip6-addr> ...] | [raw <type> <byte stream>]", /* usage */
ip6_opt_open, /* open */
ip6_opt_apply, /* apply */
ip6_opt_close /* close */
};

View File

@@ -0,0 +1,83 @@
/*
* mod_ip6_qos.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "argv.h"
#include "mod.h"
#include "pkt.h"
struct ip6_qos_data
{
int ip6_tc;
int ip6_fl;
};
static void *
ip6_qos_close(void *d)
{
if (d != NULL)
free(d);
return (NULL);
}
static void *
ip6_qos_open(int argc, char *argv[])
{
struct ip6_qos_data *data;
if (argc != 3) {
return NULL;
}
if ((data = calloc(1, sizeof(*data))) == NULL)
return (NULL);
if (sscanf(argv[1], "%x", &data->ip6_tc) != 1 ||
data->ip6_tc < 0 || data->ip6_tc > 255)
return (ip6_qos_close(data));
if (sscanf(argv[2], "%x", &data->ip6_fl) != 1 ||
data->ip6_fl < 0 || data->ip6_fl > 0x100000)
return (ip6_qos_close(data));
printf("init: %x\n", data->ip6_fl);
return (data);
}
static int
ip6_qos_apply(void *d, struct pktq *pktq)
{
struct ip6_qos_data *data = (struct ip6_qos_data *)d;
struct pkt *pkt;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
if (eth_type == ETH_TYPE_IPV6) {
if (data->ip6_tc || data->ip6_fl) {
pkt->pkt_ip6->ip6_flow = htonl((uint32_t)data->ip6_tc << 20 |
data->ip6_fl);
pkt->pkt_ip6->ip6_vfc = (IP6_VERSION | (data->ip6_tc >> 4));
}
}
}
return (0);
}
struct mod mod_ip6_qos = {
"ip6_qos", /* name */
"ip6_qos <tc> <fl>", /* usage */
ip6_qos_open, /* open */
ip6_qos_apply, /* apply */
ip6_qos_close /* close */
};

View File

@@ -0,0 +1,137 @@
/*
* mod_ip_chaff.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_ip_chaff.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mod.h"
#include "pkt.h"
#include "randutil.h"
#define CHAFF_TYPE_DUP 1
#define CHAFF_TYPE_OPT 2
#define CHAFF_TYPE_TTL 3
struct ip_chaff_data {
rand_t *rnd;
int type;
int ttl;
struct pktq *pktq;
};
void *
ip_chaff_close(void *d)
{
struct ip_chaff_data *data = (struct ip_chaff_data *)d;
if (data != NULL) {
rand_close(data->rnd);
free(data);
}
return (NULL);
}
void *
ip_chaff_open(int argc, char *argv[])
{
struct ip_chaff_data *data;
if (argc < 2)
return (NULL);
if ((data = calloc(1, sizeof(*data))) == NULL)
return (NULL);
data->rnd = rand_open();
if (strcasecmp(argv[1], "dup") == 0) {
data->type = CHAFF_TYPE_DUP;
} else if (strcasecmp(argv[1], "opt") == 0) {
data->type = CHAFF_TYPE_OPT;
} else if ((data->ttl = atoi(argv[1])) >= 0 && data->ttl < 256) {
data->type = CHAFF_TYPE_TTL;
} else
return (ip_chaff_close(data));
return (data);
}
int
ip_chaff_apply(void *d, struct pktq *pktq)
{
struct ip_chaff_data *data = (struct ip_chaff_data *)d;
struct pkt *pkt, *new, *next;
struct ip_opt opt;
int i;
uint16_t eth_type;
for (pkt = TAILQ_FIRST(pktq); pkt != TAILQ_END(pktq); pkt = next) {
next = TAILQ_NEXT(pkt, pkt_next);
eth_type = htons(pkt->pkt_eth->eth_type);
if (pkt->pkt_ip_data == NULL)
continue;
new = pkt_dup(pkt);
rand_strset(data->rnd, new->pkt_ip_data,
new->pkt_end - new->pkt_ip_data + 1);
switch (data->type) {
case CHAFF_TYPE_DUP:
new->pkt_ts.tv_usec = 1;
if (eth_type == ETH_TYPE_IP) {
ip_checksum(new->pkt_ip, new->pkt_ip_data -
new->pkt_eth_data);
}
break;
case CHAFF_TYPE_OPT:
if (eth_type == ETH_TYPE_IP) {
opt.opt_type = 0x42;
opt.opt_len = IP_OPT_LEN;
i = ip_add_option(new->pkt_ip,
PKT_BUF_LEN - ETH_HDR_LEN, IP_PROTO_IP,
&opt, opt.opt_len);
/* XXX - whack opt with random crap */
*(uint32_t *)new->pkt_ip_data = rand_uint32(data->rnd);
new->pkt_ip_data += i;
new->pkt_end += i;
ip_checksum(new->pkt_ip, new->pkt_ip_data -
new->pkt_eth_data);
} else if (eth_type == ETH_TYPE_IPV6) {
continue;
}
case CHAFF_TYPE_TTL:
if (eth_type == ETH_TYPE_IP) {
new->pkt_ip->ip_ttl = data->ttl;
ip_checksum(new->pkt_ip, new->pkt_ip_data -
new->pkt_eth_data);
} else if (eth_type == ETH_TYPE_IPV6) {
pkt->pkt_ip6->ip6_hlim = data->ttl;
}
break;
}
/* Minimal random reordering - for ipv4 and ipv6 */
if ((new->pkt_ip_data[0] & 1) == 0)
TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
else
TAILQ_INSERT_AFTER(pktq, pkt, new, pkt_next);
}
return (0);
}
struct mod mod_ip_chaff = {
"ip_chaff", /* name */
"ip_chaff dup|opt|<ttl>", /* usage */
ip_chaff_open, /* open */
ip_chaff_apply, /* apply */
ip_chaff_close /* close */
};

316
src/fragroute/mod_ip_frag.c Normal file
View File

@@ -0,0 +1,316 @@
/*
* mod_ip_frag.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_ip_frag.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mod.h"
#include "pkt.h"
#include "randutil.h"
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
#define FAVOR_OLD 1
#define FAVOR_NEW 2
static int
ip_frag_apply_ipv4(void *d, struct pktq *pktq);
static int
ip_frag_apply_ipv6(void *d, struct pktq *pktq);
static struct ip_frag_data
{
rand_t *rnd;
int size;
int overlap;
uint32_t ident;
} ip_frag_data;
void *
ip_frag_close(void *d)
{
if (ip_frag_data.rnd != NULL)
rand_close(ip_frag_data.rnd);
ip_frag_data.size = 0;
return (NULL);
}
void *
ip_frag_open(int argc, char *argv[])
{
if (argc < 2) {
warn("need fragment <size> in bytes");
return (NULL);
}
ip_frag_data.rnd = rand_open();
ip_frag_data.size = atoi(argv[1]);
if (ip_frag_data.size == 0 || (ip_frag_data.size % 8) != 0) {
warn("fragment size must be a multiple of 8");
return (ip_frag_close(&ip_frag_data));
}
if (argc == 3) {
if (strcmp(argv[2], "old") == 0 ||
strcmp(argv[2], "win32") == 0)
ip_frag_data.overlap = FAVOR_OLD;
else if (strcmp(argv[2], "new") == 0 ||
strcmp(argv[2], "unix") == 0)
ip_frag_data.overlap = FAVOR_NEW;
else
return (ip_frag_close(&ip_frag_data));
}
ip_frag_data.ident = rand_uint32(ip_frag_data.rnd);
return (&ip_frag_data);
}
int
ip_frag_apply(void *d, struct pktq *pktq)
{
struct pkt *pkt;
/* Select eth protocol via first packet in que: */
pkt = TAILQ_FIRST(pktq);
if (pkt != TAILQ_END(pktq)) {
uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
if (eth_type == ETH_TYPE_IP) {
ip_frag_apply_ipv4(d, pktq);
} else if (eth_type == ETH_TYPE_IPV6) {
ip_frag_apply_ipv6(d, pktq);
}
return 0;
}
return 0;
}
static int
ip_frag_apply_ipv4(void *d, struct pktq *pktq)
{
struct pkt *pkt, *new, *next, tmp;
int hl, fraglen, off;
u_char *p, *p1, *p2;
for (pkt = TAILQ_FIRST(pktq); pkt != TAILQ_END(pktq); pkt = next) {
next = TAILQ_NEXT(pkt, pkt_next);
if (pkt->pkt_ip == NULL || pkt->pkt_ip_data == NULL)
continue;
hl = pkt->pkt_ip->ip_hl << 2;
/*
* Preserve transport protocol header in first frag,
* to bypass filters that block `short' fragments.
*/
switch (pkt->pkt_ip->ip_p) {
case IP_PROTO_ICMP:
fraglen = MAX(ICMP_LEN_MIN, ip_frag_data.size);
break;
case IP_PROTO_UDP:
fraglen = MAX(UDP_HDR_LEN, ip_frag_data.size);
break;
case IP_PROTO_TCP:
fraglen = MAX(pkt->pkt_tcp->th_off << 2,
ip_frag_data.size);
break;
default:
fraglen = ip_frag_data.size;
break;
}
if (fraglen & 7)
fraglen = (fraglen & ~7) + 8;
if (pkt->pkt_end - pkt->pkt_ip_data < fraglen)
continue;
for (p = pkt->pkt_ip_data; p < pkt->pkt_end; ) {
new = pkt_new();
memcpy(new->pkt_eth, pkt->pkt_eth, (u_char*)pkt->pkt_eth_data - (u_char*)pkt->pkt_eth);
memcpy(new->pkt_ip, pkt->pkt_ip, hl);
new->pkt_ip_data = new->pkt_eth_data + hl;
p1 = p, p2 = NULL;
off = (p - pkt->pkt_ip_data) >> 3;
if (ip_frag_data.overlap != 0 && (off & 1) != 0 &&
p + (fraglen << 1) < pkt->pkt_end) {
rand_strset(ip_frag_data.rnd, tmp.pkt_buf,
fraglen);
if (ip_frag_data.overlap == FAVOR_OLD) {
p1 = p + fraglen;
p2 = tmp.pkt_buf;
} else if (ip_frag_data.overlap == FAVOR_NEW) {
p1 = tmp.pkt_buf;
p2 = p + fraglen;
}
new->pkt_ip->ip_off = htons(IP_MF |
(off + (fraglen >> 3)));
} else {
new->pkt_ip->ip_off = htons(off |
((p + fraglen < pkt->pkt_end) ? IP_MF: 0));
}
new->pkt_ip->ip_len = htons(hl + fraglen);
ip_checksum(new->pkt_ip, hl + fraglen);
memcpy(new->pkt_ip_data, p1, fraglen);
new->pkt_end = new->pkt_ip_data + fraglen;
TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
if (p2 != NULL) {
new = pkt_dup(new);
new->pkt_ts.tv_usec = 1;
new->pkt_ip->ip_off = htons(IP_MF | off);
new->pkt_ip->ip_len = htons(hl + (fraglen<<1));
ip_checksum(new->pkt_ip, hl + (fraglen<<1));
memcpy(new->pkt_ip_data, p, fraglen);
memcpy(new->pkt_ip_data+fraglen, p2, fraglen);
new->pkt_end = new->pkt_ip_data + (fraglen<<1);
TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
p += (fraglen << 1);
} else
p += fraglen;
if ((fraglen = pkt->pkt_end - p) > ip_frag_data.size)
fraglen = ip_frag_data.size;
}
TAILQ_REMOVE(pktq, pkt, pkt_next);
pkt_free(pkt);
}
return (0);
}
static int
ip_frag_apply_ipv6(void *d, struct pktq *pktq)
{
struct pkt *pkt, *new, *next, tmp;
struct ip6_ext_hdr *ext;
int hl, fraglen, off;
u_char *p, *p1, *p2;
uint8_t next_hdr;
ip_frag_data.ident++;
for (pkt = TAILQ_FIRST(pktq); pkt != TAILQ_END(pktq); pkt = next) {
next = TAILQ_NEXT(pkt, pkt_next);
if (pkt->pkt_ip == NULL || pkt->pkt_ip_data == NULL)
continue;
hl = IP6_HDR_LEN;
/*
* Preserve transport protocol header in first frag,
* to bypass filters that block `short' fragments.
*/
switch (pkt->pkt_ip->ip_p) {
case IP_PROTO_ICMP:
fraglen = MAX(ICMP_LEN_MIN, ip_frag_data.size);
break;
case IP_PROTO_UDP:
fraglen = MAX(UDP_HDR_LEN, ip_frag_data.size);
break;
case IP_PROTO_TCP:
fraglen = MAX(pkt->pkt_tcp->th_off << 2,
ip_frag_data.size);
break;
default:
fraglen = ip_frag_data.size;
break;
}
if (fraglen & 7)
fraglen = (fraglen & ~7) + 8;
if (pkt->pkt_end - pkt->pkt_ip_data < fraglen)
continue;
next_hdr = pkt->pkt_ip6->ip6_nxt;
for (p = pkt->pkt_ip_data; p < pkt->pkt_end; ) {
new = pkt_new();
memcpy(new->pkt_eth, pkt->pkt_eth, (u_char*)pkt->pkt_eth_data - (u_char*)pkt->pkt_eth);
memcpy(new->pkt_ip, pkt->pkt_ip, hl);
ext = (struct ip6_ext_hdr *)((u_char*)new->pkt_eth_data + hl);
new->pkt_ip_data = (u_char *)(ext) + 2 +
sizeof(struct ip6_ext_data_fragment);
new->pkt_ip6->ip6_nxt = IP_PROTO_FRAGMENT;
ext->ext_nxt = next_hdr;
ext->ext_len = 0; /* ip6 fragf reserved */
ext->ext_data.fragment.ident = ip_frag_data.ident;
p1 = p, p2 = NULL;
off = (p - pkt->pkt_ip_data) >> 3;
if (ip_frag_data.overlap != 0 && (off & 1) != 0 &&
p + (fraglen << 1) < pkt->pkt_end) {
rand_strset(ip_frag_data.rnd, tmp.pkt_buf,
fraglen);
if (ip_frag_data.overlap == FAVOR_OLD) {
p1 = p + fraglen;
p2 = tmp.pkt_buf;
} else if (ip_frag_data.overlap == FAVOR_NEW) {
p1 = tmp.pkt_buf;
p2 = p + fraglen;
}
ext->ext_data.fragment.offlg =
htons((off /*+ (fraglen >> 3)*/) << 3) | IP6_MORE_FRAG;
} else {
ext->ext_data.fragment.offlg = htons(off << 3) |
((p + fraglen < pkt->pkt_end) ? IP6_MORE_FRAG : 0);
}
new->pkt_ip6->ip6_plen = htons(fraglen + 8);
memcpy(new->pkt_ip_data, p1, fraglen);
new->pkt_end = new->pkt_ip_data + fraglen;
TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
if (p2 != NULL) {
new = pkt_dup(new);
new->pkt_ts.tv_usec = 1;
ext->ext_data.fragment.offlg = htons(off << 3) | IP6_MORE_FRAG;
new->pkt_ip6->ip6_plen = htons((fraglen << 1) + 8);
memcpy(new->pkt_ip_data, p, fraglen);
memcpy(new->pkt_ip_data + fraglen, p2, fraglen);
new->pkt_end = new->pkt_ip_data + (fraglen << 1);
TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
p += (fraglen << 1);
} else {
p += fraglen;
}
if ((fraglen = pkt->pkt_end - p) > ip_frag_data.size)
fraglen = ip_frag_data.size;
}
TAILQ_REMOVE(pktq, pkt, pkt_next);
pkt_free(pkt);
}
return 0;
}
struct mod mod_ip_frag = {
"ip_frag", /* name */
"ip_frag <size> [old|new]", /* usage */
ip_frag_open, /* open */
ip_frag_apply, /* apply */
ip_frag_close /* close */
};

102
src/fragroute/mod_ip_opt.c Normal file
View File

@@ -0,0 +1,102 @@
/*
* mod_ip_opt.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_ip_opt.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pkt.h"
#include "mod.h"
#include "iputil.h"
void *
ip_opt_close(void *d)
{
if (d != NULL)
free(d);
return (NULL);
}
void *
ip_opt_open(int argc, char *argv[])
{
struct ip_opt *opt;
struct addr addr;
int i, j;
if (argc < 4)
return (NULL);
if ((opt = calloc(1, sizeof(*opt))) == NULL)
return (NULL);
if (strcasecmp(argv[1], "lsrr") == 0) {
opt->opt_type = IP_OPT_LSRR;
} else if (strcasecmp(argv[1], "ssrr") == 0) {
opt->opt_type = IP_OPT_SSRR;
} else if (strcasecmp(argv[1], "raw") == 0) {
if (raw_ip_opt_parse(argc - 2, &argv[2], &opt->opt_type, &opt->opt_len,
&opt->opt_data.data8[0], sizeof(opt->opt_data.data8)) != 0)
return (ip_opt_close(opt));
return opt;
} else
return (ip_opt_close(opt));
if ((i = atoi(argv[2])) < 4 || i > 0xff) {
warn("<ptr> must be >= 4, and should be a multiple of 4");
return (ip_opt_close(opt));
}
opt->opt_data.rr.ptr = i;
for (i = 3, j = 0; i < argc && j < 9; i++, j++) {
if (addr_aton(argv[i], &addr) < 0) {
return (ip_opt_close(opt));
}
opt->opt_data.rr.iplist[j] = addr.addr_ip;
}
opt->opt_len = IP_OPT_LEN + 1 + (IP_ADDR_LEN * j);
return (opt);
}
int
ip_opt_apply(void *d, struct pktq *pktq)
{
struct ip_opt *opt = (struct ip_opt *)d;
struct pkt *pkt;
size_t len;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
if (eth_type == ETH_TYPE_IP) {
len = ip_add_option(pkt->pkt_ip, PKT_BUF_LEN - ETH_HDR_LEN,
IP_PROTO_IP, opt, opt->opt_len);
if (len > 0) {
pkt->pkt_end += len;
pkt_decorate(pkt);
ip_checksum(pkt->pkt_ip,
pkt->pkt_end - pkt->pkt_eth_data);
}
}
}
return (0);
}
struct mod mod_ip_opt = {
"ip_opt", /* name */
"ip_opt [lsrr|ssrr <ptr> <ip-addr> ...] | [raw <byte stream>]", /* usage */
ip_opt_open, /* open */
ip_opt_apply, /* apply */
ip_opt_close /* close */
};

View File

@@ -0,0 +1,73 @@
/*
* mod_ip_tos.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_ip_tos.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "argv.h"
#include "mod.h"
#include "pkt.h"
struct ip_tos_data {
int tos;
};
void *
ip_tos_close(void *d)
{
if (d != NULL)
free(d);
return (NULL);
}
void *
ip_tos_open(int argc, char *argv[])
{
struct ip_tos_data *data;
if (argc != 2)
return (NULL);
if ((data = calloc(1, sizeof(*data))) == NULL)
return (NULL);
if (sscanf(argv[1], "%i", &data->tos) != 1 ||
data->tos < 0 || data->tos > 255)
return (ip_tos_close(data));
return (data);
}
int
ip_tos_apply(void *d, struct pktq *pktq)
{
struct ip_tos_data *data = (struct ip_tos_data *)d;
struct pkt *pkt;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
if (eth_type == ETH_TYPE_IP) {
pkt->pkt_ip->ip_tos = data->tos;
/* XXX - do incremental checksum */
ip_checksum(pkt->pkt_ip, pkt->pkt_ip_data - pkt->pkt_eth_data);
}
}
return (0);
}
struct mod mod_ip_tos = {
"ip_tos", /* name */
"ip_tos <tos>", /* usage */
ip_tos_open, /* open */
ip_tos_apply, /* apply */
ip_tos_close /* close */
};

View File

@@ -0,0 +1,79 @@
/*
* mod_ip_ttl.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_ip_ttl.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "argv.h"
#include "mod.h"
#include "pkt.h"
struct ip_ttl_data {
int ttl;
};
void *
ip_ttl_close(void *d)
{
if (d != NULL)
free(d);
return (NULL);
}
void *
ip_ttl_open(int argc, char *argv[])
{
struct ip_ttl_data *data;
if (argc != 2)
return (NULL);
if ((data = calloc(1, sizeof(*data))) == NULL)
return (NULL);
if ((data->ttl = atoi(argv[1])) <= 0 || data->ttl > 255)
return (ip_ttl_close(data));
return (data);
}
int
ip_ttl_apply(void *d, struct pktq *pktq)
{
struct ip_ttl_data *data = (struct ip_ttl_data *)d;
struct pkt *pkt;
int ttldec;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
if (eth_type == ETH_TYPE_IP) {
ttldec = pkt->pkt_ip->ip_ttl - data->ttl;
pkt->pkt_ip->ip_ttl = data->ttl;
if (pkt->pkt_ip->ip_sum >= htons(0xffff - (ttldec << 8)))
pkt->pkt_ip->ip_sum += htons(ttldec << 8) + 1;
else
pkt->pkt_ip->ip_sum += htons(ttldec << 8);
} else if (eth_type == ETH_TYPE_IPV6) {
pkt->pkt_ip6->ip6_hlim = data->ttl;
}
}
return (0);
}
struct mod mod_ip_ttl = {
"ip_ttl", /* name */
"ip_ttl <ttl>", /* usage */
ip_ttl_open, /* open */
ip_ttl_apply, /* apply */
ip_ttl_close /* close */
};

79
src/fragroute/mod_order.c Normal file
View File

@@ -0,0 +1,79 @@
/*
* mod_order.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_order.c 2000 2008-04-27 06:17:35Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mod.h"
#define ORDER_RANDOM 1
#define ORDER_REVERSE 2
struct order_data {
rand_t *rnd;
int type;
};
void *
order_close(void *d)
{
struct order_data *data = (struct order_data *)d;
if (data != NULL) {
rand_close(data->rnd);
free(data);
}
return (NULL);
}
void *
order_open(int argc, char *argv[])
{
struct order_data *data;
if (argc < 2)
return (NULL);
if ((data = malloc(sizeof(*data))) == NULL)
return (NULL);
data->rnd = rand_open();
if (strcasecmp(argv[1], "random") == 0) {
data->type = ORDER_RANDOM;
} else if (strcasecmp(argv[1], "reverse") == 0) {
data->type = ORDER_REVERSE;
} else
return (order_close(data));
return (data);
}
int
order_apply(void *d, struct pktq *pktq)
{
struct order_data *data = (struct order_data *)d;
if (data->type == ORDER_RANDOM)
pktq_shuffle(data->rnd, pktq);
else
pktq_reverse(pktq);
return (0);
}
struct mod mod_order = {
"order", /* name */
"order random|reverse", /* usage */
order_open, /* open */
order_apply, /* apply */
order_close /* close */
};

446
src/fragroute/mod_print.c Normal file
View File

@@ -0,0 +1,446 @@
/*
* mod_print.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_print.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mod.h"
#include "pkt.h"
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
#define EXTRACT_16BITS(p) ((uint16_t)ntohs(*(uint16_t *)(p)))
#define EXTRACT_32BITS(p) ((uint32_t)ntohl(*(uint32_t *)(p)))
/* XXX - _print_* routines adapted from tcpdump */
static void
_print_icmp(u_char *p, int length)
{
struct ip_hdr *ip;
struct icmp_hdr *icmp;
ip = (struct ip_hdr *)p;
icmp = (struct icmp_hdr *)(p + (ip->ip_hl * 4));
/* XXX - truncation? */
printf("%s > %s:", ip_ntoa(&ip->ip_src), ip_ntoa(&ip->ip_dst));
printf(" icmp: type %d code %d", icmp->icmp_type, icmp->icmp_code);
}
static void
_print_icmp6(u_char *p, int length)
{
struct ip6_hdr *ip6;
struct icmp_hdr *icmp;
ip6 = (struct ip6_hdr *)p;
icmp = (struct icmp_hdr *)(p + IP6_HDR_LEN);
/* XXX - truncation? */
printf("%s > %s:", ip6_ntoa(&ip6->ip6_src), ip6_ntoa(&ip6->ip6_dst));
printf(" icmp: type %hhu code %hhu", icmp->icmp_type, icmp->icmp_code);
}
void
_print_tcp(int family, unsigned char *p, int length)
{
struct tcp_hdr *tcp;
u_short sport, dport, win, urp;
u_long seq, ack;
int len, tcp_hl;
register char ch;
char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
if (family == AF_INET6) {
struct ip6_hdr *ip6 = (struct ip6_hdr *)p;
tcp = (struct tcp_hdr *)(p + IP6_HDR_LEN);
len = length;
ip6_ntop(&ip6->ip6_src, src, sizeof(src));
ip6_ntop(&ip6->ip6_dst, dst, sizeof(dst));
} else {
struct ip_hdr *ip;
ip = (struct ip_hdr *)p;
tcp = (struct tcp_hdr *)(p + (ip->ip_hl * 4));
len = length - (ip->ip_hl * 4);
ip_ntop(&ip->ip_src, src, sizeof(src));
ip_ntop(&ip->ip_dst, dst, sizeof(dst));
}
if (len < TCP_HDR_LEN) {
printf("truncated-tcp %d", len);
return;
}
sport = ntohs(tcp->th_sport);
dport = ntohs(tcp->th_dport);
seq = ntohl(tcp->th_seq);
ack = ntohl(tcp->th_ack);
win = ntohs(tcp->th_win);
urp = ntohs(tcp->th_urp);
tcp_hl = tcp->th_off * 4;
printf("%s.%d > %s.%d: ", src, sport, dst, dport);
if (tcp->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_PUSH)) {
if (tcp->th_flags & TH_SYN) putchar('S');
if (tcp->th_flags & TH_FIN) putchar('F');
if (tcp->th_flags & TH_RST) putchar('R');
if (tcp->th_flags & TH_PUSH) putchar('P');
} else
putchar('.');
if (tcp_hl > len) {
printf(" [bad hdr length]");
return;
}
len -= tcp_hl;
if (len > 0 || tcp->th_flags & (TH_SYN | TH_FIN | TH_RST))
printf(" %lu:%lu(%d)", seq, seq + len, len);
if (tcp->th_flags & TH_ACK)
printf(" ack %lu", ack);
printf(" win %d", win);
if (tcp->th_flags & TH_URG)
printf(" urg %d", urp);
/* Handle options. */
if ((tcp_hl -= TCP_HDR_LEN) > 0) {
register const u_char *cp;
register int i, opt, len, datalen;
cp = (const u_char *)tcp + TCP_HDR_LEN;
putchar(' ');
ch = '<';
while (tcp_hl > 0) {
putchar(ch);
opt = *cp++;
if (TCP_OPT_TYPEONLY(opt)) {
len = 1;
} else {
len = *cp++; /* total including type, len */
if (len < 2 || len > tcp_hl)
goto bad;
--tcp_hl; /* account for length byte */
}
--tcp_hl; /* account for type byte */
datalen = 0;
/* Bail if "l" bytes of data are not left or were not captured */
#define LENCHECK(l) { if ((l) > tcp_hl) goto bad; }
switch (opt) {
case TCP_OPT_MSS:
printf("mss");
datalen = 2;
LENCHECK(datalen);
printf(" %u", EXTRACT_16BITS(cp));
break;
case TCP_OPT_EOL:
printf("eol");
break;
case TCP_OPT_NOP:
printf("nop");
break;
case TCP_OPT_WSCALE:
printf("wscale");
datalen = 1;
LENCHECK(datalen);
printf(" %u", *cp);
break;
case TCP_OPT_SACKOK:
printf("sackOK");
if (len != 2)
printf("[len %d]", len);
break;
case TCP_OPT_SACK:
datalen = len - 2;
if ((datalen % 8) != 0 ||
!(tcp->th_flags & TH_ACK)) {
printf("malformed sack ");
printf("[len %d] ", datalen);
break;
}
printf("sack %d ", datalen / 8);
break;
case TCP_OPT_ECHO:
printf("echo");
datalen = 4;
LENCHECK(datalen);
printf(" %u", EXTRACT_32BITS(cp));
break;
case TCP_OPT_ECHOREPLY:
printf("echoreply");
datalen = 4;
LENCHECK(datalen);
printf(" %u", EXTRACT_32BITS(cp));
break;
case TCP_OPT_TIMESTAMP:
printf("timestamp");
datalen = 8;
LENCHECK(4);
printf(" %u", EXTRACT_32BITS(cp));
LENCHECK(datalen);
printf(" %u", EXTRACT_32BITS(cp + 4));
break;
case TCP_OPT_CC:
printf("cc");
datalen = 4;
LENCHECK(datalen);
printf(" %u", EXTRACT_32BITS(cp));
break;
case TCP_OPT_CCNEW:
printf("ccnew");
datalen = 4;
LENCHECK(datalen);
printf(" %u", EXTRACT_32BITS(cp));
break;
case TCP_OPT_CCECHO:
printf("ccecho");
datalen = 4;
LENCHECK(datalen);
printf(" %u", EXTRACT_32BITS(cp));
break;
default:
printf("opt-%d:", opt);
datalen = len - 2;
for (i = 0; i < datalen; ++i) {
LENCHECK(i);
printf("%02x", cp[i]);
}
break;
}
/* Account for data printed */
cp += datalen;
tcp_hl -= datalen;
/* Check specification against observed length */
++datalen; /* option octet */
if (!TCP_OPT_TYPEONLY(opt))
++datalen; /* size octet */
if (datalen != len)
printf("[len %d]", len);
ch = ',';
if (opt == TCP_OPT_EOL)
break;
}
putchar('>');
}
return;
bad:
fputs("[bad opt]", stdout);
if (ch != '\0')
putchar('>');
return;
}
static void
_print_udp(int family, u_char *p, int length)
{
struct udp_hdr *udp;
char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
if (family == AF_INET6) {
struct ip6_hdr *ip6 = (struct ip6_hdr *)p;
udp = (struct udp_hdr *)(p + IP6_HDR_LEN);
ip6_ntop(&ip6->ip6_src, src, sizeof(src));
ip6_ntop(&ip6->ip6_dst, dst, sizeof(dst));
} else {
struct ip_hdr *ip;
ip = (struct ip_hdr *)p;
udp = (struct udp_hdr *)(p + (ip->ip_hl * 4));
ip_ntop(&ip->ip_src, src, sizeof(src));
ip_ntop(&ip->ip_dst, dst, sizeof(dst));
}
/* XXX - truncation? */
printf("%s.%d > %s.%d:", src, ntohs(udp->uh_sport),
dst, ntohs(udp->uh_dport));
printf(" udp %d", ntohs(udp->uh_ulen) - UDP_HDR_LEN);
}
static void
_print_frag6(u_char *p, int length)
{
struct ip6_hdr *ip6;
struct ip6_ext_hdr *ext;
int off;
ip6 = (struct ip6_hdr *)p;
ext = (struct ip6_ext_hdr *)(p + IP6_HDR_LEN);
off = htons(ext->ext_data.fragment.offlg & IP6_OFF_MASK);
printf("%s > %s:", ip6_ntoa(&ip6->ip6_src), ip6_ntoa(&ip6->ip6_dst));
printf(" fragment: next %hhu offset %d%s ident 0x%08x",
ext->ext_nxt, off,
(ext->ext_data.fragment.offlg & IP6_MORE_FRAG) ? " MF" : "",
htonl(ext->ext_data.fragment.ident));
}
static void
_print_ip(u_char *p, int length)
{
struct ip_hdr *ip;
u_int ip_off, ip_hl, ip_len;
ip = (struct ip_hdr *)p;
if (length < IP_HDR_LEN) {
printf("truncated-ip %d", length);
return;
}
ip_hl = ip->ip_hl * 4;
ip_len = ntohs(ip->ip_len);
if (length < ip_len) {
printf("truncated-ip - %d bytes missing!", ip_len - length);
return;
}
ip_off = ntohs(ip->ip_off);
/* Handle first fragment. */
if ((ip_off & IP_OFFMASK) == 0) {
switch (ip->ip_p) {
case IP_PROTO_TCP:
_print_tcp(AF_INET, p, ip_len);
break;
case IP_PROTO_UDP:
_print_udp(AF_INET, p, ip_len);
break;
case IP_PROTO_ICMP:
_print_icmp(p, ip_len);
break;
default:
printf("%s > %s:", ip_ntoa(&ip->ip_src),
ip_ntoa(&ip->ip_dst));
printf(" ip-proto-%d %d", ip->ip_p, ip_len);
break;
}
}
/* Handle more frags. */
if (ip_off & (IP_MF|IP_OFFMASK)) {
if (ip_off & IP_OFFMASK)
printf("%s > %s:", ip_ntoa(&ip->ip_src),
ip_ntoa(&ip->ip_dst));
printf(" (frag %d:%d@%d%s)", ntohs(ip->ip_id), ip_len - ip_hl,
(ip_off & IP_OFFMASK) << 3, (ip_off & IP_MF) ? "+" : "");
} else if (ip_off & IP_DF)
printf(" (DF)");
if (ip->ip_tos)
printf(" [tos 0x%x]", ip->ip_tos);
if (ip->ip_ttl <= 1)
printf(" [ttl %d]", ip->ip_ttl);
}
static void
_print_ip6(u_char *p, int length)
{
struct ip6_hdr *ip6;
int plen;
ip6 = (struct ip6_hdr *)p;
if (length < IP6_HDR_LEN) {
printf("truncated-ip6 %d", length);
return;
}
plen = htons(ip6->ip6_plen);
switch (ip6->ip6_nxt) {
case IP_PROTO_TCP:
_print_tcp(AF_INET6, p, plen);
break;
case IP_PROTO_UDP:
_print_udp(AF_INET6, p, plen);
break;
case IP_PROTO_ICMPV6:
_print_icmp6(p, plen);
break;
case IP_PROTO_FRAGMENT:
_print_frag6(p, plen);
break;
default:
printf("%s > %s:", ip6_ntoa(&ip6->ip6_src),
ip6_ntoa(&ip6->ip6_dst));
printf(" ip-proto-%hhu ttl %hhu payload len %hu", ip6->ip6_nxt,
ip6->ip6_hlim, plen);
break;
}
if (ip6->ip6_hlim <= 1)
printf(" [ttl %d]", ip6->ip6_hlim);
}
static void
_print_eth(struct eth_hdr* e, int length)
{
char d[20], s[20];
eth_ntop(&e->eth_dst, &d[0], sizeof(d));
eth_ntop(&e->eth_src, &s[0], sizeof(s));
printf("%s > %s type 0x%04hx length %d", d, s, htons(e->eth_type), length);
}
static char *
timerntoa(struct timeval *tv)
{
static char buf[128];
uint64_t usec;
usec = (tv->tv_sec * 1000000) + tv->tv_usec;
snprintf(buf, sizeof(buf), "%d.%03d ms",
(int)(usec / 1000), (int)(usec % 1000));
return (buf);
}
int
print_apply(void *d, struct pktq *pktq)
{
struct pkt *pkt;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
if (eth_type == ETH_TYPE_IP)
_print_ip(pkt->pkt_eth_data, pkt->pkt_end - pkt->pkt_eth_data);
else if (eth_type == ETH_TYPE_IPV6)
_print_ip6(pkt->pkt_eth_data, pkt->pkt_end - pkt->pkt_eth_data);
else
_print_eth(pkt->pkt_eth, pkt->pkt_end - pkt->pkt_data);
if (timerisset(&pkt->pkt_ts))
printf(" [delay %s]", timerntoa(&pkt->pkt_ts));
printf("\n");
}
return (0);
}
struct mod mod_print = {
"print", /* name */
"print", /* usage */
NULL, /* init */
print_apply, /* apply */
NULL /* close */
};

View File

@@ -0,0 +1,197 @@
/*
* mod_tcp_chaff.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_tcp_chaff.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pkt.h"
#include "mod.h"
#include "randutil.h"
#include "iputil.h"
#define CHAFF_TYPE_CKSUM 1
#define CHAFF_TYPE_NULL 2
#define CHAFF_TYPE_PAWS 3
#define CHAFF_TYPE_REXMIT 4
#define CHAFF_TYPE_SEQ 5
#define CHAFF_TYPE_SYN 6
#define CHAFF_TYPE_TTL 7
struct tcp_chaff_data {
rand_t *rnd;
int type;
int ttl;
};
void *
tcp_chaff_close(void *d)
{
struct tcp_chaff_data *data = (struct tcp_chaff_data *)d;
if (data != NULL) {
rand_close(data->rnd);
free(data);
}
return (NULL);
}
void *
tcp_chaff_open(int argc, char *argv[])
{
struct tcp_chaff_data *data;
if (argc < 2)
return (NULL);
if ((data = calloc(1, sizeof(*data))) == NULL)
return (NULL);
data->rnd = rand_open();
if (strcasecmp(argv[1], "cksum") == 0)
data->type = CHAFF_TYPE_CKSUM;
else if (strcasecmp(argv[1], "null") == 0)
data->type = CHAFF_TYPE_NULL;
else if (strcasecmp(argv[1], "paws") == 0)
data->type = CHAFF_TYPE_PAWS;
else if (strcasecmp(argv[1], "rexmit") == 0)
data->type = CHAFF_TYPE_REXMIT;
else if (strcasecmp(argv[1], "seq") == 0)
data->type = CHAFF_TYPE_SEQ;
else if (strcasecmp(argv[1], "syn") == 0)
data->type = CHAFF_TYPE_SYN;
else if ((data->ttl = atoi(argv[1])) > 0 && data->ttl < 256)
data->type = CHAFF_TYPE_TTL;
else
return (tcp_chaff_close(data));
return (data);
}
int
tcp_chaff_apply(void *d, struct pktq *pktq)
{
struct tcp_chaff_data *data = (struct tcp_chaff_data *)d;
struct pkt *pkt, *new, *next;
struct tcp_opt opt;
int i;
uint16_t eth_type;
uint8_t nxt;
for (pkt = TAILQ_FIRST(pktq); pkt != TAILQ_END(pktq); pkt = next) {
next = TAILQ_NEXT(pkt, pkt_next);
eth_type = htons(pkt->pkt_eth->eth_type);
if (pkt->pkt_ip == NULL)
continue;
if (eth_type == ETH_TYPE_IP) {
nxt = pkt->pkt_ip->ip_p;
} else if (eth_type == ETH_TYPE_IPV6) {
nxt = pkt->pkt_ip6->ip6_nxt;
} else {
continue;
}
if (nxt != IP_PROTO_TCP ||
pkt->pkt_tcp == NULL || pkt->pkt_tcp_data == NULL ||
(pkt->pkt_tcp->th_flags & TH_ACK) == 0)
continue;
new = pkt_dup(pkt);
rand_strset(data->rnd, new->pkt_tcp_data, new->pkt_end -
new->pkt_tcp_data + 1);
switch (data->type) {
case CHAFF_TYPE_CKSUM:
inet_checksum(eth_type, new->pkt_ip,
new->pkt_ip_data - new->pkt_eth_data);
new->pkt_tcp->th_sum = rand_uint16(data->rnd);
break;
case CHAFF_TYPE_NULL:
new->pkt_tcp->th_flags = 0;
inet_checksum(eth_type, new->pkt_ip,
new->pkt_ip_data - new->pkt_eth_data);
break;
case CHAFF_TYPE_PAWS:
/* Delete any existing TCP options. */
i = (new->pkt_tcp->th_off << 2) - TCP_HDR_LEN;
new->pkt_tcp->th_off = 5;
new->pkt_end -= i;
new->pkt_ip->ip_len = htons(new->pkt_end -
new->pkt_eth_data);
/* Insert initial timestamp, for PAWS elimination. */
opt.opt_type = TCP_OPT_TIMESTAMP;
opt.opt_len = TCP_OPT_LEN + 8;
opt.opt_data.timestamp[0] = 0;
opt.opt_data.timestamp[1] = 0;
if ((i = inet_add_option(eth_type, new->pkt_ip,
PKT_BUF_LEN - ETH_HDR_LEN,
IP_PROTO_TCP, &opt, opt.opt_len)) < 0) {
pkt_free(new);
continue;
}
new->pkt_end += i;
inet_checksum(eth_type, new->pkt_ip,
new->pkt_ip_data - new->pkt_eth_data);
pkt_decorate(new);
break;
case CHAFF_TYPE_REXMIT:
new->pkt_ts.tv_usec = 1;
inet_checksum(eth_type, new->pkt_ip,
new->pkt_ip_data - new->pkt_eth_data);
break;
case CHAFF_TYPE_SEQ:
/* XXX - dunno recv window? */
new->pkt_tcp->th_seq = htonl(666);
new->pkt_tcp->th_ack = htonl(666);
inet_checksum(eth_type, new->pkt_ip,
new->pkt_ip_data - new->pkt_eth_data);
break;
case CHAFF_TYPE_SYN:
new->pkt_tcp->th_flags = TH_SYN;
new->pkt_tcp->th_seq = rand_uint32(data->rnd);
new->pkt_tcp->th_ack = 0;
new->pkt_end = new->pkt_tcp_data;
new->pkt_tcp_data = NULL;
new->pkt_ip->ip_len = htons(new->pkt_end -
new->pkt_eth_data);
inet_checksum(eth_type, new->pkt_ip,
new->pkt_ip_data - new->pkt_eth_data);
break;
case CHAFF_TYPE_TTL:
if (eth_type == ETH_TYPE_IP) {
new->pkt_ip->ip_ttl = data->ttl;
ip_checksum(new->pkt_ip,
new->pkt_ip_data - new->pkt_eth_data);
} else if (eth_type == ETH_TYPE_IPV6) {
new->pkt_ip6->ip6_hlim = data->ttl;
}
break;
}
/* Minimal random reordering. */
if ((new->pkt_tcp->th_sum & 1) == 0)
TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
else
TAILQ_INSERT_AFTER(pktq, pkt, new, pkt_next);
}
return (0);
}
struct mod mod_tcp_chaff = {
"tcp_chaff", /* name */
"tcp_chaff cksum|null|paws|rexmit|seq|syn|<ttl>", /* usage */
tcp_chaff_open, /* open */
tcp_chaff_apply, /* apply */
tcp_chaff_close /* close */
};

View File

@@ -0,0 +1,98 @@
/*
* mod_tcp_opt.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_tcp_opt.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pkt.h"
#include "mod.h"
#include "iputil.h"
void *
tcp_opt_close(void *d)
{
if (d != NULL)
free(d);
return (NULL);
}
void *
tcp_opt_open(int argc, char *argv[])
{
struct tcp_opt *opt;
int i;
if (argc < 3)
return (NULL);
if ((opt = calloc(1, sizeof(*opt))) == NULL)
return (NULL);
if (strcasecmp(argv[1], "mss") == 0) {
opt->opt_type = TCP_OPT_MSS;
opt->opt_len = TCP_OPT_LEN + 2;
if ((i = atoi(argv[2])) <= 0 || i > 0xffff) {
warn("mss <size> must be from 0-65535");
return (tcp_opt_close(opt));
}
opt->opt_data.mss = htons(i);
} else if (strcasecmp(argv[1], "wscale") == 0) {
opt->opt_type = TCP_OPT_WSCALE;
opt->opt_len = TCP_OPT_LEN + 2;
if ((i = atoi(argv[2])) <= 0 || i > 0xff) {
warn("wscale <size> must be from 0-255");
return (tcp_opt_close(opt));
}
opt->opt_data.wscale = i;
} else if (strcasecmp(argv[1], "raw") == 0) {
if (raw_ip_opt_parse(argc - 2, &argv[2], &opt->opt_type, &opt->opt_len,
&opt->opt_data.data8[0], sizeof(opt->opt_data.data8)) != 0)
return (tcp_opt_close(opt));
} else
return (tcp_opt_close(opt));
return (opt);
}
int
tcp_opt_apply(void *d, struct pktq *pktq)
{
struct tcp_opt *opt = (struct tcp_opt *)d;
struct pkt *pkt;
size_t len;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
uint16_t eth_type = htons(pkt->pkt_eth->eth_type);
len = inet_add_option(eth_type, pkt->pkt_ip,
sizeof(pkt->pkt_data) - ETH_HDR_LEN,
IP_PROTO_TCP, opt, opt->opt_len);
if (len > 0) {
pkt->pkt_end += len;
pkt_decorate(pkt);
inet_checksum(eth_type, pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data);
}
}
return (0);
}
struct mod mod_tcp_opt = {
"tcp_opt", /* name */
"tcp_opt mss|wscale <size>|raw <byte stream>", /* usage */
tcp_opt_open, /* open */
tcp_opt_apply, /* apply */
tcp_opt_close /* close */
};

182
src/fragroute/mod_tcp_seg.c Normal file
View File

@@ -0,0 +1,182 @@
/*
* mod_tcp_seg.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: mod_tcp_seg.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mod.h"
#include "pkt.h"
#include "randutil.h"
#include "iputil.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#define FAVOR_OLD 1
#define FAVOR_NEW 2
static struct tcp_seg_data {
rand_t *rnd;
int size;
int overlap;
} tcp_seg_data;
void *
tcp_seg_close(void *d)
{
if (tcp_seg_data.rnd != NULL)
rand_close(tcp_seg_data.rnd);
tcp_seg_data.size = 0;
return (NULL);
}
void *
tcp_seg_open(int argc, char *argv[])
{
if (argc < 2) {
warn("need segment <size> in bytes");
return (NULL);
}
tcp_seg_data.rnd = rand_open();
if ((tcp_seg_data.size = atoi(argv[1])) == 0) {
warnx("invalid segment size '%s'", argv[1]);
return (tcp_seg_close(&tcp_seg_data));
}
if (argc == 3) {
if (strcmp(argv[2], "old") == 0 ||
strcmp(argv[2], "win32") == 0)
tcp_seg_data.overlap = FAVOR_OLD;
else if (strcmp(argv[2], "new") == 0 ||
strcmp(argv[2], "unix") == 0)
tcp_seg_data.overlap = FAVOR_NEW;
else
return (tcp_seg_close(&tcp_seg_data));
}
return (&tcp_seg_data);
}
int
tcp_seg_apply(void *d, struct pktq *pktq)
{
struct pkt *pkt, *new, *next, tmp;
uint32_t seq;
int hl, tl, len;
u_char *p, *p1, *p2;
uint16_t eth_type;
uint8_t nxt;
for (pkt = TAILQ_FIRST(pktq); pkt != TAILQ_END(pktq); pkt = next) {
next = TAILQ_NEXT(pkt, pkt_next);
eth_type = htons(pkt->pkt_eth->eth_type);
if (pkt->pkt_ip == NULL)
continue;
if (eth_type == ETH_TYPE_IP) {
nxt = pkt->pkt_ip->ip_p;
} else if (eth_type == ETH_TYPE_IPV6) {
nxt = pkt->pkt_ip6->ip6_nxt;
} else {
continue;
}
if (nxt != IP_PROTO_TCP ||
pkt->pkt_tcp == NULL || pkt->pkt_tcp_data == NULL ||
(pkt->pkt_tcp->th_flags & TH_ACK) == 0 ||
pkt->pkt_end - pkt->pkt_tcp_data <= tcp_seg_data.size)
continue;
if (eth_type == ETH_TYPE_IP) {
hl = pkt->pkt_ip->ip_hl << 2;
} else if (eth_type == ETH_TYPE_IPV6) {
hl = IP6_HDR_LEN;
} else {
continue;
}
tl = pkt->pkt_tcp->th_off << 2;
seq = ntohl(pkt->pkt_tcp->th_seq);
for (p = pkt->pkt_tcp_data; p < pkt->pkt_end; p += len) {
new = pkt_new();
memcpy(new->pkt_eth, pkt->pkt_eth, (u_char*)pkt->pkt_eth_data - (u_char*)pkt->pkt_eth);
p1 = p, p2 = NULL;
len = MIN(pkt->pkt_end - p, tcp_seg_data.size);
if (tcp_seg_data.overlap != 0 &&
p + (len << 1) < pkt->pkt_end) {
rand_strset(tcp_seg_data.rnd, tmp.pkt_buf,len);
if (tcp_seg_data.overlap == FAVOR_OLD) {
p1 = p + len;
p2 = tmp.pkt_buf;
} else if (tcp_seg_data.overlap == FAVOR_NEW) {
p1 = tmp.pkt_buf;
p2 = p + len;
}
len = tcp_seg_data.size;
seq += tcp_seg_data.size;
}
memcpy(new->pkt_ip, pkt->pkt_ip, hl + tl);
new->pkt_ip_data = new->pkt_eth_data + hl;
new->pkt_tcp_data = new->pkt_ip_data + tl;
memcpy(new->pkt_tcp_data, p1, len);
new->pkt_end = new->pkt_tcp_data + len;
if (eth_type == ETH_TYPE_IP) {
new->pkt_ip->ip_id = rand_uint16(tcp_seg_data.rnd);
new->pkt_ip->ip_len = htons(hl + tl + len);
} else {
new->pkt_ip6->ip6_plen = htons(tl + len);
}
new->pkt_tcp->th_seq = htonl(seq);
inet_checksum(eth_type, new->pkt_ip, hl + tl + len);
TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
if (p2 != NULL) {
new = pkt_dup(new);
new->pkt_ts.tv_usec = 1;
if (eth_type == ETH_TYPE_IP) {
new->pkt_ip->ip_id = rand_uint16(tcp_seg_data.rnd);
new->pkt_ip->ip_len = htons(hl + tl + (len << 1));
} else if (eth_type == ETH_TYPE_IPV6) {
new->pkt_ip6->ip6_plen = htons(tl + (len << 1));
}
new->pkt_tcp->th_seq = htonl(seq - len);
memcpy(new->pkt_tcp_data, p, len);
memcpy(new->pkt_tcp_data + len, p2, len);
new->pkt_end = new->pkt_tcp_data + (len << 1);
inet_checksum(eth_type, new->pkt_ip, hl + tl + (len << 1));
TAILQ_INSERT_BEFORE(pkt, new, pkt_next);
p += len;
}
seq += len;
}
TAILQ_REMOVE(pktq, pkt, pkt_next);
pkt_free(pkt);
}
return (0);
}
struct mod mod_tcp_seg = {
"tcp_seg", /* name */
"tcp_seg <size> [old|new]", /* usage */
tcp_seg_open, /* open */
tcp_seg_apply, /* apply */
tcp_seg_close /* close */
};

312
src/fragroute/pkt.c Normal file
View File

@@ -0,0 +1,312 @@
/*
* pkt.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: pkt.c 2303 2009-05-06 18:48:20Z aturner $
*/
#include "config.h"
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bget.h"
#include "pkt.h"
void
pkt_init(int size)
{
bectl(NULL, malloc, free, sizeof(struct pkt) * size);
}
struct pkt *
pkt_new(void)
{
struct pkt *pkt;
if ((pkt = bget(sizeof(*pkt))) == NULL)
return (NULL);
timerclear(&pkt->pkt_ts);
// memset(&pkt->pkt_ev, 0, sizeof(pkt->pkt_ev));
pkt->pkt_data = pkt->pkt_buf + PKT_BUF_ALIGN;
pkt->pkt_eth = (struct eth_hdr *)pkt->pkt_data;
pkt->pkt_eth_data = pkt->pkt_data + ETH_HDR_LEN;
pkt->pkt_ip_data = pkt->pkt_data + ETH_HDR_LEN + IP_HDR_LEN;
pkt->pkt_tcp_data = NULL;
pkt->pkt_end = pkt->pkt_ip_data;
return (pkt);
}
struct pkt *
pkt_dup(struct pkt *pkt)
{
struct pkt *new;
off_t off;
if ((new = bget(sizeof(*new))) == NULL)
return (NULL);
off = new->pkt_buf - pkt->pkt_buf;
new->pkt_ts = pkt->pkt_ts;
// memset(&new->pkt_ev, 0, sizeof(new->pkt_ev));
new->pkt_data = pkt->pkt_data + off;
new->pkt_eth = (pkt->pkt_eth != NULL) ?
(struct eth_hdr *)new->pkt_data : NULL;
new->pkt_eth_data = (pkt->pkt_eth_data != NULL) ?
pkt->pkt_eth_data + off : NULL;
new->pkt_ip_data = (pkt->pkt_ip_data != NULL) ?
pkt->pkt_ip_data + off : NULL;
new->pkt_tcp_data = (pkt->pkt_tcp_data != NULL) ?
pkt->pkt_tcp_data + off : NULL;
memcpy(new->pkt_data, pkt->pkt_data, pkt->pkt_end - pkt->pkt_data);
new->pkt_end = pkt->pkt_end + off;
return (new);
}
#define IP6_IS_EXT(n) \
((n) == IP_PROTO_HOPOPTS || (n) == IP_PROTO_DSTOPTS || \
(n) == IP_PROTO_ROUTING || (n) == IP_PROTO_FRAGMENT)
void
pkt_decorate(struct pkt *pkt)
{
u_char *p;
uint16_t eth_type;
int hl, len, off;
uint8_t next_hdr;
struct ip6_ext_hdr *ext;
pkt->pkt_data = pkt->pkt_buf + PKT_BUF_ALIGN;
pkt->pkt_eth = NULL;
pkt->pkt_ip = NULL;
pkt->pkt_ip_data = NULL;
pkt->pkt_tcp_data = NULL;
p = pkt->pkt_data;
if (p + ETH_HDR_LEN > pkt->pkt_end)
return;
pkt->pkt_eth = (struct eth_hdr *)p;
p += ETH_HDR_LEN;
eth_type = htons(pkt->pkt_eth->eth_type);
if (eth_type == ETH_TYPE_IP) {
if (p + IP_HDR_LEN > pkt->pkt_end)
return;
pkt->pkt_eth_data = p;
/* If IP header length is longer than packet length, stop. */
hl = pkt->pkt_ip->ip_hl << 2;
if (p + hl > pkt->pkt_end) {
pkt->pkt_ip = NULL;
return;
}
/* If IP length is longer than packet length, stop. */
len = ntohs(pkt->pkt_ip->ip_len);
if (p + len > pkt->pkt_end)
return;
/* If IP fragment, stop. */
off = ntohs(pkt->pkt_ip->ip_off);
if ((off & IP_OFFMASK) != 0 || (off & IP_MF) != 0)
return;
pkt->pkt_end = p + len;
p += hl;
next_hdr = pkt->pkt_ip->ip_p;
} else if (eth_type == ETH_TYPE_IPV6) {
if (p + IP6_HDR_LEN > pkt->pkt_end)
return;
pkt->pkt_eth_data = p;
p += IP6_HDR_LEN;
next_hdr = pkt->pkt_ip6->ip6_nxt;
for (; IP6_IS_EXT(next_hdr); p += (ext->ext_len + 1) << 3) {
if (p > pkt->pkt_end)
return;
ext = (struct ip6_ext_hdr *)p;
next_hdr = ext->ext_nxt;
}
} else {
return;
}
/* If transport layer header is longer than packet length, stop. */
switch (next_hdr) {
case IP_PROTO_ICMP:
case IP_PROTO_ICMPV6:
hl = ICMP_HDR_LEN;
break;
case IP_PROTO_TCP:
if (p + TCP_HDR_LEN > pkt->pkt_end)
return;
hl = ((struct tcp_hdr *)p)->th_off << 2;
break;
case IP_PROTO_UDP:
hl = UDP_HDR_LEN;
break;
default:
return;
}
if (p + hl > pkt->pkt_end)
return;
pkt->pkt_ip_data = p;
p += hl;
/* Check for transport layer data. */
switch (next_hdr) {
case IP_PROTO_ICMP:
pkt->pkt_icmp_msg = (union icmp_msg *)p;
switch (pkt->pkt_icmp->icmp_type) {
case ICMP_ECHO:
case ICMP_ECHOREPLY:
hl = sizeof(pkt->pkt_icmp_msg->echo);
break;
case ICMP_UNREACH:
if (pkt->pkt_icmp->icmp_code == ICMP_UNREACH_NEEDFRAG)
hl = sizeof(pkt->pkt_icmp_msg->needfrag);
else
hl = sizeof(pkt->pkt_icmp_msg->unreach);
break;
case ICMP_SRCQUENCH:
case ICMP_REDIRECT:
case ICMP_TIMEXCEED:
case ICMP_PARAMPROB:
hl = sizeof(pkt->pkt_icmp_msg->srcquench);
break;
case ICMP_RTRADVERT:
hl = sizeof(pkt->pkt_icmp_msg->rtradvert);
break;
case ICMP_RTRSOLICIT:
hl = sizeof(pkt->pkt_icmp_msg->rtrsolicit);
break;
case ICMP_TSTAMP:
case ICMP_TSTAMPREPLY:
hl = sizeof(pkt->pkt_icmp_msg->tstamp);
break;
case ICMP_INFO:
case ICMP_INFOREPLY:
case ICMP_DNS:
hl = sizeof(pkt->pkt_icmp_msg->info);
break;
case ICMP_MASK:
case ICMP_MASKREPLY:
hl = sizeof(pkt->pkt_icmp_msg->mask);
break;
case ICMP_DNSREPLY:
hl = sizeof(pkt->pkt_icmp_msg->dnsreply);
break;
default:
hl = pkt->pkt_end - p + 1;
break;
}
if (p + hl > pkt->pkt_end)
pkt->pkt_icmp_msg = NULL;
break;
case IP_PROTO_ICMPV6:
pkt->pkt_icmp_msg = (union icmp_msg *)p;
break;
case IP_PROTO_TCP:
if (p < pkt->pkt_end)
pkt->pkt_tcp_data = p;
break;
case IP_PROTO_UDP:
if (pkt->pkt_ip_data + ntohs(pkt->pkt_udp->uh_ulen) <=
pkt->pkt_end)
pkt->pkt_udp_data = p;
break;
}
}
void
pkt_free(struct pkt *pkt)
{
brel(pkt);
}
void
pktq_reverse(struct pktq *pktq)
{
struct pktq tmpq;
struct pkt *pkt, *next;
TAILQ_INIT(&tmpq);
for (pkt = TAILQ_FIRST(pktq); pkt != TAILQ_END(pktq); pkt = next) {
next = TAILQ_NEXT(pkt, pkt_next);
TAILQ_INSERT_HEAD(&tmpq, pkt, pkt_next);
}
*pktq = tmpq;
}
void
pktq_shuffle(rand_t *r, struct pktq *pktq)
{
static struct pkt **pvbase;
static int pvlen;
struct pkt *pkt;
int i;
i = 0;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
i++;
}
if (i > pvlen) {
pvlen = i;
if (pvbase == NULL)
pvbase = malloc(sizeof(pkt) * pvlen);
else
pvbase = realloc(pvbase, sizeof(pkt) * pvlen);
}
i = 0;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
pvbase[i++] = pkt;
}
TAILQ_INIT(pktq);
rand_shuffle(r, pvbase, i, sizeof(pkt));
while (--i >= 0) {
TAILQ_INSERT_TAIL(pktq, pvbase[i], pkt_next);
}
}
struct pkt *
pktq_random(rand_t *r, struct pktq *pktq)
{
struct pkt *pkt;
int i;
i = 0;
TAILQ_FOREACH(pkt, pktq, pkt_next) {
i++;
}
i = rand_uint32(r) % (i - 1);
pkt = TAILQ_FIRST(pktq);
while (--i >= 0) {
pkt = TAILQ_NEXT(pkt, pkt_next);
}
return (pkt);
}

82
src/fragroute/pkt.h Normal file
View File

@@ -0,0 +1,82 @@
/*
* pkt.h
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: pkt.h 2303 2009-05-06 18:48:20Z aturner $
*/
#ifndef PKT_H
#define PKT_H
#include "config.h"
#include "defines.h"
#include "../../lib/queue.h"
#include <sys/time.h>
#ifdef HAVE_LIBDNET
/* need to undef these which are pulled in via defines.h, prior to importing dnet.h */
#undef icmp_id
#undef icmp_seq
#undef icmp_data
#undef icmp_mask
#include <dnet.h>
#endif
#define PKT_BUF_LEN (ETH_HDR_LEN + ETH_MTU)
#define PKT_BUF_ALIGN 2
struct pkt {
struct timeval pkt_ts;
// struct event pkt_ev;
struct eth_hdr *pkt_eth;
union {
u_char *eth_data;
struct ip_hdr *ip;
struct ip6_hdr *ip6;
} pkt_n_hdr_u;
union {
u_char *ip_data;
struct icmp_hdr *icmp;
struct tcp_hdr *tcp;
struct udp_hdr *udp;
} pkt_t_hdr_u;
union {
u_char *t_data;
union icmp_msg *icmp;
} pkt_t_data_u;
u_char pkt_buf[PKT_BUF_ALIGN + PKT_BUF_LEN];
u_char *pkt_data;
u_char *pkt_end;
TAILQ_ENTRY(pkt) pkt_next;
};
#define pkt_ip pkt_n_hdr_u.ip
#define pkt_ip6 pkt_n_hdr_u.ip6
#define pkt_eth_data pkt_n_hdr_u.eth_data
#define pkt_icmp pkt_t_hdr_u.icmp
#define pkt_tcp pkt_t_hdr_u.tcp
#define pkt_udp pkt_t_hdr_u.udp
#define pkt_ip_data pkt_t_hdr_u.ip_data
#define pkt_tcp_data pkt_t_data_u.t_data
#define pkt_udp_data pkt_t_data_u.t_data
#define pkt_icmp_msg pkt_t_data_u.icmp
TAILQ_HEAD(pktq, pkt);
void pkt_init(int size);
struct pkt *pkt_new(void);
struct pkt *pkt_dup(struct pkt *);
void pkt_decorate(struct pkt *pkt);
void pkt_free(struct pkt *pkt);
void pktq_reverse(struct pktq *pktq);
void pktq_shuffle(rand_t *r, struct pktq *pktq);
struct pkt *pktq_random(rand_t *r, struct pktq *pktq);
#endif /* PKT_H */

55
src/fragroute/randutil.c Normal file
View File

@@ -0,0 +1,55 @@
/*
* randutil.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: randutil.c 2191 2009-02-01 21:34:27Z aturner $
*/
#include "config.h"
#ifdef HAVE_LIBDNET
/* need to undef these which are pulled in via defines.h, prior to importing dnet.h */
#undef icmp_id
#undef icmp_seq
#undef icmp_data
#undef icmp_mask
#include <dnet.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "randutil.h"
static const char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void
rand_strset(rand_t *r, void *buf, size_t len)
{
uint32_t u;
char *p;
int i;
p = (char *)buf;
i = (len + 3) / 4;
u = rand_uint32(r);
/* XXX - more Duff's device tomfoolery. */
switch (len % 4) {
case 0: do {
u = rand_uint32(r);
*p++ = base64[(u >> 18) & 0x3f];
case 3:
*p++ = base64[(u >> 12) & 0x3f];
case 2:
*p++ = base64[(u >> 6) & 0x3f];
case 1:
*p++ = base64[(u >> 0) & 0x3f];
} while (--i > 0);
}
p[-1] = '\0';
}

14
src/fragroute/randutil.h Normal file
View File

@@ -0,0 +1,14 @@
/*
* randutil.h
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: randutil.h 2000 2008-04-27 06:17:35Z aturner $
*/
#ifndef RANDUTIL_H
#define RANDUTIL_H
void rand_strset(rand_t *r, void *buf, size_t len);
#endif /* RANDUTIL_H */

715
src/send_packets.c Normal file
View File

@@ -0,0 +1,715 @@
/* $Id: send_packets.c 2444 2010-03-30 04:47:09Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <sys/time.h>
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "tcpreplay.h"
#ifdef TCPREPLAY
#ifdef TCPREPLAY_EDIT
#include "tcpreplay_edit_opts.h"
#include "tcpedit/tcpedit.h"
extern tcpedit_t *tcpedit;
#else
#include "tcpreplay_opts.h"
#endif
#endif /* TCPREPLAY */
#include "send_packets.h"
#include "sleep.h"
extern tcpreplay_opt_t options;
extern struct timeval begin, end;
extern COUNTER bytes_sent, failed, pkts_sent;
extern volatile int didsig;
#ifdef DEBUG
extern int debug;
#endif
int send_pkt_driver_mode = 1; /* ͬƽ̨<C6BD><CCA8><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD>ֵ, 1=pcap, 12=marsio */
extern int stream_burst_send_pkt(void *handle, const u_char *pkt, size_t pktlen);
extern int stream_burst(sendpacket_t *sp, const u_char *pkt, size_t pktlen, int, int);
static void do_sleep(struct timeval *time, struct timeval *last, int len,
int accurate, sendpacket_t *sp, COUNTER counter, delta_t *ctx);
static u_int32_t get_user_count(sendpacket_t *sp, COUNTER counter);
/**
* the main loop function for tcpreplay. This is where we figure out
* what to do with each packet
*/
void
send_packets(pcap_t *pcap, int cache_file_idx)
{
struct timeval last = { 0, 0 }, last_print_time = { 0, 0 }, print_delta, now;
COUNTER packetnum = 0;
struct pcap_pkthdr pkthdr;
const u_char *pktdata = NULL;
sendpacket_t *sp = options.intf1;
u_int32_t pktlen;
packet_cache_t *cached_packet = NULL;
packet_cache_t **prev_packet = NULL;
#if defined TCPREPLAY && defined TCPREPLAY_EDIT
struct pcap_pkthdr *pkthdr_ptr;
#endif
delta_t delta_ctx;
init_delta_time(&delta_ctx);
/* register signals */
didsig = 0;
if (options.speed.mode != SPEED_ONEATATIME) {
(void)signal(SIGINT, catcher);
} else {
(void)signal(SIGINT, break_now);
}
if (options.enable_file_cache) {
prev_packet = &cached_packet;
} else {
prev_packet = NULL;
}
/* MAIN LOOP
* Keep sending while we have packets or until
* we've sent enough packets
*/
while ((pktdata = get_next_packet(pcap, &pkthdr, cache_file_idx, prev_packet)) != NULL) {
/* die? */
if (didsig)
break_now(0);
/* stop sending based on the limit -L? */
if (options.limit_send > 0 && pkts_sent >= options.limit_send)
return;
packetnum++;
#ifdef TCPREPLAY
/* do we use the snaplen (caplen) or the "actual" packet len? */
pktlen = HAVE_OPT(PKTLEN) ? pkthdr.len : pkthdr.caplen;
#elif TCPBRIDGE
pktlen = pkthdr.caplen;
#else
#error WTF??? We should not be here!
#endif
dbgx(2, "packet " COUNTER_SPEC " caplen %d", packetnum, pktlen);
/* Dual nic processing */
if (options.intf2 != NULL) {
sp = (sendpacket_t *) cache_mode(options.cachedata, packetnum);
/* sometimes we should not send the packet */
if (sp == TCPR_DIR_NOSEND)
continue;
}
/* do we need to print the packet via tcpdump? */
#ifdef ENABLE_VERBOSE
if (options.verbose)
tcpdump_print(options.tcpdump, &pkthdr, pktdata);
#endif
#if defined TCPREPLAY && defined TCPREPLAY_EDIT
pkthdr_ptr = &pkthdr;
if (tcpedit_packet(tcpedit, &pkthdr_ptr, &pktdata, sp->cache_dir) == -1) {
errx(-1, "Error editing packet #" COUNTER_SPEC ": %s", packetnum, tcpedit_geterr(tcpedit));
}
pktlen = HAVE_OPT(PKTLEN) ? pkthdr_ptr->len : pkthdr_ptr->caplen;
#endif
/*
* we have to cast the ts, since OpenBSD sucks
* had to be special and use bpf_timeval.
* Only sleep if we're not in top speed mode (-t)
*/
if (options.speed.mode != SPEED_TOPSPEED)
do_sleep((struct timeval *)&pkthdr.ts, &last, pktlen, options.accurate, sp, packetnum, &delta_ctx);
/* mark the time when we send the last packet */
start_delta_time(&delta_ctx);
dbgx(2, "Sending packet #" COUNTER_SPEC, packetnum);
#if 0
/* write packet out on network */
if (1== send_pkt_driver_mode ){
if(options.encap_cfg_file != NULL){
return sendpacket_with_encapsulation((sendpacket_t *)sp, pkt, pktlen);
}
if(sendpacket(sp, pktdata, pktlen) < (int)pktlen){
warnx("Unable to send packet: %s", sendpacket_geterr(sp));
}
}
#endif
#ifdef TCPBURST
#ifdef TCPREPLAY
/* write packet out on network */
if (stream_burst_send_pkt(sp, pktdata, pktlen) < (int)pktlen){
//warnx("Unable to send packet: %s", sendpacket_geterr(sp));
}
if(options.stream_multiple > 0) /* <20><><EFBFBD>Ŵ<EFBFBD> */
{
stream_burst(sp, pktdata, pktlen, 0, cache_file_idx);
}
#endif
#endif
/*
* track the time of the "last packet sent". Again, because of OpenBSD
* we have to do a mempcy rather then assignment.
*
* A number of 3rd party tools generate bad timestamps which go backwards
* in time. Hence, don't update the "last" unless pkthdr.ts > last
*/
if (timercmp(&last, &pkthdr.ts, <))
memcpy(&last, &pkthdr.ts, sizeof(struct timeval));
pkts_sent ++;
bytes_sent += pktlen;
/* print stats during the run? */
if (options.stats > 0) {
if (gettimeofday(&now, NULL) < 0)
errx(-1, "gettimeofday() failed: %s", strerror(errno));
if (! timerisset(&last_print_time)) {
memcpy(&last_print_time, &now, sizeof(struct timeval));
} else {
timersub(&now, &last_print_time, &print_delta);
if (print_delta.tv_sec >= options.stats) {
packet_stats(&begin, &now, bytes_sent, pkts_sent, failed);
memcpy(&last_print_time, &now, sizeof(struct timeval));
}
}
}
} /* while */
#ifdef TCPBURST
#ifdef TCPREPLAY
if(options.stream_multiple > 0)
{
stream_burst(sp, NULL, 0, 1, cache_file_idx);
}
#endif
#endif
if (options.enable_file_cache) {
options.file_cache[cache_file_idx].cached = TRUE;
}
}
/**
* Gets the next packet to be sent out. This will either read from the pcap file
* or will retrieve the packet from the internal cache.
*
* The parameter prev_packet is used as the parent of the new entry in the cache list.
* This should be NULL on the first call to this function for each file and
* will be updated as new entries are added (or retrieved) from the cache list.
*/
const u_char *
get_next_packet(pcap_t *pcap, struct pcap_pkthdr *pkthdr, int file_idx,
packet_cache_t **prev_packet)
{
u_char *pktdata = NULL;
u_int32_t pktlen;
/* pcap may be null in cache mode! */
/* packet_cache_t may be null in file read mode! */
assert(pkthdr);
/*
* Check if we're caching files
*/
if ((options.enable_file_cache || options.preload_pcap) && (prev_packet != NULL)) {
/*
* Yes we are caching files - has this one been cached?
*/
if (options.file_cache[file_idx].cached) {
if (*prev_packet == NULL) {
/*
* Get the first packet in the cache list directly from the file
*/
*prev_packet = options.file_cache[file_idx].packet_cache;
} else {
/*
* Get the next packet in the cache list
*/
*prev_packet = (*prev_packet)->next;
}
if (*prev_packet != NULL) {
pktdata = (*prev_packet)->pktdata;
memcpy(pkthdr, &((*prev_packet)->pkthdr), sizeof(struct pcap_pkthdr));
}
} else {
/*
* We should read the pcap file, and cache the results
*/
pktdata = (u_char *)pcap_next(pcap, pkthdr);
if (pktdata != NULL) {
if (*prev_packet == NULL) {
/*
* Create the first packet in the list
*/
*prev_packet = safe_malloc(sizeof(packet_cache_t));
options.file_cache[file_idx].packet_cache = *prev_packet;
} else {
/*
* Add a packet to the end of the list
*/
(*prev_packet)->next = safe_malloc(sizeof(packet_cache_t));
*prev_packet = (*prev_packet)->next;
}
if (*prev_packet != NULL) {
(*prev_packet)->next = NULL;
pktlen = pkthdr->len;
(*prev_packet)->pktdata = safe_malloc(pktlen);
memcpy((*prev_packet)->pktdata, pktdata, pktlen);
memcpy(&((*prev_packet)->pkthdr), pkthdr, sizeof(struct pcap_pkthdr));
}
}
}
} else {
/*
* Read pcap file as normal
*/
pktdata = (u_char *)pcap_next(pcap, pkthdr);
}
/* this get's casted to a const on the way out */
return pktdata;
}
/**
* determines based upon the cachedata which interface the given packet
* should go out. Also rewrites any layer 2 data we might need to adjust.
* Returns a void cased pointer to the options.intfX of the corresponding
* interface.
*/
void *
cache_mode(char *cachedata, COUNTER packet_num)
{
void *sp = NULL;
int result;
if (packet_num > options.cache_packets)
err(-1, "Exceeded number of packets in cache file.");
result = check_cache(cachedata, packet_num);
if (result == TCPR_DIR_NOSEND) {
dbgx(2, "Cache: Not sending packet " COUNTER_SPEC ".", packet_num);
return TCPR_DIR_NOSEND;
}
else if (result == TCPR_DIR_C2S) {
dbgx(2, "Cache: Sending packet " COUNTER_SPEC " out primary interface.", packet_num);
sp = options.intf1;
}
else if (result == TCPR_DIR_S2C) {
dbgx(2, "Cache: Sending packet " COUNTER_SPEC " out secondary interface.", packet_num);
sp = options.intf2;
}
else {
err(-1, "check_cache() returned an error. Aborting...");
}
return sp;
}
/**
* Given the timestamp on the current packet and the last packet sent,
* calculate the appropriate amount of time to sleep and do so.
*/
static void
do_sleep(struct timeval *time, struct timeval *last, int len, int accurate,
sendpacket_t *sp, COUNTER counter, delta_t *delta_ctx)
{
static struct timeval didsleep = { 0, 0 };
static struct timeval start = { 0, 0 };
#ifdef DEBUG
static struct timeval totalsleep = { 0, 0 };
#endif
struct timespec adjuster = { 0, 0 };
static struct timespec nap = { 0, 0 }, delta_time = {0, 0};
struct timeval nap_for, now, sleep_until;
struct timespec nap_this_time;
static int32_t nsec_adjuster = -1, nsec_times = -1;
float n;
static u_int32_t send = 0; /* accellerator. # of packets to send w/o sleeping */
u_int32_t ppnsec; /* packets per usec */
static int first_time = 1; /* need to track the first time through for the pps accelerator */
#ifdef TCPREPLAY
adjuster.tv_nsec = options.sleep_accel * 1000;
dbgx(4, "Adjuster: " TIMESPEC_FORMAT, adjuster.tv_sec, adjuster.tv_nsec);
#else
adjuster.tv_nsec = 0;
#endif
/* acclerator time? */
if (send > 0) {
send --;
return;
}
/*
* pps_multi accelerator. This uses the existing send accelerator above
* and hence requires the funky math to get the expected timings.
*/
if (options.speed.mode == SPEED_PACKETRATE && options.speed.pps_multi) {
send = options.speed.pps_multi - 1;
if (first_time) {
first_time = 0;
return;
}
}
dbgx(4, "This packet time: " TIMEVAL_FORMAT, time->tv_sec, time->tv_usec);
dbgx(4, "Last packet time: " TIMEVAL_FORMAT, last->tv_sec, last->tv_usec);
if (gettimeofday(&now, NULL) < 0)
errx(-1, "Error gettimeofday: %s", strerror(errno));
dbgx(4, "Now time: " TIMEVAL_FORMAT, now.tv_sec, now.tv_usec);
/* First time through for this file */
if (pkts_sent == 0 || ((options.speed.mode != SPEED_MBPSRATE) && (counter == 0))) {
start = now;
timerclear(&sleep_until);
timerclear(&didsleep);
}
else {
timersub(&now, &start, &sleep_until);
}
/* If top speed, you shouldn't even be here */
assert(options.speed.mode != SPEED_TOPSPEED);
/*
* 1. First, figure out how long we should sleep for...
*/
switch(options.speed.mode) {
case SPEED_MULTIPLIER:
/*
* Replay packets a factor of the time they were originally sent.
*/
if (timerisset(last)) {
if (timercmp(time, last, <)) {
/* Packet has gone back in time! Don't sleep and warn user */
warnx("Packet #" COUNTER_SPEC " has gone back in time!", counter);
timesclear(&nap);
} else {
/* time has increased or is the same, so handle normally */
timersub(time, last, &nap_for);
dbgx(3, "original packet delta time: " TIMEVAL_FORMAT, nap_for.tv_sec, nap_for.tv_usec);
TIMEVAL_TO_TIMESPEC(&nap_for, &nap);
dbgx(3, "original packet delta timv: " TIMESPEC_FORMAT, nap.tv_sec, nap.tv_nsec);
timesdiv(&nap, options.speed.speed);
dbgx(3, "original packet delta/div: " TIMESPEC_FORMAT, nap.tv_sec, nap.tv_nsec);
}
} else {
/* Don't sleep if this is our first packet */
timesclear(&nap);
}
break;
case SPEED_MBPSRATE:
/*
* Ignore the time supplied by the capture file and send data at
* a constant 'rate' (bytes per second).
*/
if (pkts_sent != 0) {
n = (float)len / (options.speed.speed * 1024 * 1024 / 8); /* convert Mbps to bps */
nap.tv_sec = n;
nap.tv_nsec = (n - nap.tv_sec) * 1000000000;
dbgx(3, "packet size %d\t\tequals %f bps\t\tnap " TIMESPEC_FORMAT, len, n,
nap.tv_sec, nap.tv_nsec);
}
else {
/* don't sleep at all for the first packet */
timesclear(&nap);
}
break;
case SPEED_PACKETRATE:
/*
* Only need to calculate this the first time since this is a
* constant time function
*/
if (! timesisset(&nap)) {
/* run in packets/sec */
ppnsec = 1000000000 / options.speed.speed * (options.speed.pps_multi > 0 ? options.speed.pps_multi : 1);
NANOSEC_TO_TIMESPEC(ppnsec, &nap);
dbgx(1, "sending %d packet(s) per %lu nsec", (options.speed.pps_multi > 0 ? options.speed.pps_multi : 1), nap.tv_nsec);
}
break;
case SPEED_ONEATATIME:
/*
* Prompt the user for sending each packet(s)
*/
/* do we skip prompting for a key press? */
if (send == 0) {
send = get_user_count(sp, counter);
}
/* decrement our send counter */
printf("Sending packet " COUNTER_SPEC " out: %s\n", counter,
sp == options.intf1 ? options.intf1_name : options.intf2_name);
send --;
return; /* leave do_sleep() */
break;
default:
errx(-1, "Unknown/supported speed mode: %d", options.speed.mode);
break;
}
/*
* since we apply the adjuster to the sleep time, we can't modify nap
*/
memcpy(&nap_this_time, &nap, sizeof(nap_this_time));
dbgx(2, "nap_time before rounding: " TIMESPEC_FORMAT, nap_this_time.tv_sec, nap_this_time.tv_nsec);
if (accurate != ACCURATE_ABS_TIME) {
switch (options.speed.mode) {
/*
* We used to round to the nearest uset for Mbps & Multipler
* because they are "dynamic timings", but that seems stupid
* so I'm turning that off and we do nothing now
*/
case SPEED_MBPSRATE:
case SPEED_MULTIPLIER:
break;
/* Packets/sec is static, so we weight packets for .1usec accuracy */
case SPEED_PACKETRATE:
if (nsec_adjuster < 0)
nsec_adjuster = (nap_this_time.tv_nsec % 10000) / 1000;
/* update in the range of 0-9 */
nsec_times = (nsec_times + 1) % 10;
if (nsec_times < nsec_adjuster) {
/* sorta looks like a no-op, but gives us a nice round usec number */
nap_this_time.tv_nsec = (nap_this_time.tv_nsec / 1000 * 1000) + 1000;
} else {
nap_this_time.tv_nsec -= (nap_this_time.tv_nsec % 1000);
}
dbgx(3, "(%d)\tnsec_times = %d\tnap adjust: %lu -> %lu", nsec_adjuster, nsec_times, nap.tv_nsec, nap_this_time.tv_nsec);
break;
default:
errx(-1, "Unknown/supported speed mode: %d", options.speed.mode);
}
}
dbgx(2, "nap_time before delta calc: " TIMESPEC_FORMAT, nap_this_time.tv_sec, nap_this_time.tv_nsec);
get_delta_time(delta_ctx, &delta_time);
dbgx(2, "delta: " TIMESPEC_FORMAT, delta_time.tv_sec, delta_time.tv_nsec);
if (timesisset(&delta_time)) {
if (timescmp(&nap_this_time, &delta_time, >)) {
timessub(&nap_this_time, &delta_time, &nap_this_time);
dbgx(3, "timesub: %lu %lu", delta_time.tv_sec, delta_time.tv_nsec);
} else {
timesclear(&nap_this_time);
dbgx(3, "timesclear: " TIMESPEC_FORMAT, delta_time.tv_sec, delta_time.tv_nsec);
}
}
/* apply the adjuster... */
if (timesisset(&adjuster)) {
if (timescmp(&nap_this_time, &adjuster, >)) {
timessub(&nap_this_time, &adjuster, &nap_this_time);
} else {
timesclear(&nap_this_time);
}
}
dbgx(2, "Sleeping: " TIMESPEC_FORMAT, nap_this_time.tv_sec, nap_this_time.tv_nsec);
/* don't sleep if nap = {0, 0} */
if (!timesisset(&nap_this_time))
return;
/*
* Depending on the accurate method & packet rate computation method
* We have multiple methods of sleeping, pick the right one...
*/
switch (accurate) {
#ifdef HAVE_SELECT
case ACCURATE_SELECT:
select_sleep(nap_this_time);
break;
#endif
#ifdef HAVE_IOPERM
case ACCURATE_IOPORT:
ioport_sleep(nap_this_time);
break;
#endif
#ifdef HAVE_RDTSC
case ACCURATE_RDTSC:
rdtsc_sleep(nap_this_time);
break;
#endif
#ifdef HAVE_ABSOLUTE_TIME
case ACCURATE_ABS_TIME:
absolute_time_sleep(nap_this_time);
break;
#endif
case ACCURATE_GTOD:
gettimeofday_sleep(nap_this_time);
break;
case ACCURATE_NANOSLEEP:
nanosleep_sleep(nap_this_time);
break;
/*
timeradd(&didsleep, &nap_this_time, &didsleep);
dbgx(4, "I will sleep " TIMEVAL_FORMAT, nap_this_time.tv_sec, nap_this_time.tv_usec);
if (timercmp(&didsleep, &sleep_until, >)) {
timersub(&didsleep, &sleep_until, &nap_this_time);
TIMEVAL_TO_TIMESPEC(&nap_this_time, &sleep);
dbgx(4, "Sleeping " TIMEVAL_FORMAT, nap_this_time.tv_sec, nap_this_time.tv_usec);
#ifdef DEBUG
timeradd(&totalsleep, &nap_this_time, &totalsleep);
#endif
if (nanosleep(&sleep, &ignore) == -1) {
warnx("nanosleep error: %s", strerror(errno));
}
}
break;
*/
default:
errx(-1, "Unknown timer mode %d", accurate);
}
#ifdef DEBUG
dbgx(4, "Total sleep time: " TIMEVAL_FORMAT, totalsleep.tv_sec, totalsleep.tv_usec);
#endif
dbgx(2, "sleep delta: " TIMESPEC_FORMAT, delta_time.tv_sec, delta_time.tv_nsec);
}
/**
* Ask the user how many packets they want to send.
*/
static u_int32_t
get_user_count(sendpacket_t *sp, COUNTER counter)
{
struct pollfd poller[1]; /* use poll to read from the keyboard */
char input[EBUF_SIZE];
u_int32_t send = 0;
printf("**** Next packet #" COUNTER_SPEC " out %s. How many packets do you wish to send? ",
counter, (sp == options.intf1 ? options.intf1_name : options.intf2_name));
fflush(NULL);
poller[0].fd = STDIN_FILENO;
poller[0].events = POLLIN | POLLPRI | POLLNVAL;
poller[0].revents = 0;
if (fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK))
errx(-1, "Unable to clear non-blocking flag on stdin: %s", strerror(errno));
/* wait for the input */
if (poll(poller, 1, -1) < 0)
errx(-1, "Error reading user input from stdin: %s", strerror(errno));
/*
* read to the end of the line or EBUF_SIZE,
* Note, if people are stupid, and type in more text then EBUF_SIZE
* then the next fgets() will pull in that data, which will have poor
* results. fuck them.
*/
if (fgets(input, sizeof(input), stdin) == NULL) {
errx(-1, "Unable to process user input for fd %d: %s", fileno(stdin), strerror(errno));
} else if (strlen(input) > 1) {
send = strtoul(input, NULL, 0);
}
/* how many packets should we send? */
if (send == 0) {
dbg(1, "Input was less then 1 or non-numeric, assuming 1");
/* assume send only one packet */
send = 1;
}
return send;
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

50
src/send_packets.h Normal file
View File

@@ -0,0 +1,50 @@
/* $Id: send_packets.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SEND_PACKETS_H__
#define __SEND_PACKETS_H__
void send_packets(pcap_t *, int);
void *cache_mode(char *, COUNTER);
const u_char * get_next_packet(pcap_t *pcap, struct pcap_pkthdr *pkthdr,
int file_idx, packet_cache_t **prev_packet);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

125
src/signal_handler.c Normal file
View File

@@ -0,0 +1,125 @@
/* $Id: signal_handler.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "tcpreplay.h"
#include "signal_handler.h"
struct timeval suspend_time;
static struct timeval suspend_start;
static struct timeval suspend_end;
/**
* init_signal_handlers -
* Initialize signal handlers to be used in tcpreplay.
*/
void
init_signal_handlers()
{
signal(SIGUSR1, suspend_handler);
signal(SIGCONT, continue_handler);
reset_suspend_time();
}
/**
* reset_suspend_time -
* Reset time values for suspend signal.
*/
void
reset_suspend_time()
{
timerclear(&suspend_time);
timerclear(&suspend_start);
timerclear(&suspend_end);
}
/**
* suspend signal handler -
* Signal handler for signal SIGUSR1. SIGSTOP cannot be
* caught, so SIGUSR1 is caught and it throws SIGSTOP.
*/
void
suspend_handler(int signo)
{
if (signo != SIGUSR1) {
warnx("suspend_handler() got the wrong signal: %d", signo);
return;
}
if (gettimeofday(&suspend_start, NULL) < 0)
errx(-1, "gettimeofday(): %s", strerror(errno));
kill(getpid(), SIGSTOP);
}
/**
* continue_handler -
* Signal handler for continue signal.
*/
void
continue_handler(int signo)
{
struct timeval suspend_delta;
if (signo != SIGCONT) {
warnx("continue_handler() got the wrong signal: %d", signo);
return;
}
if (gettimeofday(&suspend_end, NULL) < 0)
errx(-1, "gettimeofday(): %s", strerror(errno));
timersub(&suspend_end, &suspend_start, &suspend_delta);
timeradd(&suspend_time, &suspend_delta, &suspend_time);
}
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

51
src/signal_handler.h Normal file
View File

@@ -0,0 +1,51 @@
/* $Id: signal_handler.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2001-2010 Aaron Turner
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SIGNAL_HANDLER_H
#define SIGNAL_HANDLER_H
void init_signal_handlers();
void reset_suspend_time();
void suspend_handler(int signo);
void continue_handler(int signo);
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

101
src/sleep.c Normal file
View File

@@ -0,0 +1,101 @@
/* $Id:$ */
/*
* Copyright (c) 2008-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#ifdef HAVE_SYS_EVENT
#include <sys/event.h>
#endif
/* necessary for ioport_sleep() functions */
#ifdef HAVE_SYS_IO_H /* Linux */
#include <sys/io.h>
#elif defined HAVE_ARCHITECTURE_I386_PIO_H /* OS X */
#include <architecture/i386/pio.h>
#endif
float gettimeofday_sleep_value;
int ioport_sleep_value;
void
ioport_sleep_init(void)
{
#ifdef HAVE_IOPERM
ioperm(0x80,1,1);
ioport_sleep_value = inb(0x80);
#else
err(-1, "Platform does not support IO Port for timing");
#endif
}
void
ioport_sleep(const struct timespec nap)
{
#ifdef HAVE_IOPERM
struct timeval nap_for;
u_int32_t usec;
time_t i;
TIMESPEC_TO_TIMEVAL(&nap_for, &nap);
/*
* process the seconds, we do this in a loop so we don't have to
* use slower 64bit integers or worry about integer overflows.
*/
for (i = 0; i < nap_for.tv_sec; i ++) {
usec = SEC_TO_MICROSEC(nap_for.tv_sec);
while (usec > 0) {
usec --;
outb(ioport_sleep_value, 0x80);
}
}
/* process the usec */
usec = nap.tv_nsec / 1000;
usec --; /* fudge factor for all the above */
while (usec > 0) {
usec --;
outb(ioport_sleep_value, 0x80);
}
#else
err(-1, "Platform does not support IO Port for timing");
#endif
}

146
src/sleep.h Normal file
View File

@@ -0,0 +1,146 @@
/* $Id:$ */
/*
* Copyright (c) 2008-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#ifdef HAVE_SYS_SELECT /* According to POSIX 1003.1-2001 */
#include <sys/select.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#ifdef HAVE_SYS_EVENT
#include <sys/event.h>
#endif
/* necessary for ioport_sleep() functions */
#ifdef HAVE_SYS_IO_H /* Linux */
#include <sys/io.h>
#elif defined HAVE_ARCHITECTURE_I386_PIO_H /* OS X */
#include <architecture/i386/pio.h>
#endif
#ifndef __SLEEP_H__
#define __SLEEP_H__
static inline void
nanosleep_sleep(struct timespec nap)
{
nanosleep(&nap, NULL);
}
/*
* Straight forward... keep calling gettimeofday() unti the apporpriate amount
* of time has passed. Pretty damn accurate from 1 to 100Mbps
*/
static inline void
gettimeofday_sleep(struct timespec nap)
{
struct timeval now, sleep_until, nap_for;
gettimeofday(&now, NULL);
TIMESPEC_TO_TIMEVAL(&nap_for, &nap);
timeradd(&now, &nap_for, &sleep_until);
do {
gettimeofday(&now, NULL);
} while (timercmp(&now, &sleep_until, <));
}
#ifdef HAVE_ABSOLUTE_TIME
#include <CoreServices/CoreServices.h>
/*
* Apple's AbsoluteTime functions give at least .1usec precision
* which is pretty damn sweet
*/
static inline void
absolute_time_sleep(struct timespec nap)
{
AbsoluteTime sleep_until, naptime, time_left;
Nanoseconds nanosec;
nanosec = UInt64ToUnsignedWide(TIMESPEC_TO_NANOSEC(&nap));
naptime = NanosecondsToAbsolute(nanosec);
sleep_until = AddAbsoluteToAbsolute(UpTime(), naptime);
do {
time_left = SubAbsoluteFromAbsolute(sleep_until, UpTime());
} while (NonZero(time_left));
}
#endif /* HAVE_ABSOLUTE_TIME */
#ifdef HAVE_SELECT
/*
* sleep for some time using the select() call timeout method. This is
* highly portable for sub-second sleeping, but only for about 1msec
* resolution which is pretty much useless for our needs. Keeping it here
* for furture reference
*/
static inline void
select_sleep(const struct timespec nap)
{
struct timeval timeout;
TIMESPEC_TO_TIMEVAL(&timeout, &nap);
if (select(0, NULL, NULL, NULL, &timeout) < 0)
warnx("select_sleep() returned early due to error: %s", strerror(errno));
}
#endif /* HAVE_SELECT */
/*
* ioport_sleep() only works on Intel and quite possibly only Linux.
* But the basic idea is to write to the IO Port 0x80 which should
* take exactly 1usec regardless of the CPU speed and without
* calling a sleep method which allows the kernel to service another thread
* Idea stolen from: http://c-faq.com/osdep/sd25.html
*/
extern int ioport_sleep_value;
/* before calling port_sleep(), you have to call port_sleep_init() */
void ioport_sleep_init(void);
void ioport_sleep(const struct timespec nap);
#endif /* __SLEEP_H__ */

Binary file not shown.

623
src/tcpbridge.1 Normal file
View File

@@ -0,0 +1,623 @@
.TH TCPBRIDGE 1 2010-04-04 "(tcpbridge )" "Programmer's Manual"
.\" DO NOT EDIT THIS FILE (tcpbridge.1)
.\"
.\" It has been AutoGen-ed April 4, 2010 at 05:59:20 PM by AutoGen 5.9.9
.\" From the definitions tcpbridge_opts.def
.\" and the template file agman1.tpl
.\"
.SH NAME
tcpbridge \- Bridge network traffic across two interfaces
.SH SYNOPSIS
.B tcpbridge
.\" Mixture of short (flag) options and long options
.RB [ \-\fIflag\fP " [\fIvalue\fP]]... [" \--\fIopt-name\fP " [[=| ]\fIvalue\fP]]..."
.PP
All arguments must be options.
.PP
tcpbridge is a tool for selectively briding network traffic across two interfaces
and optionally modifying the packets in betweeen
.SH "DESCRIPTION"
This manual page briefly documents the \fBtcpbridge\fP command.
The basic operation of tcpbridge is to be a network bridge between two
subnets. All packets received on one interface are sent via the other.
Optionally, packets can be edited in a variety of ways according to your needs.
For more details, please see the Tcpreplay Manual at:
http://tcpreplay.synfin.net/trac/wiki/manual
.SH OPTIONS
.SS ""
.TP
.BR \-r " \fIstring\fP, " \--portmap "=" \fIstring\fP
Rewrite TCP/UDP ports.
This option may appear up to \-1 times.
.sp
Specify a list of comma delimited port mappingings consisting of
colon delimited port number pairs. Each colon delimited port pair
consists of the port to match followed by the port number to rewrite.
Examples:
.nf
\--portmap=80:8000 \--portmap=8080:80 # 80->8000 and 8080->80
\--portmap=8000,8080,88888:80 # 3 different ports become 80
\--portmap=8000-8999:80 # ports 8000 to 8999 become 80
.fi
.TP
.BR \-s " \fInumber\fP, " \--seed "=" \fInumber\fP
Randomize src/dst IPv4/v6 addresses w/ given seed.
This option may appear up to 1 times.
This option takes an integer number as its argument.
.sp
Causes the source and destination IPv4/v6 addresses to be pseudo
randomized but still maintain client/server relationships.
Since the randomization is deterministic based on the seed,
you can reuse the same seed value to recreate the traffic.
.TP
.BR \-N " \fIstring\fP, " \--pnat "=" \fIstring\fP
Rewrite IPv4/v6 addresses using pseudo-NAT.
This option may appear up to 2 times.
This option must not appear in combination with any of the following options:
srcipmap.
.sp
Takes a comma delimited series of colon delimited CIDR
netblock pairs. Each netblock pair is evaluated in order against
the IP addresses. If the IP address in the packet matches the
first netblock, it is rewriten using the second netblock as a
mask against the high order bits.
IPv4 Example:
.nf
\--pnat=192.168.0.0/16:10.77.0.0/16,172.16.0.0/12:10.1.0.0/24
.fi
IPv6 Example:
.nf
\--pnat=[2001:db8::/32]:[dead::/16],[2001:db8::/32]:[::ffff:0:0/96]
.fi
.TP
.BR \-S " \fIstring\fP, " \--srcipmap "=" \fIstring\fP
Rewrite source IPv4/v6 addresses using pseudo-NAT.
This option may appear up to 1 times.
This option must not appear in combination with any of the following options:
pnat.
.sp
Works just like the \--pnat option, but only affects the source IP
addresses in the IPv4/v6 header.
.TP
.BR \-D " \fIstring\fP, " \--dstipmap "=" \fIstring\fP
Rewrite destination IPv4/v6 addresses using pseudo-NAT.
This option may appear up to 1 times.
This option must not appear in combination with any of the following options:
pnat.
.sp
Works just like the \--pnat option, but only affects the destination IP
addresses in the IPv4/v6 header.
.TP
.BR \-e " \fIstring\fP, " \--endpoints "=" \fIstring\fP
Rewrite IP addresses to be between two endpoints.
This option may appear up to 1 times.
This option must appear in combination with the following options:
cachefile.
.sp
Takes a pair of colon delimited IPv4/v6 addresses which will be used to rewrite
all traffic to appear to be between the two IP's.
IPv4 Example:
.nf
\--endpoints=172.16.0.1:172.16.0.2
.fi
IPv6 Example:
.nf
\--endpoints=[2001:db8::dead:beef]:[::ffff:0:0:ac:f:0:2]
.fi
.TP
.BR \-b ", " \--skipbroadcast
Skip rewriting broadcast/multicast IPv4/v6 addresses.
.sp
By default \--seed, \--pnat and \--endpoints will rewrite
broadcast and multicast IPv4/v6 and MAC addresses. Setting this flag
will keep broadcast/multicast IPv4/v6 and MAC addresses from being rewritten.
.TP
.BR \-C ", " \--fixcsum
Force recalculation of IPv4/TCP/UDP header checksums.
.sp
Causes each IPv4/v6 packet to have it's checksums recalcualted and
fixed. Automatically enabled for packets modified with \fB--seed\fP,
\fB--pnat\fP, \fB--endpoints\fP or \fB--fixlen\fP.
.TP
.BR \-m " \fInumber\fP, " \--mtu "=" \fInumber\fP
Override default MTU length (1500 bytes).
This option may appear up to 1 times.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
in the range 1 through MAXPACKET
.fi
.in -4
.sp
Override the default 1500 byte MTU size for determining the maximum padding length
(--fixlen=pad) or when truncating (--mtu-trunc).
.TP
.BR \--mtu-trunc
Truncate packets larger then specified MTU.
This option may appear up to 1 times.
.sp
Similar to \--fixlen, this option will truncate data in packets from Layer 3 and above to be
no larger then the MTU.
.TP
.BR \-E ", " \--efcs
Remove Ethernet checksums (FCS) from end of frames.
.sp
Note, this option is pretty dangerous! We don't actually check to see if a FCS
actually exists in the frame, we just blindly delete the last two bytes. Hence,
you should only use this if you know know that your OS provides the FCS when
reading raw packets.
.TP
.BR \--ttl "=\fIstring\fP"
Modify the IPv4/v6 TTL/Hop Limit.
.sp
Allows you to modify the TTL/Hop Limit of all the IPv4/v6 packets. Specify a number to hard-code
the value or +/-value to increase or decrease by the value provided (limited to 1-255).
Examples:
.nf
\--ttl=10
\--ttl=+7
\--ttl=-64
.fi
.TP
.BR \--tos "=\fInumber\fP"
Set the IPv4 TOS/DiffServ/ECN byte.
This option may appear up to 1 times.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
in the range 0 through 255
.fi
.in -4
.sp
Allows you to override the TOS (also known as DiffServ/ECN) value in IPv4.
.TP
.BR \--tclass "=\fInumber\fP"
Set the IPv6 Traffic Class byte.
This option may appear up to 1 times.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
in the range 0 through 255
.fi
.in -4
.sp
Allows you to override the IPv6 Traffic Class field.
.TP
.BR \--flowlabel "=\fInumber\fP"
Set the IPv6 Flow Label.
This option may appear up to 1 times.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
in the range 0 through 1048575
.fi
.in -4
.sp
Allows you to override the 20bit IPv6 Flow Label field. Has no effect on IPv4
packets.
.TP
.BR \-F " \fIstring\fP, " \--fixlen "=" \fIstring\fP
Pad or truncate packet data to match header length.
This option may appear up to 1 times.
.sp
Packets may be truncated during capture if the snaplen is smaller then the
packet. This option allows you to modify the packet to pad the packet back
out to the size stored in the IPv4/v6 header or rewrite the IP header total length
to reflect the stored packet length.
.sp 1
\fBpad\fP
Truncated packets will be padded out so that the packet length matches the
IPv4 total length
.sp 1
\fBtrunc\fP
Truncated packets will have their IPv4 total length field rewritten to match
the actual packet length
.sp 1
\fBdel\fP
Delete the packet
.TP
.BR \--skipl2broadcast
Skip rewriting broadcast/multicast Layer 2 addresses.
.sp
By default, editing Layer 2 addresses will rewrite
broadcast and multicast MAC addresses. Setting this flag
will keep broadcast/multicast MAC addresses from being rewritten.
.TP
.BR \--dlt "=\fIstring\fP"
Override output DLT encapsulation.
This option may appear up to 1 times.
.sp
By default, no DLT (data link type) conversion will be made.
To change the DLT type of the output pcap, select one of the following values:
.sp 1
\fBenet\fP
Ethernet aka DLT_EN10MB
.sp 1
\fBhdlc\fP
Cisco HDLC aka DLT_C_HDLC
.sp 1
\fBuser\fP
User specified Layer 2 header and DLT type
.br
.TP
.BR \--enet-dmac "=\fIstring\fP"
Override destination ethernet MAC addresses.
This option may appear up to 1 times.
.sp
Takes a pair of comma deliminated ethernet MAC addresses which
will replace the destination MAC address of outbound packets.
The first MAC address will be used for the server to client traffic
and the optional second MAC address will be used for the client
to server traffic.
Example:
.nf
\--enet-dmac=00:12:13:14:15:16,00:22:33:44:55:66
.fi
.TP
.BR \--enet-smac "=\fIstring\fP"
Override source ethernet MAC addresses.
This option may appear up to 1 times.
.sp
Takes a pair of comma deliminated ethernet MAC addresses which
will replace the source MAC address of outbound packets.
The first MAC address will be used for the server to client traffic
and the optional second MAC address will be used for the client
to server traffic.
Example:
.nf
\--enet-smac=00:12:13:14:15:16,00:22:33:44:55:66
.fi
.TP
.BR \--enet-vlan "=\fIstring\fP"
Specify ethernet 802.1q VLAN tag mode.
This option may appear up to 1 times.
.sp
Allows you to rewrite ethernet frames to add a 802.1q header to standard 802.3
ethernet headers or remove the 802.1q VLAN tag information.
.sp 1
\fBadd\fP
Rewrites the existing 802.3 ethernet header as an 802.1q VLAN header
.sp 1
\fBdel\fP
Rewrites the existing 802.1q VLAN header as an 802.3 ethernet header
.TP
.BR \--enet-vlan-tag "=\fInumber\fP"
Specify the new ethernet 802.1q VLAN tag value.
This option may appear up to 1 times.
This option must appear in combination with the following options:
enet-vlan.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
in the range 0 through 4095
.fi
.in -4
.sp
.TP
.BR \--enet-vlan-cfi "=\fInumber\fP"
Specify the ethernet 802.1q VLAN CFI value.
This option may appear up to 1 times.
This option must appear in combination with the following options:
enet-vlan.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
in the range 0 through 1
.fi
.in -4
.sp
.TP
.BR \--enet-vlan-pri "=\fInumber\fP"
Specify the ethernet 802.1q VLAN priority.
This option may appear up to 1 times.
This option must appear in combination with the following options:
enet-vlan.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
in the range 0 through 7
.fi
.in -4
.sp
.TP
.BR \--hdlc-control "=\fInumber\fP"
Specify HDLC control value.
This option may appear up to 1 times.
This option takes an integer number as its argument.
.sp
The Cisco HDLC header has a 1 byte "control" field. Apparently this should
always be 0, but if you can use any 1 byte value.
.TP
.BR \--hdlc-address "=\fInumber\fP"
Specify HDLC address.
This option may appear up to 1 times.
This option takes an integer number as its argument.
.sp
The Cisco HDLC header has a 1 byte "address" field which has two valid
values:
.sp 1
\fB0x0F\fP
Unicast
.sp 1
\fB0xBF\fP
Broadcast
.br
You can however specify any single byte value.
.TP
.BR \--user-dlt "=\fInumber\fP"
Set output file DLT type.
This option may appear up to 1 times.
This option takes an integer number as its argument.
.sp
Set the DLT value of the output pcap file.
.TP
.BR \--user-dlink "=\fIstring\fP"
Rewrite Data-Link layer with user specified data.
This option may appear up to 2 times.
.sp
Provide a series of comma deliminated hex values which will be
used to rewrite or create the Layer 2 header of the packets.
The first instance of this argument will rewrite both server
and client traffic, but if this argument is specified a second
time, it will be used for the client traffic.
Example:
.nf
\--user-dlink=01,02,03,04,05,06,00,1A,2B,3C,4D,5E,6F,08,00
.fi
.TP
.BR \-d " \fInumber\fP, " \--dbug "=" \fInumber\fP
Enable debugging output.
This option may appear up to 1 times.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
in the range 0 through 5
.fi
.in -4
The default \fInumber\fP for this option is:
.ti +4
0
.sp
If configured with \--enable-debug, then you can specify a verbosity
level for debugging output. Higher numbers increase verbosity.
.TP
.BR \-i " \fIstring\fP, " \--intf1 "=" \fIstring\fP
Primary interface (listen in uni-directional mode).
This option may appear up to 1 times.
.sp
.TP
.BR \-I " \fIstring\fP, " \--intf2 "=" \fIstring\fP
Secondary interface (send in uni-directional mode).
This option may appear up to 1 times.
.sp
.TP
.BR \-u ", " \--unidir
Send and receive in only one direction.
This option may appear up to 1 times.
.sp
Normally, tcpbridge will send and receive traffic in both directions
(bi-directionally). However, if you choose this option, traffic will
be sent uni-directionally.
.TP
.BR \--listnics
List available network interfaces and exit.
.sp
.TP
.BR \-L " \fInumber\fP, " \--limit "=" \fInumber\fP
Limit the number of packets to send.
This option may appear up to 1 times.
This option takes an integer number as its argument.
The value of \fInumber\fP is constrained to being:
.in +4
.nf
.na
greater than or equal to 1
.fi
.in -4
The default \fInumber\fP for this option is:
.ti +4
\-1
.sp
By default, tcpbridge will send packets forever or until Ctrl-C. Alternatively,
you can specify a maximum number of packets to send.
.TP
.BR \-M " \fIstring\fP, " \--mac "=" \fIstring\fP
MAC addresses of local NIC's.
This option may appear up to 2 times.
.sp
tcpbridge does not support detecting the MAC addresses of the local network
interfaces under Windows. Please specify both MAC addresses of the interfaces
used in the bridge: \-M <intf1 mac> \-M <intf2 mac>
.TP
.BR \-x " \fIstring\fP, " \--include "=" \fIstring\fP
Include only packets matching rule.
This option may appear up to 1 times.
This option must not appear in combination with any of the following options:
exclude.
.sp
Override default of sending all packets stored in the capture file and only
send packets which match the provided rule. Rules can be one of:
.sp
.IR "S:<CIDR1>,..."
- Source IP must match specified CIDR(s)
.sp
.IR "D:<CIDR1>,..."
- Destination IP must match specified CIDR(s)
.sp
.IR "B:<CIDR1>,..."
- Both source and destination IP must match specified CIDR(s)
.sp
.IR "E:<CIDR1>,..."
- Either IP must match specified CIDR(s)
.sp
.IR "P:<LIST>"
- Must be one of the listed packets where the list
corresponds to the packet number in the capture file.
.nf
\--include=P:1-5,9,15,72-
.fi
would send packets 1 thru 5, the 9th and 15th packet, and packets 72 until the
end of the file
.sp
.IR "F:'<bpf>'"
- BPF filter. See the \fItcpdump(8)\fP man page for syntax.
.br
.TP
.BR \-X " \fIstring\fP, " \--exclude "=" \fIstring\fP
Exclude any packet matching this rule.
This option may appear up to 1 times.
This option must not appear in combination with any of the following options:
include.
.sp
Override default of sending all packets stored in the capture file and only
send packets which do not match the provided rule. Rules can be one of:
.sp
.IR "S:<CIDR1>,..."
- Source IP must not match specified CIDR(s)
.sp
.IR "D:<CIDR1>,..."
- Destination IP must not match specified CIDR(s)
.sp
.IR "B:<CIDR1>,..."
- Both source and destination IP must not match specified CIDR(s)
.sp
.IR "E:<CIDR1>,..."
- Either IP must not match specified CIDR(s)
.sp
.IR "P:<LIST>"
- Must not be one of the listed packets where the list
corresponds to the packet number in the capture file.
.nf
\--exclude=P:1-5,9,15,72-
.fi
would drop packets 1 thru 5, the 9th and 15th packet, and packets 72 until the
end of the file
.br
.TP
.BR \-P ", " \--pid
Print the PID of tcpbridge at startup.
.sp
.TP
.BR \-v ", " \--verbose
Print decoded packets via tcpdump to STDOUT.
This option may appear up to 1 times.
.sp
.TP
.BR \-A " \fIstring\fP, " \--decode "=" \fIstring\fP
Arguments passed to tcpdump decoder.
This option may appear up to 1 times.
This option must appear in combination with the following options:
verbose.
.sp
When enabling verbose mode (\fB-v\fP) you may also specify one or more
additional arguments to pass to \fBtcpdump\fP to modify the way packets
are decoded. By default, \-n and \-l are used. Be sure to
quote the arguments like: \--verbose="-axxx" so that they are not interpreted
by tcpbridge. The following arguments are vaild:
[ \-aAeNqRStuvxX ]
[ \-E spi@ipaddr algo:secret,... ]
[ \-s snaplen ]
.TP
.BR \-V ", " \--version
Print version information.
.sp
.TP
.BR \-h ", " \--less-help
Display less usage information and exit.
.sp
.TP
.BR \-H , " \--help"
Display usage information and exit.
.TP
.BR \-! , " \--more-help"
Extended usage information passed thru pager.
.TP
.BR \- " [\fIrcfile\fP]," " \--save-opts" "[=\fIrcfile\fP]"
Save the option state to \fIrcfile\fP. The default is the \fIlast\fP
configuration file listed in the \fBOPTION PRESETS\fP section, below.
.TP
.BR \- " \fIrcfile\fP," " \--load-opts" "=\fIrcfile\fP," " \--no-load-opts"
Load options from \fIrcfile\fP.
The \fIno-load-opts\fP form will disable the loading
of earlier RC/INI files. \fI--no-load-opts\fP is handled early,
out of order.
.SH OPTION PRESETS
Any option that is not marked as \fInot presettable\fP may be preset
by loading values from configuration ("RC" or ".INI") file(s).
The \fIhomerc\fP file is "\fI$$/\fP", unless that is a directory.
In that case, the file "\fI.tcpbridgerc\fP"
is searched for within that directory.
.SH "SIGNALS"
tcpbridge understands the following signals:
.sp
.IR "\fBSIGUSR1\fP"
Suspend tcpbridge
.sp
.IR "\fBSIGCONT\fP"
Restart tcpbridge
.br
.SH "SEE ALSO"
tcpdump(1), tcpprep(1), tcprewrite(1), tcpreplay(1)
.SH "BUGS"
tcpbridge can only send packets as fast as your computer's interface,
processor and system bus will allow.
Connecting both interfaces to the same subnet may create a broadcast storm and
take down the network. Improper use of the packet editing functions may have
other undefined and possible negative consequences.
Some operating systems by default do not allow for forging source MAC
addresses. Please consult your operating system's documentation and the
tcpreplay FAQ if you experiance this issue.
.SH AUTHOR
Copyright 2000-2010 Aaron Turner
For support please use the tcpreplay-users@lists.sourceforge.net mailing list.
The latest version of this software is always available from:
http://tcpreplay.synfin.net/
.PP
Released under the Free BSD License.
.PP
This manual page was \fIAutoGen\fP-erated from the \fBtcpbridge\fP
option definitions.

266
src/tcpbridge.c Normal file
View File

@@ -0,0 +1,266 @@
/* $Id: tcpbridge.c 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2004-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Purpose: Modify packets in a pcap file based on rules provided by the
* user to offload work from tcpreplay and provide a easier means of
* reproducing traffic for testing purposes.
*/
#include "config.h"
#include "defines.h"
#include "common.h"
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include "tcpbridge.h"
#include "tcpbridge_opts.h"
#include "bridge.h"
#include "tcpedit/tcpedit.h"
#include "send_packets.h"
#ifdef DEBUG
int debug;
#endif
COUNTER bytes_sent, total_bytes, failed, pkts_sent, cache_packets;
struct timeval begin, end;
volatile int didsig;
tcpbridge_opt_t options;
tcpedit_t *tcpedit;
/* local functions */
void init(void);
void post_args(int argc, char *argv[]);
int
main(int argc, char *argv[])
{
int optct, rcode;
init();
/* call autoopts to process arguments */
optct = optionProcess(&tcpbridgeOptions, argc, argv);
argc -= optct;
argv += optct;
post_args(argc, argv);
/* init tcpedit context */
if (tcpedit_init(&tcpedit, pcap_datalink(options.pcap1)) < 0) {
errx(-1, "Error initializing tcpedit: %s", tcpedit_geterr(tcpedit));
}
/* parse the tcpedit args */
rcode = tcpedit_post_args(&tcpedit);
if (rcode < 0) {
errx(-1, "Unable to parse args: %s", tcpedit_geterr(tcpedit));
} else if (rcode == 1) {
warnx("%s", tcpedit_geterr(tcpedit));
}
if (tcpedit_validate(tcpedit) < 0) {
errx(-1, "Unable to edit packets given options:\n%s",
tcpedit_geterr(tcpedit));
}
#ifdef ENABLE_VERBOSE
if (options.verbose) {
options.tcpdump = (tcpdump_t*)safe_malloc(sizeof(tcpdump_t));
tcpdump_open(options.tcpdump, options.pcap1);
}
#endif
if (gettimeofday(&begin, NULL) < 0)
err(-1, "gettimeofday() failed");
/* process packets */
do_bridge(&options, tcpedit);
/* clean up after ourselves */
pcap_close(options.pcap1);
if (options.unidir) {
pcap_close(options.pcap2);
}
#ifdef ENABLE_VERBOSE
tcpdump_close(options.tcpdump);
#endif
return 0;
}
void
init(void)
{
bytes_sent = total_bytes = failed = pkts_sent = cache_packets = 0;
memset(&options, 0, sizeof(options));
options.snaplen = 65535;
options.promisc = 1;
options.to_ms = 1;
total_bytes = 0;
if (fcntl(STDERR_FILENO, F_SETFL, O_NONBLOCK) < 0)
warnx("Unable to set STDERR to non-blocking: %s", strerror(errno));
}
void
post_args(_U_ int argc, _U_ char *argv[])
{
char ebuf[SENDPACKET_ERRBUF_SIZE];
struct tcpr_ether_addr *eth_buff;
char *intname;
sendpacket_t *sp;
#ifdef ENABLE_PCAP_FINDALLDEVS
interface_list_t *intlist = get_interface_list();
#else
interface_list_t *intlist = NULL;
#endif
#ifdef DEBUG
if (HAVE_OPT(DBUG))
debug = OPT_VALUE_DBUG;
#else
if (HAVE_OPT(DBUG))
warn("not configured with --enable-debug. Debugging disabled.");
#endif
#ifdef ENABLE_VERBOSE
if (HAVE_OPT(VERBOSE))
options.verbose = 1;
if (HAVE_OPT(DECODE))
options.tcpdump->args = safe_strdup(OPT_ARG(DECODE));
#endif
if (HAVE_OPT(UNIDIR))
options.unidir = 1;
if (HAVE_OPT(LIMIT))
options.limit_send = OPT_VALUE_LIMIT; /* default is -1 */
if ((intname = get_interface(intlist, OPT_ARG(INTF1))) == NULL)
errx(-1, "Invalid interface name/alias: %s", OPT_ARG(INTF1));
options.intf1 = safe_strdup(intname);
if (HAVE_OPT(INTF2)) {
if ((intname = get_interface(intlist, OPT_ARG(INTF2))) == NULL)
errx(-1, "Invalid interface name/alias: %s", OPT_ARG(INTF2));
options.intf2 = safe_strdup(intname);
}
if (HAVE_OPT(MAC)) {
int ct = STACKCT_OPT(MAC);
char **list = STACKLST_OPT(MAC);
int first = 1;
do {
char *p = *list++;
if (first)
mac2hex(p, (u_char *)options.intf1_mac, ETHER_ADDR_LEN);
else
mac2hex(p, (u_char *)options.intf2_mac, ETHER_ADDR_LEN);
first = 0;
} while (--ct > 0);
}
/*
* Figure out MAC addresses of sending interface(s)
* if user doesn't specify MAC address on CLI, query for it
*/
if (memcmp(options.intf1_mac, "\00\00\00\00\00\00", ETHER_ADDR_LEN) == 0) {
if ((sp = sendpacket_open(options.intf1, ebuf, TCPR_DIR_C2S)) == NULL)
errx(-1, "Unable to open interface %s: %s", options.intf1, ebuf);
if ((eth_buff = sendpacket_get_hwaddr(sp)) == NULL) {
warnx("Unable to get MAC address: %s", sendpacket_geterr(sp));
err(-1, "Please consult the man page for using the -M option.");
}
sendpacket_close(sp);
memcpy(options.intf1_mac, eth_buff, ETHER_ADDR_LEN);
}
if (memcmp(options.intf2_mac, "\00\00\00\00\00\00", ETHER_ADDR_LEN) == 0) {
if ((sp = sendpacket_open(options.intf2, ebuf, TCPR_DIR_S2C)) == NULL)
errx(-1, "Unable to open interface %s: %s", options.intf2, ebuf);
if ((eth_buff = sendpacket_get_hwaddr(sp)) == NULL) {
warnx("Unable to get MAC address: %s", sendpacket_geterr(sp));
err(-1, "Please consult the man page for using the -M option.");
}
sendpacket_close(sp);
memcpy(options.intf2_mac, eth_buff, ETHER_ADDR_LEN);
}
/*
* Open interfaces for sending & receiving
*/
if ((options.pcap1 = pcap_open_live(options.intf1, options.snaplen,
options.promisc, options.to_ms, ebuf)) == NULL)
errx(-1, "Unable to open interface %s: %s", options.intf1, ebuf);
if (strcmp(options.intf1, options.intf2) == 0)
errx(-1, "Whoa tiger! You don't want to use %s twice!", options.intf1);
/* we always have to open the other pcap handle to send, but we may not listen */
if ((options.pcap2 = pcap_open_live(options.intf2, options.snaplen,
options.promisc, options.to_ms, ebuf)) == NULL)
errx(-1, "Unable to open interface %s: %s", options.intf2, ebuf);
/* poll should be -1 to wait indefinitely */
options.poll_timeout = -1;
}

109
src/tcpbridge.h Normal file
View File

@@ -0,0 +1,109 @@
/* $Id: tcpbridge.h 2423 2010-03-13 07:09:49Z aturner $ */
/*
* Copyright (c) 2005-2010 Aaron Turner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright owners nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __TCPBRIDGE_H__
#define __TCPBRIDGE_H__
/* we don't support endpoints w/ tcpbridge */
#define TCPEDIT_ENDPOINTS_DISABLE 1
#include "config.h"
#include "defines.h"
#include "common.h"
#include "tcpedit/tcpedit.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <regex.h>
#ifdef ENABLE_DMALLOC
#include <dmalloc.h>
#endif
/* run-time options */
struct tcpbridge_opt_s {
char *intf1;
char *intf2;
/* store the mac address of each interface here to prevent loops */
char intf1_mac[ETHER_ADDR_LEN];
char intf2_mac[ETHER_ADDR_LEN];
/* truncate packet ? */
int truncate;
COUNTER limit_send;
pcap_t *pcap1;
pcap_t *pcap2;
int unidir;
int snaplen;
int to_ms;
int promisc;
int poll_timeout;
#ifdef ENABLE_VERBOSE
/* tcpdump verbose printing */
int verbose;
char *tcpdump_args;
tcpdump_t *tcpdump;
#endif
/* filter options */
tcpr_xX_t xX;
tcpr_bpf_t bpf;
regex_t preg;
tcpr_cidr_t *cidrdata;
int mtu;
int maxpacket;
int fixcsum;
u_int16_t l2proto;
u_int16_t l2_mem_align; /* keep things 4 byte aligned */
};
typedef struct tcpbridge_opt_s tcpbridge_opt_t;
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

1979
src/tcpbridge_opts.c Normal file

File diff suppressed because it is too large Load Diff

385
src/tcpbridge_opts.def Normal file
View File

@@ -0,0 +1,385 @@
autogen definitions options;
copyright = {
date = "2000-2010";
owner = "Aaron Turner";
type = "bsd";
author = <<- EOText
Copyright 2000-2010 Aaron Turner
For support please use the tcpreplay-users@lists.sourceforge.net mailing list.
The latest version of this software is always available from:
http://tcpreplay.synfin.net/
EOText;
};
package = "tcpbridge";
prog-name = "tcpbridge";
prog-title = "Bridge network traffic across two interfaces";
long-opts;
gnu-usage;
help-value = "H";
save-opts-value = "";
load-opts-value = "";
config-header = "config.h";
include = "#include \"defines.h\"\n"
"#include \"tcpbridge.h\"\n"
"#include \"common.h\"\n"
"#include \"config.h\"\n"
"#include <stdlib.h>\n"
"#include <string.h>\n"
"#include <sys/types.h>\n"
"#include <unistd.h>\n"
"extern tcpbridge_opt_t options;\n";
#include tcpedit/tcpedit_opts.def
homerc = "$$/";
explain = <<- EOExplain
tcpbridge is a tool for selectively briding network traffic across two interfaces
and optionally modifying the packets in betweeen
EOExplain;
detail = <<- EODetail
The basic operation of tcpbridge is to be a network bridge between two
subnets. All packets received on one interface are sent via the other.
Optionally, packets can be edited in a variety of ways according to your needs.
For more details, please see the Tcpreplay Manual at:
http://tcpreplay.synfin.net/trac/wiki/manual
EODetail;
man-doc = <<- EOMan
.SH "SIGNALS"
tcpbridge understands the following signals:
@enumerate
@item @var{SIGUSR1}
Suspend tcpbridge
@item @var{SIGCONT}
Restart tcpbridge
@end enumerate
.SH "SEE ALSO"
tcpdump(1), tcpprep(1), tcprewrite(1), tcpreplay(1)
.SH "BUGS"
tcpbridge can only send packets as fast as your computer's interface,
processor and system bus will allow.
Connecting both interfaces to the same subnet may create a broadcast storm and
take down the network. Improper use of the packet editing functions may have
other undefined and possible negative consequences.
Some operating systems by default do not allow for forging source MAC
addresses. Please consult your operating system's documentation and the
tcpreplay FAQ if you experiance this issue.
EOMan;
/*
* Debugging
*/
flag = {
ifdef = DEBUG;
name = dbug;
value = d;
arg-type = number;
max = 1;
immediate;
arg-range = "0->5";
arg-default = 0;
descrip = "Enable debugging output";
doc = <<- EOText
If configured with --enable-debug, then you can specify a verbosity
level for debugging output. Higher numbers increase verbosity.
EOText;
};
/*
* Outputs: -i, -I
*/
flag = {
name = intf1;
value = i;
arg-type = string;
max = 1;
must-set;
descrip = "Primary interface (listen in uni-directional mode)";
doc = "";
};
flag = {
name = intf2;
value = I;
arg-type = string;
max = 1;
descrip = "Secondary interface (send in uni-directional mode)";
doc = "";
};
flag = {
name = unidir;
value = u;
max = 1;
descrip = "Send and receive in only one direction";
doc = <<- EOText
Normally, tcpbridge will send and receive traffic in both directions
(bi-directionally). However, if you choose this option, traffic will
be sent uni-directionally.
EOText;
};
flag = {
ifdef = ENABLE_PCAP_FINDALLDEVS;
name = listnics;
descrip = "List available network interfaces and exit";
immediate;
doc = "";
flag-code = <<- EOFlag
interface_list_t *list = get_interface_list();
list_interfaces(list);
free(list);
exit(0);
EOFlag;
};
/*
* Select which packets to process
*/
flag = {
name = limit;
value = L;
arg-type = number;
max = 1;
arg-default = -1;
arg-range = "1->";
descrip = "Limit the number of packets to send";
doc = <<- EOText
By default, tcpbridge will send packets forever or until Ctrl-C. Alternatively,
you can specify a maximum number of packets to send.
EOText;
};
/*
* Windows users need to provide the MAC addresses of the interfaces
* so we can prevent looping (since winpcap doesn't have an API to query)
* the MAC address of the NIC's
*/
flag = {
name = mac;
value = M;
arg-type = string;
max = 2;
stack-arg;
descrip = "MAC addresses of local NIC's";
doc = <<- EOText
tcpbridge does not support detecting the MAC addresses of the local network
interfaces under Windows. Please specify both MAC addresses of the interfaces
used in the bridge: -M <intf1 mac> -M <intf2 mac>
EOText;
};
/* Include/Exclude */
flag = {
name = include;
value = x;
arg-type = string;
max = 1;
descrip = "Include only packets matching rule";
flags-cant = exclude;
flag-code = <<- EOInclude
char *include;
include = safe_strdup(OPT_ARG(INCLUDE));
options.xX.mode = xX_MODE_INCLUDE;
if ((options.xX.mode = parse_xX_str(&options.xX, include, &options.bpf)) == xXError)
errx(-1, "Unable to parse include/exclude rule: %s", OPT_ARG(INCLUDE));
free(include);
EOInclude;
doc = <<- EOText
Override default of sending all packets stored in the capture file and only
send packets which match the provided rule. Rules can be one of:
@table @bullet
@item S:<CIDR1>,...
- Source IP must match specified CIDR(s)
@item D:<CIDR1>,...
- Destination IP must match specified CIDR(s)
@item B:<CIDR1>,...
- Both source and destination IP must match specified CIDR(s)
@item E:<CIDR1>,...
- Either IP must match specified CIDR(s)
@item P:<LIST>
- Must be one of the listed packets where the list
corresponds to the packet number in the capture file.
@example
--include=P:1-5,9,15,72-
@end example
would send packets 1 thru 5, the 9th and 15th packet, and packets 72 until the
end of the file
@item F:'<bpf>'
- BPF filter. See the @file{tcpdump(8)} man page for syntax.
@end table
EOText;
};
flag = {
name = exclude;
value = X;
arg-type = string;
max = 1;
descrip = "Exclude any packet matching this rule";
flags-cant = include;
flag-code = <<- EOExclude
char *exclude;
exclude = safe_strdup(OPT_ARG(EXCLUDE));
options.xX.mode = xX_MODE_EXCLUDE;
if ((options.xX.mode = parse_xX_str(&options.xX, exclude, &options.bpf)) == xXError)
errx(-1, "Unable to parse include/exclude rule: %s", OPT_ARG(EXCLUDE));
free(exclude);
EOExclude;
doc = <<- EOText
Override default of sending all packets stored in the capture file and only
send packets which do not match the provided rule. Rules can be one of:
@table @bullet
@item S:<CIDR1>,...
- Source IP must not match specified CIDR(s)
@item D:<CIDR1>,...
- Destination IP must not match specified CIDR(s)
@item B:<CIDR1>,...
- Both source and destination IP must not match specified CIDR(s)
@item E:<CIDR1>,...
- Either IP must not match specified CIDR(s)
@item P:<LIST>
- Must not be one of the listed packets where the list
corresponds to the packet number in the capture file.
@example
--exclude=P:1-5,9,15,72-
@end example
would drop packets 1 thru 5, the 9th and 15th packet, and packets 72 until the
end of the file
@end table
EOText;
};
flag = {
name = pid;
value = P;
descrip = "Print the PID of tcpbridge at startup";
flag-code = <<- EOPid
fprintf(stderr, "PID: %hu\n", getpid());
EOPid;
doc = "";
};
/* Verbose decoding via tcpdump */
flag = {
ifdef = ENABLE_VERBOSE;
name = verbose;
value = v;
max = 1;
immediate;
descrip = "Print decoded packets via tcpdump to STDOUT";
settable;
doc = "";
};
flag = {
ifdef = ENABLE_VERBOSE;
name = decode;
flags-must = verbose;
value = A;
arg-type = string;
max = 1;
descrip = "Arguments passed to tcpdump decoder";
doc = <<- EOText
When enabling verbose mode (@var{-v}) you may also specify one or more
additional arguments to pass to @code{tcpdump} to modify the way packets
are decoded. By default, -n and -l are used. Be sure to
quote the arguments like: --verbose="-axxx" so that they are not interpreted
by tcpbridge. The following arguments are vaild:
[ -aAeNqRStuvxX ]
[ -E spi@ipaddr algo:secret,... ]
[ -s snaplen ]
EOText;
};
flag = {
name = version;
value = V;
descrip = "Print version information";
flag-code = <<- EOVersion
fprintf(stderr, "tcpbridge version: %s (build %s)", VERSION, svn_version());
#ifdef DEBUG
fprintf(stderr, " (debug)");
#endif
fprintf(stderr, "\n");
fprintf(stderr, "Copyright 2000-2010 by Aaron Turner <aturner at synfin dot net>\n");
#ifdef HAVE_LIBDNET
fprintf(stderr, "Compiled against libdnet: %s\n", LIBDNET_VERSION);
#else
fprintf(stderr, "Not compiled with libdnet.\n");
#endif
#ifdef HAVE_WINPCAP
fprintf(stderr, "Compiled against winpcap: %s\n", get_pcap_version());
#else
fprintf(stderr, "Compiled against libpcap: %s\n", get_pcap_version());
#endif
#ifdef ENABLE_64BITS
fprintf(stderr, "64 bit packet counters: enabled\n");
#else
fprintf(stderr, "64 bit packet counters: disabled\n");
#endif
#ifdef ENABLE_VERBOSE
fprintf(stderr, "Verbose printing via tcpdump: enabled\n");
#else
fprintf(stderr, "Verbose printing via tcpdump: disabled\n");
#endif
fprintf(stderr, "Injection method: %s\n", sendpacket_get_method());
exit(0);
EOVersion;
doc = "";
};
flag = {
name = less-help;
value = "h";
immediate;
descrip = "Display less usage information and exit";
flag-code = <<- EOHelp
USAGE(EXIT_FAILURE);
EOHelp;
doc = "";
};

291
src/tcpbridge_opts.h Normal file
View File

@@ -0,0 +1,291 @@
/* -*- buffer-read-only: t -*- vi: set ro:
*
* DO NOT EDIT THIS FILE (tcpbridge_opts.h)
*
* It has been AutoGen-ed April 4, 2010 at 05:59:19 PM by AutoGen 5.9.9
* From the definitions tcpbridge_opts.def
* and the template file options
*
* Generated from AutoOpts 32:2:7 templates.
*/
/*
* This file was produced by an AutoOpts template. AutoOpts is a
* copyrighted work. This header file is not encumbered by AutoOpts
* licensing, but is provided under the licensing terms chosen by the
* tcpbridge author or copyright holder. AutoOpts is licensed under
* the terms of the LGPL. The redistributable library (``libopts'') is
* licensed under the terms of either the LGPL or, at the users discretion,
* the BSD license. See the AutoOpts and/or libopts sources for details.
*
* This source file is copyrighted and licensed under the following terms:
*
* tcpbridge copyright (c) 2000-2010 Aaron Turner - all rights reserved
*
* tcpbridge is free software copyrighted by Aaron Turner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name ``Aaron Turner'' nor the name of any other
* contributor may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* tcpbridge IS PROVIDED BY Aaron Turner ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Aaron Turner OR ANY OTHER CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This file contains the programmatic interface to the Automated
* Options generated for the tcpbridge program.
* These macros are documented in the AutoGen info file in the
* "AutoOpts" chapter. Please refer to that doc for usage help.
*/
#ifndef AUTOOPTS_TCPBRIDGE_OPTS_H_GUARD
#define AUTOOPTS_TCPBRIDGE_OPTS_H_GUARD 1
#include "config.h"
#include <autoopts/options.h>
/*
* Ensure that the library used for compiling this generated header is at
* least as new as the version current when the header template was released
* (not counting patch version increments). Also ensure that the oldest
* tolerable version is at least as old as what was current when the header
* template was released.
*/
#define AO_TEMPLATE_VERSION 131074
#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \
|| (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION)
# error option template version mismatches autoopts/options.h header
Choke Me.
#endif
/*
* Enumeration of each option:
*/
typedef enum {
INDEX_OPT_PORTMAP = 1,
INDEX_OPT_SEED = 2,
INDEX_OPT_PNAT = 3,
INDEX_OPT_SRCIPMAP = 4,
INDEX_OPT_DSTIPMAP = 5,
INDEX_OPT_ENDPOINTS = 6,
INDEX_OPT_SKIPBROADCAST = 7,
INDEX_OPT_FIXCSUM = 8,
INDEX_OPT_MTU = 9,
INDEX_OPT_MTU_TRUNC = 10,
INDEX_OPT_EFCS = 11,
INDEX_OPT_TTL = 12,
INDEX_OPT_TOS = 13,
INDEX_OPT_TCLASS = 14,
INDEX_OPT_FLOWLABEL = 15,
INDEX_OPT_FIXLEN = 16,
INDEX_OPT_SKIPL2BROADCAST = 17,
INDEX_OPT_DLT = 18,
INDEX_OPT_ENET_DMAC = 19,
INDEX_OPT_ENET_SMAC = 20,
INDEX_OPT_ENET_VLAN = 21,
INDEX_OPT_ENET_VLAN_TAG = 22,
INDEX_OPT_ENET_VLAN_CFI = 23,
INDEX_OPT_ENET_VLAN_PRI = 24,
INDEX_OPT_HDLC_CONTROL = 25,
INDEX_OPT_HDLC_ADDRESS = 26,
INDEX_OPT_USER_DLT = 27,
INDEX_OPT_USER_DLINK = 28,
INDEX_OPT_DBUG = 29,
INDEX_OPT_INTF1 = 30,
INDEX_OPT_INTF2 = 31,
INDEX_OPT_UNIDIR = 32,
INDEX_OPT_LISTNICS = 33,
INDEX_OPT_LIMIT = 34,
INDEX_OPT_MAC = 35,
INDEX_OPT_INCLUDE = 36,
INDEX_OPT_EXCLUDE = 37,
INDEX_OPT_PID = 38,
INDEX_OPT_VERBOSE = 39,
INDEX_OPT_DECODE = 40,
INDEX_OPT_VERSION = 41,
INDEX_OPT_LESS_HELP = 42,
INDEX_OPT_HELP = 43,
INDEX_OPT_MORE_HELP = 44,
INDEX_OPT_SAVE_OPTS = 45,
INDEX_OPT_LOAD_OPTS = 46
} teOptIndex;
#define OPTION_CT 47
/*
* Interface defines for all options. Replace "n" with the UPPER_CASED
* option name (as in the teOptIndex enumeration above).
* e.g. HAVE_OPT( TCPEDIT )
*/
#define DESC(n) (tcpbridgeOptions.pOptDesc[INDEX_OPT_## n])
#define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n)))
#define OPT_ARG(n) (DESC(n).optArg.argString)
#define STATE_OPT(n) (DESC(n).fOptState & OPTST_SET_MASK)
#define COUNT_OPT(n) (DESC(n).optOccCt)
#define ISSEL_OPT(n) (SELECTED_OPT(&DESC(n)))
#define ISUNUSED_OPT(n) (UNUSED_OPT(& DESC(n)))
#define ENABLED_OPT(n) (! DISABLED_OPT(& DESC(n)))
#define STACKCT_OPT(n) (((tArgList*)(DESC(n).optCookie))->useCt)
#define STACKLST_OPT(n) (((tArgList*)(DESC(n).optCookie))->apzArgs)
#define CLEAR_OPT(n) STMTS( \
DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \
if ( (DESC(n).fOptState & OPTST_INITENABLED) == 0) \
DESC(n).fOptState |= OPTST_DISABLED; \
DESC(n).optCookie = NULL )
/* * * * * *
*
* Interface defines for specific options.
*/
#define VALUE_OPT_PORTMAP 'r'
#define VALUE_OPT_SEED 's'
#define OPT_VALUE_SEED (DESC(SEED).optArg.argInt)
#define VALUE_OPT_PNAT 'N'
#define VALUE_OPT_SRCIPMAP 'S'
#define VALUE_OPT_DSTIPMAP 'D'
#ifdef HAVE_CACHEFILE_SUPPORT
#define VALUE_OPT_ENDPOINTS 'e'
#endif /* HAVE_CACHEFILE_SUPPORT */
#define VALUE_OPT_SKIPBROADCAST 'b'
#define VALUE_OPT_FIXCSUM 'C'
#define VALUE_OPT_MTU 'm'
#define OPT_VALUE_MTU (DESC(MTU).optArg.argInt)
#define VALUE_OPT_MTU_TRUNC 10
#define VALUE_OPT_EFCS 'E'
#define VALUE_OPT_TTL 12
#define VALUE_OPT_TOS 13
#define OPT_VALUE_TOS (DESC(TOS).optArg.argInt)
#define VALUE_OPT_TCLASS 14
#define OPT_VALUE_TCLASS (DESC(TCLASS).optArg.argInt)
#define VALUE_OPT_FLOWLABEL 15
#define OPT_VALUE_FLOWLABEL (DESC(FLOWLABEL).optArg.argInt)
#define VALUE_OPT_FIXLEN 'F'
#define VALUE_OPT_SKIPL2BROADCAST 17
#define VALUE_OPT_DLT 18
#define VALUE_OPT_ENET_DMAC 19
#define VALUE_OPT_ENET_SMAC 20
#define VALUE_OPT_ENET_VLAN 21
#define VALUE_OPT_ENET_VLAN_TAG 22
#define OPT_VALUE_ENET_VLAN_TAG (DESC(ENET_VLAN_TAG).optArg.argInt)
#define VALUE_OPT_ENET_VLAN_CFI 23
#define OPT_VALUE_ENET_VLAN_CFI (DESC(ENET_VLAN_CFI).optArg.argInt)
#define VALUE_OPT_ENET_VLAN_PRI 24
#define OPT_VALUE_ENET_VLAN_PRI (DESC(ENET_VLAN_PRI).optArg.argInt)
#define VALUE_OPT_HDLC_CONTROL 25
#define OPT_VALUE_HDLC_CONTROL (DESC(HDLC_CONTROL).optArg.argInt)
#define VALUE_OPT_HDLC_ADDRESS 26
#define OPT_VALUE_HDLC_ADDRESS (DESC(HDLC_ADDRESS).optArg.argInt)
#define VALUE_OPT_USER_DLT 27
#define OPT_VALUE_USER_DLT (DESC(USER_DLT).optArg.argInt)
#define VALUE_OPT_USER_DLINK 28
#ifdef DEBUG
#define VALUE_OPT_DBUG 'd'
#define OPT_VALUE_DBUG (DESC(DBUG).optArg.argInt)
#endif /* DEBUG */
#define VALUE_OPT_INTF1 'i'
#define VALUE_OPT_INTF2 'I'
#define VALUE_OPT_UNIDIR 'u'
#ifdef ENABLE_PCAP_FINDALLDEVS
#define VALUE_OPT_LISTNICS 129
#endif /* ENABLE_PCAP_FINDALLDEVS */
#define VALUE_OPT_LIMIT 'L'
#define OPT_VALUE_LIMIT (DESC(LIMIT).optArg.argInt)
#define VALUE_OPT_MAC 'M'
#define VALUE_OPT_INCLUDE 'x'
#define VALUE_OPT_EXCLUDE 'X'
#define VALUE_OPT_PID 'P'
#ifdef ENABLE_VERBOSE
#define VALUE_OPT_VERBOSE 'v'
#define SET_OPT_VERBOSE STMTS( \
DESC(VERBOSE).optActualIndex = 39; \
DESC(VERBOSE).optActualValue = VALUE_OPT_VERBOSE; \
DESC(VERBOSE).fOptState &= OPTST_PERSISTENT_MASK; \
DESC(VERBOSE).fOptState |= OPTST_SET )
#endif /* ENABLE_VERBOSE */
#ifdef ENABLE_VERBOSE
#define VALUE_OPT_DECODE 'A'
#endif /* ENABLE_VERBOSE */
#define VALUE_OPT_VERSION 'V'
#define VALUE_OPT_LESS_HELP 'h'
#define VALUE_OPT_HELP 'H'
#define VALUE_OPT_MORE_HELP '!'
#define VALUE_OPT_SAVE_OPTS INDEX_OPT_SAVE_OPTS
#define VALUE_OPT_LOAD_OPTS INDEX_OPT_LOAD_OPTS
#define SET_OPT_SAVE_OPTS(a) STMTS( \
DESC(SAVE_OPTS).fOptState &= OPTST_PERSISTENT_MASK; \
DESC(SAVE_OPTS).fOptState |= OPTST_SET; \
DESC(SAVE_OPTS).optArg.argString = (char const*)(a) )
/*
* Interface defines not associated with particular options
*/
#define ERRSKIP_OPTERR STMTS( tcpbridgeOptions.fOptSet &= ~OPTPROC_ERRSTOP )
#define ERRSTOP_OPTERR STMTS( tcpbridgeOptions.fOptSet |= OPTPROC_ERRSTOP )
#define RESTART_OPT(n) STMTS( \
tcpbridgeOptions.curOptIdx = (n); \
tcpbridgeOptions.pzCurOpt = NULL )
#define START_OPT RESTART_OPT(1)
#define USAGE(c) (*tcpbridgeOptions.pUsageProc)( &tcpbridgeOptions, c )
/* extracted from /usr/local/share/autogen/opthead.tpl near line 409 */
/* * * * * *
*
* Declare the tcpbridge option descriptor.
*/
#ifdef __cplusplus
extern "C" {
#endif
extern tOptions tcpbridgeOptions;
#if defined(ENABLE_NLS)
# ifndef _
# include <stdio.h>
static inline char* aoGetsText( char const* pz ) {
if (pz == NULL) return NULL;
return (char*)gettext( pz );
}
# define _(s) aoGetsText(s)
# endif /* _() */
# define OPT_NO_XLAT_CFG_NAMES STMTS(tcpbridgeOptions.fOptSet |= \
OPTPROC_NXLAT_OPT_CFG;)
# define OPT_NO_XLAT_OPT_NAMES STMTS(tcpbridgeOptions.fOptSet |= \
OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;)
# define OPT_XLAT_CFG_NAMES STMTS(tcpbridgeOptions.fOptSet &= \
~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);)
# define OPT_XLAT_OPT_NAMES STMTS(tcpbridgeOptions.fOptSet &= \
~OPTPROC_NXLAT_OPT;)
#else /* ENABLE_NLS */
# define OPT_NO_XLAT_CFG_NAMES
# define OPT_NO_XLAT_OPT_NAMES
# define OPT_XLAT_CFG_NAMES
# define OPT_XLAT_OPT_NAMES
# ifndef _
# define _(_s) _s
# endif
#endif /* ENABLE_NLS */
#ifdef __cplusplus
}
#endif
#endif /* AUTOOPTS_TCPBRIDGE_OPTS_H_GUARD */
/* tcpbridge_opts.h ends here */

36
src/tcpedit/Makefile.am Normal file
View File

@@ -0,0 +1,36 @@
# $Id: Makefile.am 1630 2007-02-03 04:23:14Z aturner $
#SUBDIRS = plugins
noinst_LIBRARIES = libtcpedit.a
BUILT_SOURCES = tcpedit_stub.h
libtcpedit_a_SOURCES = tcpedit.c parse_args.c edit_packet.c \
portmap.c dlt.c checksum.c
manpages: tcpedit.1
tcpedit.1: tcpedit_stub.def
@AUTOGEN@ -T agman1.tpl --base-name tcpedit tcpedit_stub.def
tcpedit.c: tcpedit_stub.h
# Get AutoOpts search path
#opts_list=`find plugins -type d -not -regex ".*\.svn.*" -not -regex ".*\.deps.*" -exec echo -n "-L {} " \;`
tcpedit_stub.h: tcpedit_opts.def tcpedit_stub.def $(srcdir)/plugins/dlt_stub.def
@AUTOGEN@ $(opts_list) tcpedit_stub.def
AM_CFLAGS = -I.. -I../common -I../.. @LDNETINC@ $(LIBOPTS_CFLAGS) $(LNAV_CFLAGS)
noinst_HEADERS = tcpedit.h edit_packet.h portmap.h \
tcpedit_stub.h parse_args.h dlt.h checksum.h tcpedit-int.h
MOSTLYCLEANFILES = *~
MAINTAINERCLEANFILES = Makefile.in tcpedit_stub.h tcpedit.1
EXTRA_DIST = tcpedit_stub.def tcpedit_opts.def
include $(srcdir)/plugins/Makefile.am

Some files were not shown because too many files have changed in this diff Show More