一.nf_register_hook挂钩之截获数据包
1.include\linux\netfilter.h
查看nf_hookfn函数以及nf_hook_ops结构体的定义,再具体初始化
typedef unsigned int nf_hookfn(unsigned int hooknum,
struct sk_buff **skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *));
struct nf_hook_ops
{
struct list_head list;
/* User fills in from here down. */
nf_hookfn *hook;
struct module *owner;
int pf;
int hooknum;
/* Hooks are ordered in ascending priority. */
int priority;
};
static struct nf_hook_ops os_attack_ops;
os_attack_ops.hook = os_attack_detect;
os_attack_ops.hooknum = NF_IP_LOCAL_IN;//linux/netfilter_ipv4.h>
os_attack_ops.pf = PF_INET;
os_attack_ops.priority = NF_IP_PRI_FIRST;//linux/netfilter_ipv4.h>
ret = nf_register_hook(&os_attack_ops);
if (ret < 0) {
printk("os_attack:can't register post_proto hook!\n");
return ret;
}
其实一般版本的变化重要就是nf_hookfn的变化....
2. 主要linux/ip.h
linux/tcp.h
linux/udp.h
linux/if_ether.h
也可以看下对应版本的ipt_LOG.c基本包含了所有的东东
ipt_ULOG.c还用到了netlink
TCP层获取相关偏移的函数
static inline struct tcphdr *tcp_hdr(const struct sk_buff *skb)
获得sk_buff结构中TCP头的指针
static inline unsigned int tcp_hdrlen(const struct sk_buff *skb)
这个函数用来获得TCP头的长度
static inline unsigned int tcp_optlen(const struct sk_buff *skb)
获取tcp option的长度
IP相关的函数
static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
该函数获得ip头
static inline struct iphdr *ipip_hdr(const struct sk_buff *skb)
该函数获得ipip头,实际上偏移已经跑到了传输层的开始
net/ip.h还有个ip_hdrlen
3、MAC相关函数
static inline struct ebt_802_3_hdr *ebt_802_3_hdr(const struct sk_buff *skb)
{
return (struct ebt_802_3_hdr *)skb_mac_header(skb);
}
获取802.3MAC头指针。
static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
{
return (struct ethhdr *)skb_mac_header(skb);
}
获取以太网MAC头指针。以太网头指针结构体:
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
__be16 h_proto; /* packet type ID field */
} __attribute__((packed));
内核中网络地址转化为字符串形式的IP地址的宏定义:
#define NIPQUAD(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[3]
#define NIPQUAD_FMT "%u.%u.%u.%u"
char *print_mac(char *buf, const u8 *addr)
{
sprintf(buf, MAC_FMT,
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
return buf;
}
|