「技术干货」Ip头udp数据包ARP协议(代码实现netmap)
gudong366 2025-07-28 16:46 5 浏览
协议栈数据组成格式
用户层:用户数据
传输层:8个字节udp头+用户层
网络层:20个字节的ip头 + 传输层
链路层:14个字节的以太网头 + 网络层
网卡(在链路层和物理层之间):将链路层数据经过DA转换,变成电信号/光信号
以太网头
#pragma pack(1)
#define ETH_ADDR_LENGTH 6
// 以太网的头
struct ethhdr{
unsigned char h_dst[ETH_ADDR_LENGTH];
unsigned char h_src[ETH_ADDR_LENGTH];
unsigned short h_proto;
};
嵌入式进阶教程分门别类整理好了,看的时候十分方便,由于内容较多,这里就截取一部分图吧。
需要的朋友转发本文+关注+私信【内核】即可领取
ip头
// ip头
struct iphdr{
unsigned char hdrlen:4,
version:4;
unsigned char tos;
unsigned short totlen;
unsigned short id;
unsigned short flag_offest;
unsigned char ttl; // 初始值为64, 经过一个网关-1,为0不可用
unsigned char type;
unsigned short check;
unsigned int sip;
unsigned int dip;
};
udp协议头
// udp协议头
struct udphdr{
unsigned short sport;
unsigned short dport;
unsigned short length;
unsigned short check;
};
udp数据包
struct udppkt{
ethhdr eh;
iphdr ip;
udphdr udp;
// 0长数组(柔性数组)作为一个标签
// 使用场景:
// 1、不关心长度,长度定义在头中
// 2、数据长度提前分配好,不会出现数组越界
unsigned char data[0];
};
ARP协议
1、发送请求
本机通过路由器,广播给局域网内所有的机器,找ip为xxx.xxx.xxx.xxx的机器,对应ip的机器收到广播后将自己的mac地址返回给本机
ARP攻击:不管谁发送什么ip,都响应随便返回一个mac,会导致局域网内的电脑都没法上网,因为连网关的mac都不对。
2、接受请求,注册ip与mac的映射关系到ARP表中
ARP协议格式
代码实现
netmap可以从github上面clone
#include <stdio.h>
#include <sys/poll.h>
#include <arpa/inet.h>
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
#pragma pack(1)
#define ETH_ADDR_LENGTH 6
#define PROTO_IP 0x0800
#define PROTO_ARP 0x0806
#define PROTO_UDP 17
#define PROTO_ICMP 1
struct ethhdr {
unsigned char h_dst[ETH_ADDR_LENGTH];
unsigned char h_src[ETH_ADDR_LENGTH];
unsigned short h_proto;
}; // 14
struct iphdr {
unsigned char hdrlen:4,
version:4; // 0x45
unsigned char tos;
unsigned short totlen;
unsigned short id;
unsigned short flag_offset; //
unsigned char ttl; //time to live
// 0x1234// htons
unsigned char type;
unsigned short check;
unsigned int sip;
unsigned int dip;
}; // 20
struct udphdr {
unsigned short sport;
unsigned short dport;
unsigned short length;
unsigned short check;
}; // 8
struct udppkt {
struct ethhdr eh; // 14
struct iphdr ip; // 20
struct udphdr udp; // 8
unsigned char data[0];
}; // sizeof(struct udppkt) ==
struct arphdr {
unsigned short h_type;
unsigned short h_proto;
unsigned char h_addrlen;
unsigned char h_protolen;
unsigned short oper;
unsigned char smac[ETH_ADDR_LENGTH];
unsigned int sip;
unsigned char dmac[ETH_ADDR_LENGTH];
unsigned int dip;
};
struct arppkt {
struct ethhdr eh;
struct arphdr arp;
};
int str2mac(char *mac, char *str) {
char *p = str;
unsigned char value = 0x0;
int i = 0;
while (p != '\0') {
if (*p == ':') {
mac[i++] = value;
value = 0x0;
} else {
unsigned char temp = *p;
if (temp <= '9' && temp >= '0') {
temp -= '0';
} else if (temp <= 'f' && temp >= 'a') {
temp -= 'a';
temp += 10;
} else if (temp <= 'F' && temp >= 'A') {
temp -= 'A';
temp += 10;
} else {
break;
}
value <<= 4;
value |= temp;
}
p ++;
}
mac[i] = value;
return 0;
}
void echo_arp_pkt(struct arppkt *arp, struct arppkt *arp_rt, char *mac) {
memcpy(arp_rt, arp, sizeof(struct arppkt));
memcpy(arp_rt->eh.h_dst, arp->eh.h_src, ETH_ADDR_LENGTH);
str2mac(arp_rt->eh.h_src, mac);
arp_rt->eh.h_proto = arp->eh.h_proto;
arp_rt->arp.h_addrlen = 6;
arp_rt->arp.h_protolen = 4;
arp_rt->arp.oper = htons(2);
str2mac(arp_rt->arp.smac, mac);
arp_rt->arp.sip = arp->arp.dip;
memcpy(arp_rt->arp.dmac, arp->arp.smac, ETH_ADDR_LENGTH);
arp_rt->arp.dip = arp->arp.sip;
}
//
int main() {
struct nm_pkthdr h;
struct nm_desc *nmr = nm_open("netmap:eth0", NULL, 0, NULL);
if (nmr == NULL) return -1;
struct pollfd pfd = {0};
pfd.fd = nmr->fd;
pfd.events = POLLIN;
while (1) {
int ret = poll(&pfd, 1, -1);
if (ret < 0) continue;
if (pfd.revents & POLLIN) {
unsigned char *stream = nm_nextpkt(nmr, &h);
struct ethhdr *eh = (struct ethhdr *)stream;
if (ntohs(eh->h_proto) == PROTO_IP) {
struct udppkt *udp = (struct udppkt *)stream;
if (udp->ip.type == PROTO_UDP) { //
int udplength = ntohs(udp->udp.length);
udp->data[udplength-8] = '\0';
printf("udp --> %s\n", udp->data);
} else if (udp->ip.type == PROTO_ICMP) {
}
} else if (ntohs(eh->h_proto) == PROTO_ARP) {
struct arppkt *arp = (struct arppkt *)stream;
struct arppkt arp_rt;
if (arp->arp.dip == inet_addr("192.168.0.123")) { //
echo_arp_pkt(arp, &arp_rt, "00:50:56:33:1c:ca");
nm_inject(nmr, &arp_rt, sizeof(arp_rt));
printf("arp ret\n");
}
}
}
}
}
相关推荐
- 怎么利用Python实现一个远程监控多台Linux主机资源的管理工具
-
摘要:这款基于Python和Flask设计的监控软件,主要是为了实现多主机Linux系统资源监控的目的,支持对本机及远程主机的资源进行监控。不但能定时收集包括CPU、内存、磁盘、IO和网络在内的关键数...
- Linux 流量监控怎么玩?5 个工具 + 3 个维度,保姆级教程来了
-
在数字化运维场景中,Linux服务器因其稳定性和开放性,成为承载核心应用与网络管理的主流平台。而高效监控网络流量,不仅是保障系统性能的关键,更是抵御安全威胁的第一道防线。本文将系统拆解Linux...
- Linux系统监控工具,你知道几个?(linux监控平台有哪些)
-
常用的Linux系统监控工具,可帮助您监视系统性能、资源利用率和进程活动等方面的信息:top:top是一个命令行工具,用于实时监视系统的进程活动和系统资源使用情况。它提供了CPU、内存、磁盘和网络等方...
- Linux服务器上监控网络带宽的18个常用命令和工具
-
一、如何查看CentOS的网络带宽出口检查维护系统的时候,经常会要查看服务器的网络端口是多大的,所以需要用到Linux的一个命令。如何查看CentOS的网络带宽出口多大?可以用下面的命令来查看。#e...
- 查看MySQL所有数据库列表(mysql怎样查看数据库)
-
请关注本头条号,每天坚持更新原创干货技术文章。如需学习视频,请在微信搜索公众号“智传网优”直接开始自助视频学习1.前言本文主要讲解如何在Linux系统上查看MySQL所有数据库列表。在管理MySQL...
- Linux系统中的who命令你真的会用吗?
-
请关注本头条号,每天坚持更新原创干货技术文章。如需学习视频,请在微信搜索公众号“智传网优”直接开始自助视频学习1.前言本教程主要介绍如何使用who命令检查用户登录信息。Linux中的who命令列出了...
- Linux系统中,查看CPU信息的多样方法
-
一、命令行工具(适合所有Linux发行版)1.lscpu命令功能:显示CPU架构、核心数、线程数、缓存、NUMA节点等详细信息。使用:bashlscpu示例输出:Architecture:x86_...
- Linux系统 用户信息的显示:users、w、who
-
前言在Linux系统中,当我们需要查看登入系统的用户相关信息的时候,可以通过如下三条命令来查看:【users|w|who】。本文来具体学习一下这三条命令。目录一、命令描述二、命令常用选项三...
- Linux 用户、用户组、文件权限、文件查找
-
3-linux用户、用户组、文件权限、文件查找概述在Linux操作系统中,用户与权限管理是系统安全和稳定运行的核心环节。Linux是典型的多用户操作系统,每个使用系统的人都需要拥有独立的用...
- 使用linux中.ssh/config配置客户端host
-
~/.ssh/config文件是一个很有用的文件,它用于配置客户端的参数在~/.ssh/config中可以定义ssh的参数,这个文件在当前用户的目录下面,即该配置只能被当前用户使用,其他用户使用不了!...
- 「技术干货」Ip头udp数据包ARP协议(代码实现netmap)
-
协议栈数据组成格式用户层:用户数据传输层:8个字节udp头+用户层网络层:20个字节的ip头+传输层链路层:14个字节的以太网头+网络层网卡(在链路层和物理层之间):将链路层数据经过DA转换,...
- uboot常用命令汇总(uboot详解)
-
我们经常使用uboot命令,虽然资料光盘->常见问题目录有U-boot常用命令汇总文档,但从大家的反馈来看,并没有很多人注意到这个文档,所以把它挪到这里。如此全的uboot命令汇总,建议收藏。注...
- 腾讯面试中的TCP/IP协议简述+经典面试题
-
面试题有福利TCP/IP协议简述+TCP握手协议在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入...
- socket连接数受端口号的限制?谬论
-
初学网络的同学对socket可能会有误解:服务器能接受的最大连接数跟端口的个数65536有关系!为什么会有这样的误会?服务器端的程序无非是这样的:socket();//创建sock...
- 研究发现近期零日IP漏洞激增,被利用攻击 Mac 和 Linux 计算机
-
据pcmag网8月8日报道,据悉,使用0.0.0.0IP地址的零日漏洞近几个月来出现激增,并被黑客利用,可能使MacOS或Linux上Safari、Chrome和Firefox等...
- 一周热门
- 最近发表
- 标签列表
-
- linux一键安装 (31)
- linux运行java (33)
- ln linux (27)
- linux 磁盘管理 (31)
- linux 内核升级 (30)
- linux 运行python (28)
- linux 备份文件 (30)
- linux 网络测试 (30)
- linux 网关配置 (31)
- linux jre (32)
- linux 杀毒软件 (32)
- linux语法 (33)
- linux博客 (33)
- linux 压缩目录 (37)
- linux 查看任务 (32)
- 制作linux启动u盘 (35)
- linux 查看存储 (29)
- linux乌班图 (31)
- linux挂载镜像 (31)
- linux 软件源 (28)
- linux题目 (30)
- linux 定时脚本 (30)
- linux 网站搭建 (28)
- linux 远程控制 (34)
- linux bind (31)