static int udp_multicastgroup_join(URLContext *s)
{
struct ip_mreqn mreq;
memset(&mreq, 0, sizeof(struct ip_mreqn) );
mreq.imr_multiaddr.s_addr = inet_addr(s->url_info.hostname);
mreq.imr_address.s_addr= ( NULL==s->urlctt_opt.udp_opt.localhostip_in) ? INADDR_ANY : inet_addr(s->urlctt_opt.udp_opt.localhostip_in);
struct ifreq ifr;
strcpy(ifr.ifr_name, "eth1");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
mreq.imr_ifindex=ifr.ifr_ifindex;
ms_debug("interface index(eth1) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "eth0");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(eth0) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "eth2");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(eth2) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "lo");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(lo) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "wlan0");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(wlan0) :%d",ifr.ifr_ifindex);
if( NULL!=s->urlctt_opt.udp_opt.localhostip_in){
ms_debug("imr_address:%s",s->urlctt_opt.udp_opt.localhostip_in);
}
ms_debug("interface index(eth1) :%d",mreq.imr_ifindex);
if (setsockopt(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
ms_errret(-1, "setsockopt(IP_ADD_MEMBERSHIP) %s (%d,%s)", s->urlctt_opt.udp_opt.localhostip_in,errno,strerror(errno) );
}
return 0;
}
依然不行呢?eth1抓包有数据[/quote]
最后一招了, 试下设置socket选项(man 7 socket):
SO_BINDTODEVICE
Bind this socket to a particular device like “eth0”, as specified in the
passed interface name. If the name is an empty string or the option
length is zero, the socket device binding is removed. The passed option
is a variable-length null-terminated interface name string with the maxi‐
mum size of IFNAMSIZ. If a socket is bound to an interface, only packets
received from that particular interface are processed by the socket.[/quote]
这个试过了不行,现在是IGMP确定是从ETH1发出去的,输入网口也接收了,但在进行路由(内核函数ip_rcv_finish)时被丢弃了[/quote]
在bind绑定端口号时指定网卡的ip地址也没用吗?
static int udp_multicastgroup_join(URLContext *s)
{
struct ip_mreqn mreq;
memset(&mreq, 0, sizeof(struct ip_mreqn) );
mreq.imr_multiaddr.s_addr = inet_addr(s->url_info.hostname);
mreq.imr_address.s_addr= ( NULL==s->urlctt_opt.udp_opt.localhostip_in) ? INADDR_ANY : inet_addr(s->urlctt_opt.udp_opt.localhostip_in);
struct ifreq ifr;
strcpy(ifr.ifr_name, "eth1");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
mreq.imr_ifindex=ifr.ifr_ifindex;
ms_debug("interface index(eth1) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "eth0");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(eth0) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "eth2");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(eth2) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "lo");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(lo) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "wlan0");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(wlan0) :%d",ifr.ifr_ifindex);
if( NULL!=s->urlctt_opt.udp_opt.localhostip_in){
ms_debug("imr_address:%s",s->urlctt_opt.udp_opt.localhostip_in);
}
ms_debug("interface index(eth1) :%d",mreq.imr_ifindex);
if (setsockopt(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
ms_errret(-1, "setsockopt(IP_ADD_MEMBERSHIP) %s (%d,%s)", s->urlctt_opt.udp_opt.localhostip_in,errno,strerror(errno) );
}
return 0;
}
依然不行呢?eth1抓包有数据[/quote]
最后一招了, 试下设置socket选项(man 7 socket):
SO_BINDTODEVICE
Bind this socket to a particular device like “eth0”, as specified in the
passed interface name. If the name is an empty string or the option
length is zero, the socket device binding is removed. The passed option
is a variable-length null-terminated interface name string with the maxi‐
mum size of IFNAMSIZ. If a socket is bound to an interface, only packets
received from that particular interface are processed by the socket.[/quote]
这个试过了不行,现在是IGMP确定是从ETH1发出去的,输入网口也接收了,但在进行路由(内核函数ip_rcv_finish)时被丢弃了
static int udp_multicastgroup_join(URLContext *s)
{
struct ip_mreqn mreq;
memset(&mreq, 0, sizeof(struct ip_mreqn) );
mreq.imr_multiaddr.s_addr = inet_addr(s->url_info.hostname);
mreq.imr_address.s_addr= ( NULL==s->urlctt_opt.udp_opt.localhostip_in) ? INADDR_ANY : inet_addr(s->urlctt_opt.udp_opt.localhostip_in);
struct ifreq ifr;
strcpy(ifr.ifr_name, "eth1");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
mreq.imr_ifindex=ifr.ifr_ifindex;
ms_debug("interface index(eth1) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "eth0");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(eth0) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "eth2");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(eth2) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "lo");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(lo) :%d",ifr.ifr_ifindex);
strcpy(ifr.ifr_name, "wlan0");
ioctl(s->fd, SIOCGIFINDEX, &ifr);
ms_debug("interface index(wlan0) :%d",ifr.ifr_ifindex);
if( NULL!=s->urlctt_opt.udp_opt.localhostip_in){
ms_debug("imr_address:%s",s->urlctt_opt.udp_opt.localhostip_in);
}
ms_debug("interface index(eth1) :%d",mreq.imr_ifindex);
if (setsockopt(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
ms_errret(-1, "setsockopt(IP_ADD_MEMBERSHIP) %s (%d,%s)", s->urlctt_opt.udp_opt.localhostip_in,errno,strerror(errno) );
}
return 0;
}
依然不行呢?eth1抓包有数据[/quote]
最后一招了, 试下设置socket选项(man 7 socket):
SO_BINDTODEVICE
Bind this socket to a particular device like “eth0”, as specified in the
passed interface name. If the name is an empty string or the option
length is zero, the socket device binding is removed. The passed option
is a variable-length null-terminated interface name string with the maxi‐
mum size of IFNAMSIZ. If a socket is bound to an interface, only packets
received from that particular interface are processed by the socket.
IP_ADD_MEMBERSHIP (since Linux 1.2)
Join a multicast group. Argument is an ip_mreqn structure.
struct ip_mreqn {
struct in_addr imr_multiaddr; /* IP multicast group
address */
struct in_addr imr_address; /* IP address of local
interface */
int imr_ifindex; /* interface index */
};
在linux应是用imr_ifindex指定网卡的序号