Linux网络编程——原始套接字实例:MAC 头部报文分析
通过《Linux网络编程——原始套接字编程》得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢?
链路层封包格式
MAC 头部(有线局域网)
注意:CRC、PAD 在组包时可以忽略
链路层数据包的其中一种情况:
unsigned char msg[] = {
//--------------组MAC--------14------
0xb8, 0x88, 0xe3, 0xe1, 0x10, 0xe6, // dst_mac: b8:88:e3:e1:10:e6
0xc8, 0x9c, 0xdc, 0xb7, 0x0f, 0x19, // src_mac: c8:9c:dc:b7:0f:19
0x08, 0x00, // 类型:0x0800 IP协议
// …… ……
// …… ……
};
接收的链路层数据包,并对其进行简单分析:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ether.h> int main(int argc,char *argv[])
{
int i = ;
unsigned char buf[] = "";
int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
while()
{
unsigned char src_mac[] = "";
unsigned char dst_mac[] = "";
//获取链路层的数据帧
recvfrom(sock_raw_fd, buf, sizeof(buf),,NULL,NULL);
//从buf里提取目的mac、源mac
sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", buf[], buf[], buf[], buf[], buf[], buf[]);
sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", buf[], buf[], buf[], buf[], buf[], buf[]);
//判断是否为IP数据包
if(buf[]==0x08 && buf[]==0x00)
{
printf("______________IP数据报_______________\n");
printf("MAC:%s >> %s\n",src_mac,dst_mac);
}//判断是否为ARP数据包
else if(buf[]==0x08 && buf[]==0x06)
{
printf("______________ARP数据报_______________\n");
printf("MAC:%s >> %s\n",src_mac,dst_mac);
}//判断是否为RARP数据包
else if(buf[]==0x80 && buf[]==0x35)
{
printf("______________RARP数据报_______________\n");
printf("MAC:%s>>%s\n",src_mac,dst_mac);
}
}
return ;
}
记得以管理者权限运行程序:
每个报文头部都有一个相应的结构体,通过这些结构体对报文进行相应的组包或拆包会方便很多。
ubuntu 12.04 中描述网络协议结构的文件如下:
以太网头部(所需要头文件:#include <net/ethernet.h>):
上面的例子,改为用结构体实现,如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#include <net/ethernet.h> // 以太网头部 头文件
#include <netinet/ip.h> // ip头部 头文件
// #include <net/if_arp.h> // arp头部 头文件 int main(int argc,char *argv[])
{
int i = ;
unsigned char buf[] = "";
int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
while()
{
unsigned char src_mac[] = "";
unsigned char dst_mac[] = "";
//获取链路层的数据帧
recvfrom(sock_raw_fd, buf, sizeof(buf),,NULL,NULL); //从数据中提取mac首部信息(14个字节)
struct ether_header *ethdr = NULL;
ethdr = (struct ether_header *)buf; //从buf里提取目的mac、源mac
sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", ethdr->ether_dhost[], ethdr->ether_dhost[],ethdr->ether_dhost[],ethdr->ether_dhost[],ethdr->ether_dhost[],ethdr->ether_dhost[]);
sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", ethdr->ether_shost[], ethdr->ether_shost[],ethdr->ether_shost[],ethdr->ether_shost[],ethdr->ether_shost[],ethdr->ether_shost[]); //判断是否为IP数据包
if( 0x0800 == ntohs(ethdr->ether_type) )
{
printf("______________IP数据报_______________\n");
printf("MAC:%s >> %s\n",src_mac,dst_mac); }//0x0806为ARP数据包, 0x8035为RARP数据包
else if( 0x0806 == ntohs(ethdr->ether_type) || 0x8035 == ntohs(ethdr->ether_type) )
{
printf("______________ARP数据报_______________\n");
printf("MAC:%s >> %s\n",src_mac,dst_mac);
} }
return ;
}
转自:http://blog.csdn.net/tennysonsky/article/details/44751997
Linux网络编程——原始套接字实例:MAC 头部报文分析的更多相关文章
- Linux网络编程——原始套接字编程
原始套接字编程和之前的 UDP 编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据.区别在于,原始套接字可以自行组装数据包(伪装本地 IP,本地 MAC),可以接收本机网卡上所有 ...
- Linux网络编程——原始套接字能干什么?
通常情况下程序员接所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的 Socket,针对于面向连接的TCP 服务应用: (2)数据报式套接字(SOCK ...
- LINUX 网络编程 原始套接字
一 原始套接字 原始套接字(SOCK_RAW)是一种不同于SOCK_STREAM.SOCK_DGRAM的套接字,它实现于系统核心.然而,原始套接字能做什么呢?首先来说,普通的套接字无法处理ICMP.I ...
- UNIX网络编程——原始套接字(dos攻击)
原始套接字(SOCK_RAW).应用原始套接字,我们可以编写出由TCP和UDP套接字不能够实现的功能. 注意原始套接字只能够由有 root权限的人创建. 可以参考前面的博客<<UNIX网络 ...
- UNIX网络编程——原始套接字的魔力【续】
如何从链路层直接发送数据帧 上一篇里面提到的是从链路层"收发"数据,该篇是从链路层发送数据帧. 上一节我们主要研究了如何从链路层直接接收数据帧,可以通过bind函数来将原始套接字绑 ...
- UNIX网络编程——原始套接字的魔力【上】
基于原始套接字编程 在开发面向连接的TCP和面向无连接的UDP程序时,我们所关心的核心问题在于数据收发层面,数据的传输特性由TCP或UDP来保证: 也就是说,对于TCP或UDP的程序开发,焦点在Dat ...
- UNIX网络编程——原始套接字SOCK_RAW
实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包都是由系统提供的协议栈实现, ...
- UNIX网络编程——原始套接字的魔力【下】
可以接收链路层MAC帧的原始套接字 前面我们介绍过了通过原始套接字socket(AF_INET, SOCK_RAW, protocol)我们可以直接实现自行构造整个IP报文,然后对其收发.提醒一点,在 ...
- Linux网络编程之套接字基础
1.套接字的基本结构 struct sockaddr 这个结构用来存储套接字地址. 数据定义: struct sockaddr { unsigned short sa_family; /* addre ...
随机推荐
- CISP/CISA 每日一题 20
CISSP 每日一题(答) What methods can be used to protectmobile devices such as a smartphone? Encryption,GPS ...
- linux 命令之 apt-get
apt-get 是一个下载安装软件包的简单命令行接口 使用方法: apt-get [OPTIONS] [COMMANDS] [PACKAGE_NAMES] OPTIONS: -h 帮助信息 -q 输出 ...
- Python 极简教程(九)元组 tuple
元组(tuple)是 Python 中的一种序列.和列表类似,但是元组不可变. 也就是说元组一旦声明后,值就不能再改变.我们先来看看元组的样式: >>> t = () # 空元组 & ...
- C#调用第三方ocx控件 (winform /aspx)
C#调用第三方ocx控件 1..net环境在工具箱上点右键,选择自定义工具箱,然后选择你需要的COM或者OCX控件就可以了. 2.在自定义工具箱中加入相应的控件,设置id,在客户端脚本中直接引用它 ...
- postman--基本使用1
本文转自:http://blog.csdn.net/five3/article/details/53021084 HTTP的接口测试工具有很多,可以进行http请求的方式也有很多,但是可以直接拿来就用 ...
- WebApi自定义返回类型和命名空间实现
1.自定义ContentNegotiator /// <summary> /// 返回json的ContentNegotiator /// </summary> public ...
- Altium Designer的pcb上添加文字说明
- PHP 分布式集群中session共享问题以及session有效期的设置
https://blog.csdn.net/m_nanle_xiaobudiu/article/details/81177698
- 22、DMA驱动程序框架
一.使用DMA的优点及DMA支持的请求源(请求源是启动DMA传输的事件,可以认为是触发.它可以是软件,也可以是中断,或者外部事件) 1.DMA优点是其进行数据传输时不需要CPU的干涉,可以大大提高CP ...
- 【例题3-1 UVA - 272 】TEX Quotes
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 大水题. 用一个int记录遇到的是左括号还是右括号. [错的次数] 在这里输入错的次数 [反思] 在这里输入反思 [代码] #inc ...