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 ...
随机推荐
- 【2017 Multi-University Training Contest - Team 6】Classes
[链接]http://acm.hdu.edu.cn/showproblem.php?pid=6106 [题意] 给出选 A,B,C,AB,AC,BC,ABC 课程的学生,其中 AB 是 A 和 B 都 ...
- 设计模式六大原则(二):里氏替换原则(Liskov Substitution Principle)
里氏替换原则(LSP)由来: 最早是在 妖久八八 年, 由麻神理工学院得一个女士所提出来的. 定义: 1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 ...
- [NPM] Update published npm packages using np
When we want to update our package we need to do a few things: pull latest from our git remote, bump ...
- JS防止全局变量污染解决方案
1.目前出现的问题: a.随意使用全局变量,会存在冲突的风险和难以解决的问题. b.现有JS代码共享流程中的状态,参数,都是通过按钮传递,非常别扭,不易于管理. c.通过完成后的代码很难知晓业务流程, ...
- loadrunner--设置代理录制
为了解决loadrunner录制不到脚本或录制经常无响应等情况,可以选用代理录制方式,步骤如下. 打开配置好代理的浏览器,输入要录制的服务器ip,开始操作,录制完成后点击Shutdown
- [置顶]
WebService学习总结(3)——使用java JDK开发WebService
一.WebService的开发手段 使用Java开发WebService时可以使用以下两种开发手段 1. 使用JDK开发(1.6及以上版本) 2.使用CXF框架开发(工作中) 二.使用JDK开发Web ...
- log4j配置文件及nutch中的日志配置 分类: B1_JAVA 2015-02-17 10:58 483人阅读 评论(0) 收藏
吐槽几句,log4j的坑啊.... (1)CLASSPATH中不能有多个log4j的版本本,否则有有奇形怪状的NoSuchMethod, NoSuchFiled, NoClassDefineFound ...
- amazeui学习笔记--css(常用组件14)--缩略图Thumbnail
amazeui学习笔记--css(常用组件14)--缩略图Thumbnail 一.总结 1.基本样式:在 <img> 添加 .am-thumbnail 类:也可以在 <img> ...
- Altium Designer 在pcb下导入的原件引脚是绿的
当然也可能是其他规则原因导致的
- 【Educational Codeforces Round 31 C】Bertown Subway
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 最后肯定会形成若干个环的. 把最大的两个环合在一起就好. 每个环贡献: 假设x=环的大小 ->x*x 注意int的溢出 [代码 ...