ARP 之 发送请求arp_solicit
概述
arp_solicit用来发送ARP请求,首先会根据ARP_ANNOUNCE参数来选取源地址,然后判断是否达到内核发送次数上限,未达到则调用内核arp_send_dst函数发送,如果达到上限,则继续判断是否达到应用程序请求发送次数上限,未达到则通知应用程序发送ARP请求;
源码分析
/*
发送arp请求
ARP请求的目的邻居项
缓存在该邻居项中的待发送报文,来获取该skb的源IP地址
*/
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
{
__be32 saddr = ;
u8 dst_ha[MAX_ADDR_LEN], *dst_hw = NULL;
struct net_device *dev = neigh->dev;
__be32 target = *(__be32 *)neigh->primary_key;
int probes = atomic_read(&neigh->probes);
struct in_device *in_dev;
struct dst_entry *dst = NULL; rcu_read_lock(); /* 获取IP配置块 */
in_dev = __in_dev_get_rcu(dev);
if (!in_dev) {
rcu_read_unlock();
return;
} /* 选取源地址 */
switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
default:
case : /* By default announce any local IP */
/* 使用任意本地地址 */
if (skb && inet_addr_type_dev_table(dev_net(dev), dev,
ip_hdr(skb)->saddr) == RTN_LOCAL)
saddr = ip_hdr(skb)->saddr;
break;
case : /* Restrict announcements of saddr in same subnet */
/* 在同一子网 */
if (!skb)
break;
/* 获取skb的源ip */
saddr = ip_hdr(skb)->saddr;
/* 源地址是本地接口地址 */
if (inet_addr_type_dev_table(dev_net(dev), dev,
saddr) == RTN_LOCAL) {
/* saddr should be known to target */
/* 判断是否在同一子网 */
if (inet_addr_onlink(in_dev, target, saddr))
break;
}
saddr = ;
break;
case : /* Avoid secondary IPs, get a primary/preferred one */
/* 禁止从IP,获取主IP */
break;
}
rcu_read_unlock(); /* 源地址为空,选择一个地址 */
if (!saddr)
saddr = inet_select_addr(dev, target, RT_SCOPE_LINK); /* 计算是否使用完单播发送次数 */
probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES); /* 未使用完 */
if (probes < ) {
if (!(neigh->nud_state & NUD_VALID))
pr_debug("trying to ucast probe in NUD_INVALID\n");
/* 目的硬件地址 */
neigh_ha_snapshot(dst_ha, neigh, dev);
dst_hw = dst_ha;
}
/* 使用完 */
else {
/* 计算是否使用完应用程序ARPD发送次数 */
probes -= NEIGH_VAR(neigh->parms, APP_PROBES); /* 未使用完 */
if (probes < ) {
/* 应用程序ARPD请求 */
neigh_app_ns(neigh);
return;
}
} /* 获取目的路由缓存 */
if (skb && !(dev->priv_flags & IFF_XMIT_DST_RELEASE))
dst = skb_dst(skb); /* 发送arp请求包 */
arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
dst_hw, dev->dev_addr, NULL, dst);
}
ARP 之 发送请求arp_solicit的更多相关文章
- RestTemplate发送请求并携带header信息
1.使用restTemplate的postForObject方法 注:目前没有发现发送携带header信息的getForObject方法. HttpHeaders headers = new Http ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- 用Retrofit发送请求中添加身份验证
用Retrofit发送请求中添加身份验证====================在安卓应用开发中, retrofit可以极大的方便发送http网络请求,不管是GET, POST, 还是PUT, DEL ...
- ajax-向服务器发送请求
ajax-向服务器发送请求 1.将请求发送到服务器,使用XMLHttpRequest对象的 open() 和 send() 方法. xmlhttp. open(method,url,async ...
- Android HTTP实例 使用GET方法和POST方法发送请求
Android HTTP实例 使用GET方法和POST方法发送请求 Web程序:使用GET和POST方法发送请求 首先利用MyEclispe+Tomcat写好一个Web程序,实现的功能就是提交用户信息 ...
- Android HTTP实例 发送请求和接收响应
Android HTTP实例 发送请求和接收响应 Android Http连接 实例:发送请求和接收响应 添加权限 首先要在manifest中加上访问网络的权限: <manifest ... & ...
- PHP发送请求头和接收打印请求头
一.发送请求头 //发送地址 $url = 'http://127.0.0.1/2.php'; //请求头内容 $headers = array( 'Authorization: '.$basic, ...
- URLConnection 和 HttpClients 发送请求范例
. java.net.URLConnection package test; import java.io.BufferedReader; import java.io.IOException; im ...
- Query通过Ajax向PHP服务端发送请求并返回JSON数据
Query通过Ajax向PHP服务端发送请求并返回JSON数据 服务端PHP读取MYSQL数据,并转换成JSON数据,传递给前端Javascript,并操作JSON数据.本文将通过实例演示了jQuer ...
随机推荐
- mysql5.7 密码字段名更改
由password更改为authentication_string update user set authentication_string=password("123456") ...
- 如何确定asp.net请求生命周期的当前处理事件
1 首先在全局应用程序里面添加如下代码 using System; using System.Collections.Generic; using System.Linq; using System. ...
- C++ STL 之 deque容器 打分案例(内含sort排序用法)
#include <iostream> #include <vector> #include <time.h> #include <deque> #in ...
- 7.JSP技术
JSP和Servlet一样,都是用于开发动态web资源的技术 JSP的两个特性:1.写JSP代码就像是在写HTML代码,但JSP技术允许在页面中编写java代码(理解为一种特殊的HTML) 2.JSP ...
- Spring中事务的传播行为,7种事务的传播行为,数据库事务的隔离级别
Propagation.REQUIRED 代表当前方法支持当前的事务,且与调用者处于同一事务上下文中,回滚统一回滚(如果当前方法是被其他方法调用的时候,且调用者本身即有事务),如果没有事务,则自己新建 ...
- 2.Bacula Server端安装配置
1. Bacula Server端安装配置 1.1. Bacula Server端安装 1.1.1. 安装bacula依赖包 For Centos6: yum install -y mysql ...
- Socket问题
http://www.cnblogs.com/mareymarey111/archive/2011/12/08/2280253.html
- 使用python2与python3创建一个简单的http服务(基于SimpleHTTPServer)
python2与python3基于SimpleHTTPServer创建一个http服务的方法是不同的: 一.在linux服务器上面检查一下自己的python版本:如: [root@zabbix ~]# ...
- git远程分支创建,本地分支关联远程分支,第一次发布、更新分支
git远程分支创建,本地分支关联远程分支,第一次发布.更新分支 github托管服务器地址为https://github.com git提交更新代码示意图: 本地与远程进行免密码配置(本地与远程关联) ...
- Linux之ln文件创建链接
ln命令用来为文件创建链接,链接类型分为硬链接和软链接(符号链接)两种 1)软连接和Windows系统中的快捷方式有点类似 2)硬链接,相当于多了一个文件名指向同一块内存空间,目录无法创建硬链接,不可 ...