定义:
#include "/usr/include/sys/socket. h"
#include "/usr/includ/sys/if_packet. h"
packet_socket = socket(PF_PACKET, socket_type, protocol);
描述:
packet socket用于从设备驱动层接收或发送原始数据包, 可用于用户在物理层以上构建自己的通信协议.
socket_type 可为:SOCK_RAW或SOCK_DGRAM.
其中SOCK_RAW可用于发送原始数据包, 此时可自定义数据链路层头部; SOCK_DGRAM可用于在数据链路层以上构建包. 结构sockaddr_ll中会用到链路层头部信息. 协议为IEEE 802. 3 协议号的网络序列. 所有到达的属于已定义物理层协议的包先通过packet socket到达已在内核实现的链路层协议处理层.
仅有特权进程或有CAP_NET_RAW属性的进程才能打开packet套接口.
如果用SOCK_RAW, 则数据包将直接通过设备驱动程序不加任何改变地发送出去. 这就要求用户程序必须了解物理层头部结构, 并适当地构建包, 此时地址解析将用到标准sockaddr_ll结构. SOCK_RAW很象用于2. 0版核心老的SOCK_PACKET, 但他们并不完全一致.
SOCK_DGRAM建立在更高层. 在接受包时, 物理头将在到达用户前被去掉; 而在发包时, 物理头部将在发送前被自动添加.
默认地所有的包都从packet socket层接收. 当仅接收从特定界面来的包时将使用bind来绑定由sockaddr_ll地址结构指定的接口.
为发送SOCK_RAW包, 用户必须提供空间并构建包括物理头部在内的完整的数据包. 此包将不加任何改变地加入网卡驱动程序发送队列, 而网卡将由目的地址确认. 对于SOCK_DGRAM包, 其头部将在包被加入发送队列前由系统根据地址结构(sockaddr_ll)信息自动填写.
地址结构:
sockaddr_ll为设备无关的物理层地址结构.
struct sockaddr_ll
{
unsigned short sll_family; /* 总填 AF_PACKET */
unsigned short sll_protocol;/* 网络序列的物理层协议号 */
int sll_ifindex; /* 接口编号 */
unsigned short sll_hatype; /* 头部类型 */
unsigned char sll_pkttype; /* 包类型 */
unsigned char sll_halen; /* 地址长度 */
unsigned char sll_addr[8]; /* 物理地址 */
};
sll_protocol为在sys/if_ether. h中定义的标准以太协议好的网络序列.
sll_pkttype为包类型. 可用的有:
PACKET_HOST类型用于本机地址的包;
PACKET_BROADCAST类型用于物理广播;
PACKET_MULTICAST类型用于物理组播;
PACKET_OTHERHOST用于在网卡混杂模式下从别的主机通信上接收包;
PACKET_OUTGOING类型用于从本机packet socket发出的包.
sll_halen和sll_addr为物理地址及其长度.
组播和混杂模式的支持:
Linux2. 2支持一种建立在packet socket上的新方法来配置组播和混杂模式. 它调用setsockopt来工作, 其工作建立在SOL_PACKET packet socket之上, 其选项为PACKET_ADD_MEMBERSHIP或PACKET_DROP_MEMBERSHIP. 底层结构为:
struct packet_mreq
{
intmr_ifindex; /* 接口编号 */
unsigned shortmr_type; /* mreq 类型 */
unsigned shortmr_alen; /* 地址长度 */
unsigned charmr_address[8]; /* 物理地址 */
};
mr_interfac包含接口索引, 它指出了谁将要被改变.
mr_type有:
PACKET_MR_MULTICAST用于绑定套接口和由mr_address指定的物理组播地址;
PACKET_MR_PROMISC 用于激活混杂模式以接受所有网络包;
PACKET_DROP_MEMBERSHIP用于撤销绑订或重置.
输入输出控制:
输入输出控制可调用ioct:
ioctl(tcp_socket, ioctl_type, value_ptr);
SIOCGSTAMP 返回一个标准timeval结构, 则在须精确时间记录时很有用.
FIOCSETOWN 和 SIOCSPGRP 用于在进程异步通信结束时发送SIGIO信号, 其参数为pid_t类型.
FIOCGETOWN 和 SIOCGPGRP 用于得到当前接收到SIGIO信号的进程组, 当没有设置时返回0, 参数类型为pid_t.
出错处理:
无出错处理机制.
兼容性:
Linux 2. 0仅支持SOCK_RAW, 它使用老的结构:
struct sockaddr_pkt
{
unsigned short spkt_family;
unsigned char spkt_device[14];
unsigned short spkt_protocol;
};
spkt_family包含设备类型.
spkt_protocol为IEEE 802. 3标准协议.
spkt_device为设备名, 如"eth0";
出错类型:
ENETDOWN 接口未工作.
ENOTCONN 没有接口地址.
ENODEV 未知的设备或接口名.
EMSGSIZE 包太大.
ENOBUFS 没有足够的内存来存放接收的包.
EFAULT 错误的内存地址.
EINVAL 参数错.
ENXIO 接口地址包含不合法接口索引.
EPERM 无打开packet socket接口权用户.
EADDRNOTAVAIL 未知组播地址. oup address passed.
ENOENT 未接收到包.
分享到:
相关推荐
本资源“PF_PACKET.rar”聚焦于PF_PACKET接口在Linux下的应用,以及如何使用vc_PF_PACKET进行链路层的数据收发。让我们深入探讨这个主题。 首先,PF_PACKET是Linux内核提供的一种原始套接字协议家族,它允许应用...
**Packet套接字**是一种特殊的网络编程接口,主要用于在MAC层(数据链路层)上收发原始数据帧。这种套接字允许应用程序直接利用网络驱动程序进行数据包的发送和接收,从而绕过了传统的网络协议栈。 在Linux系统中,...
1. **数据包捕获(Packet Capture)**:PF_RING 允许应用程序以极高的速度捕获网络上的数据包,这得益于其优化的内核驱动和用户空间库。它能够绕过传统的网络堆栈,直接访问网络接口,减少延迟并提高吞吐量。 2. **...
在PF_RING中,数据包的旅程从网络接口开始,通过硬件加速路径到达内核,然后被PF_RING驱动捕获,最后传递给用户空间的应用程序。这个过程涉及到了硬件、内核模块和用户空间接口的交互。 5. **Packet Clustering** ...
`raw_sock`编程主要指通过原始套接字(Raw Socket)直接与网络接口卡(NIC)进行数据交互的技术。这种技术允许程序员绕过TCP/IP协议栈,直接在链路层发送或接收数据包。在Linux环境下,这种操作通常用于网络嗅探器、...
Linux中的sock_raw原始套接字编程是网络编程中一种高级技术,主要用于获取网络接口层的原始数据包,包括IP、ARP、ICMP等协议的数据。它允许程序员绕过操作系统网络堆栈的部分处理,直接访问底层的数据包,这对于网络...
- 更新了API,提供了更多灵活的编程接口。 - 改进了对虚拟化环境的支持,如VMware和KVM。 - 修复了一些已知的bug,增强了系统的稳定性和可靠性。 4. **离线安装步骤** - 首先,确保你的系统满足PF_RING的硬件和...
- **PF_PACKET**:表示我们将使用原始套接字来与链路层进行通信。 - **type**:可以选择`SOCK_RAW`或`SOCK_DGRAM`。这两种类型的具体区别在于: - `SOCK_RAW`:这种类型的套接字会将完整的数据帧(包括MAC头部)...
WinPcap是一个开源工具包,用于在网络层捕获和注入数据包,支持多种编程语言。使用WinPcap可以直接构建并发送以太网帧,绕过IP和UDP协议栈。 - **构造广播包**: 发送消息时,将目的MAC地址设为全F (FF:FF:FF:FF:FF:...
1. **Raw Packet Sockets**: 这是一种高级网络编程接口,允许直接访问网络驱动程序,绕过操作系统内核的协议栈。使用raw sockets可以构造任意协议头,实现自定义的网络通信协议。 2. **Packet Socket API**: 包括`...
- `PF_PACKET`:底层包访问。 - **type** 参数指定套接字类型,如 `SOCK_STREAM`(面向连接的服务)或 `SOCK_DGRAM`(无连接的服务)。 - **protocol** 参数通常设置为 `0`,表示使用默认协议。 ##### 4.3 绑定一...
Windows Socket(WinSock)是Microsoft为Windows操作系统提供的网络编程接口,它基于Berkeley Socket进行扩展,增加了异步函数和符合Windows消息驱动的网络事件异步选择机制。WinSock DLL是实现这一接口的关键,16位...
创建原始套接字的函数`socket()`的参数包括协议族(PF_PACKET)、套接字类型(SOCK_RAW)和协议类别(如ETH_P_IP、ETH_P_ARP或ETH_P_ALL)。例如: ```c int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_...
在Linux环境下,网络通信往往涉及各种协议和编程接口。本话题主要关注的是使用RAW SOCKET来接收和解析LLDP(Link Layer Discovery Protocol)报文。LLDP是一种网络邻接发现协议,用于交换设备间关于自身身份和能力的...
Packet socket允许程序直接访问网络设备驱动程序,提供了一种低级别的网络编程接口,对于需要精细控制网络通信的应用非常有用。 在使用packet socket进行多播通信时,需要了解以下关键点: 1. 创建packet socket:...
- 根据协议号,IP层会查找已注册的传输层接口,并将数据包传递给对应的传输层协议软件进行进一步处理,例如解封装数据包并执行相应的协议操作。 理解这些基础知识对进行网络编程至关重要,它们涵盖了从创建套接字...
`cpp-PFRING` 是一个基于C++的高级接口,它利用了PF_RING库,这是一个专为高性能数据包处理设计的Linux内核模块和用户空间框架。这个框架允许开发者构建能够处理网络数据包的高效应用,尤其适用于网络安全、深度包...
在Linux中,数据捕获通常通过socket编程接口实现。当数据帧到达网卡时,会触发硬件中断,CPU响应中断并调用网卡的中断处理程序。数据帧通过DMA(Direct Memory Access)传输到内核,然后经过一系列内核操作,通过sys...
在Linux系统中,进行网络编程通常是在应用层利用socket接口来收发数据,这使得程序员无需关心底层的数据包结构,因为网络协议栈会自动处理这些细节。然而,有些情况下,我们可能需要深入到数据链路层,直接接收来自...
2. 使用socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)) 创建的原始套接字,用来捕获以太网数据帧。 3. socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)) 是过时的方法,不...