其中的PRO,AM,AB跟地址有关:
PRO为1时,将接收所有的数据包,不管任何地址, 统统收下来。通常用在一些网桥,或一些用来监视网络的电脑里。sniffer软件就是利用这个特性,将以太网上所有数据包都收下来进行分析,以统计以太网里的数据传输率,冲突,出错情况,网卡地址情况,ip数据包等情况。
PRO为0时,接收跟自己的地址一样的数据包,其他目的地址的被丢弃(不包括广播和组播包)。我们设置为0就可以了。
AM=1时,接收组播地址的数据包,AM=0时,不接收组播地址的数据包。 将该位根据你的情况设置为1或0,推荐设置为1。
AB=1时,接收广播地址的数据包,AB=0时,不接收广播地址FF:FF:FF:FF:FF:FF的数据包。该位要设置为1,才能实现tcp/ip协议。
PHY跟地址有关: 为接收的情况报告。
参考:IP组播地址转换为以太网组播地址 二、组播地址
大家知道,IP地址空间被划分为A、B、C三类。第四类即D类地址被保留用做组播地址。在第四版的IP协议(IPv4)中,从224.0.0.0到239.255.255.255间的所有IP地址都属于D类地址。
组播地址中最重要的是第24位到27位间的这四位,对应到十进制是224到239,其它28位保留用做组播的组标识,如下图所示:
图1 组播地址示意图
16
IPv4的组播地址在网络层要转换成网络物理地址。对一个单播的网络地址,通过ARP协议可以获取与IP地址对应的物理地址。但在组播方式下ARP协议无法完成类似功能,必须得用其它的方法获取物理地址。在下面列出的RFC文档中提出了完成这个转换过程的方法:
RFC1112:Multicast IPv4 to Ethernet physical address correspondence RFC1390:Correspondence to FDDI
RFC1469:Correspondence to Token-Ring networks
在最大的以太网地址范围内,转换过程是这样的:将以太网地址的前24位最固定为01:00:5E,这几位是重要的标志位。紧接着的一位固定为0,其它23位用IPv4组播地址中的低23位来填充。该转换过程如下图所示:
图2 地址转换示意图
例如,组播地址为224.0.0.5其以太网物理地址为01:00:5E:00:00:05。 还有一些特殊的IPv4组播地址:
224.0.0.1:标识子网中的所有主机。同一个子网中具有组播功能的主机都是这个组的成员。 224.0.0.2:该地址用来标识网络中每个具有组播功有的路由器。
224.0.0.0----224.0.0.255范围内的地址被分配给了低层次的协议。向这些范围内的地址发送数据包,有组播功能的路由器将不会为其提供路由。
239.0.0.0----239.255.255.255间的地址分配用做管理用途。这些地址被分配给局部的每一个组织,但不可以分配到组织外部,组织内的路由器不向在组织外的地址提供路由。
除了上面列出的部分组播地址外,还有许多的组播地址。在最新版本的RFC文档“Assinged Numbers”中有完整的介绍。
下面的表中列出了全部的组播地址空间,同时还列出了相应的地址段的常用名称及其TTL(IP包的存活时间)。在IPv4组播方式下,TTL有双重意义:正如大家所知的,TTL原本用来控制数据包在网络中的存活时间,防止由于路由器配置错误导致出现数据包传播的死循环;在组播方式下,它还代表了数据包的活动范围,如:数据包在网络中能够传送多远?这样就可以基于数据包的分类来定义其传送范围。 范围 TTL 地址区间 描述
节点(Node) 0 只能向本机发送的数据包,不能向网络中的其它接口传送链路(Link) 1 224.0.0.0-224.0.0.255 只能在发送主机所在的一个子网内的传送,不会通过路由器转发。 部门 32 239.255.0.0-239.255.255.255 只在整个组织下的一个部门内 (Department) 传送
组织 64 239.192.0.0--239.195.255.255 在整个组织内传送 (Organization)
全局(Global)255 224.0.1.0--238.255.255.255 没有限制,可全局范围内传送 三、组播的工作过程
在局域网内,主机的网络接口将到目的主机的数据包发送到高层,这些数据包中的目的地址是物理接口地址或广播地址。
17
如果主机已经加入到一个组播组中,主机的网络接口就会识别出发送到该组成员的数据包。 因此,如果主机接口的物理地址为80:C0:F6:A0:4A:B1,其加入的组播组为224.0.1.10,则发送给主机的数据包中的目的地址必是下面三种类型之一: 接口地址:80:C0:F6:A0:4A:B1 广播地址:FF:FF:FF:FF:FF:FF 组播地址:01:00:5E:00:01:0A
广域网中,路由器必须支持组播路由。当主机中运行的进程加入到某个组播组中时,主机向子网中的所有组播路由器发送IGMP(Internet分组管理协议)报文,告诉路由器凡是发送到这个组播组的组播报文都必须发送到本地的子网中,这样主机的进程就可以接收到报文了。子网中的路由器再通知其它的路由器,这些路由器就知道该将组播报文转发到哪些子网中去。
子网中的路由器也向224.0.0.1发送一个IGMP报文(224.0.0.1代表组中的全部主机),要求组中的主机提供组的相关信息。组中的主机收到这个报文后,都各将计数器的值设为随机值,当计数器递减为0时再向路由器发送应答。这样就防止了组中所有的主机同时向路由器发送应答,造成网络拥塞。主机向组播地址发送一个报文做为对路由器的应答,组中的其它主机一旦看到这个应答报文,就不再发送应答报文了,因为组中的主机向路由器提供的都是相同的信息,所以子网路由器只需得到组中一个主机提供的信息就可以了。
如果组中的主机都退出了,路由器就收不到应答,因此路由器认为该组目前没有主机加入,遂停止到该子网报文的路由。IGMPv2的解决方案是:组中的主机在退出时向224.0.0.2 发送报文通知组播路由器。
RTL8019AS--以太网组播地址过滤寄存器的计算
终于找到关于RTL8019AS里的 MAR0-MAR7的计算的程序,源程序是80x86的汇编,我把它转换成了在keil c51里的程序,以便可以在51单片机里使用。
跟组播地址有关的寄存器:
为8个寄存器,提供对组播地址的过滤。跟crc的逻辑有关。MAR0-7 全部设置为0xff时,将接收所有的组播数据包,将MAR0-7 全部设置为0x00时,将不接收所有组播地址的数据包。在windows98里,该值被设置为: MAR0=0x00; MAR1=0x41; MAR2=0x00; MAR3=0x80; MAR4=0x00; MAR5=0x00; MAR6=0x00; MAR7=0x00;
用户在嵌入式的应用当中,可以设置为全部0xff,也可以对特定的组播地址(比如你用在网络电台广播)进行计算,生成一个你需要的过滤参数。建议该过滤的算法不写在单片机里,最好是先算好,存储在单片机里,用的时候直接调用,以节省单片机的程序空间。
18
这8个寄存器的值是根据组播地址数组的值生成的,提供对组播地址的过滤,过滤掉一些不属于自己接收组播数据包。
以下是在80x86 里的汇编程序: 点击这里打开。
;注解: laogu http://www.laogu.com
;这是一段在80x86里的汇编源程序,用来生成多播地址过滤的 MAR0-MAR7(以太网卡里的多播地址过滤寄存器)
;多播也叫组播。程序调用的时候 将组播地址列表的地址传递到ds:si ,
;列表相当于c语言里的二维数组 unsigned char multicast_addresses[ax][6]; ; 因为每个地址的长度为6,总共有ax个组播地址。
; ds:si 相当于c语言里的指针 unsigned char *multicast_addresses ;
;将地址总数传递到ax,字节数(=地址总数*6)传递到 cx里(在这个程序里,没有用到cx传递的值)
;程序运算的结果放在mcast_list_bits里,相当于c语言里的unsigned char mcast_list_bits[8];
;程序里的di相当于c语言里的指针 unsigned char *mcast_list_bits; ;mcast_list_bits[8]对应于地址过滤寄存器MAR[8],即MAR0---MAR7
;函数 set_hw_multi ; Set the multicast mask bits in chip是将mcast_list_bits[8]写入到MAR0--MAR7
;的一个函数调用,这里没有写。 public set_multicast_list set_multicast_list:
;enter with ds:si ->list of multicast addresses, ax = number of addresses, ; cx = number of bytes.
;入口调用: 将list of multicast addresses 组播地址列表(可以有多个组播地址)的地址放在 ;ds:si 指针里。ax为多播地址的个数。cx为字节数
;return nc if we set all of them, or cy,dh=error if we didn't. ;设置成功返回c=0,失败c=1(c就是cy,cpu标志位) assume ds:code
mov cx,ax ;keep a count of addresses in cx. ;cx=多播地址的个数
mov di,offset mcast_list_bits ;di=64位的多播地址crc xor ax,ax mov [di+0],ax mov [di+2],ax mov [di+4],ax
mov [di+6],ax ;将多播地址8个字节的crc全部设置为0
jcxz set_mcl_2 ;cx=0 跳到set_mc1_2,将多播地址crc设置为全部0 set_mcl_1:
call add_mc_bits ;调用crc计算 loop set_mcl_1 set_mcl_2:
19
call set_hw_multi ; Set the multicast mask bits in chip
;将mcast_list_bits[8] 8个字节分别写入到MAR0--MAR7 ;mcast_list_bits[0]对应于MAR0 . clc ret
;================= add_mc_bits: 开始计算
;entry: ds:si -> multicast address, di-> sixty-four bit multicast filter. ;preserve cx, di, increment si by EADDR_LEN push cx ;保存cx,就是保存多播地址的个数
mov cx,EADDR_LEN ;EADDR_LEN就是以太网地址的长度=6 mov dx,0ffffh ; this is msw. mov bx,0ffffh ; set 32 bit number add_mcb_1:
lodsb ;将一个字节的数(地址为si指向的数)装到AL里,同时使si地址+1 call upd_crc ; update crc loop add_mcb_1 ; and loop. ;=============
ifdef MULTICRC_REVERSE ;ifdef 到endif这段函数是产生CRC过滤的反顺序码的, ;例如 0000001 反顺序就是 1000000 ;就是高位和低位反过来。
;程序的执行将dh里的数反顺序排列
;这段程序应该是没有使用,也就是说我们用的是正顺序码。而不是反顺序码。 mov cl,8 add_mcb_2:
shl dh,1 ;逻辑左移1位,高位进c,地位补0 rcr dl,1 ;带进位的循环右移,c进高位,低位进c loop add_mcb_2 mov dh,dl endif
;==================== mov al,dh ; get ms 8 bits, rol al,1 ;循环左移,高位进c和低位, rol al,1
rol al,1 ; put 3 bits at bottom and al,7
mov bl,al ; save in bl
xor bh,bh ; make bx into an index to the byte. mov al,dh ; get ms 8 bits, ror al,1 ;循环右移,低位进c和高位 ror al,1 ; but at bottom and al,7
mov cl,al ; save in cl mov al,1
20
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库RTL8019AS使用 - 图文(4)在线全文阅读。
相关推荐: