Programming with pcap编程参考资料

合集下载

c语言参考书

c语言参考书

c语言参考书
C语言是一门重要的编程语言,有很多优秀的参考书籍可以帮助学习者更好地掌握它。

以下是一些推荐的C语言参考书籍:
1. 《C Primer Plus》(第6版):这是一本非常经典的C语言入门教材,详细介绍了C语言的基础知识和编程技巧,并通过大量实例让读者更好地掌握如何应用这些知识进行程序设计。

此外,书中还涵盖了C99标准和C11标准的新特性,让读者了解最新的C语言开发技术。

2. 《The C Programming Language》(第2版):这本书是由C语言的创始人Dennis M. Ritchie和著名计算机科学家Brian W. Kernighan合作编写的,是一本经典的C语言教材。

书中详细介绍了C语言的基础知识和编程技巧,并通过大量实例让读者更好地掌握如何应用这些知识进行程序设计。

此外,书中还介绍了C语言标准库函数和系统调用等内容。

3. 《手把手教你学C语言》:这本书主要针对学习C语言的初学者,即使完全没有编程基础,也能够通过阅读本书快速掌握C语言的核心知识。

4. 《C和指针》:这本书通过讲述指针来让初学者更好地理解C语言。

5. 《C专家编程》:这本书的特色诙谐幽默,把C上升到一个更高的层次,更容易让初学者接纳。

6. 《C标准库》:这本书是一本圣经,全面阐释了函数的应用,是程序员必备的参考书籍。

7. 《计算机算法设计与分析(第3版)》:这本书是学习数据结构和算法的进阶教材,为后面进阶做了铺垫。

此外,《C陷阱与缺陷》、《计算机算法设计与分析(第3版)》也是不错的参考书。

总之,学习C语言需要多读多实践,只有不断地练习才能更好地掌握它。

基于libcap、winpcap的网络编程

基于libcap、winpcap的网络编程

第五章基于libpcap的网络编程技术5. 1常见的包捕获机制简介包捕获就是利用以太网的介质共享的特性,通过将网络适配器设置为混杂模式的方法,接收到所有网络上的以太网帧。

包捕获的机制大致可以分为两类:一类是由操作系统内核提供的捕获机制。

另一类是由应用软件或系统开发包捕获驱动程序提供的捕获机制。

常见的包捕获机制如表5-1所示。

其中最主要的是下列4种:BPF ( Berkeley Packet Filter )DLPI ( Data Link Provider In terface )NIT ( Network In terface Tap ) SOCK-PACKET 类型套接口。

BPF由基于BSD的Unix系统内核所实现。

DLPI是Solaris (和其他System V UNIX ) 系统的内嵌子系统。

NIT是SUN OS4 系统的一部分,但在Solaris /SUN OS5 中被DLPI 所取代。

Linux核心则实现了SOCK-PACKET 的包捕获机制。

从性能上看,BPF比DLPI 和NIT 好得多,SOCK-PACKET 最弱。

表5-1常用的包捕获机制由于现在很多局域网为NT网,其网络传输方式大多采用以太网标准,所以涉及的编程也是在Windows 环境下实现的。

Windows 操作系统没有提供包捕获机制,只提供了数量很少并且功能有限的API调用。

在Windows 环境下由于其自身的封装性,很难对其底层进行编程。

本章将对BSD系列的libpcap进行深入地介绍。

5.2 Libpcap 与 BPF(1) libpcap 概述libpcap(Packet Capturelibrary),即数据包捕获函数库。

该库提供的 C 函数接口可用于捕获经过网络接口 (只要经过该接口,目标地址不一定为本机)的数据包。

它是由洛仑兹 伯克利试验室的研究人员 Steven McCanne 和Van Jacobson 于1993 年在Usenix'93 会议上正式提出的一种用于 Unix 内核数据包过滤体制。

programming and problem solving with c++ 中文版

programming and problem solving with c++ 中文版

《Programming and Problem Solving with C++》(中文版《C++程序设计教程》)是一本由美国作家Bjarne Stroustrup所著的教材。

以下是这本书的主要内容:
1.程序设计的基本元素:数据类型、控制结构和变量等基本概念,以及如何
使用它们来编写程序。

2.函数和程序结构:介绍如何使用函数来组织程序,包括函数的定义、声明
和调用,以及如何处理函数参数和返回值。

3.面向对象编程:介绍如何使用类和对象来组织程序,包括类的定义、对象
的创建和使用,以及如何使用继承和多态等面向对象编程技术。

4.泛型编程:介绍如何使用模板来编写泛型程序,包括模板函数的定义和使
用,以及如何使用标准模板库(STL)中的容器和算法等。

5.异常处理:介绍如何使用异常处理技术来处理程序中的错误和异常情况,
包括异常的抛出、捕获和处理。

6.文件和流:介绍如何使用文件和流来读写数据,包括文件的打开、读取、
写入和关闭等操作。

7.高级主题:介绍一些高级主题,包括多线程编程、网络编程和并发编程等。

总的来说,这本书是一本全面介绍C++编程语言的教材,适合初学者和有一定经验的程序员阅读。

SharpPcap开发全攻略(英文版)【范本模板】

SharpPcap开发全攻略(英文版)【范本模板】

CONTENTSIntroduction (2)Background (2)About SharpPcap (3)Packet。

Net architecture and usage (4)SharpPcap tutorial: A step by step guide to using SharpPcap (6)Obtaining the device list (Example 1 in the source package) (6)Opening an adapter and capturing packets (Example 3 in the source package) (8)Capturing packets without the event handler (Example 4 in the source package) (10)Filtering the traffic (Example 5 in the source package) (11)Interpreting the packets (Example 6 in the source package) (12)Handling offline dump files (Example 8 in the source package) (14)Sending packets (Example 9 in the source package) (17)Gathering statistics on the network traffic - WinPcap only (Example 11 in the source package) (21)References (23)History (23)Eg: (24)[A 。

NET sniffer application written with SharpPcap]IntroductionPacket capturing (or packet sniffing)is the process of collecting all packets of data that pass through a given network interface. Capturing network packets in our applications is a powerful capability which lets us write network monitoring, packet analyzers and security tools. The libpcap library for UNIX based systems and WinPcap for Windows are the most widely used packet capture drivers that provide API for low—level network monitoring. Among the applications that use libpcap/WinPcap as its packet capture subsystem are the famous tcpdump and Wireshark.In this article, we will introduce the SharpPcap。

计算机科学与技术专业编程考试复习资料推荐

计算机科学与技术专业编程考试复习资料推荐

计算机科学与技术专业编程考试复习资料推荐计算机科学与技术专业的编程考试对学生来说是一项重要的挑战。

为了帮助同学们更好地备考,本文将推荐一些优质的复习资料,希望能够为大家提供一些参考和指导。

一、教材推荐1.《C++ Primer》《C++ Primer》是一本经典的C++教材,适合初学者和有一定基础的同学。

