momo zone

调核人的blog

多宿主机中从指定的接口发包

目前知道两种方法:
一种是使用bind函数绑定到指定ip上,这个众所周知:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
	struct sockaddr_ll sll;
	int fd;
	struct ifreq ifr;
	char *dev;
	
	fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	dev = "eth0";
	
	strncpy((char *)ifr.ifr_name, dev, sizeof(ifr.ifr_name));
	assert(ioctl(fd, SIOCGIFINDEX, &ifr)==0);

	memset(&sll, 0, sizeof(sll));
	sll.sll_family = AF_PACKET;
	sll.sll_protocol = htons(ETH_P_ALL);
	sll.sll_ifindex = ifr.ifr_ifindex;

	assert(bind(fd, (struct sockaddr *)&sll, sizeof(sll)==0));
}

另一种方法是使用socket option SO_BINDTODEVICE:

#include 
#include 
struct ifreq ifr;
struct socket fd;

strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
if(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifr, sizeof(irq))<0){
      perror("SO_BINDTODEVICE failed");
}
不过这个方法有两个问题,
SO_BINDTODEVICE不是poxis所定义的,所以不具有可移植性
使用该方法不能代替bind函数,也就是说它仅绑定发送设备,这样回来的包会被rp_filter过滤掉

对于perl而言可以使用下面的方法:
setsockopt($sock, SOL_SOCKET, 25, pack("Z*", "eth0"))
如果使用的io::socket的话,new的时候不要指定ip,然后:
$sock->sockopt(25,pack("Z*", "eth0"));
Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: