(十三)Packet socket 和 sockaddr_ll
描述
本文简单描述了数据链路层的socket使用的两种方法
正文
Linux下有两种方式接收数据链路层的数据包:
(1)原始的方法,即创建一个类型为SOCK_PACKET的socket,该方法很普遍,但是缺乏灵活性;
(2)最新的方法,引入了帧过滤功能和性能上的提升,即创建一个指定协议簇为 PF_PACKET的socket,这需要root权限(类似于创建一个raw socket),并且socket的第三个参数必须指定一个以太网帧类型(Ethernet frame type);
使用第二种方法时,socket的第二个参数可以被设置为SOCK_DGRAM,主要区别是当指定SOCK_DGRAM时,获取的数据包是去掉了数据链路层的头(link-layer header),当指定SOCK_RAW时,获取的数据包是一个完整的数据链路层数据包; SOCK_PACKET只返返回完整的数据链路层数据包,示例,接收完整的数据链路层数据包,可以这样写:
- fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL)); /* older systems */
或者
- fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); /* newer systems */
这样将会接收到数据链路层所有协议帧;
如果我们只需要IPv4帧,可以这样写:
- fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); /* new systems */
或者
- fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP)); /* older systems */
其它数据链路层类型定义的常量参数有 ETH_P_ARP 和 ETH_P_IPV6;
指定协议(protocol)为ETH_P_XXX即告诉数据链路层我只接收该类型的帧(frame),socket会自动过滤。如果数据链路支持混杂模式(promiscuous mode),可以设置socket可选参数PACKET_ADD_MEMBERSHIP选项,使用packet_mreq结构体指定一个以太网接口和混杂模式行为(PACKET_MR_PROMISC)。
接下来详解 数据链路层的头信息结构体 sockaddr_ll :
点击(此处)折叠或打开
- #include <sys/socket.h>
- #include <linux/if_packet.h>
- #include <net/ethernet.h> /* the L2 protocols */
- packet_socket = socket(AF_PACKET, int socket_type, int protocol);
数据链路层的头信息通常定义在 sockaddr_ll 的结构体中,protocol是按照网络字节顺序(network byte order),大部分定义在头文件中,设置协议时,例如 htons(ETH_P_ALL)来接收所有的数据包;
如果要获取从指定以太网接口卡上的数据包时,在 struct sockaddr_ll中指定网络接口卡,绑定(bind)数据包到该interface上。只有sll_protocol和 sll_ifindex这两个地址字段是用来bind的。
- struct sockaddr_ll {
- unsigned short sll_family; /* Always AF_PACKET */
- unsigned short sll_protocol; /* Physical-layer protocol */
- int sll_ifindex; /* Interface number */
- unsigned short sll_hatype; /* ARP hardware type */
- unsigned char sll_pkttype; /* Packet type */
- unsigned char sll_halen; /* Length of address */
- unsigned char sll_addr[8]; /* Physical-layer address */
- };
sll_protocol : 标准以太网协议类型,按网络字节顺序。定义在中。
sll_ifindex: interface索引,0 匹配所有的网络接口卡;
sll_hatype: ARP 硬件地址类型(hardware address type) 定义在中,常用 ARPHRD_ETHER
sll_pkttype: 包含了packet类型。
PACK_HOST 包地址为本地主机地址。
PACK_BROADCAST 物理层广播包。
PACK_MULTICAST 发送到物理层多播地址的包。
PACK_OTHERHOST 发往其它在混杂模式下被设备捕获的主机的包。
PACK_OUTGOING 本地回环包;
sll_addr 和 ssl_halen 包含了物理层地址和其长度;
当发送数据包时,指定 sll_family, sll_addr, sll_halen, sll_ifindex, sll_protocol 就足够了。其它字段设置为0; sll_hatype和 sll_pkttype是在接收数据包时使用的; 如果要bind, 只需要使用 sll_protocol和 sll_ifindex;
(十三)Packet socket 和 sockaddr_ll的更多相关文章
- linux Packet socket (1)简单介绍
本文主要来自于linux自带的man packet手冊: http://man7.org/linux/man-pages/man7/packet.7.html 平时常常使用的INET套接字提供的是7层 ...
- Python高手之路【十三】socket网络编程
什么是客户/服务器架构? 什么是客户/服务器架构?不同的人有不同的答案.这要看你问的是什么人,以及指的是软件系统还是硬件系统了.但是,有一点是共通的:服务器是一个软件或硬件,用于提供客户需要的&quo ...
- Python基础笔记系列十三:socket网络编程
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!!使用python编写一个简易的服务端程序和客户端程序,启动服务端和客户端(监 ...
- 计算机网络(十三),Socket编程实现TCP和UDP
十三.Socket编程实现TCP和UDP 1.TCP (1)TCPServer.java类 package com.interview.javabasic.socket; import com.int ...
- python网络编程-socket编程
一.服务端和客户端 BS架构 (腾讯通软件:server+client) CS架构 (web网站) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 二.OSI七层 ...
- 项目总结22:Java UDP Socket数据的发送和接收
项目总结22:Java UDP Socket数据的发送和接收 1-先上demo 客户端(发送数据) package com.hs.pretest.udp; import java.io.IOExcep ...
- Socket 网络通信
Socket 网络通信 1.OSI (Open System Interconnect Reference Model)(开放系统互联参考模型) 从下低到高 :物理层.数据链路层.网络层.传输层.会话 ...
- Socket INADDR_ANY详解
转载:http://hi.baidu.com/zorro_knight/item/37af9e8c9dc71253e73d1924 linux下的socket INADDR_ANY表示的是一个服务器上 ...
- Java Socket编程之UDP
UDP编程: 将要传输的数据定义成数据包(Datagram),在数据报中指明所要到达的Socket(主机地址和端口号),然后再将数据报发送出去. 相关操作类: DatagramPacket ...
随机推荐
- 《玩转D语言系列》一、通过四个版本的 Hello Word 初识D语言
对于D语言,相信很多朋友还没听说过,因为它还不够流行,跟出自名门的一些语言比起来也没有名气,不过这并不影响我对它的偏爱,我就是这样的一种人,我喜欢的女孩子一定是知己型,而不会因为她外表,出身,学历,工 ...
- Redis客户端连接池
使用场景 对于一些大对象,或者初始化过程较长的可复用的对象,我们如果每次都new对象出来,那么意味着会耗费大量的时间. 我们可以将这些对象缓存起来,当接口调用完毕后,不是销毁对象,当下次使用的时候,直 ...
- python基础入门一(语法基础)
作为自己正式接触并应用的第一门编程语言,在Alex和武sir两位大王的要求下,开始了写博客总结的日子.学习编程语言是很有趣的一件事情,但有2点请一定要谨记:1.做人靠自己,码代码也必须靠自己.能不能成 ...
- Java:通过反射复制父类字段到子类。
有些时候需要建立子类继承于父类,尤其是java里面很多类是用mybatis generator生成的.通过父类构造子类,好像很麻烦,要逐个字段进行赋值(反正我没有找到其他好办法). 想到用反射复制的方 ...
- linux内核的makefile.txt讲解
linux内核的linux-3.6.5\Documentation\kbuild\makefiles.txt Linux Kernel Makefiles This document describe ...
- 【小梅哥FPGA进阶学习之旅】基于Altera FPGA 的DDR2+千兆以太网电路设计
DDR2电路设计 在高速大数据的应用中,高速大容量缓存是必不可少的硬件.当前在FPGA系统中使用较为广泛的高速大容量存储器有经典速度较低的单数据速率的SDRAM存储器,以及速度较高的双速率DDR.DD ...
- 教你轻松计算AOE网关键路径(转)
原文链接:http://blog.csdn.net/wang379275614/article/details/13990163 本次结合系统分析师-运筹方法-网络规划技术-关键路径章节,对原文链接描 ...
- Volley全方位解析,带你从源码的角度彻底理解
Volley 是 Google 推出的轻量级 Android 异步网络请求框架和图片加载框架.在 Google I/O 2013 大会上发布.其适用场景是数据量小,通信频繁的网络操作. 主要特点: ( ...
- Java当中的反射
1:反射的概念 反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自 ...
- [原]ComFriendlyWaitMtaThreadProc
c++代码(大体逻辑没问题,细节需要确认) DWORD __stdcall *ComFriendlyWaitMtaThreadProc(LPVOID lpThreadParameter) { CoIn ...