该书全面介绍了C++的语法和常用编程技巧,并通过大量的实例帮助读者理解和掌握知识点。

同时,书中还包含了一些编程练习题,有助于巩固所学知识。

2.《算法导论》《算法导论》是一本经典的算法教材,对计算机科学与技术专业的学生来说是必备的参考书之一。

该书详细介绍了各种常用算法和数据结构,并提供了相应的伪代码和实现方法。

通过学习和理解这本书,同学们可以提高编程能力和解决实际问题的能力。

二、在线资源推荐1.leetcodeleetcode是一个在线的编程练习平台,提供了大量的编程题目和解答。

同学们可以通过在leetcode上刷题,提高自己的编程能力和解题思维。

该平台还提供了讨论区,可以与其他同学交流和分享解题思路,对于理解和掌握算法和数据结构非常有帮助。

2.GitHubGitHub是一个全球最大的代码托管平台,上面有大量的开源项目和代码资源。

同学们可以通过搜索相关的项目,找到一些优秀的编程示例和实践经验。

此外,GitHub还提供了版本控制和协作开发的功能,可以帮助同学们更好地组织和管理自己的代码。

三、学习方法推荐1.理论与实践相结合编程考试不仅要求掌握理论知识,还需要具备实际操作的能力。

因此,同学们在复习过程中应该注重理论与实践相结合。

可以通过编写小项目或者参与开源项目的方式,将所学知识应用到实际中,提高自己的编程能力。

2.刷题与总结编程考试中经常会涉及到一些经典的算法和数据结构。

同学们可以通过刷题的方式来加深对这些知识点的理解和掌握。

在刷题的过程中,可以总结一些常用的解题思路和技巧,形成自己的思维导图或者笔记,方便复习和回顾。

pcap 物理层协议

pcap 物理层协议

pcap 物理层协议
物理层协议是计算机网络中最重要的一部分,它是数据从源端发送到目的端的基础。

最常用的物理层协议是 Packet Capture(PCAP)协议,它可以捕捉从网络中传输的数据报文,并将其存储在收集的数据帧中。

PCAP是一种硬件协议,又是一种软件协议,它的功能包括在网络中联系网络层协议和应用层协议,使它们可以合作传输数据,以及提供对网络状态的观察和检测,帮助管理网络性能。

特别是,PCAP 议主要用来提供有效的数据帧捕获,分析和保存网络流量。

PCAP议可以提供有效的数据帧捕获,分析和保存网络流量,因此在许多网络安全相关的应用中,它被广泛使用。

在实际的网络流量记录中,它的主要作用是监控网络流量并发现安全漏洞,从而帮助网络管理人员决定未来的网络安全策略。

PCAP 也被用来确定网络中恶意流量的来源和特征,比如网络攻击、蠕虫病毒和木马等。

此外,PCAP议还可以用来监控网络性能,包括网络的吞吐量、延迟和可用性。

它可以帮助系统管理员识别网络问题的根源,并进行诊断和调优,以提高网络性能。

总之,PCAP理层协议是计算机网络的重要组成部分,它的功能包括数据帧捕获、网络安全监测和网络性能监控等。

它的出现,大大改善了网络管理者的工作效率,为网络安全带来了广泛的应用。

- 1 -。

pcap使用手册

pcap使用手册

让我们从看看这篇文章写给谁开始。

显而易见的,需要一些C语言基础知识,除非你只想了解基本的理论。

你不必是一个编码专家,因为这个领域只有经验丰富的程序员涉足,而我将尽可能详细的描述这些概念。

另外,考虑到这是有关一个包嗅探器的,所以对网络基础知识的理解是有帮助的。

所有在此出现的代码示例都已在FreeBSD 4.3平台上测试通过。

开始:pcap应用程序的格式我们所要理解的第一件事情是一个基于pcap的嗅探器程序的总体布局。

流程如下:1.我们从决定用哪一个接口进行嗅探开始。

在Linux中,这可能是eth0,而在BSD系统中则可能是xl1等等。

我们也可以用一个字符串来定义这个设备,或者采用pcap提供的接口名来工作。

2.初始化pcap。

在这里我们要告诉pcap对什么设备进行嗅探。

假如愿意的话,我们还可以嗅探多个设备。

怎样区分它们呢?使用文件句柄。

就像打开一个文件进行读写一样,必须命名我们的嗅探“会话”,以此使它们各自区别开来。

3.如果我们只想嗅探特定的传输(如TCP/IP包,发往端口23的包等等),我们必须创建一个规则集合,编译并且使用它。

这个过程分为三个相互紧密关联的阶段。

规则集合被置于一个字符串内,并且被转换成能被pcap读的格式(因此编译它)。

编译实际上就是在我们的程序里调用一个不被外部程序使用的函数。

接下来我们要告诉pcap使用它来过滤出我们想要的那一个会话。

4.最后,我们告诉pcap进入它的主体执行循环。

在这个阶段内pcap一直工作到它接收了所有我们想要的包为止。

每当它收到一个包就调用另一个已经定义好的函数,这个函数可以做我们想要的任何工作,它可以剖析所部获的包并给用户打印出结果,它可以将结果保存为一个文件,或者什么也不作。

5.在嗅探到所需的数据后,我们要关闭会话并结束。

这是实际上一个很简单的过程。

一共五个步骤,其中一个(第3个)是可选的。

我们为什么不看一看是怎样实现每一个步骤呢?设置设备这是很简单的。

WinPcap编程

WinPcap编程

W i n P c a p编程WinPcap是一个开源的、运行于Win32平台下的体系结构,它的主要功能是进行数据包捕获和网络分析。

它允许应用程序通过协议栈捕获和传输网络数据包,也包括内核级别的数据包过滤、网络静态引擎和支持远程数据包捕获等有用的功能。

WinPcap由两部分组成:1. 驱动程序: 扩展操作系统功能提供低层次的网络访问2. 动态链接库:运行在Win32平台上的应用程序可以非常方便地访问网络低层次的数据。

Ethereal是大名鼎鼎的捕获数据包专业软件,它的运行是在WinPcap的支持之下的,如果没有安装WinPcap,Ethereal也无法正常捕获数据包。

在正式WinPcap编程之前,要配置运行环境。

Win32 平台下WinPcap应用程序需要以下四个动态链接库才能正常运行:这四个动态链接库在WinPcap驱动程序里。

如果应用程序出现一下提示,那就是没有安装驱动程序的原因了。

被过滤广告也可以不安装WinPcap驱动程序。

但是需要把上面提到的四个动态链接库文件拷贝到系统分区/WINDOWS/system32目录下或者接下来配置编程环境。

如果一个源文件使用了WinPcap提供的库函数,那么就需要在该文件开始的位置添加包含文件(或者在引用的文件中),即#include “”也许会出现下面的错误:fatal error C1083: 无法打开包括文件:“”: No such file or directory这个错误表明找不到文件这个头文件在驱动程序安装完成后也是没有的,它是开发包里面的一个头文件所以,如果要运行程序还需要到官方网站上去下载WinPcap SDK―WpdPackWinPcap SDk里面包含库文件,头文件,文档文件和一些例子。

