amaverick 发表于 2010-05-20 16:37

BSD的TCPIP协议栈,不支持有限广播(255.255.255.255) 的问题

本帖最后由 amaverick 于 2010-05-20 17:15 编辑

我从windows pc机(192.168.0.100)发送一个UDP的有限广播包(目的地址为255.255.255.255)
位于192.168.0.1的开发板收到后,发送UDP响应包的目的IP却成了 192.168.0.255 。我希望开发板的UDP 响应包的目的地址也为有限广播地址255.255.255.255 而不是直接广播地址192.168.0.255
上层用的是socket() , sendto() , recvfrom()。

开发板是一个用BSD TCPIP栈的路由器。
pc机发送广播包给开发板的eth0


查看了BSD的TCPIP协议栈源码。
在in_pcb.c 中的in_pcbconnect()中, 协议栈将目的地址255.255.255.255 改成了192.168.0.255      if (in_ifaddr.tqh_first != 0) {
                /*
               * If the destination address is INADDR_ANY,
               * use the primary local address.
               * If the supplied address is INADDR_BROADCAST,
               * and the primary interface supports broadcast,
               * choose the broadcast address for that interface.
               */
                if (sin->sin_addr.s_addr == INADDR_ANY)
                        sin->sin_addr = in_ifaddr.tqh_first->ia_addr.sin_addr;
                else if (sin->sin_addr.s_addr == INADDR_BROADCAST &&
                  (in_ifaddr.tqh_first->ia_ifp->if_flags & IFF_BROADCAST))
                        sin->sin_addr = in_ifaddr.tqh_first->ia_broadaddr.sin_addr;//***这里
      }同时,在ip_output.c 的 ip_output()中, 协议栈也将目的地址255.255.255.255改成了192.168.0.255      /*
         * If routing to interface only,
         * short circuit routing lookup.
         */
      if (flags & IP_ROUTETOIF) {
                if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
                  (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
                        ipstat.ips_noroute++;
                        error = ENETUNREACH;
                        goto bad;
                }
                ifp = ia->ia_ifp;
                ip->ip_ttl = 1;
    } else if (!(IN_MULTICAST(ip->ip_dst.s_addr) && imo &&
                      ((imo->imo_multicast_ifp != NULL)))) {
                if (ro->ro_rt == 0)
                        rtalloc_mpath(ro, &ip->ip_src.s_addr, 0);
                if (ro->ro_rt == 0) {
                        net_hook_func(NHOOK_L3_ROUTE_FAIL, &m, 0, 0);

                        ipstat.ips_noroute++;
                        error = EHOSTUNREACH;
                        goto bad;
                }
                ia = ifatoia(ro->ro_rt->rt_ifa);
                ifp = ro->ro_rt->rt_ifp;

                ro->ro_rt->rt_use++;
                if (ro->ro_rt->rt_flags & RTF_GATEWAY)
                        dst = satosin(ro->ro_rt->rt_gateway);//***这里
      }我暂时将这两行注释掉。
这下开发板可以发出目的地址为255.255.255.255的UDP有限广播包了。但是源IP地址却变成了另一个接口(eth1而不是原来的eth0)的IP地址。
跟踪发现同样是在udp_output()调用的in_pcbconnect()中设置了源IP地址。

同样的程序,我在linux的协议栈下就可以达到预期的效果。BSD的就不行。
请熟悉BSD的TCPIP协议栈的朋友指点。
要解决BSD的TCPIP发送有限广播包,应给怎么做。或者如何改协议栈。

amaverick 发表于 2010-05-20 16:49

上层用的socket,并设置了SO_BROADCAST属性。这样在linux下就可以实现。BSD却不行。

mirnshi 发表于 2010-05-21 23:22

既然都知道哪了,咋不会改嗫

amaverick 发表于 2010-06-04 09:09

协议栈不好改,
最后还是绕过协议栈,通过 raw socket 解决的。

ZSMDEV 发表于 2012-06-29 16:38

回复 4# amaverick


    开发板有网关吗?

如果没有网关能发送响应包吗?
页: [1]
查看完整版本: BSD的TCPIP协议栈,不支持有限广播(255.255.255.255) 的问题