linux指定网卡转发socket,linux下socket指定网卡

系统中存在两个网卡,如何根据socket号知道哪个连接(tcp)在哪个网卡上? 根据getpeername好像有点行不通。或者通过SIOCGARP?netlink?

将问题进行分解,分为主动方式和被动方式两种。主动方式即是系统调用socket创建接口得到的socket号,被动方式即是通过类似accept得到的socket号。

主动方式创建之后,可以利用setsockopt的

SO_BINDTODEVICE。

在socket(7)中对该套接口选项的说明如下:

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 maximum size  of  IFNAMSIZ. If a socket is bound to an interface, only packets received from that particular interface are processed by the socket. Note that this  only  works  for  some  socket types, particularly AF_INET sockets. It is not supported  for  packet  sockets  (use  normal bind(8) there).

strncpy(interface.ifr_ifrn.ifrn_name, "eth0", \

strlen("eth0"));

if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, \

(char *)&interface, sizeof(interface)) 0) {

perror("SO_BINDTODEVICE failed");

/* Deal with error... */

}

对被动方式的socket,如何区分?一种方法是获得MAC与socket的映射关系,进一步确定是哪个网卡对应的哪些socket。

一段代码:

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#ifdef SOLARIS

#include 

#endif

#define MAXINTERFACES 16

main (argc, argv)

register int argc;

register char *argv[];

{

register int fd, intrface, retn = 0;

struct ifreq buf[MAXINTERFACES];

struct arpreq arp;

struct ifconf ifc;

if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0)

{

ifc.ifc_len = sizeof buf;

ifc.ifc_buf = (caddr_t) buf;

if (!ioctl (fd, SIOCGIFCONF, (char *) &ifc))

{//获取接口信息

intrface = ifc.ifc_len / sizeof (struct ifreq);

printf("interface num is intrface=%d\n\n\n",intrface);//根据借口信息循环获取设备IP和MAC地址

while (intrface-- > 0)

{//获取设备名称

printf ("net device %s\n", buf[intrface].ifr_name);//判断网卡类型

if (!(ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface])))

{

if (buf[intrface].ifr_flags & IFF_PROMISC)

{

puts ("the interface is PROMISC" );

retn++;

}

}

else

{

char str[256];

sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);

perror (str);

}//判断网卡状态

if (buf[intrface].ifr_flags & IFF_UP)

{

puts("the interface status is UP" );

}

else

{

puts("the interface status is DOWN" );

}//获取当前网卡的IP地址

if (!(ioctl (fd, SIOCGIFADDR, (char *) &buf[intrface])))

{

puts ("IP address is:" );

puts(inet_ntoa(((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr));

puts("" );//puts (buf[intrface].ifr_addr.sa_data);

}

else

{

char str[256];

sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);

perror (str);

}

/* this section can't get Hardware Address,I don't know whether the reason is module driver*/

#ifdef SOLARIS//获取MAC地址

arp.arp_pa.sa_family = AF_INET;

arp.arp_ha.sa_family = AF_INET;

((struct sockaddr_in*)&arp.arp_pa)->sin_addr.s_addr=((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr.s_addr;

if (!(ioctl (fd, SIOCGARP, (char *) &arp)))

{

puts ("HW address is:" );//以十六进制显示MAC地址

printf("%02x:%02x:%02x:%02x:%02x:%02x\n",

(unsigned char)arp.arp_ha.sa_data[0],

(unsigned char)arp.arp_ha.sa_data[1],

(unsigned char)arp.arp_ha.sa_data[2],

(unsigned char)arp.arp_ha.sa_data[3],

(unsigned char)arp.arp_ha.sa_data[4],

(unsigned char)arp.arp_ha.sa_data[5]);

puts("" );

puts("" );

}

#else

#if 0

/*Get HW ADDRESS of the net card */

if (!(ioctl (fd, SIOCGENADDR, (char *) &buf[intrface])))

{

puts ("HW address is:" );

printf("%02x:%02x:%02x:%02x:%02x:%02x\n",

(unsigned char)buf[intrface].ifr_enaddr[0],

(unsigned char)buf[intrface].ifr_enaddr[1],

(unsigned char)buf[intrface].ifr_enaddr[2],

(unsigned char)buf[intrface].ifr_enaddr[3],

(unsigned char)buf[intrface].ifr_enaddr[4],

(unsigned char)buf[intrface].ifr_enaddr[5]);

puts("" );

puts("" );

}

#endif

if (!(ioctl (fd, SIOCGIFHWADDR, (char *) &buf[intrface])))

{

puts ("HW address is:" );

printf("%02x:%02x:%02x:%02x:%02x:%02x\n",

(unsigned char)buf[intrface].ifr_hwaddr.sa_data[0],

(unsigned char)buf[intrface].ifr_hwaddr.sa_data[1],

(unsigned char)buf[intrface].ifr_hwaddr.sa_data[2],

(unsigned char)buf[intrface].ifr_hwaddr.sa_data[3],

(unsigned char)buf[intrface].ifr_hwaddr.sa_data[4],

(unsigned char)buf[intrface].ifr_hwaddr.sa_data[5]);

puts("" );

puts("" );

}

#endif

else

{

char str[256];

sprintf (str, "cpm: ioctl device %s", buf[intrface].ifr_name);

perror (str);

}

}//while

} else

perror ("cpm: ioctl" );

} else

perror ("cpm: socket" );

close (fd);

return retn;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值