解压缩后把Include目录添加到IDE的包含文件中(Tools->Option->Directory; VS 2003/2005 工具->选项->项目和解决方案/项目->VC++目录)error LNK2019: 无法解析的外部符号_pcap_findalldevs_ex,该符号在函数XXX 中被引用如果发生上面的错误就表明缺少库文件,需要添加到工程中Project->Settings->Link->Object/library modules; VS 2003/2005 项目->添加现有项->所有文件)error C2065: “PCAP_SRC_IF_STRING”: 未声明的标识符error C3861: “pcap_findalldevs_ex”: 找不到标识符error C2065: “PCAP_OPENFLAG_PROMISCUOUS”: 未声明的标识符error C3861: “pcap_open”: 找不到标识符新的版本里WinPcap支持远程数据包获取,发生上面的错误很有可能是新的版本导致不兼容的问题,所以还应当添加一个头文件,即#include ""如果还有问题,可以到WinPcaP官方网站上找FAQ。

算法学习的学习资料和书籍推荐

算法学习的学习资料和书籍推荐

算法学习的学习资料和书籍推荐在计算机科学领域,算法是一门核心的学科,它涉及到问题的解决方法和步骤的设计。

无论是计算机程序员、数据科学家还是人工智能工程师,都需要掌握良好的算法学习能力。

下面将推荐一些优秀的学习资料和书籍,帮助读者更好地学习算法。

首先,推荐《算法导论》这本经典教材。

这本书由Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest和Clifford Stein合著,是算法学习的必读之作。

它详细介绍了各种常见的算法和数据结构,包括排序、图算法、动态规划等。

书中的内容深入浅出,适合初学者和有一定算法基础的读者。

除了《算法导论》,还有一本非常受欢迎的书籍是《算法(第4版)》。

这本书由Robert Sedgewick和Kevin Wayne合著,以Java语言为基础,介绍了各种经典的算法和数据结构。

除了文字说明,书中还包含了大量的示例代码和图示,帮助读者更好地理解算法的实现和应用。

对于想要深入学习特定领域算法的读者,推荐《机器学习》一书。

这本书由Tom Mitchell编写,是机器学习领域的经典教材。

它涵盖了机器学习的基本概念、算法和应用,包括监督学习、无监督学习、强化学习等。

书中的内容丰富而全面,适合有一定编程和数学基础的读者。

此外,对于对图算法感兴趣的读者,推荐《算法之美》一书。

这本书由吴军编写,以生动的语言讲述了图算法在现实生活中的应用。

作者通过讲述一些有趣的故事,引出了图算法的原理和应用,使得读者更容易理解和记忆。

这本书不仅适合计算机科学专业的学生,也适合对算法感兴趣的非专业读者。

除了书籍,还有一些优秀的在线学习资源可供选择。

例如,Coursera平台上的《算法设计与分析》课程,由斯坦福大学的Tim Roughgarden教授讲授。

这门课程系统地介绍了算法设计和分析的基本原理和技巧,包括贪心算法、动态规划、网络流等。

通过这门课程,学习者可以深入了解算法的设计思想和应用场景。

python竞赛教材

python竞赛教材

python竞赛教材
关于Python竞赛的教材,可以参考以下几本:
《Python算法竞赛入门经典》(胡凡、曾磊著,人民邮电出版社):这本书主要介绍Python算法竞赛的基本知识和常用算法,包括排序、搜索、动态规划等,同时提供了大量优秀的代码实例和练习题。

《Python竞赛编程入门经典》(高桥征义著,人民邮电出版社):这本书主要介绍Python竞赛编程的基本知识和编程技巧,包括数据类型、控制结构、函数、文件操作等,同时提供了大量的练习题和解答。

《Python算法竞赛实战指南》(刘汝佳著,人民邮电出版社):这本书是一本经典的算法竞赛入门教材,主要介绍算法竞赛的基本知识和常用算法,同时提供了大量的代码实例和练习题。

《Python编程之美》(王斌著,电子工业出版社):这本书主要介绍Python编程的高级技巧和实用经验,包括并行编程、网络编程、GUI编程等,同时提供了大量的代码实例和练习题。

《Python编程从入门到实践》(Eric Matthes 著,机械工业出版社):这本书适合初学者,介绍了Python的基础知识和编程思维,同时通过一些实际案例帮助读者提高编程技能。

以上书籍可以作为Python竞赛的参考教材,帮助你深入了解Python语言及其应用。

游戏辅助教程

游戏辅助教程
参考链接: /subject/1088168/ 深入: 《Windows 核心编程》 作者:Jeffrey Richter / Christophe Nasarre 译者:葛子昂 / 周靖 / 廖敏 出版社:清华大学出版社
10
参考链接: /subject/3235659/ 《Win32 多线程程序设计》 作者:Jim Beveridge / Robert Wiener 译者:侯捷 出版社:华中科技大学出版社
参考链接: /subject/3117898/ 算法和数据结构 入门: 《数据结构(C 语言版)》 作者:吴伟民 / 严蔚敏 出版社:清华大学出版社
6
参考链接: /subject/2024655/ 深入: 《算法导论》 作者:[美] Thomas H.Cormen / Charles E.Leiserson / Ronald L.Rivest 译者:潘金贵 等 出版社:机械工业出版社
游戏辅助工具开发教程

历史将会记录在这个社会转型期,却发现,最大的悲哀不是坏人的嚣张,而是好人的过度沉 默。--马丁.路德.金 仅仅因为偶尔说几句实话,我的独立站点和托管博客就不断被国家防火墙和运营商封锁,当 看到李刚事件的结局时,我对这个体系的改变彻底心死了:好人被欺负 ,坏人得嚣张。赶快 攒钱,赶快移民才是正道,否则你的孩子会和你一样仍旧是奴隶。 现在回顾过去写的教程,发现很多不足,所以这次的整理不是简单的 Copy。如果说原来我 试图写成百科全书式的大全教程,那么这次的更新更像一次核心部分的提取(the good part): 把专业的事交给专业的人和书籍去做。 本教程使用的编程语言有 C 和 python,如果你是其他编程语言系的,仍旧可以通过学习到 原理部分。在讲解的过程中,我尽量把原理和实现分开。 本教程分为以下几个部分: 上篇:前置知识及书籍介绍 中篇:辅助类型及工具介绍 下篇:游戏辅助编程实践 附录:深入学习指导 限于本人技术的局限性,教程中如有错误在所难免,因此,请读者朋友“择其善者而从之, 其不善者而改之”。下面开始我们的辅助工具编程学习吧。

WINPCAP开发(一):零基础入门

WINPCAP开发(一):零基础入门

