关于sockaddr_ll.sll_ifindex

appleswanglei 2008-08-22 09:30:17
关于sockaddr_ll.sll_ifindex

PF_PACKET/SOCK_RAW模式下,不绑定地址,在调用sendto时,将目的地信息填入sockaddr_ll并作为参数传递,
这时候,sockaddr_ll.sll_ifindex是指本地的网卡index?还是目的地的网卡index?
按道理,sockaddr_ll应该填入目的地的信息。。。但是我试验了一下,的确应该填入本地机的网卡index.
实在不能理解。。。
...全文
3307 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
praying 2011-09-23
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 a020332004004 的回复:]

我想问问这个地方sockaddr_ll.sll_addr的mac地址是对方的吗?要怎么写。我也想用这个函数发包,但是sendto的这个地址是对方的还是自己的阿
[/Quote]
这种发包是在 LINK LAYER, 可以不指定 sll_addr,(或者是全0)这是我的理解.参见
libnet src/libnet_link_linux.c

int
libnet_write_link(libnet_t *l, u_int8_t *packet, u_int32_t size)
{
int c;
#if (HAVE_PACKET_SOCKET)
struct sockaddr_ll sa;
#else
struct sockaddr sa;
#endif

if (l == NULL)
{
return (-1);
}

memset(&sa, 0, sizeof (sa));
#if (HAVE_PACKET_SOCKET)
sa.sll_family = AF_PACKET;
sa.sll_ifindex = get_iface_index(l->fd, l->device);
if (sa.sll_ifindex == -1)
{
return (-1);
}
sa.sll_protocol = htons(ETH_P_ALL);
#else
strncpy(sa.sa_data, l->device, sizeof (sa.sa_data) - 1);
sa.sa_data[sizeof (sa.sa_data) - 1] = 0;
#endif

c = sendto(l->fd, packet, size, 0,
(struct sockaddr *)&sa, sizeof (sa));
if (c != size)
{
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
"libnet_write_link(): only %d bytes written (%s)\n", c,
strerror(errno));
}
return (c);
}
a020332004004 2009-11-19
  • 打赏
  • 举报
回复
我明白了。而且经过测试,我已经确定,sockaddr_ll.sll_ifindex是指本地的网卡index.

多谢各位专家!

我想问问这个地方sockaddr_ll.sll_addr的mac地址是对方的吗?要怎么写。我也想用这个函数发包,但是sendto的这个地址是对方的还是自己的阿
appleswanglei 2008-08-29
  • 打赏
  • 举报
回复
我明白了。而且经过测试,我已经确定,sockaddr_ll.sll_ifindex是指本地的网卡index.

多谢各位专家!
fierygnu 2008-08-29
  • 打赏
  • 举报
回复
漏看了memset
还不明白吗?sendto是一个接口函数,实际是多态接口,于是对参数的解释也可以完全不同。而对于二层报文发送,没有根据目的地址进行选路的依据,所以发送者必须指定要使用的出接口,那么在sockaddr_ll里增加这样一项就是非常合适的一种方法。
appleswanglei 2008-08-29
  • 打赏
  • 举报
回复
上面的代码全是用于指定目的地址的。
fierygnu 2008-08-29
  • 打赏
  • 举报
回复
在哪里指定了目的地址?
快乐田伯光 2008-08-29
  • 打赏
  • 举报
回复
狂热GNU信徒的意思是:

首先你要指定本地网卡的索引号,这样就知道用哪个网卡来发送,另外还是指定发送目的地址的MAC地址,这样就知道发到哪里去。

另外,这些应该不是编译器检查的工作吧。
appleswanglei 2008-08-29
  • 打赏
  • 举报
回复
这是源代码(上面的不全):
//send packet
dest.sll_family=PF_PACKET;
dest.sll_halen=ETH_ALEN;
dest.sll_ifindex=if_nametoindex(ifname);//非要指定目的网卡索引号吗?
memset(dest.sll_addr,0xFF,sizeof(dest.sll_addr));在此指定广播地址,广播数据包。
sendto(sockfd, send_buf, send_len, 0, (struct sockaddr*) &dest, sizeof(dest))
appleswanglei 2008-08-29
  • 打赏
  • 举报
回复
这是源代码:
//send packet
dest.sll_family=PF_PACKET;
dest.sll_halen=ETH_ALEN;
dest.sll_ifindex=if_nametoindex(ifname);//非要指定目的网卡索引号吗? memset(dest.sll_addr,0xFF,sizeof(dest.sll_addr));//在此指定广播地址,广播数据包。
send_len=sizeof(struct ether_header)+sizeof(struct pppoe_hdr)+sizeof(struct pppoe_tag);
appleswanglei 2008-08-29
  • 打赏
  • 举报
回复
fierygnu:
我可能没给你说明情况,的确没有目的地址当然不能发送了,所以我已经指定目的地址了!可是编译器要求指定目的地址的mac,同时也要指定网卡索引号sll_ifindex,否则程序就会出错,但我怎么能知道目的地址的网卡索引号呀?
求教!
fierygnu 2008-08-29
  • 打赏
  • 举报
回复
本地网卡只指明了发送端,没有目的地址当然不能发送了。
appleswanglei 2008-08-28
  • 打赏
  • 举报
回复
fierygnu:谢谢你的回复,可是,
这里问题中的地址是sendto(sockfd, send_buf, send_len, 0, (struct sockaddr*) &sockaddr_ll, sizeof(dest))<0)中的二层地址结构sockaddr_ll,它的属性元素sockaddr_ll.sll_ifindex是指本地的网卡index?还是目的地的网卡index?
如果不给目的地址指定sll_ifindex值程序就出错。

请解答。万分谢谢!
fierygnu 2008-08-28
  • 打赏
  • 举报
回复
为什么不理解?就是用来bind发送用的接口的,当然是本地的index。发送方怎么能知道接收方的index呢?
appleswanglei 2008-08-25
  • 打赏
  • 举报
回复
没有知道的么?

23,215

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