探究linux下c语言与ARP协议的实现 (linux c arp)

探究Linux下C语言与ARP协议的实现

随着计算机网络的迅猛发展,网络通信协议也越来越成熟和复杂,ARP(Address Resolution Protocol)协议是用于将IP地址转换为物理地址的一种网络协议。在Linux系统下,ARP协议的实现是由C语言编写的。本文将探究Linux下C语言与ARP协议的实现。

一、ARP协议的概述

ARP协议是指Address Resolution Protocol,即地址解析协议,它在互联网协议(IP)中被用来将IPv4地址转换成物理硬件地址,例如MAC地址。通俗的理解,ARP协议实现了IP地址到MAC地址的映射,当我们想要与其他设备通信时,首先需要知道目标设备的MAC地址,而ARP协议就是用来完成这个任务的。

当一个网络设备(网卡、路由器、交换机等)需要发送网络数据包时,它会尝试去获取目标IP地址对应的MAC地址,步骤如下:

1. 在ARP缓存中查找对应的IP地址的MAC地址,如果存在,则直接发送数据包到目标设备的MAC地址。

2. 如果ARP缓存中不存在对应的MAC地址,则网卡需要发送一个ARP请求数据包广播到整个网络中,请求目标设备回应自己的MAC地址。广播的数据包的源MAC地址为发送方的MAC地址,目标MAC地址为广播地址FF:FF:FF:FF:FF:FF,目标IP地址为目标设备的IP地址,发送方的IP地址为发送方IP地址。

3. 目标设备接收到ARP请求数据包后,如果发现请求中目标IP与自己的IP地址相同,则回复一个ARP应答数据包,表明自己的MAC地址是什么,此时源设备可以获取到目标设备的MAC地址,并在以后的网络通信中使用该地址。

二、 Linux C语言下的ARP实现

在Linux下,ARP协议的实现主要由C语言编写。下面将介绍Linux C语言下ARP协议实现的主要代码框架。

1. ARP协议数据结构

在Linux中,ARP请求数据包与应答数据包的结构是一致的。下面是ARP数据包的数据结构定义。

“`c

struct arphdr {

__be16 ar_hrd; //硬件地址类型

__be16 ar_pro; //协议地址类型

unsigned char ar_hln; //硬件地址长度

unsigned char ar_pln; //协议地址长度

__be16 ar_op; //ARP操作码

unsigned char ar_sha[ETH_ALEN]; //源MAC地址

__be32 ar_sip; //源IP地址

unsigned char ar_tha[ETH_ALEN]; //目标MAC地址

__be32 ar_tip; //目标IP地址

};

“`

其中,ar_hrd表示硬件地址类型,ar_pro表示协议地址类型,ar_hln表示硬件地址长度,ar_pln表示协议地址长度,ar_op表示ARP操作码,ar_sha表示源MAC地址,ar_sip表示源IP地址,ar_tha表示目标MAC地址,ar_tip表示目标IP地址。

2. ARP协议接口程序

ARP协议的实现主要由arp.c程序实现,下面是该程序的主要代码框架。

“`c

#include

#include

#include

#include

void arp_rcv(struct sk_buff *skb) {

//接收ARP数据包并进行处理

}

int arp_send(unsigned int type, struct net_device *dev,

unsigned long dest_ip, const unsigned char *dest_hw,

unsigned long src_ip, const unsigned char *src_hw,

const unsigned char *target_hw) {

//发送ARP数据包

}

void arp_create(struct net_device *dev) {

//创建ARP缓存

}

void arp_destroy(struct net_device *dev) {

//销毁ARP缓存

}

void arp_timer(unsigned long data) {

//处理ARP缓存中的超时数据

}

static struct neigh_parms * arp_parms_alloc(struct net_device *dev) {

//分配neigh_parms结构体

}

static void arp_parms_free(struct neigh_parms *parms) {

//释放neigh_parms结构体

}

static struct neigh_parms_template arp_parms_template = {

.parmsize = sizeof(struct arp_parms),

.neigh_priv_size = sizeof(struct arp_neigh),

.neigh_setup = arp_neigh_setup,

.neigh_cleanup = arp_neigh_cleanup,

};

void __init arp_init(void) {

//注册ARP协议到内核

}

“`