unsigned char ucPhysicalAddr
{
pcap_if_t *alldevs;
pcap_if_t *d;
pcap_t *fp = NULL;
int i = 0;
char errbuf[PCAP_ERRBUF_SIZE], *p;
/* 这个 API 用来获得网卡的列表 */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
tion) - 1; j > 0; j--)
for(int j = strlen(d->descrip
{
== 0x20)
if (d->description[j]
[j] = '';
d->description
else
break;
}
\n", szIPSelf, d->description);
printf("[*] Bind on %s %s ...
pcap_if_t *d;//用于遍历网卡链表的临时变量
int i = 0;//记录网卡个数
char errbuf[PCAP_ERRBUF_SIZE];//存储错误信息
char szGateIPAddr[16];//网卡对应网关地址
char *p;//网卡名词
char szIPAddr[16];//网卡对应 IP
{
pen the adapter. \ WinPcap\n", d->name);
fprintf(stderr,"\nUnable to o %s is not supported by

go语言的参考文献

go语言的参考文献

go语言的参考文献Go语言(也被称为Golang)是由Google开发的一种静态强类型,编译型的编程语言。

它以其简洁、高效、并发安全以及内置并发特性而广受开发者的喜爱。

作为一门相对年轻的编程语言,Go语言的学习和应用需要依靠一些权威的参考文献来帮助开发者深入理解和掌握这门语言。

本文将介绍一些Go语言的参考文献,这些书籍和资料将对Go语言的学习和应用有着极大的帮助。

1. 《The Go Programming Language》《The Go Programming Language》(中文名《Go语言编程》)是由Go语言的创建者Rob Pike和Ken Thompson共同编写的权威教材。

本书详细介绍了Go语言的语法、并发模型、I/O操作、网络编程等方面的知识,并提供了丰富的示例代码。

它不仅适合Go语言的初学者,也适用于有经验的开发者。

这本书深入浅出地解释了Go语言的设计思想和最佳实践。

2. 《Go语言圣经》《Go语言圣经》是Go语言开源社区提供的一本权威指南,由Alan A. A. Donovan和Brian W. Kernighan合著。

这本书以简明扼要的方式介绍了Go语言的核心概念和基本语法,并通过丰富的示例代码帮助开发者快速上手。

它还涵盖了Go语言的包管理、测试和调试等高级主题,是一本系统而全面的学习Go语言的参考书籍。

3. 《Go in Action》《Go in Action》是由William Kennedy等人合著的一本实战型书籍。

它通过大量实际应用案例,讲解了如何使用Go语言开发高效、可维护的应用程序。

这本书不仅涵盖了Go语言的基础知识,还介绍了如何构建Web应用、编写并发代码以及处理错误等实用技术。

对于已经掌握Go语言基础知识的开发者来说,这本书能够帮助他们更好地理解和应用Go语言的高级特性。

4. 《Concurrency in Go》《Concurrency in Go》是Katherine Cox-Buday编写的一本专注于并发编程的书籍。

Winpcap 程序员手册

Winpcap 程序员手册

Winpcap 程序员手册Packet.dll API :程序员手册1.介绍PACKET.DLL 是一个动态连接库。

它提供了一套面向用户的包捕捉驱动程序接口。

这套动态连接库实现了一系列的函数,使得用户与驱动器的通信变得更为简便。

这避免了在用户程序中使用系统调用或控制输入/输出设备驱动模式(IOCTLs)。

而且,这套动态连接库还提供了网络适配器控制函数,对网络上捕获的数据包进行读取/写入函数,在驱动器中设置缓冲区和过滤器函数等等。

目前,有两个版本的PACKET.DLL:第一个适用于Windows95/98,第二个版本适用于WindowsNT/2000。

这两个版本都提供了相同的应用程序接口,这使得编写独立于系统的包捕获应用程序变得更为容易。

通过调用PACKET.DLL API,同一个应用程序可不做任何修改就在Windows95/98/NT/2000环境下运行。

本手册讲述了如何使用PACKET.DLL,并详细讲解这套动态连接库提供的函数和数据结构。

2.PACKET.DLL 与wpcap的比较如果你要编写一个没有特别/底层要求的包捕获应用程序,推荐使用wpcap.dll的函数,这是包捕获库(libpcap)的一个扩展集,而不是本章节中讨论的API。

在wpcap.dll中也使用PACKET.DLL的函数。

但wpcap.dll提供了一个更强大、更直接、更简洁的编程环境。

通过使用wpcap.dll,诸如捕获包、创建一个包过滤器或者在文件中保存dump 这些操作会被准确地执行并使程序变得直观。

Libpcap能够为一个标准的网络监听或嗅探程序提供所有需要的函数。

而且,利用libpcap编写的程序也能在UNIX平台上进行编译,这是因为这个库的Win32版本和UNIX版本有很好的兼容性。

然而,PACKET.DLL API 有一些libpcap没有提供的可能的操作。

Libpcap相对简单,它提供了一套系统无关的捕获包的API。

pcap原理

pcap原理

pcap原理
PCAP(Packet Capture)是一种捕获代理网络数据包的技术。

它是网络编程中非常重要的一种技术,可以帮助开发人员分析、调试和研究网络协议。

PCAP通常用于抓取广域网(WAN)或局域网(LAN)上的数据包,以帮助管理员、开发人员进行网络故障诊断与分析。

在计算机网络中,数据是以数据包的形式传输的。

当一个计算机从网络上接收到数据包时,它会把数据包交给操作系统,而操作系统需要将数据包传递给应用程序,以便进行二次开发或分析。

在这个过程中,操作系统需要使用一定的技术来对数据包进行捕获和处理。

而PCAP就是一种捕获和处理网络数据包的技术。

PCAP技术基于操作系统内核层的实现来进行数据包的捕获。

在Linux中,内核中实现了一个Packet Socket接口,用于向用户程序提供数据包的捕获和发送功能。

Windows中则是使用WinPcap或Npcap等第三方库来实现PCAP功能。

PCAP技术可以捕获数据包并进行多种操作,例如过滤、深度分析等。

通过PCAP 技术,开发人员或管理员可以对数据包进行捕获和分析,以便定位网络问题,或优化网络性能。

常见的分析工具包括Wireshark等,通过这些工具的分析,可以有效的发现网络问题,快速解决故障。

总的来说,PCAP技术已经成为了一个网络开发人员不可缺少的技能。

掌握PCAP 技术可以帮助开发人员更全面地了解网络协议和通信机制,定位网络问题,提高
网络性能,同时可以提升工作效率和开发速度。

代码审计教材

代码审计教材

代码审计教材
代码审计教材有很多,以下是一些经典的教材:
1. 《C Primer Plus(第6版)》- Stephen Prata:这本书是一个非常受欢迎的代码审计教材,适合零基础的学习者。

它以简洁明了的方式介绍了C语言的基础知识和编程技巧。

2. 《代码审计:从基础到实践》:这本书系统地介绍了代码审计的基础知识和实践技巧,包括代码审计的方法、工具、技巧和案例等。

3. 《黑客攻防技术宝典:Web实战篇》:这本书主要介绍了Web应用程序的攻防技术,包括常见的漏洞和攻击手段,以及如何进行有效的代码审计和防御。

4. 《代码审计实战教程》:这本书是一本较为系统的代码审计教材,从基础到实践,详细介绍了代码审计的流程、方法、技巧和工具等。

5. 《软件安全与代码审计》:这本书主要介绍了软件安全和代码审计的基本概念、方法和技术,包括常见的安全漏洞和攻击手段,以及如何进行有效的代码审计和防御。

以上教材可以作为参考,选择一本适合自己的教材,结合实际项目进行学习与实践,才能更好地掌握代码审计的技术。

并行计算入门书籍

并行计算入门书籍

并行计算入门书籍以下是一些介绍并行计算的入门书籍:1.《并行计算导论》(Introduction to Parallel Computing),第2版,作者:Ananth Grama, George Karypis, Vipin Kumar, Anshul Gupta。

这是一本经典的并行计算教材,详细介绍了并行计算的基本概念、并行编程模型、并行算法和应用等内容。

2.《并行程序设计导论》(Introduction to Parallel Programming),作者:Peter Pacheco。

这本书讲解了基于共享内存和分布式内存的并行编程技术,包括线程、锁、条件变量、信号量、MPI等,并提供了大量的编程示例和练习题。

3.《并行计算——体系结构、编程和算法》(Parallel Computing: Architecture, Programming and Algorithms),作者:David Culler, Jaswinder Pal Singh, Anoop Gupta。

这本书介绍了并行计算的各种体系结构、编程模型和算法,包括多处理器、多核处理器、GPU、分布式内存等,并提供了很多实际案例和编程示例。

4.《高性能计算:现代化方法》(High Performance Computing: Modern Systems and Practices),作者:Thomas Sterling, Matthew Anderson, Maciej Brodowicz, et al.。

这本书涵盖了高性能计算的各个方面,包括硬件体系结构、编程模型、优化技术、应用案例等,是一本全面介绍高性能计算的参考书籍。

5.《CUDA并行程序设计》(CUDA by Example: An Introduction to General-Purpose GPU Programming),作者:Jason Sanders, Edward Kandrot。

循序渐进学习使用WINPCAP二

循序渐进学习使用WINPCAP二

循序渐进学习使用WINPCAP(二)在第一章中演示了如何获得已存在适配器的静态信息。

实际上WinPcap同样也提供其他的高级信息,特别是pcap_findalldevs()这个函数返回的每个pcap_if结构体都同样包含一个pcap_addr结构的列表,它包含:一个地址列表,一个掩码列表,一个广播地址列表和一个目的地址列表。

下面的例子通过一个ifprint()函数打印出了pcap_if结构的的所有字段信息,该程序对每一个pcap_findalldevs()所返回的pcap_if结构循环调用ifprint()来显示详细的字段信息。

#include "pcap.h"void ifprint(pcap_if_t *d);int main(){pcap_if_t *alldevs, *d;char errbuf[PCAP_ERRBUF_SIZE+1];if (pcap_findalldevs(&alldevs, errbuf) == -1) /* 获得网卡的列表*/{fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);return -1;}/* 循环调用ifprint() 来显示pcap_if结构的信息*/for(d=alldevs;d;d=d->next){ ifprint(d); }return 1 ;}/* Print all the available information on the given interface */void ifprint(pcap_if_t *d){ IN_ADDR sinaddr;//IPv4地址pcap_addr_t *a;printf("%s\n",d->name); /* Name */if (d->description) /* Description */printf("\tDescription: %s\n",d->description);/* Loopback Address*/printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");/* IP addresses */for(a=d->addresses;a;a=a->next){printf("\tAddress Family:#%d\n",a->addr->sa_family);/*关于sockaddr_in 结构请参考程序后注释*/switch(a->addr->sa_family){case AF_INET:printf("\tAddress Family Name: AF_INET\n");//打印网络地址类型if (a->addr)//打印IP地址{sinaddr=((struct sockaddr_in *)a->addr)->sin_addr;printf("\tAddress:%d.%d.%d.%d\n",sinaddr.S_un.S_un_b.s_b1,sinaddr.S_un.S_un_b.s_b2,sinaddr.S_un.S_un_b.s_b3,sinaddr.S_un.S_un_b.s_b4);}if (a->netmask)//打印掩码{ sinaddr=((struct sockaddr_in *)a->netmask)->sin_addr;printf("\tNetmask:%s\n",inet_ntoa(sinaddr));}if (a->broadaddr)//打印广播地址{ sinaddr=((struct sockaddr_in *)a->broadaddr)->sin_addr;printf("\tBroadcast Address:%s\n",inet_ntoa(sinaddr));}if (a->dstaddr)//目的地址{ sinaddr=((struct sockaddr_in *)a->dstaddr)->sin_addr;printf("\tDestination Address:%s\n",inet_ntoa(sinaddr));}break;default:printf("\tAddress Family Name:Unknown\n"); break;} /*end of switch*/} /*end of for */printf("\n");} /*void ifprint(pcap_if_t *d) *//*以下是关于地址的定义,详细说明参考下面这本书:罗军舟,黎波涛,杨明等.TCP/IP协议及网络编程技术,北京:清华大学出版社,2004:183-187 ISBN:7-302-09558-2//通用地址结构,不直接使用,务必采用(struct sockaddr_in *)强制转换struct sockaddr{unsigned short sa_family;char sa_data[14];};//INET协议族地址结构struct sockaddr_in{short sin_family;unsigned short sin_port;IN_ADDR sin_addr;char sin_zero[8];};//IPV4地址结构typedef struct in_addr {union {struct{unsigned char s_b1,s_b2,s_b3,s_b4;} S_un_b;struct {unsigned short s_w1,s_w2;} S_un_w;unsigned long S_addr;} S_un;} IN_ADDR;两个重要函数unsigened long inet_addr(const char FAR *cp);char FAR * inet_ntoa(struct in_addr in);应用举例:in_addr addr;addr.S_un.S_addr=inet_addr("192.168.0.1");//或adr.s_addr=inet_addr("192.168.0.1");printf("%s\n",inet_ntoa(addr));*/。

计算机网络网络编程课件 课件(7)

计算机网络网络编程课件  课件(7)

第六章 WinPcap编程内容提要什么是WinPcap WinPcap的结构 WinPcap编程环境配置 数据结构 WinPcap编程1.什么是WinPcap1. 什么是WinPcap?当应用程序需要访问原始数据包,即没有被操作系统 利用网络协议处理过的数据包时,socket无法满足需要, WinPcap为Win32应用程序提供这种访问方式。

WinPcap提供了以下功能捕获原始数据包,无论它是发往本机的,还是在其他设 备(共享媒介)上交互的 在数据包递交给某应用程序前,根据用户指定的规则过 滤数据包 将原始数据包通过网络发送出去 收集并统计网络流量信息1. 什么是WinPcap?基于WinPcap的典型应用网络与协议分析器 (network and protocol analyzers) 网络监视器 (network monitors) 网络流量记录器 (traffic loggers) 网络流量发生器 (traffic generators) 用户级网桥及路由 (user-level bridges and routers) 网络入侵检测系统 (network intrusion detection systems (NIDS)) 网络扫描器 (network scanners) 安全工具 (security tools)1. 什么是WinPcap?什么是WinPcap做不到的? WinPcap不能阻止、过滤或操纵同一机器上的其他应用程序的通讯:它仅仅能简单地“监 视”在网络上传输的数据包。

所以,它不能提供 以下支持:网络流量控制 服务质量调度 个人防火墙1.什么是WinPcap2. WinPcap的结构WinPcap组成WinPcap is an architecture forpacket capture and networkanalysis for the Win32 platforms.It includes a kernel-level packetfilter(NPF), a low-level dynamic接口link library (packet.dll), and ahigh-level and system-independent library (wpcap.dll).设备驱动 ---数据捕获 ---数据发送 ---可编程的过滤系统 ---监听引擎 ---……WinPcap组成--Packet.dll packet.dll(Packet DriverAPI) 提供了一个底层的API访问接口,可以直接访问网卡,为win32 平台提供了一个公共的接口。

SharpPcap开发全攻略(_中文版)

SharpPcap开发全攻略(_中文版)

SharpPcap开发全攻略(_中文版) CONTENTSIntroduction ....................................................... ........................................................................ .. (2)Background ............................................................. ........................................................................ ......... 2 AboutSharpPcap .............................................................. ................................... 错误~未定义书签。

3 architecture andusage .................................................................. ........................................ 4 SharpPcap tutorial: A step by step guide to using SharpPcap ............................. 错误~未定义书签。

6Obtaining the device list (Example 1 in the sourcepackage) .............................. 错误~未定义书签。

6 Opening an adapter and capturing packets (Example 3 in the source package) . 错误~未定义书签。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Programming with pcapTim Carstenstimcarst at yahoo dot comFurther editing and development by Guy Harrisguy at alum dot mit dot eduOk, let's begin by defining who this document is written for. Obviously, some basic knowledge of C is required, unless you only wish to know the basic theory. You do not need to be a code ninja; for the areas likely to be understood only by more experienced programmers, I'll be sure to describe concepts in greater detail. Additionally, some basic understanding of networking might help, given that this is a packet sniffer and all. All of the code examples presented here have been tested on FreeBSD 4.3 with a default kernel.Getting Started: The format of a pcap applicationThe first thing to understand is the general layout of a pcap sniffer. The flow of code is as follows:1.We begin by determining which interface we want to sniff on. In Linux this may be something like eth0, in BSD it may be xl1, etc. We can either define this device ina string, or we can ask pcap to provide us with the name of an interface that will do the job.2.Initialize pcap. This is where we actually tell pcap what device we are sniffing on. We can, if we want to, sniff on multiple devices. How do we differentiate betweenthem? Using file handles. Just like opening a file for reading or writing, we must name our sniffing "session" so we can tell it apart from other such sessions.3.In the event that we only want to sniff specific traffic (e.g.: only TCP/IP packets, only packets going to port 23, etc) we must create a rule set, "compile" it, andapply it. This is a three phase process, all of which is closely related. The rule set is kept in a string, and is converted into a format that pcap can read (hence compiling it.) The compilation is actually just done by calling a function within our program; it does not involve the use of an external application. Then we tell pcap to apply it to whichever session we wish for it to filter.4.Finally, we tell pcap to enter it's primary execution loop. In this state, pcap waits until it has received however many packets we want it to. Every time it gets a newpacket in, it calls another function that we have already defined. The function that it calls can do anything we want; it can dissect the packet and print it to the user, it can save it in a file, or it can do nothing at all.5.After our sniffing needs are satisfied, we close our session and are complete.This is actually a very simple process. Five steps total, one of which is optional (step 3, in case you were wondering.) Let's take a look at each of the steps and how to implement them.Setting the deviceThis is terribly simple. There are two techniques for setting the device that we wish to sniff on.The first is that we can simply have the user tell us. Consider the following program:#include <stdio.h>#include <pcap.h>int main(int argc, char *argv[]){char *dev = argv[1];printf("Device: %s\n", dev);return(0);}The user specifies the device by passing the name of it as the first argument to the program. Now the string "dev" holds the name of the interface that we will sniff on in a format that pcap can understand (assuming, of course, the user gave us a real interface).The other technique is equally simple. Look at this program:#include <stdio.h>#include <pcap.h>int main(int argc, char *argv[]){char *dev, errbuf[PCAP_ERRBUF_SIZE];dev = pcap_lookupdev(errbuf);if (dev == NULL) {fprintf(stderr, "Couldn't find default device: %s\n", errbuf);return(2);}printf("Device: %s\n", dev);return(0);}In this case, pcap just sets the device on its own. "But wait, Tim," you say. "What is the deal with the errbuf string?" Most of the pcap commands allow us to pass them a string as an argument. The purpose of this string? In the event that the command fails, it will populate the string with a description of the error. In this case, ifpcap_lookupdev() fails, it will store an error message in errbuf. Nifty, isn't it? And that's how we set our device.Opening the device for sniffingThe task of creating a sniffing session is really quite simple. For this, we use pcap_open_live(). The prototype of this function (from the pcap man page) is as follows: pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms,pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms,char *ebuf)The first argument is the device that we specified in the previous section. snaplen is an integer which defines the maximum number of bytes to be captured by pcap. promisc, when set to true, brings the interface into promiscuous mode (however, even if it is set to false, it is possible under specific cases for the interface to be in promiscuous mode, anyway). to_ms is the read time out in milliseconds (a value of 0 means no time out; on at least some platforms, this means that you may wait until a sufficient number of packets arrive before seeing any packets, so you should use a non-zero timeout). Lastly, ebuf is a string we can store any error messages within (as we did above with errbuf). The function returns our session handler.To demonstrate, consider this code snippet:#include <pcap.h>...pcap_t *handle;handle = pcap_open_live(somedev, BUFSIZ, 1, 1000, errbuf);if (handle == NULL) {fprintf(stderr, "Couldn't open device %s: %s\n", somedev, errbuf);return(2);}This code fragment opens the device stored in the strong "somedev", tells it to read however many bytes are specified in BUFSIZ (which is defined in pcap.h). We are telling it to put the device into promiscuous mode, to sniff until an error occurs, and if there is an error, store it in the string errbuf; it uses that string to print an error message.A note about promiscuous vs. non-promiscuous sniffing: The two techniques are very different in style. In standard, non-promiscuous sniffing, a host is sniffing only traffic that is directly related to it. Only traffic to, from, or routed through the host will be picked up by the sniffer. Promiscuous mode, on the other hand, sniffs all traffic on the wire. In a non-switched environment, this could be all network traffic. The obvious advantage to this is that it provides more packets for sniffing, which may or may not be helpful depending on the reason you are sniffing the network. However, there are regressions. Promiscuous mode sniffing is detectable; a host can test with strong reliability to determine if another host is doing promiscuous sniffing. Second, it only works in a non-switched environment (such as a hub, or a switch that is being ARP flooded). Third, on high traffic networks, the host can become quite taxed for system resources.Filtering trafficOften times our sniffer may only be interested in specific traffic. For instance, there may be times when all we want is to sniff on port 23 (telnet) in search of passwords. Or perhaps we want to highjack a file being sent over port 21 (FTP). Maybe we only want DNS traffic (port 53 UDP). Whatever the case, rarely do we just want to blindly sniff all network traffic. Enter pcap_compile() and pcap_setfilter().The process is quite simple. After we have already called pcap_open_live() and have a working sniffing session, we can apply our filter. Why not just use our own if/else if statements? Two reasons. First, pcap's filter is far more efficient, because it does it directly with the BPF filter; we eliminate numerous steps by having the BPF driver do it directly. Second, this is a lot easier :)Before applying our filter, we must "compile" it. The filter expression is kept in a regular string (char array). The syntax is documented quite well in the man page for tcpdump; I leave you to read it on your own. However, we will use simple test expressions, so perhaps you are sharp enough to figure it out from my examples.To compile the program we call pcap_compile(). The prototype defines it as:int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize,bpf_u_int32 netmask)The first argument is our session handle (pcap_t *handle in our previous example). Following that is a reference to the place we will store the compiled version of our filter. Then comes the expression itself, in regular string format. Next is an integer that decides if the expression should be "optimized" or not (0 is false, 1 is true. Standard stuff.) Finally, we must specify the net mask of the network the filter applies to. The function returns -1 on failure; all other values imply success.After the expression has been compiled, it is time to apply it. Enter pcap_setfilter(). Following our format of explaining pcap, we shall look at the pcap_setfilter() prototype:int pcap_setfilter(pcap_t *p, struct bpf_program *fp)This is very straightforward. The first argument is our session handler, the second is a reference to the compiled version of the expression (presumably the same variable as the second argument to pcap_compile()).Perhaps another code sample would help to better understand:#include <pcap.h>...pcap_t *handle; /* Session handle */char dev[] = "rl0"; /* Device to sniff on */char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */struct bpf_program fp; /* The compiled filter expression */char filter_exp[] = "port 23"; /* The filter expression */bpf_u_int32 mask; /* The netmask of our sniffing device */bpf_u_int32 net; /* The IP of our sniffing device */if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {fprintf(stderr, "Can't get netmask for device %s\n", dev);net = 0;mask = 0;}handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);if (handle == NULL) {fprintf(stderr, "Couldn't open device %s: %s\n", somedev, errbuf);if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));return(2);}if (pcap_setfilter(handle, &fp) == -1) {fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));return(2);}This program preps the sniffer to sniff all traffic coming from or going to port 23, in promiscuous mode, on the device rl0.You may notice that the previous example contains a function that we have not yet discussed. pcap_lookupnet() is a function that, given the name of a device, returns its IP and net mask. This was essential because we needed to know the net mask in order to apply the filter. This function is described in the Miscellaneous section at the end of the document.It has been my experience that this filter does not work across all operating systems. In my test environment, I found that OpenBSD 2.9 with a default kernel does support this type of filter, but FreeBSD 4.3 with a default kernel does not. Your mileage may vary.The actual sniffingAt this point we have learned how to define a device, prepare it for sniffing, and apply filters about what we should and should not sniff for. Now it is time to actually capture some packets.There are two main techniques for capturing packets. We can either capture a single packet at a time, or we can enter a loop that waits for n number of packets to be sniffed before being done. We will begin by looking at how to capture a single packet, then look at methods of using loops. For this we use pcap_next().The prototype for pcap_next() is fairly simple:u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)The first argument is our session handler. The second argument is a pointer to a structure that holds general information about the packet, specifically the time in which it was sniffed, the length of this packet, and the length of his specific portion (incase it is fragmented, for example.) pcap_next() returns a u_char pointer to the packet that is described by this structure. We'll discuss the technique for actually reading the packet itself later.Here is a simple demonstration of using pcap_next() to sniff a packet.#include <pcap.h>#include <stdio.h>int main(int argc, char *argv[]){pcap_t *handle; /* Session handle */char *dev; /* The device to sniff on */char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */struct bpf_program fp; /* The compiled filter */char filter_exp[] = "port 23"; /* The filter expression */bpf_u_int32 mask; /* Our netmask */bpf_u_int32 net; /* Our IP */struct pcap_pkthdr header; /* The header that pcap gives us */const u_char *packet; /* The actual packet *//* Define the device */dev = pcap_lookupdev(errbuf);if (dev == NULL) {fprintf(stderr, "Couldn't find default device: %s\n", errbuf);return(2);}/* Find the properties for the device */if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);net = 0;mask = 0;}/* Open the session in promiscuous mode */handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);if (handle == NULL) {fprintf(stderr, "Couldn't open device %s: %s\n", somedev, errbuf);return(2);}/* Compile and apply the filter */if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));return(2);}if (pcap_setfilter(handle, &fp) == -1) {fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));return(2);}/* Grab a packet */packet = pcap_next(handle, &header);/* Print its length */printf("Jacked a packet with length of [%d]\n", header.len);/* And close the session */pcap_close(handle);This application sniffs on whatever device is returned by pcap_lookupdev() by putting it into promiscuous mode. It finds the first packet to come across port 23 (telnet) and tells the user the size of the packet (in bytes). Again, this program includes a new call, pcap_close(), which we will discuss later (although it really is quite self explanatory).The other technique we can use is more complicated, and probably more useful. Few sniffers (if any) actually use pcap_next(). More often than not, they use pcap_loop() or pcap_dispatch() (which then themselves use pcap_loop()). To understand the use of these two functions, you must understand the idea of a callback function. Callback functions are not anything new, and are very common in many API's. The concept behind a callback function is fairly simple. Suppose I have a program that is waiting for an event of some sort. For the purpose of this example, let's pretend that my program wants a user to press a key on the keyboard. Every time they press a key, I want to call a function which then will determine that to do. The function I am utilizing is a callback function. Every time the user presses a key, my program will call the callback function. Callbacks are used in pcap, but instead of being called when a user presses a key, they are called when pcap sniffs a packet. The two functions that one can use to define their callback is pcap_loop() and pcap_dispatch(). pcap_loop() and pcap_dispatch() are very similar in their usage of callbacks. Both of them call a callback function every time a packet is sniffed that meets our filter requirements (if any filter exists, of course. If not, then all packets that are sniffed are sent to the callback.)The prototype for pcap_loop() is below:int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)The first argument is our session handle. Following that is an integer that tells pcap_loop() how many packets it should sniff for before returning (a negative value means it should sniff until an error occurs). The third argument is the name of the callback function (just its identifier, no parentheses). The last argument is useful in some applications, but many times is simply set as NULL. Suppose we have arguments of our own that we wish to send to our callback function, in addition to the arguments that pcap_loop() sends. This is where we do it. Obviously, you must typecast to a u_char pointer to ensure the results make it there correctly; as we will see later, pcap makes use of some very interesting means of passing information in the form of a u_char pointer. After we show an example of how pcap does it, it should be obvious how to do it here. If not, consult your local C reference text, as an explanation of pointers is beyond the scope of this document. pcap_dispatch() is almost identical in usage. The only difference between pcap_dispatch() and pcap_loop() is that pcap_dispatch() will only process the first batch of packets that it receives from the system, while pcap_loop() will continue processing packets or batches of packets until the count of packets runs out. For a more in depth discussion of their differences, see the pcap man page.Before we can provide an example of using pcap_loop(), we must examine the format of our callback function. We cannot arbitrarily define our callback's prototype; otherwise, pcap_loop() would not know how to use the function. So we use this format as the prototype for our callback function:void got_packet(u_char *args, const struct pcap_pkthdr *header,const u_char *packet);Let's examine this in more detail. First, you'll notice that the function has a void return type. This is logical, because pcap_loop() wouldn't know how to handle a return value anyway. The first argument corresponds to the last argument of pcap_loop(). Whatever value is passed as the last argument to pcap_loop() is passed to the first argument of our callback function every time the function is called. The second argument is the pcap header, which contains information about when the packet was sniffed, how large it is, etc. The pcap_pkthdr structure is defined in pcap.h as:struct pcap_pkthdr {struct timeval ts; /* time stamp */bpf_u_int32 caplen; /* length of portion present */bpf_u_int32 len; /* length this packet (off wire) */};These values should be fairly self explanatory. The last argument is the most interesting of them all, and the most confusing to the average novice pcap programmer. It is another pointer to a u_char, and it points to the first byte of a chunk of data containing the entire packet, as sniffed by pcap_loop().But how do you make use of this variable (named "packet" in our prototype)? A packet contains many attributes, so as you can imagine, it is not really a string, but actually a collection of structures (for instance, a TCP/IP packet would have an Ethernet header, an IP header, a TCP header, and lastly, the packet's payload). Thisu_char pointer points to the serialized version of these structures. To make any use of it, we must do some interesting typecasting.First, we must have the actual structures define before we can typecast to them. The following are the structure definitions that I use to describe a TCP/IP packet over Ethernet./* Ethernet addresses are 6 bytes */#define ETHER_ADDR_LEN 6/* Ethernet header */struct sniff_ethernet {u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */u_short ether_type; /* IP? ARP? RARP? etc */};/* IP header */struct sniff_ip {u_char ip_vhl; /* version << 4 | header length >> 2 */u_char ip_tos; /* type of service */u_short ip_len; /* total length */u_short ip_id; /* identification */u_short ip_off; /* fragment offset field */#define IP_RF 0x8000 /* reserved fragment flag */#define IP_DF 0x4000 /* dont fragment flag */#define IP_MF 0x2000 /* more fragments flag */#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */u_char ip_ttl; /* time to live */u_char ip_p; /* protocol */u_short ip_sum; /* checksum */struct in_addr ip_src,ip_dst; /* source and dest address */};#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)#define IP_V(ip) (((ip)->ip_vhl) >> 4)/* TCP header */struct sniff_tcp {u_short th_sport; /* source port */u_short th_dport; /* destination port */tcp_seq th_seq; /* sequence number */tcp_seq th_ack; /* acknowledgement number */u_char th_offx2; /* data offset, rsvd */#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)u_char th_flags;#define TH_FIN 0x01#define TH_SYN 0x02#define TH_RST 0x04#define TH_PUSH 0x08#define TH_ACK 0x10#define TH_URG 0x20#define TH_ECE 0x40#define TH_CWR 0x80#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)u_short th_win; /* window */u_short th_sum; /* checksum */u_short th_urp; /* urgent pointer */};Note: On my Slackware Linux 8 box (stock kernel 2.2.19) I found that code using the above structures would not compile. The problem, as it turns out, was in include/features.h, which implements a POSIX interface unless _BSD_SOURCE is defined. If it was not defined, then I had to use a different structure definition for the TCP header. The more universal solution, that does not prevent the code from working on FreeBSD or OpenBSD (where it had previously worked fine), is simply to do the following:#define _BSD_SOURCE 1prior to including any of your header files. This will ensure that a BSD style API is being used. Again, if you don't wish to do this, then you can simply use the alternative TCP header structure, which I've linked to here, along with some quick notes about using it.So how does all of this relate to pcap and our mysterious u_char pointer? Well, those structures define the headers that appear in the data for the packet. So how can we break it apart? Be prepared to witness one of the most practical uses of pointers (for all of those new C programmers who insist that pointers are useless, I smite you).Again, we're going to assume that we are dealing with a TCP/IP packet over Ethernet. This same technique applies to any packet; the only difference is the structure types that you actually use. So let's begin by defining the variables and compile-time definitions we will need to deconstruct the packet data./* ethernet headers are always exactly 14 bytes */#define SIZE_ETHERNET 14const struct sniff_ethernet *ethernet; /* The ethernet header */const struct sniff_ip *ip; /* The IP header */const struct sniff_tcp *tcp; /* The TCP header */const char *payload; /* Packet payload */u_int size_ip;u_int size_tcp;And now we do our magical typecasting:ethernet = (struct sniff_ethernet*)(packet);ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);size_ip = IP_HL(ip)*4;if (size_ip < 20) {printf(" * Invalid IP header length: %u bytes\n", size_ip);return;}tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);size_tcp = TH_OFF(tcp)*4;if (size_tcp < 20) {printf(" * Invalid TCP header length: %u bytes\n", size_tcp);return;}payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);How does this work? Consider the layout of the packet data in memory. The u_char pointer is really just a variable containing an address in memory. That's what a pointer is; it points to a location in memory.For the sake of simplicity, we'll say that the address this pointer is set to is the value X. Well, if our three structures are just sitting in line, the first of them (sniff_ethernet) being located in memory at the address X, then we can easily find the address of the structure after it; that address is X plus the length of the Ethernet header, which is 14, or SIZE_ETHERNET.Similarly if we have the address of that header, the address of the structure after it is the address of that header plus the length of that header. The IP header, unlike the Ethernet header, does not have a fixed length; its length is given, as a count of 4-byte words, by the header length field of the IP header. As it's a count of 4-byte words, it must be multiplied by 4 to give the size in bytes. The minimum length of that header is 20 bytes.The TCP header also has a variable length; its length is given, as a number of 4-byte words, by the "data offset" field of the TCP header, and its minimum length is also 20 bytes.。

相关文档
最新文档