📄 ip_masq_app.c
字号:
}/* * Output pkt hook. Will call bound ip_masq_app specific function * called by ip_fw_masquerade(), assumes previously checked ms!=NULL * returns (new - old) skb->len diff. */int ip_masq_app_pkt_out(struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr){ struct ip_masq_app * mapp; struct iphdr *iph; struct tcphdr *th; int diff; __u32 seq; /* * check if application masquerading is bound to * this ip_masq. * assumes that once an ip_masq is bound, * it will not be unbound during its life. */ if ( (mapp = ms->app) == NULL) return 0; iph = (*skb_p)->nh.iph; th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]); /* * Remember seq number in case this pkt gets resized */ seq = ntohl(th->seq); /* * Fix seq stuff if flagged as so. */ if (ms->protocol == IPPROTO_TCP) { if (ms->flags & IP_MASQ_F_OUT_SEQ) masq_fix_seq(&ms->out_seq, th); if (ms->flags & IP_MASQ_F_IN_SEQ) masq_fix_ack_seq(&ms->in_seq, th); } /* * Call private output hook function */ if ( mapp->pkt_out == NULL ) return 0; diff = mapp->pkt_out(mapp, ms, skb_p, maddr); /* * Update ip_masq seq stuff if len has changed. */ if (diff != 0 && ms->protocol == IPPROTO_TCP) masq_seq_update(ms, &ms->out_seq, IP_MASQ_F_OUT_SEQ, seq, diff); return diff;}/* * Input pkt hook. Will call bound ip_masq_app specific function * called by ip_fw_demasquerade(), assumes previously checked ms!=NULL. * returns (new - old) skb->len diff. */int ip_masq_app_pkt_in(struct ip_masq *ms, struct sk_buff **skb_p, __u32 maddr){ struct ip_masq_app * mapp; struct iphdr *iph; struct tcphdr *th; int diff; __u32 seq; /* * check if application masquerading is bound to * this ip_masq. * assumes that once an ip_masq is bound, * it will not be unbound during its life. */ if ( (mapp = ms->app) == NULL) return 0; iph = (*skb_p)->nh.iph; th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]); /* * Remember seq number in case this pkt gets resized */ seq = ntohl(th->seq); /* * Fix seq stuff if flagged as so. */ if (ms->protocol == IPPROTO_TCP) { if (ms->flags & IP_MASQ_F_IN_SEQ) masq_fix_seq(&ms->in_seq, th); if (ms->flags & IP_MASQ_F_OUT_SEQ) masq_fix_ack_seq(&ms->out_seq, th); } /* * Call private input hook function */ if ( mapp->pkt_in == NULL ) return 0; diff = mapp->pkt_in(mapp, ms, skb_p, maddr); /* * Update ip_masq seq stuff if len has changed. */ if (diff != 0 && ms->protocol == IPPROTO_TCP) masq_seq_update(ms, &ms->in_seq, IP_MASQ_F_IN_SEQ, seq, diff); return diff;}/* * /proc/ip_masq_app entry function */int ip_masq_app_getinfo(char *buffer, char **start, off_t offset, int length, int dummy){ off_t pos=0, begin=0; int len=0; struct ip_masq_app * mapp; unsigned idx; if (offset < 40) len=sprintf(buffer,"%-39s\n", "prot port n_attach name"); pos = 40; for (idx=0 ; idx < IP_MASQ_APP_TAB_SIZE; idx++) for (mapp = ip_masq_app_base[idx]; mapp ; mapp = mapp->next) { /* * If you change the length of this sprintf, then all * the length calculations need fixing too! * Line length = 40 (3 + 2 + 7 + 1 + 7 + 1 + 2 + 17) */ pos += 40; if (pos < offset) continue; len += sprintf(buffer+len, "%-3s %-7u %-7d %-17s\n", masq_proto_name(IP_MASQ_APP_PROTO(mapp->type)), IP_MASQ_APP_PORT(mapp->type), mapp->n_attach, mapp->name); if(len >= length) goto done; }done: begin = len - (pos - offset); *start = buffer + begin; len -= begin; if (len > length) len = length; return len;}#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry proc_net_ip_masq_app = { PROC_NET_IP_MASQ_APP, 3, "app", S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_net_inode_operations, ip_masq_app_getinfo};#endif/* * Initialization routine */__initfunc(int ip_masq_app_init(void)){#ifdef CONFIG_PROC_FS ip_masq_proc_register(&proc_net_ip_masq_app);#endif return 0;}/* * Replace a segment (of skb->data) with a new one. * FIXME: Should re-use same skb if space available, this could * be done if n_len < o_len, unless some extra space * were already allocated at driver level :P . */static struct sk_buff * skb_replace(struct sk_buff *skb, int pri, char *o_buf, int o_len, char *n_buf, int n_len){ int maxsize, diff, o_offset; struct sk_buff *n_skb; int offset; maxsize = skb->truesize; diff = n_len - o_len; o_offset = o_buf - (char*) skb->data; if (maxsize <= n_len) { if (diff != 0) { memcpy(skb->data + o_offset + n_len,o_buf + o_len, skb->len - (o_offset + o_len)); } memcpy(skb->data + o_offset, n_buf, n_len); n_skb = skb; skb->len = n_len; skb->end = skb->head+n_len; } else { /* * Sizes differ, make a copy. * * FIXME: move this to core/sbuff.c:skb_grow() */ n_skb = alloc_skb(MAX_HEADER + skb->len + diff, pri); if (n_skb == NULL) { IP_MASQ_ERR("skb_replace(): no room left (from %p)\n", __builtin_return_address(0)); return skb; } skb_reserve(n_skb, MAX_HEADER); skb_put(n_skb, skb->len + diff); /* * Copy as much data from the old skb as possible. Even * though we're only forwarding packets, we need stuff * like skb->protocol (PPP driver wants it). */ offset = n_skb->data - skb->data; n_skb->nh.raw = skb->nh.raw + offset; n_skb->h.raw = skb->h.raw + offset; n_skb->dev = skb->dev; n_skb->mac.raw = skb->mac.raw + offset; n_skb->pkt_type = skb->pkt_type; n_skb->protocol = skb->protocol; n_skb->ip_summed = skb->ip_summed; n_skb->dst = dst_clone(skb->dst); /* * Copy pkt in new buffer */ memcpy(n_skb->data, skb->data, o_offset); memcpy(n_skb->data + o_offset, n_buf, n_len); memcpy(n_skb->data + o_offset + n_len, o_buf + o_len, skb->len - (o_offset + o_len) ); /* * Problem, how to replace the new skb with old one, * preferably inplace */ kfree_skb(skb); } return n_skb;}/* * calls skb_replace() and update ip header if new skb was allocated */struct sk_buff * ip_masq_skb_replace(struct sk_buff *skb, int pri, char *o_buf, int o_len, char *n_buf, int n_len){ int diff; struct sk_buff *n_skb; unsigned skb_len; diff = n_len - o_len; n_skb = skb_replace(skb, pri, o_buf, o_len, n_buf, n_len); skb_len = skb->len; if (diff) { struct iphdr *iph; IP_MASQ_DEBUG(1, "masq_skb_replace(): pkt resized for %d bytes (len=%d)\n", diff, skb->len); /* * update ip header */ iph = n_skb->nh.iph; iph->check = 0; iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); iph->tot_len = htons(skb_len + diff); } return n_skb;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -