閱讀902 返回首頁    go 阿裏雲 go 技術社區[雲棲]


網絡子係統50_ip協議選項填充

//調用路徑ip_queue_xmit->ip_options_build
//函數主要任務:
//	1.非分片ip報文,向ip報頭填充ip選項,ip選項在創建socket時設置
//	2.分片ip報文,將record route選項,time stamp選項設置為NOP
//	daddr,ip接收方的地址
1.1 void ip_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));//將socket中提供的ip選項拷貝到skb->cb中
	memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen);//複製ip選項到ip報頭後
	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) {//在ip_queue_xmit->ip_options_build調用路徑上,is_frag為0
		if (opt->rr_needaddr)//record route選項
			ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, rt);//獲取路由的首選源地址填充到選項ptr所指的位置
		if (opt->ts_needaddr)//time stamp選項
			ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt);
		if (opt->ts_needtime) {
			struct timeval tv;
			__u32 midtime;
			do_gettimeofday(&tv);//通過do_gettimeofday獲取係統時間,填充當天的ms
			midtime = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
			memcpy(iph+opt->ts+iph[opt->ts+2]-5, &midtime, 4);
		}
		return;
	}
	//ip分片中的選項
	if (opt->rr) {
		memset(iph+opt->rr, IPOPT_NOP, iph[opt->rr+1]);//設置record route為NOP
		opt->rr = 0;
		opt->rr_needaddr = 0;
	}
	if (opt->ts) {
		memset(iph+opt->ts, IPOPT_NOP, iph[opt->ts+1]);//設置time stamp為NOP
		opt->ts = 0;
		opt->ts_needaddr = opt->ts_needtime = 0;
	}
}

最後更新:2017-04-03 14:53:40

  上一篇:go nanosleep納秒級延遲
  下一篇:go Java多線程--線程常用操作方法