copy from intranet.
This commit is contained in:
472
src/MESA_list.c
Normal file
472
src/MESA_list.c
Normal 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
68
src/MESA_list.h
Normal 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
122
src/Makefile.am
Normal 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
1258
src/Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
518
src/bridge.c
Normal file
518
src/bridge.c
Normal 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
81
src/bridge.h
Normal 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
28
src/common.h
Normal 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
34
src/common/Makefile.am
Normal 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
559
src/common/Makefile.in
Normal 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
92
src/common/abort.c
Normal 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
49
src/common/abort.h
Normal 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
379
src/common/cache.c
Normal 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
125
src/common/cache.h
Normal 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
708
src/common/cidr.c
Normal 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
83
src/common/cidr.h
Normal 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
511
src/common/dlt_names.c
Normal 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
461
src/common/dlt_names.h
Normal 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
157
src/common/err.c
Normal 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
128
src/common/err.h
Normal 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
86
src/common/fakepcap.c
Normal 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
70
src/common/fakepcap.h
Normal 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
108
src/common/fakepcapnav.c
Normal 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
69
src/common/fakepcapnav.h
Normal 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
148
src/common/fakepoll.c
Normal 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
86
src/common/fakepoll.h
Normal 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
633
src/common/get.c
Normal 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
75
src/common/get.h
Normal 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
158
src/common/interface.c
Normal 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
53
src/common/interface.h
Normal 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
218
src/common/list.c
Normal 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
58
src/common/list.h
Normal 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
167
src/common/mac.c
Normal 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
50
src/common/mac.h
Normal 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
52
src/common/pcap_dlt.h
Normal 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
79
src/common/rdtsc.c
Normal 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
125
src/common/rdtsc.h
Normal 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
960
src/common/sendpacket.c
Normal 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
101
src/common/sendpacket.h
Normal 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
116
src/common/services.c
Normal 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
50
src/common/services.h
Normal 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
4
src/common/svn_version.c
Normal 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
387
src/common/tcpdump.c
Normal 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
93
src/common/tcpdump.h
Normal 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
81
src/common/timer.c
Normal 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
260
src/common/timer.h
Normal 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
222
src/common/utils.c
Normal 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
75
src/common/utils.h
Normal 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
249
src/common/xX.c
Normal 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
66
src/common/xX.h
Normal 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
547
src/config.h.in
Normal 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
285
src/defines.h.in
Normal 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
7
src/encap_sample.cfg
Normal 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
29
src/fragroute/LICENSE
Normal 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
19
src/fragroute/Makefile.am
Normal 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
879
src/fragroute/Makefile.in
Normal 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
33
src/fragroute/README
Normal 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
68
src/fragroute/argv.c
Normal 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
15
src/fragroute/argv.h
Normal 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
1592
src/fragroute/bget.c
Normal file
File diff suppressed because it is too large
Load Diff
30
src/fragroute/bget.h
Normal file
30
src/fragroute/bget.h
Normal 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
144
src/fragroute/fragroute.c
Normal 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
69
src/fragroute/fragroute.h
Normal 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
147
src/fragroute/iputil.c
Normal 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
13
src/fragroute/iputil.h
Normal 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
187
src/fragroute/mod.c
Normal 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
27
src/fragroute/mod.h
Normal 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
97
src/fragroute/mod_delay.c
Normal 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
97
src/fragroute/mod_drop.c
Normal 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
100
src/fragroute/mod_dup.c
Normal 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
57
src/fragroute/mod_echo.c
Normal 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
196
src/fragroute/mod_ip6_opt.c
Normal 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 */
|
||||
};
|
||||
83
src/fragroute/mod_ip6_qos.c
Normal file
83
src/fragroute/mod_ip6_qos.c
Normal 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 */
|
||||
};
|
||||
137
src/fragroute/mod_ip_chaff.c
Normal file
137
src/fragroute/mod_ip_chaff.c
Normal 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
316
src/fragroute/mod_ip_frag.c
Normal 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
102
src/fragroute/mod_ip_opt.c
Normal 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 */
|
||||
};
|
||||
73
src/fragroute/mod_ip_tos.c
Normal file
73
src/fragroute/mod_ip_tos.c
Normal 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 */
|
||||
};
|
||||
79
src/fragroute/mod_ip_ttl.c
Normal file
79
src/fragroute/mod_ip_ttl.c
Normal 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
79
src/fragroute/mod_order.c
Normal 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
446
src/fragroute/mod_print.c
Normal 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 */
|
||||
};
|
||||
197
src/fragroute/mod_tcp_chaff.c
Normal file
197
src/fragroute/mod_tcp_chaff.c
Normal 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 */
|
||||
};
|
||||
98
src/fragroute/mod_tcp_opt.c
Normal file
98
src/fragroute/mod_tcp_opt.c
Normal 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
182
src/fragroute/mod_tcp_seg.c
Normal 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
312
src/fragroute/pkt.c
Normal 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
82
src/fragroute/pkt.h
Normal 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
55
src/fragroute/randutil.c
Normal 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
14
src/fragroute/randutil.h
Normal 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
715
src/send_packets.c
Normal 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
50
src/send_packets.h
Normal 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
125
src/signal_handler.c
Normal 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
51
src/signal_handler.h
Normal 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
101
src/sleep.c
Normal 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
146
src/sleep.h
Normal 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__ */
|
||||
BIN
src/suppport_lib/libMESA_prof_load.a
Normal file
BIN
src/suppport_lib/libMESA_prof_load.a
Normal file
Binary file not shown.
623
src/tcpbridge.1
Normal file
623
src/tcpbridge.1
Normal 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
266
src/tcpbridge.c
Normal 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
109
src/tcpbridge.h
Normal 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
1979
src/tcpbridge_opts.c
Normal file
File diff suppressed because it is too large
Load Diff
385
src/tcpbridge_opts.def
Normal file
385
src/tcpbridge_opts.def
Normal 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
291
src/tcpbridge_opts.h
Normal 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
36
src/tcpedit/Makefile.am
Normal 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
Reference in New Issue
Block a user