其中,arp_rcv函数用于接收ARP数据包,并进行处理;arp_send函数用于发送ARP数据包;arp_create函数用于创建ARP缓存;arp_destroy函数用于销毁ARP缓存;arp_timer函数用于处理ARP缓存中的超时数据。此外,arp_parms_alloc函数和arp_parms_free函数用于分配和释放neigh_parms结构体,而arp_parms_template结构体则定义了ARP协议相关的参数模板。

3. ARP协议的实现流程

ARP协议的实现流程主要包含以下几个步骤。

1. 接收ARP数据包

当一个ARP数据包到达时,首先需要通过arp_rcv函数接收数据包。

“`c

void arp_rcv(struct sk_buff *skb) {

struct arphdr *arp;

struct neighbour *neigh;

//检查数据包的长度是否正确

if (/* !数据包长度正确 */) {

kfree_skb(skb);

return;

}

//获取ARP协议头

arp = arp_hdr(skb);

//分配缓存结构体

neigh = neighbour_alloc(&arp_tbl, &arp->saddr, arp->ar_hln, 0, skb->dev);

if (neigh) {

//缓存数据包

neighbour_update(neigh, skb);

neighbour_release(neigh);

}

//释放缓存

kfree_skb(skb);

}

“`

在接收到数据包后,首先需要检查数据包的长度是否正确,然后通过arp_hdr函数获取ARP协议头。接下来需要分配缓存结构体,这里使用neighbour_alloc函数完成,该函数可以分配一个neighbour结构体并将其插入到neighbour表中。当缓存数据包后,使用neighbour_update函数更新缓存,并通过neighbour_release函数将缓存的neigh结构释放。最后将skb数据包指针释放。

2. 发送ARP数据包

当需要发送ARP数据包时,需要调用arp_send函数。

“`c

int arp_send(unsigned int type, struct net_device *dev,

unsigned long dest_ip, const unsigned char *dest_hw,

unsigned long src_ip, const unsigned char *src_hw,

const unsigned char *target_hw) {

struct sk_buff *skb;

struct arphdr *arp;

//分配skb缓存结构体

skb = alloc_skb(/* 指定缓存长度 */, GFP_ATOMIC);

if (!skb) {

return -ENOMEM;

}

//填充ARP头部

arp = (struct arphdr *) skb_put(skb, sizeof(struct arphdr));

//设置各个字段值

arp->ar_hrd = htons(ARPHRD_ETHER);

arp->ar_pro = htons(ETH_P_IP);

arp->ar_hln = ETH_ALEN;

arp->ar_pln = 4;

arp->ar_op = htons(type);

memcpy(arp->ar_sha, src_hw, ETH_ALEN);

arp->ar_sip = htonl(src_ip);

memset(arp->ar_tha, 0, ETH_ALEN);

arp->ar_tip= htonl(dest_ip);

if (target_hw) {

memcpy(arp->ar_tha, target_hw, ETH_ALEN);

}

//填充数据链路头

//调用dev_hard_start_xmit函数发送数据包

//释放skb缓存结构体

return 0;

}

“`

发送ARP数据包时,首先需要分配一个skb缓存结构体,然后填充ARP头部,设置各个字段值。最后将数据链路头填充,调用dev_hard_start_xmit函数发送数据包,发送完成后释放skb缓存结构体。

3. 创建和销毁ARP缓存

在ARP协议的实现中,需要创建一个缓存表用于存储ARP请求的响应数据。当缓存中的数据超时后,需要将其从缓存表中释放。

