int get_ipaddr_netmask(char *dev,char *ip,char *subnet_mask)
{
struct ifreq ifr;
int so;
if(NULL==dev)
return -1;
if(so=socket(PF_PACKET,SOCK_RAW,0)<0)
return -1;
strcpy(ifr.ifr_name,dev);
if(ip)
{
bzero(&(ifr.ifr_addr),sizeof(struct sockaddr_in));
}
}
注:
1、
Linux提供了多种Low level socket供用户选择:SOCK_RAW、SOCK_PACKET、PF_PACKET以及NETLINK。无论哪种Socket都给用户提供了直接操 作数据包的能力。使用传统的BSD Socket接口,用户无法直接控制数据包,需要调用各种System Call,具体的处理则是由kernel来进行。
RAW Socket
RAW Socket是运行在IP层之上的。RAW Socket可以通过以下函数调用来创建:
int fd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
SOCK_PACKET
另外一种socket叫做PACKET Socket,位于链路层之上。创建方法类似,只需把SOCK_RAW换成SOCK_PACKET即可。SOCK_PACKET也是鼎鼎大名的 tcpdump最初所选用的方案,因为tcpdump需要截获IP层之下的包,用SOCK_RAW是不行的。不过由于设计缺陷,目前Linux官方认为已 经过时,强烈不推荐这一方式。
PF_PACKET
替代SOCK_PACKET的叫做PF_PACKET,PF_PACKET 的调用形式为:
socket(PF_PACKET, int socket_type, int protocol)
严格说,PF_PACKET是一个协议簇而不是一种Socket。在上面的例子中,socket_type 可以是SOCK_RAW或者SOCK_DGRAM。前者可以直接读写链路层的数据包,后者得到的数据包则是被去掉了链路层头部的。PF_PACKET有一个常用接口叫做PCAP,而现在的tcpdump也已经改为使用libpcap了。这里 和这里 有一些libpcap使用的资料,有兴趣可以仔细看看。
NETLINK
和PF_PACKET一样,NETLINK是一种协议簇或者“域”(比如AF_INET即是互联网域)。典型调用形式为:
sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
这种套接字在RFC 3549中有详细介绍,它是用户模式和kernel的IP网络配置之间的推荐接口。据说Zebra也采用了这种接口。
NETLINK很适合用来开发用户态下的路由协议,因为它可以提供内核中的路由信息。也可以用它来截获数据包,不过不能用来发送数据,因为没有明确的方法防止这个包不被NETLINK自己再抓获。
2、