Tcpxtract是用來從網卡抓包並將其還原成文件的一個開源軟件,它的基本原理是在抓取的數據包中匹配文件的特徵頭和特徵尾。
下面對其中用的庫函數進行了學習:
void * memset(void*s,int ch,size_t n):將s指向的內存地址中的前n個字節用ch中的內容替換,並返回修改後的s。通常用於初始化新申請的變量;
#include <string.h>or#include<memory.h>
int getopt_long (int argc, char *const argv[], const char*shortopts, const struct option *longopts, int longindex) ;#include <getopt.h>
argc與argv是main函數的兩個參數,shortopts--字符數組,表示短選項(不要加-),如果需要指定該該選項一定需要參數,則可在該選項後面添加冒號,否則連着寫即可;如字符數組optstring:odb:c表示選項b一定要有參數,而o/d/c選項可以沒有參數;
option是一個結構體,又叫長選項表,它的定義如下:
struct option
{
const char* name;//該長選項的名字
int has_arg;//是否一定需要參數,有三種情況:#define no_argument 0(不需要參數) #define required_argument 1(必選參數) #define optional_argument 2(參數可選)
int *flag;//一般用NULL
int val;};//該長選項對應的短選項
option數組要求最後一個元素的內容爲{NULL,0,NULL,0};
對應上面的短選項,可以將長選項定義
struct option *longoptions {
{"open",0,NULL,'o'},
{"data",0,NULL,'d'},
{"busy",1,NULL,'b'},
{"count",0,NULL,'c'},
{NULL,0,NULL,0}
};可以看出這個長選項的作用就在於將長選項和短選項建立一一對應的關係
函數第四個參數和結構體option的第四個參數一樣,設爲NULL即可。調用時形式爲:c=getopt_long(argc,argv,optstring,longoptions,NULL )c爲選項;
調用該函數後,每個選項的參數會被存放在一個叫做optarg的全局變量中(字符指針),可以隨時使用(只保存最後一個的輸入)。
getopt系函數還會在得到選項時改變數組argv中元素的順序,有另一個相關的參數是optind,它初始值爲1,每次getopt函數執行之後,指向下一個可以作爲選項參數的argv中元素的位置,如執行下面的程序:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void
main(int argc,char **argv)
{
char c;
while((c=getopt(argc,argv,"ab:c:d"))!=-1)
{
printf("%d,%s\n",optind,argv[optind]);
switch(c)
{
case 'a':
printf("Have option -a%s\n",optarg);
break;
case 'b':
printf("Have option -b%s\n",optarg);
break;
case 'c':
printf("Have option -c%s\n",optarg);
break;
case 'd':
printf("Have option -d%s\n",optarg);
break;
}
}
for(;optind<argc;optind++)
printf("%d,%s\n",optind,argv[optind]);
}
得到的結果爲:
./a.out file1 -b file2 file3 -c file4 file5 file6
4,file3
Have option -bfile2
7,file5
Have option -cfile4
5,file1
6,file3
7,file5
8,file6
上面的分析爲:執行第一次getopt函數之後,得到b選項的參數,接着optind指向argv的第四個位置(argv的第0個位置不考慮),下一次getopt時,得到了c選項的參數,optind指向argv的第7個位置,在這個過程中optind跳過了位置1,4,7,8的printf,是因爲他們都時非選項的參數,同時optind標識下一個getopt的開始位置。循環結束後,argv數組變爲了-b file2 -c file4 file1 file3 file5 file6(沒有考慮argv[0],它爲執行文件名,這裏無影響),optind重新被設置爲5,也就時下一個getopt開始的位置(前4個參數均爲選項或者選項對應的參數,也就是分配已經完成)。
getopt_long()函數有個兄弟,getopt(),原型爲:
int getopt(int argc, char * const argv[], const char *optstring);optstring與上面的shortopts格式一樣。
char* sdup=char * strdup (const char *s),函數返回一個指向字符串s的副本的指針,由於副本另外申請了內存,對sdup的操作不會影響s指向的字符串。
void perror(const char *s):根據上一個函數出錯原因打出相應字符串,S所指向的字符串會先打印。原因是根據全局變量errno確定,因爲某些函數在出錯的時候會重新設置errorn的值,使它能對應函數出錯原因的字符串。使用該函數 的時候需要包含頭文件stdio.h與stdlib.h
這個網址有libpcap函數庫的說明,先收藏一下http://www.turbolinux.com.cn/turbo/wiki/doku.php?id=libpcap%E5%87%BD%E6%95%B0%E5%BA%93
void assert(int expression)--如果expression的結果爲false,則assert先打印一條出錯的信息,然後調用abort程序中止該進程。它的主要作用在於用來加入調試信息,可以明確出錯的地方。使用的時候需要加入頭文件assert.h
search函數,定義在search.c中,代碼如下:
srch_results_t *search(srch_node_t *tree, srchptr_list_t **srchptr_list, uint8_t *buf, size_t len)
{
srch_results_t *retval = NULL;
int i;
assert(tree != NULL);
assert(srchptr_list != NULL);
assert(buf != NULL);
for (i = 0; i < len; i++)
update_search(tree, srchptr_list, &retval, buf[i], i);
return retval;
}
暫停下---