- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
17.11. MAC 地址解析
17.11. MAC 地址解析
17.11. MAC 地址解析
以太⽹通讯的⼀个有趣的⽅⾯是如何将 MAC 地址( 接⼜的唯⼀硬件 ID )和 IP 编号结
合起来. ⼤ 分协议有类似的问题, 但我们这⾥集中于类以太⽹的情况. 我们试图提供
这个问题的完整描述, 因此我们展⽰三个情形: ARP , ⽆ ARP 的以太⽹头 ( 例如 plip),
以及⾮以太⽹头 .
17.11.1. 以太⽹使⽤ ARP
处理地址解析的通常⽅法是使⽤ Address Resolution Protocol (ARP) . 幸运的是, ARP 由
内核来管理, 并且⼀个以太⽹接⼜不需要做特别的事情来⽀持 ARP . 只要 dev-addr 和
dev-addr_len 在 open 时正确的赋值了, 驱动就不需要担⼼解决 IP 编号对应于 MAC 地
址; et er_setup 安排正确的设备⽅法给 dev- ard_ eader 和 dev_rebuild_ eader .
尽管通常内核处理地址解析的细节(并且缓存结果), 它需要接⼜驱动来帮助建⽴报⽂.
毕竟, 驱动知道物理层头 细节, 然⽽⽹络代码的作者已经试图隔离内核其他 分. 为
此, 内核调⽤驱动的 ard_ eader ⽅法使⽤ ARP 查询的结果来布置报⽂. 正常地, 以太
⽹驱动编写者不需要知道这个过程 -- 公共的以太⽹代码负责了所有事情.
17.11.2. 不考虑 ARP
简单的点对点⽹络接⼜, 例如 plip , 可能从使⽤以太⽹头 中受益, ⽽避免来回发送
ARP 报⽂的开销. snull 中的例⼦代码也属于这⼀类的⽹络设备. snull 不能使⽤ ARP 因
为驱动改变发送报⽂中的 IP 地址, ARP 报⽂也交换 IP 地址. 尽管我们可能轻易实现了
⼀个简单 ARP 应答发⽣器, 更多的是演⽰性的来展⽰如何直接处理⽹络层头 .
如果你的设备想使⽤通常的硬件头⽽不运⾏ ARP , 你需要重写缺省的 dev- ard_ eader
⽅法. 这是 snull 的实现, 作为⼀个⾮常短的函数:
int snull_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, void *daddr, void *saddr,
unsigned int len)
{
struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_H EN);
eth-h_proto = htons(type);
memcpy(eth-h_source, saddr ? saddr : dev-dev_addr, dev-addr
memcpy(eth-h_dest, daddr ? daddr : dev-dev_addr, dev-addr_
eth-h_dest[ETH_A EN-1] ^= 0x01; /* dest is us xor 1 */
return (dev-hard_header_len);
}
这个函数仅仅⽤内核提供的信息并把它格式成标准以太⽹头. 它也翻转⽬的以太⽹地
址的 1 位, 理由下⾯叙述.
当接⼜收到⼀个报⽂, et _type_trans 以⼏种⽅法来使⽤硬件头 . 我们已经在 snull_rx
看到这个调⽤.
skb-protocol = eth_type_trans(skb, dev);
这个函数抽取协议标识( ETH_P_IP , 在这个情况下 )从以太⽹头; 它也赋值 skb-
mac .raw , 从报⽂ data (使⽤ skb_pull)去掉硬件头 , 并且设置 skb-pkt_type . 最后⼀项
在 skb 分配是缺省为 PACKET_HOST(指⽰报⽂是发向这个主机的), et _type_trans 改
变它来反映以太⽹⽬的地址: 如果这个地址不匹配接收它的接⼜地址, pkt_type 成员被
设为 PACKET_OTHERHOST . 结果, 除⾮接⼜处于混杂模式或者内核打开了报⽂转发,
netif_rx 丢弃任何类型为 PACKET_OTHERHOST 的报⽂. 因为这样, snull_ eader ⼩⼼
地使
文档评论(0)