通过《Linux网络编程——原始套接字编程》得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢

MAC 头部(有线局域网)

注意:CRC、PAD 在组包时可以忽略

链路层数据包的其中一种情况:

unsigned char msg[1024] = {//--------------组MAC--------14------0xb8, 0x88, 0xe3, 0xe1, 0x10, 0xe6, // dst_mac: b8:88:e3:e1:10:e60xc8, 0x9c, 0xdc, 0xb7, 0x0f, 0x19, // src_mac: c8:9c:dc:b7:0f:190x08, 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 = 0;unsigned char buf[1024] = "";int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));while(1){unsigned char src_mac[18] = "";unsigned char dst_mac[18] = "";//获取链路层的数据帧recvfrom(sock_raw_fd, buf, sizeof(buf),0,NULL,NULL);//从buf里提取目的mac、源macsprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);//判断是否为IP数据包if(buf[12]==0x08 && buf[13]==0x00){ printf("______________IP数据报_______________\n");printf("MAC:%s >> %s\n",src_mac,dst_mac);}//判断是否为ARP数据包else if(buf[12]==0x08 && buf[13]==0x06){printf("______________ARP数据报_______________\n");printf("MAC:%s >> %s\n",src_mac,dst_mac);}//判断是否为RARP数据包else if(buf[12]==0x80 && buf[13]==0x35){printf("______________RARP数据报_______________\n");printf("MAC:%s>>%s\n",src_mac,dst_mac);}}return 0;
}

记得以管理者权限运行程序:

每个报文头部都有一个相应的结构体,通过这些结构体对报文进行相应的组包或拆包会方便很多。

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 = 0;unsigned char buf[1024] = "";int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));while(1){unsigned char src_mac[18] = "";unsigned char dst_mac[18] = "";//获取链路层的数据帧recvfrom(sock_raw_fd, buf, sizeof(buf),0,NULL,NULL);//从数据中提取mac首部信息(14个字节)struct ether_header *ethdr = NULL;ethdr = (struct ether_header *)buf;//从buf里提取目的mac、源macsprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", ethdr->ether_dhost[0], ethdr->ether_dhost[1],ethdr->ether_dhost[2],ethdr->ether_dhost[3],ethdr->ether_dhost[4],ethdr->ether_dhost[5]);sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", ethdr->ether_shost[0], ethdr->ether_shost[1],ethdr->ether_shost[2],ethdr->ether_shost[3],ethdr->ether_shost[4],ethdr->ether_shost[5]);//判断是否为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 0;
}

【Linux网络编程】原始套接字实例:MAC 头部报文分析相关推荐

  1. Linux 网络编程——原始套接字实例:MAC 地址扫描器

    如果 A (192.168.1.1 )向 B (192.168.1.2 )发送一个数据包,那么需要的条件有 ip.port.使用的协议(TCP/UDP)之外还需要 MAC 地址,因为在以太网数据包中 ...

  2. Linux网络编程——原始套接字编程

    Linux网络编程--原始套接字编程 转自:http://blog.csdn.net/tennysonsky/article/details/44676377 原始套接字编程和之前的 UDP 编程差不 ...

  3. linux串口编程实例_Linux 网络编程——原始套接字实例:发送 UDP 数据包

    以太网报文格式: IP 报文格式: UDP 报文格式: 校验和函数: /*******************************************************功能:校验和函数参 ...

  4. Linux网络编程——原始套接字能干什么?

    一.知识回顾: 通常情况下程序员接所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的 Socket,针对于面向连接的TCP 服务应用: (2)数据报式 ...

  5. Linux原始网络编程,Linux操作系统网络编程 原始套接字 (1)

    Linux操作系统网络编程--原始套接字 (1) http://soft.zdnet.com.cn/software_zone/2007/1020/568223.shtml 我们在前面已经学习过了网络 ...

  6. Linux网络编程之套接字基础

    Linux网络编程之套接字基础 1.套接字的基本结构 struct sockaddr 这个结构用来存储套接字地址. 数据定义: struct sockaddr { unsigned short sa_ ...

  7. 网络编程——原始套接字实现原理

    目录 1. 基础知识 1.1.概述 1.2.链路层原始套接字 1.3.网络层原始套接字 2.原始套接字的实现 2.1  原始套接字报文收发流程 2.2链路层原始套接字的实现 2.2.1  套接字创建 ...

  8. 【Linux网络编程】套接字简介

    00. 目录 文章目录 00. 目录 01. 概述 02. 套接字属性 03. socket函数 04. 套接字地址结构 05. 附录 01. 概述 Socket套接字由远景研究规划局(Advance ...

  9. 【Linux网络编程】套接字的介绍

    套接字是一种通信机制(通信的两方的一种约定),凭借这种机制,不同主机之间的进程可以进行通信.我们可以用套接字中的相关函数来完成通信过程. 套接字的特性有三个属性确定,它们是:域(domain),类型( ...

  10. Linux网络编程 之 套接字(四)

    目录 1. 套接字的定义 2. 套接字的创建方法 3. 套接字的地址 本地套接字 网络套接字 1. 套接字的定义 套接字是一种通信机制(通信的两方的一种约定),凭借这种机制,不同主机之间的进程可以进行 ...

最新文章

  1. 解除计算机软件开发协议书,计算机软件著作权转让的协议书
  2. [转]我们为什么需要工作流
  3. JAVA程序禁用Hbase中的表_HBase禁用表
  4. 机器学习中的矩阵向量求导(二) 矩阵向量求导之定义法
  5. python教程:一篇文章让你理解字符串的格式化
  6. javascript控制html高,Javascript可以控制css吗?
  7. 录播图的分页使用进度条形式显示
  8. swagger2 注解说明文档
  9. android+动画悬浮窗口,悬浮窗能实现自定Animation动画效果吗?
  10. [bzoj1497][NOI2006]最大获利_网络流_最小割
  11. 解决iview中</Input>标签报错的方法
  12. 管理感悟:派谁进行技术合作
  13. State Machine Workflow 入门篇
  14. 仓储系统货位优化毕业论文【Flexsim仿真】
  15. Java实验输出希腊字母表
  16. 2w 字长文带你搞懂 Linux 命令行
  17. GDScript:关于派生类调用基类方法的一个注意事项
  18. FreeKD:Free-direction Knowledge Distillation for Graph Neural Networks
  19. 黑苹果0x0501_黑苹果原版安装从零开始---3-clover配置篇
  20. HUAWEI华为荣耀MagicBook V14 I5 集显 16GB+512GB (HGE-W56)原装出厂WIN11系统恢复原厂oem系统

热门文章

  1. 再发:VS怎么会这个样子的?
  2. vst3插件_Blue Cat Audio Blue Cat PatchWork mac(蓝猫桥接插件)
  3. L2-1 简单计算器 (25 分)详解c语言 模拟堆栈
  4. python电话号码对应的字符组合_Python3 在字符串中提取字母+数字组合微信账号、电话等 - pytorch中文网...
  5. Java黑皮书课后题第7章:7.10(找出最小元素的下标)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素下标。编写测试程序,提示用户输入10个数字,调用这个方法返回最小值的下标(多个则最小
  6. Java黑皮书课后题第4章:*4.15(电话键盘)电话上的国际标准字母/数字映射如下所示。编写程序,提示用户输入一个小写或大写字母,然后显示对应数字。对于非字母输入,提示非法输入
  7. Java黑皮书课后题第1章:1.5(计算表达式)编写程序,显示以下式子的结果
  8. paramiko 使用总结(SSH 操作远端机器)
  9. springboot 不同环境不同的配置
  10. 广播(broadcast)、电视与电视网络