关于设置网卡的混杂模式的实现方法,很多地方都有提及,现在也能搜集到很多具 体的实现方法的代码,在此只是搜集整理,有的是从文章中摘录,有的就直接从其 他代码中抽取,希望对大家的能有所帮助。 一、在普通程序中设置网卡混杂模式。 在普通程序中普遍用ioctl函数来设置,该函数很值得大家好好的了解,因为它的使 用非常的广泛。下面给出设置网卡混杂模式的实现代码: #include #include #include #include int set_all_promisc() { struct ifreq ifaces[16]; struct ifconf param; int sock, i; param.ifc_len = sizeof(ifaces); param.ifc_req = ifaces; sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock <= 0) return 0; if (ioctl(sock, SIOCGIFCONF, ?m)) return 0; for (i = 0; i < param.ifc_len / sizeof(struct ifreq); i++) { if (ioctl(sock, SIOCGIFFLAGS, ifaces + i)) return 0; ifaces[i].ifr_flags |= IFF_PROMISC; /*如果恢复网卡模式,把|= 改成 &=~ */ if (ioctl(sock, SIOCSIFFLAGS, ifaces + i)) return 0; } return 1; } 二、在核心空间中设置混杂模式 1.在kernel-2.2.x 中 static struct device *sniffer_dev = NULL; static unsigned short old_flags, old_gflags; int init_module ( void ) /* 模块初始化 */ { ...... sniffer_dev = dev_get("eth0"); if ( sniffer_dev != NULL ) { /* thanks for difeijing of whnet's Security */ old_flags = sniffer_dev->flags; old_gflags = sniffer_dev->gflags; /* * 参看net/core/dev.c里的dev_change_flags() * ->gflags的作用是避免多次重复设置混杂模式,没有其他特别含义 */ /* 设置混杂模式 */ sniffer_dev->flags |= IFF_PROMISC; sniffer_dev->gflags |= IFF_PROMISC; start_bh_atomic(); /* 注意,这个回调函数还是会报告 eth0: Setting promiscuous mode. */ sniffer_dev->set_multicast_list( sniffer_dev ); end_bh_atomic(); } ...... return 0; } void cleanup_module(void) { ...... if (sniffer_dev != NULL) { /* 恢复原有模式 */ sniffer_dev>flags = old_flags; sniffer_dev>gflags = old_gflags; start_bh_atomic(); sniffer_dev>set_multicast_list( sniffer_dev ); end_bh_atomic(); } ...... } 2.在kernel-2.4.x 中 在2.4中有了许多变化,首先struct device结构改为struct net_device, 再者de v_get 功能改为测试网络设备是否存在,真正的设置网络混杂模式的函数改为 void dev_set_promiscuity(struct net_device *dev, int inc); 其中根据inc的值来设置混杂模式还是恢复原来设置模式,通过计数来恢复原来模式 ,这样的好处就是 不会和其他的程序冲突,不在像上述两种实现方式中恢复原来模式就全恢复了,不 管还有没有其他的程 序是否也设置了混杂模式。现在就通过计数来恢复原来的模式,只要当计数相加为 零才设置成普通模式。 linux源代码的注释如下: /** * dev_set_promiscuity - update promiscuity count on a device * @dev: device * @inc: modifier * * Add or remove promsicuity from a device. While the count in the device * remains above zero the interface remains promiscuous. Once it hits zer o * the device reverts back to normal filtering operation. A negative inc * value is used to drop promiscuity on the device. */ 设置网卡混杂模式的实现代码如下: struct net_device *sniffer_dev = NULL; int dev_flags = 0; int init_module ( void ) /* 模块初始化 */ { ...... sniffer_dev = dev_get_by_name("eth0"); if (sniffer_dev != NULL) { dev_flags = 1; dev_set_promiscuity(sniffer_dev, 1); dev_put(sniffer_dev); sniffer_dev = NULL; } ...... return 0; } void cleanup_module(void) { ...... if (dev_flags) { sniffer_dev = dev_get_by_name("eth0"); if (sniffer_dev != NULL) { dev_flags = 0; dev_set_promiscuity(sniffer_dev, -1); /*注意此处的第二个参数*/ dev_put(sniffer_dev); sniffer_dev = NULL; } } ...... } 三、参考资料 1.利用LLKM处理网络通信----对抗IDS、Firewall(修订)
设置网卡的混杂模式
最新推荐文章于 2023-09-21 17:22:51 发布