📄 myip_options.c
字号:
void myip_rt_get_source(u8 *addr, struct rtable *rt);void myip_options_build(struct sk_buff * skb, struct ip_options * opt, u32 daddr, struct rtable *rt, int is_frag) { unsigned char * iph = skb->nh.raw; memcpy(&(IPCB(skb)->opt), opt, sizeof(struct ip_options)); memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen); opt = &(IPCB(skb)->opt); opt->is_data = 0; if (opt->srr) memcpy(iph+opt->srr+iph[opt->srr+1]-4, &daddr, 4); if (!is_frag) { if (opt->rr_needaddr) myip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, rt); if (opt->ts_needaddr) myip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt); if (opt->ts_needtime) { struct timeval tv; __u32 midtime; do_gettimeofday(&tv); midtime = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000); memcpy(iph+opt->ts+iph[opt->ts+2]-5, &midtime, 4); } return; } if (opt->rr) { memset(iph+opt->rr, IPOPT_NOP, iph[opt->rr+1]); opt->rr = 0; opt->rr_needaddr = 0; } if (opt->ts) { memset(iph+opt->ts, IPOPT_NOP, iph[opt->ts+1]); opt->ts = 0; opt->ts_needaddr = opt->ts_needtime = 0; }}unsigned myinet_addr_type(u32 addr);int myip_options_echo(struct ip_options * dopt, struct sk_buff * skb) { struct ip_options *sopt; unsigned char *sptr, *dptr; int soffset, doffset; int optlen; u32 daddr; memset(dopt, 0, sizeof(struct ip_options)); dopt->is_data = 1; sopt = &(IPCB(skb)->opt); if (sopt->optlen == 0) { dopt->optlen = 0; return 0; } sptr = skb->nh.raw; dptr = dopt->__data; if (skb->dst) daddr = ((struct rtable*)skb->dst)->rt_spec_dst; else daddr = skb->nh.iph->daddr; if (sopt->rr) { optlen = sptr[sopt->rr+1]; soffset = sptr[sopt->rr+2]; dopt->rr = dopt->optlen + sizeof(struct iphdr); memcpy(dptr, sptr+sopt->rr, optlen); if (sopt->rr_needaddr && soffset <= optlen) { if (soffset + 3 > optlen) return -EINVAL; dptr[2] = soffset + 4; dopt->rr_needaddr = 1; } dptr += optlen; dopt->optlen += optlen; } if (sopt->ts) { optlen = sptr[sopt->ts+1]; soffset = sptr[sopt->ts+2]; dopt->ts = dopt->optlen + sizeof(struct iphdr); memcpy(dptr, sptr+sopt->ts, optlen); if (soffset <= optlen) { if (sopt->ts_needaddr) { if (soffset + 3 > optlen) return -EINVAL; dopt->ts_needaddr = 1; soffset += 4; } if (sopt->ts_needtime) { if (soffset + 3 > optlen) return -EINVAL; if ((dptr[3]&0xF) != IPOPT_TS_PRESPEC) { dopt->ts_needtime = 1; soffset += 4; } else { dopt->ts_needtime = 0; if (soffset + 8 <= optlen) { __u32 addr; memcpy(&addr, sptr+soffset-1, 4); if( myinet_addr_type(addr) != RTN_LOCAL ){ dopt->ts_needtime = 1; soffset += 8; } } } } dptr[2] = soffset; } dptr += optlen; dopt->optlen += optlen; } if (sopt->srr) { unsigned char * start = sptr+sopt->srr; u32 faddr; optlen = start[1]; soffset = start[2]; doffset = 0; if (soffset > optlen) soffset = optlen + 1; soffset -= 4; if (soffset > 3) { memcpy(&faddr, &start[soffset-1], 4); for (soffset-=4, doffset=4; soffset > 3; soffset-=4, doffset+=4) memcpy(&dptr[doffset-1], &start[soffset-1], 4); if (memcmp(&skb->nh.iph->saddr, &start[soffset+3], 4) == 0) doffset -= 4; } if (doffset > 3) { memcpy(&start[doffset-1], &daddr, 4); dopt->faddr = faddr; dptr[0] = start[0]; dptr[1] = doffset+3; dptr[2] = 4; dptr += doffset+3; dopt->srr = dopt->optlen + sizeof(struct iphdr); dopt->optlen += doffset+3; dopt->is_strictroute = sopt->is_strictroute; } } while (dopt->optlen & 3) { *dptr++ = IPOPT_END; dopt->optlen++; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -