以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 安全理论 』  (http://bbs.xml.org.cn/list.asp?boardid=65)
----  [原创]Winpcap学习第二天  (http://bbs.xml.org.cn/dispbbs.asp?boardid=65&rootid=&id=33471)


--  作者:binaryluo
--  发布时间:6/1/2006 9:31:00 AM

--  [原创]Winpcap学习第二天
今天在阅读Winpcap Manual的时候发现一句话:

       “This means that on shared media (like non-switched Ethernet), WinPcap will be able to capture the packets of other hosts.”

   我理解为:如果在通过没有交换功能的集线器连接的网络上,只要把网卡设置为混杂(promiscuous)模式,winpcap能够捕获到其他主机通信的数据包。如果是具有交换功能的集线器连接的网络winpcap还能管用吗?这个在后边的实习中将会进行试验。

    试验程序2:

/*
* 截获数据包的试验。先打印出所有网络适配器的列表,然后选择
* 想在哪个适配器上截获数据包。然后通过pcap_loop()函数将截获
* 的数据包传给回调函数packet_handler()处理。

* 通过该程序初步了解了使用winpcap截获数据包的步骤以及一些在
* 截获数据包时非常重要的函数和结构体。
* 2006-1-26
*/

#include <pcap.h>
#include <remote-ext.h>

/* Prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);

int main() {
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i = 0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];

/* Retrieve the devices list on the local machine */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
  fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
  exit(1);
}

/* Print the list */
for (d = alldevs; d; d = d->next)
{
  /* Print name */
  printf("%d. %s", ++ i, d->name);

  /* Print description */
  if (d->description)
  {
   printf(" (%s)\n", d->description);
  }
  else
  {
   printf(" (No description available)\n");
  }
}

if (i == 0)
{
  printf("\nNo interfaces found! Make sure Winpcap is installed.\n");
  return -1;
}

/* Select an adapter */
printf("Enter the interface number (1 - %d):", i);
scanf("%d", &inum);

if (inum < 1 || inum > i)
{
  printf("\nInterface number out of range.\n");
  /* Free the device list */
  pcap_freealldevs(alldevs);
  return -1;
}

/* Jump to the selected adapter */
for (d = alldevs, i = 0; i < inum - 1; d = d->next, ++ i);

/*Open the device */
if ((adhandle = pcap_open(d->name, /* name of the device */
  65536,         /* portion of the packet to capture */
  /* 65535 guarantees that the whole packet will be captured on all the link layers */
  PCAP_OPENFLAG_PROMISCUOUS,     /* promiscuous mode */
  1000,         /* read timeout */
  NULL,         /* authentication on the remote machine */
  errbuf         /* error buffer */
  )) == NULL)
{
   fprintf(stderr, "\nnable to open the adapter. %s is not supported by Winpcap\n", d->name);
   /* Free the devices list */
   pcap_freealldevs(alldevs);

   return -1;
}

printf("\nlistening on %s...\n", d->description);

/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* start the capture */
pcap_loop(adhandle, 0, packet_handler, NULL);

return 1;
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {
struct tm *ltime;
char timestr[16];

/* convert the timestamp to readable format */
ltime = localtime(&header->ts.tv_sec);
strftime(timestr, sizeof(timestr), "%H:%M:%S", ltime);
printf("%s, %.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
}

函数1:

pcap_t *pcap_open(const char *               source,

int                              snaplen,

int                              flags,

int                              read_timeout,

struct pcap_rmtauth *       auth,

char *                        errbuf

)

    为捕获/发送数据打开一个普通的源。pcap_open()能够替代所有的pcap_open_xxx()函数,它隐藏了不同的pcap_open_xxx()之间的差异,所以程序员不必使用不同的open函数。

source:的是包含要打开的源名称的以’\0’结尾的字符串。源名称得包含新的源规范语法(Source Specification Syntax),并且它不能为NULL。为了方便的使用源语法,请记住:(1)pcap_findalldevs_ex()返回的适配器(网卡)可以直接被pcap_open()使用;(2)万一用户想传递他自己的源字符串给pcap_open(),pcap_createsrcstr()可以创建正确的源标识。

snaplen:需要保留的数据包的长度。对每一个过滤器接收到的数据包,第一个‘snaplen’字节的内容将被保存到缓冲区,并且传递给用户程序。例如,snaplen等于100,那么仅仅每一个数据包的第一个100字节的内容被保存。简言之就是从每一个包的开头到snaplen的那段内容将被保存。

flags:保存一些由于抓包需要的标志。Winpcap定义了三种标志:

l         PCAP_OPENFLAG_PROMISCUOUS:1,它定义了适配器(网卡)是否进入混杂模式(promiscuous mode)。

l         PCAP_OPENFLAG_DATATX_UDP:2,它定义了数据传输(假如是远程抓包)是否用UDP协议来处理。

l         PCAP_OPENFLAG_NOCAPTURE_RPCAP:4,它定义了远程探测器是否捕获它自己产生的数据包。

read_timeout:以毫秒为单位。read timeout被用来设置在遇到一个数据包的时候读操作不必立即返回,而是等待一段时间,让更多的数据包到来后从OS内核一次读多个数据包。并非所有的平台都支持read timeout;在不支持read timeout的平台上它将被忽略。

auth:一个指向’struct pcap_rmtauth’的指针,保存当一个用户登录到某个远程机器上时的必要信息。假如不是远程抓包,该指针被设置为NULL。

errbuf:一个指向用户申请的缓冲区的指针,存放当该函数出错时的错误信息。

返回值是一个’pcap_t’指针,它可以作为下一步调用(例如pcap_compile()等)的参数,并且指定了一个已经打开的Winpcap会话。在遇到问题的情况下,它返回NULL并且’errbuf’变量保存了错误信息。

函数2:

int pcap_loop(  pcap_t*           p,

int                   cnt,

pcap_hander    callback,

u_char*           user

)

    收集一群数据包。pcap_loop()与pcap_dispatch()类似,但是它会一直保持读数据包的操作直到cnt包被处理或者发生了错误。当有活动的读超时(read timeout)时它并不返回。然而,对pcap_open_live()指定一个非0的读超时(read timeout),当发生超时的时候调用pcap_dispatch()来接收并处理到来的所有数据包更好。Cnt指明了返回之前要处理数据包的最大数目。如果cnt为负值,pcap_loop()将一直循环(直到发生错误才停止)。如果出错时返回-1;如果cnt用完时返回0;如果在任何包被处理前调用pcap_breakloop()来中止循环将返回-2。所以,如果程序中使用了pcap_breakloop(),必须准确的来判断返回值是-1还是-2,而不能简单的判断<0。

函数3:

hypedef void (* pcap_handler)(u_char* user,

const struct pcap_pkthdr* pkt_header,

const u_char* pkt_data)

    接收数据包的回调函数原型。当用户程序使用pcap_dispatch()或者pcap_loop(),数据包以这种回调的方法传给应用程序。用户参数是用户自己定义的包含捕获会话状态的参数,它必须跟pcap_dispatch()和pcap_loop()的参数相一致。pkt_hader是与抓包驱动有关的头。pkt_data指向包里的数据,包括协议头。

结构体1:

struct pcap_pkthdr {

      struct timeval ts;

      bpf_u_int32 caplen;

      bpf_u_int32 len;

}

ts:时间戳

cpalen:当前分组的长度

len:数据包的长度


--  作者:liang12
--  发布时间:6/6/2006 3:52:00 PM

--  
强 人 啊

--  作者:zhangsen_817
--  发布时间:8/7/2006 2:29:00 PM

--  先顶一个。
先顶一下 再欣赏!
--  作者:jiaozi1216
--  发布时间:8/10/2006 9:17:00 AM

--  
强!楼主能不能介绍一下,学习wincap后能够干什么?
--  作者:binaryluo
--  发布时间:8/15/2006 11:33:00 PM

--  
以下是引用jiaozi1216在2006-8-10 9:17:00的发言:
强!楼主能不能介绍一下,学习wincap后能够干什么?

简单地说,Winpcap可以在广播网上捕获或发送原始数据包,这样,就可以实现协议栈、网络监控等。


--  作者:sony2935
--  发布时间:12/19/2006 10:46:00 AM

--  
windows下如何安装使用Winpcap,
--  作者:yin
--  发布时间:12/19/2006 10:56:00 AM

--  
没看懂它是怎么辨别数据包的
--  作者:binaryluo
--  发布时间:12/19/2006 12:58:00 PM

--  

windows下如何安装使用Winpcap,

可以www.winpcap.org网站下载最新的Winpcap驱动安装包和开发包。安装包是个exe程序,运行就可安装,开发包解压缩后将include目录和lib目录包含到你的开发环境中即可进行开发。


--  作者:yin
--  发布时间:12/19/2006 1:03:00 PM

--  
楼主,请教个问题:我怎么才能在合法的情况下从国内的DNS服务器查看国外代理服务器的日志????
--  作者:binaryluo
--  发布时间:12/19/2006 1:12:00 PM

--  
以下是引用yin在2006-12-19 13:03:00的发言:
楼主,请教个问题:我怎么才能在合法的情况下从国内的DNS服务器查看国外代理服务器的日志????

不好意思,对你的这个问题我不是很清楚。


--  作者:yin
--  发布时间:12/19/2006 1:21:00 PM

--  
楼主,在问个问题:我有一次做局域网的时候,先是接了一台有线路由,然后接一台无线路由,然后用一台PC接那个无线
路由.我想问一下,那个无线路由到底起到了什么的作用????如果说它还是路由功能,在同一个局域网,连续接两个路由做同样的功能,不是上不了网,就是浪费资源.
如果说它是交换机的功能,那还要路由干什么,直接用交换机不就可以了.
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
2,191.406ms