Chinaunix首页 | 论坛 | 博客
  • 博客访问: 74388
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-11 10:56
文章分类

全部博文(35)

文章存档

2016年(2)

2015年(33)

我的朋友

分类: LINUX

2015-04-15 16:13:22

 

网卡驱动11-网卡中的广播地址 0x8000解释

分类: 网卡驱动2014-04-02 16:24 417人阅读 评论(0)  举报

经常在网卡里面看到广播地址,赋值为0x8000,网上几乎没人去解释这个东西。

例如dm9000.

    /* broadcast address */
    hash_table[3] = 0x8000;

u16 hash_table[4];这个是16位的表,我们知道mac广播地址是FF:FF:FF:FF:FF:FF

那么为什么在这是个0x8000。

这要结合一下硬件,dm9000有个叫Multicast Address Register的寄存器

那个hash_table[4]会写入这里,这是为了组播用的。为什么组播里面要搞一个广播。

首先,组播是第一个字节的最低位为1的所有地址,例如01-12-0f-00-00-02。广播地址是全1的48位地址,也属于组播地址。但是广播又是组播中的特例,就像是正方形属于长方形,但是正方形有长方形没有的特点

顺便说一下这里指的是mac组播和广播,不是ip地址。

其次,当网卡设为Pass ALL Multicast,这个在dm9000的Rx Control Register中,网卡会通过校验后得到的值与上面的MAR寄存器里的值比较,相同的才会接收数据(这些都是硬件做的)。所以要有广播来支持arp。

上面说了那个0x8000其实是crc后的值,那么它对应的肯定是FF:FF:FF:FF:FF:FF。下面简单模块可以运行看一下:


  1. #include   
  2. #include   
  3. static char macaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};  
  4. static __exit void crc_cleanup(void)  
  5. {  
  6. }  
  7.   
  8. static __init int crc_init(void)  
  9. {  
  10.     unsigned long val = crc32_le(~0, macaddr, 6);  
  11.   
  12.     printk("%lx\n", (unsigned long)(1 << (val % 16)));  
  13.   
  14.     return 1;  
  15. }  
  16.   
  17. module_init(crc_init);  
  18. module_exit(crc_cleanup);  
  19.   
  20. MODULE_LICENSE("GPL");  
结果就是:


对于crc32_le(),有兴趣自己看看吧!


阅读(972) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~