“`c

void arp_create(struct net_device *dev) {

//创建ARP缓存

}

void arp_destroy(struct net_device *dev) {

//销毁ARP缓存

}

“`

这里的arp_create和arp_destroy函数用于创建和销毁ARP缓存表。

4. ARP定时器

在ARP协议的实现中,由于网络环境可能会发生变化,ARP缓存中的数据可能会失效。因此,需要使用ARP定时器定期检查ARP缓存中的数据是否已经超时,如果已经超时,则需要将其释放。

“`c

void arp_timer(unsigned long data) {

//处理ARP缓存中的超时数据

}

“`

在定时器中,需要遍历缓存表,检查缓存中每个元素的时间戳是否已经超时,如果已经超时,则需要将其从缓存表中释放。

三、结论

相关问题拓展阅读:

Linux主机如何防范ARP攻击?

最根本的方法,是关掉网卡的ARP功能(ifconfig ethx -arp)。很多情况下,我们只需要与网关通信,网络里面其他的机器很少通信。所以我们建立一个ip地址和mac地址的对应关系文件:/etc/ethers

cat /etc/ethers

192.168.1.:14:78:8B:C4:54

然后执行 arp -f 的命令,即可绑定。

经过以上两个步骤,arp攻击中对你的欺骗裂谨就不起作用了。但是,arp欺骗还有另外一种方式,就是欺骗网关,以至于网关无法获得你棚档的正确mac地址,这个问题又要怎样解决呢?

arping -U -I eth0 -s 192.168.1.17 192.168.1.254

这个命令的含义为将绑定在eth0上的IP地址(192.168.1.17)对应的MAC地址告诉网关(192.168.1.254)

但是,请链源乱大家注意,关闭了网卡的arp功能之后,这个命令也就不能使用了。也就是说,以上两个方法分别可以应付单一的ARP欺骗攻击。但是由于上述两法无法同时使用,攻击方若采取“中间人”攻击,被攻击的机器必然无法正常与网关通信,但是“中间人”的攻击也是无法得逞的。

我仍然在寻找更好的方法,如有哪位朋友知道,还请不吝赐教!

arp欺骗的原理不多述,基本就是利用发 送假的arp数据包,冒充网关。一般在网上通讯的时候网关的IP和MAC的绑定是放在arp 缓存里面的,假的arp包就会刷新这个缓存,导致本该发送到网关的数据包发到了欺骗 者那里。解决的办法就是静态arp。

假设网关的IP是192.168.0.1,我们要 先得到网关的正确MAC,先ping一下网关:

ping 192.168.0.

然后运行arp查看arp缓存中的网关MAC:

localhost~$ arp

AddressHWtype HWaddressFlags Mask Interface

192.168.0.1 ether 00:12:34:56:78:9A Ceth0

、这里得到的网关MAC假定 为00:12:34:56:78:9A,C代表这个绑定是保存在缓冲里的,我们要做的就是把毕棚这个IP和 MAC静态的绑定在一起,首先建立/etc/ethers文件,输入以下内容:

192.168.0.1 00:12:34:56:78:9A

保存退出,之后便是应 用这手族则个静态绑定:

localhost~$ arp -f

再运行arp查看:

localhost~$ arp

AddressHWtype HWaddressFlags Mask Interface

192.168.0.1 ether 00:12:34:56:78:9A CMeth0

多了个M,表示静态网关 ~

另外,如果你不会和局域网内的用户通讯的话,那么可以干脆 把arp解析关掉,假定你的网卡是eth0,那么可以运行:

localhost~$ ifconfig eth0 -arp

这样对付那些终结者软件就可以了,但是真的有人 向攻击的话,这样还是不够的,因为攻击者还可以欺骗网关,解决的办法就是在网关和 局域网内机器上做双向绑定,原理方法同上,一般网吧里面也是这样做的。穗辩

试试金山的ARP防火墙。。。

关于linux c arp的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 探究linux下c语言与ARP协议的实现 (linux c arp)