概述

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的更多相关文章

  1. RestTemplate发送请求并携带header信息

    1.使用restTemplate的postForObject方法 注:目前没有发现发送携带header信息的getForObject方法. HttpHeaders headers = new Http ...

  2. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  3. 用Retrofit发送请求中添加身份验证

    用Retrofit发送请求中添加身份验证====================在安卓应用开发中, retrofit可以极大的方便发送http网络请求,不管是GET, POST, 还是PUT, DEL ...

  4. ajax-向服务器发送请求

    ajax-向服务器发送请求 1.将请求发送到服务器,使用XMLHttpRequest对象的 open() 和 send() 方法.     xmlhttp. open(method,url,async ...

  5. Android HTTP实例 使用GET方法和POST方法发送请求

    Android HTTP实例 使用GET方法和POST方法发送请求 Web程序:使用GET和POST方法发送请求 首先利用MyEclispe+Tomcat写好一个Web程序,实现的功能就是提交用户信息 ...

  6. Android HTTP实例 发送请求和接收响应

    Android HTTP实例 发送请求和接收响应 Android Http连接 实例:发送请求和接收响应 添加权限 首先要在manifest中加上访问网络的权限: <manifest ... & ...

  7. PHP发送请求头和接收打印请求头

    一.发送请求头 //发送地址 $url = 'http://127.0.0.1/2.php'; //请求头内容 $headers = array( 'Authorization: '.$basic, ...

  8. URLConnection 和 HttpClients 发送请求范例

    . java.net.URLConnection package test; import java.io.BufferedReader; import java.io.IOException; im ...

  9. Query通过Ajax向PHP服务端发送请求并返回JSON数据

    Query通过Ajax向PHP服务端发送请求并返回JSON数据 服务端PHP读取MYSQL数据,并转换成JSON数据,传递给前端Javascript,并操作JSON数据.本文将通过实例演示了jQuer ...

随机推荐

  1. mybatis generator代码生成器的使用

    一.有关mybatis generator的使用可以查看如下网址:http://www.mybatis.org/generator/index.html 二.如下是我自己整理的学习步骤: <1& ...

  2. Spring Cloud(四)服务提供者 Eureka + 服务消费者 Feign

    上一篇文章,讲述了如何通过RestTemplate + Ribbon去消费服务,这篇文章主要讲述如何通过Feign去消费服务. Feign简介 Feign是一个声明式的伪Http客户端,它使得写Htt ...

  3. 如何使用cgdb(一)——窗口切换

    cgdb是一个轻量级的基于控制台的多窗口gdb调试界面.除了标准的gdb控制台之外,cgdb还提供了一个分屏视图,可以在执行的时候显示具备语法高亮的源代码.键盘控制是仿照vim设计的,所以vim用户使 ...

  4. 【python+beautifulsoup4】Python中安装bs4后,pycharm报错ModuleNotFoundError: No module named 'bs4'

    本文主要分享关于在对应python版本中安装beautifulsoup之后,在代码执行时还会提示“No module named 'bs4'”的问题. 安装beautifsoup4 在命令窗口执行 p ...

  5. RabbitMQ 功能

    学习完了rabbitmq总一下 RabbitMQ依赖的语言 erlang 第一它可以实现不同程序之间的程序信息储存交互,在易用性.扩展性.高可用性的方面不俗. rabbitmq相当于一个中间人,我们同 ...

  6. etcd安装和简单使用

    etcd作为一个高可用强一致性的服务发现存储仓库,在Kubernetes等开源项目中用的很多,这里简单记录下安装和常用命令以及api 安装 安装包可以从 https://github.com/etcd ...

  7. web开发:css总结与应用

    一.常用标签的使用 二.边界圆角 三.背景样式 四.精灵图 五.盒模型布局细节 六.盒模型案例 七.w3c主页 一.常用标签的使用 <!DOCTYPE html> <html> ...

  8. 06_Hive分桶机制及其作用

    1.Clustered By 对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分. Hive也是针对某一列进行桶的组织.Hive采用对列值哈希,然后 ...

  9. jQuery超酷响应式瀑布流效果

    参考 http://www.sucaihuo.com/js/74.html <script src="scripts/blocksit.min.js"></scr ...

  10. vector简单使用

    在刷ccf题的时候日常做完去网上查看别的同学怎么做的 发现有使用vector后三十几行代码就写出来的,虽然时间复杂度和我一样十几毫秒,but !我看中了它的代码量啊!多么的少啊! 所以百度了vecto ...