1、驱动层:
1.1、netfilter_hook.c
/** * @file netfilter_hook.c */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/ip.h> #include <linux/netfilter_ipv4.h> #include <linux/netfilter_arp.h> MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("yuuyuu"); MODULE_DESCRIPTION("netfilter"); MODULE_VERSION("1.0"); #define printk_ip(info, be32_addr) \ printk("%s %d.%d.%d.%d\n", \ info, \ ((unsigned char *)&(be32_addr))[0], \ ((unsigned char *)&(be32_addr))[1], \ ((unsigned char *)&(be32_addr))[2], \ ((unsigned char *)&(be32_addr))[3]) int filter_ip(__be32 addr) { unsigned char net_num = ((unsigned char *)&addr)[0]; unsigned char host_num = ((unsigned char *)&addr)[3]; if (net_num == 10 || host_num == 1 || host_num == 2) return 1; return 0; } int filter_src_dst_ip(__be32 s_addr, __be32 d_addr) { int i = filter_ip(s_addr) && filter_ip(d_addr); return i; } unsigned int g_uiPktCntLow = 0; unsigned int g_uiPktCntHigh = 0; unsigned int g_uiPktLenLow = 0; unsigned int g_uiPktLenHigh = 0; /* NF_INET_PRE_ROUTING */ unsigned int pre_routing_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { // unsigned char *puc = skb->head + skb->mac_header; // unsigned char *puc = &skb->head[(int)skb->mac_header]; // skb->head + skb->mac_header; unsigned char *pucMacHdr = skb_mac_header(skb); unsigned int ui12 = pucMacHdr[12]; unsigned int ui13 = pucMacHdr[13]; unsigned int ui14 = pucMacHdr[14]; unsigned int uiVersion = (ui14 >> 4) & 0xF; unsigned int uiIpHdrLen = ui14 & 0xF; unsigned int uiOnePktLen = skb->len + skb->mac_len; // ZC: Bacause we filter ip packet,so the len is calculated from IpHeader?? struct iphdr *ip_header; unsigned int uiPktCnt = g_uiPktCntLow; unsigned int uiPktLen = g_uiPktLenLow; g_uiPktCntLow ++; if (g_uiPktCntLow < uiPktCnt) g_uiPktCntHigh ++; g_uiPktLenLow += uiOnePktLen; if (g_uiPktLenLow < uiPktLen) g_uiPktLenHigh ++; ip_header = ip_hdr(skb); // if (filter_src_dst_ip(ip_header->saddr, ip_header->daddr)) { unsigned char * pucIpSour = (unsigned char *)&ip_header->saddr; unsigned char * pucIpDest = (unsigned char *)&ip_header->daddr; //printk("pre_routing_hook()==================================\n"); printk("%d-%d, %d-%d, (%d), [%02X, %02X], [%X, %X], [%d.%d.%d.%d --> %d.%d.%d.%d]\n", g_uiPktCntHigh, g_uiPktCntLow, g_uiPktLenHigh, g_uiPktLenLow, uiOnePktLen, ui12, ui13, uiVersion, uiIpHdrLen, pucIpSour[0],pucIpSour[1],pucIpSour[2],pucIpSour[3], pucIpDest[0],pucIpDest[1],pucIpDest[2],pucIpDest[3]); } //*/ return NF_ACCEPT; } struct nf_hook_ops pre_routing_ops = { .hook = pre_routing_hook, .pf = PF_INET, .hooknum = NF_INET_PRE_ROUTING, .priority = NF_IP_PRI_FIRST }; static int hook_init(void) { printk("hook_init()======================\n"); nf_register_hook(&pre_routing_ops); // nf_register_hook(&post_routing_ops); return 0; } static void hook_exit(void) { printk("hook_exit()=====================\n"); nf_unregister_hook(&pre_routing_ops); // nf_unregister_hook(&post_routing_ops); } module_init(hook_init); module_exit(hook_exit);
1.2、Makefile :
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
obj-m := netfilter_hook.o
default:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
2、应用层:
2.1、main.cpp
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/if_ether.h> #include <net/if.h> #include <string.h> #include <sys/ioctl.h> #include <arpa/inet.h> //#include <linux/ip.h> #include <linux/sockios.h> int main(int argc, char **argv) { int sock, n; char buffer[2048]; struct ethhdr *eth; struct iphdr *iph; if (0>(sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)))) //if (0>(sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))) { perror("socket"); exit(1); } struct ifreq ethreq; strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); if(-1 == ioctl(sock, SIOCGIFFLAGS, ðreq)) { perror("ioctl"); close(sock); exit(1); } ethreq.ifr_flags |= IFF_PROMISC; if(-1 == ioctl(sock, SIOCGIFFLAGS, ðreq)) { perror("ioctl"); close(sock); exit(1); } unsigned int g_uiPktCntLow = 0; unsigned int g_uiPktCntHigh = 0; unsigned int g_uiPktLenLow = 0; unsigned int g_uiPktLenHigh = 0; while (1) { //printf("=====================================\n"); //注意:在这之前我没有调用bind函数,原因是什么呢? n = recvfrom(sock, buffer, 2048, 0, NULL, NULL); unsigned int ui12 = buffer[12]; unsigned int ui13 = buffer[13]; ui12 &= 0xFF; ui13 &= 0xFF; unsigned int ui14 = buffer[14]; unsigned int uiVersion = (ui14 >> 4) & 0xF; unsigned int uiIpHdrLen = ui14 & 0xF; unsigned char *pucIpSour = (unsigned char *)&buffer[26]; unsigned char *pucIpDest = (unsigned char *)&buffer[30]; unsigned int uiPktCnt = g_uiPktCntLow; g_uiPktCntLow ++; if (g_uiPktCntLow < uiPktCnt) g_uiPktCntHigh ++; unsigned int uiPktLen = g_uiPktLenLow; g_uiPktLenLow += n; if (g_uiPktLenLow < uiPktLen) g_uiPktLenHigh ++; printf("%d-%d, %d-%d (%d), [%02X, %02X], [%X, %X], [%d.%d.%d.%d --> %d.%d.%d.%d]\n", g_uiPktCntHigh, g_uiPktCntLow, g_uiPktLenHigh, g_uiPktLenLow, n, ui12, ui13, uiVersion, uiIpHdrLen, pucIpSour[0],pucIpSour[1],pucIpSour[2],pucIpSour[3], pucIpDest[0],pucIpDest[1],pucIpDest[2],pucIpDest[3]); } }
3、
4、
5、