1) ip包由包頭和資料區組成, 包頭由ip頭(iphdr)和ip選項區組成, ip頭的開始4位為版本號,下4位為包頭32位元字數, 因此ip包頭最大長度為64位元組, 最小長度為ip頭長度(20位元組),
資料區起始於32位邊界上. 當包頭長度大於ip頭長度時, 從ip頭開始的區域為ip選項區.
2) ip包接收器(ip_rcv)接收幀型別為eth_p_ip(0x0800)的包, 它首先檢查包的正確性,
再將輸入包過濾器進行過濾, 再將過濾包繫結到輸出路由, 分析其選項區,
最後從路由目的入口輸出,
根據不同的路由型別, 輸入到ip**器(ip_forward)或ip本地分發器(ip_local_deliver)以及
ip同播**器(ip_mc_output)中.
3) 如果系統允許接收帶有信源路由選項(ipopt_lsrr或ipopt_ssrr)的ip包, 如果是本地包,
則將包重新繫結到信源路由表第1項位址所指定的路由上, 如果該位址是本地位址,
則用它替換ip頭的目的位址並分析下一信源路由位址.
; net/ipv4/ip_output.c:
static struct packet_type ip_packet_type =
;void __init ip_init(void)
; net/ipv4/ip_input.c:
/** main ip receive routine.
*/ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
return nf_hook(pf_inet, nf_ip_pre_routing, skb, dev, null,
ip_rcv_finish);
inhdr_error:
ip_inc_stats_bh(ipinhdrerrors);
drop:
kfree_skb(skb);
out:
return net_rx_drop;
}#define in_dev_source_route(in_dev) (ipv4_devconf.accept_source_route &&
(in_dev)->cnf.accept_source_route)
#define in_dev_log_martians(in_dev) (ipv4_devconf.log_martians ||
(in_dev)->cnf.log_martians)
static inline int ip_rcv_finish(struct sk_buff *skb)
#ifdef config_net_cls_route
if (skb->dst->tclassid)
#endif
if (iph->ihl > 5)
in_dev_put(in_dev);
}if (ip_options_rcv_srr(skb))
goto drop;}}
return skb->dst->input(skb);
inhdr_error:
ip_inc_stats_bh(ipinhdrerrors);
drop:
kfree_skb(skb);
return net_rx_drop;
}; net/ipv4/ip_options.c:
struct ip_options ;
struct inet_skb_parm
;#define ipcb(skb) ((struct inet_skb_parm*)((skb)->cb))
int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
else
for (l = opt->optlen; l > 0; )
}goto eol;
case ipopt_noop: 空選項
l--;
optptr++;
continue;
}optlen = optptr[1];
if (optlen<2 || optlen>l)
switch (*optptr)
if (optptr[2] < 4)
/* nb: cf rfc-1812 5.2.4.1 */
if (opt->srr)
if (!skb)
memcpy(&opt->faddr, &optptr[3], 4);
if (optlen > 7)
memmove(&optptr[3], &optptr[7], optlen-7);
}opt->is_strictroute = (optptr[0] == ipopt_ssrr);
opt->srr = optptr - iph;
break;
case ipopt_rr: 路徑記錄表
if (opt->rr)
if (optlen < 3)
if (optptr[2] < 4)
if (optptr[2] <= optlen)
if (skb)
optptr[2] += 4;
opt->rr_needaddr = 1;
}opt->rr = optptr - iph;
break;
case ipopt_timestamp: 登記系統的時戳
if (opt->ts)
if (optlen < 4)
if (optptr[2] < 5)
if (optptr[2] <= optlen)
switch (optptr[3]&0xf)
opt->ts = optptr - iph;
if (skb)
opt->ts_needaddr = 1;
opt->ts_needtime = 1;
optptr[2] += 8;
break;
case ipopt_ts_prespec: 取特定位址的時戳
if (optptr[2]+7 > optptr[1])
opt->ts = optptr - iph;
opt->ts_needtime = 1;
optptr[2] += 8;
break;
default:
if (!skb && !capable(cap_net_raw))
break;
}if (timeptr)
} else
opt->ts = optptr - iph;
if (skb)
}break;
case ipopt_ra:
if (optlen < 4)
if (optptr[2] == 0 && optptr[3] == 0)
opt->router_alert = optptr - iph;
break;
case ipopt_sec:
case ipopt_sid:
default:
if (!skb && !capable(cap_net_raw))
break;
}l -= optlen;
optptr += optlen;
}eol:
if (!pp_ptr)
return 0;
error:
if (skb)
return -einval;
}int ip_options_rcv_srr(struct sk_buff *skb)
if (rt->rt_type != rtn_local)
return -einval;
for (srrptr=optptr[2], srrspace = optptr[1]; srrptr <= srrspace; srrptr += 4)
memcpy(&nexthop, &optptr[srrptr-1], 4);
rt = (struct rtable*)skb->dst;
skb->dst = null;
err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev);
rt2 = (struct rtable*)skb->dst;
if (err || (rt2->rt_type != rtn_unicast && rt2->rt_type != rtn_local))
ip_rt_put(rt);
if (rt2->rt_type != rtn_local)
break;
/* supe***st 8) loopback forward */
memcpy(&iph->daddr, &optptr[srrptr-1], 4);
opt->is_changed = 1;
}if (srrptr <= srrspace)
return 0;
}
GPRS MS接受過程
不管使用cs 1,cs 2,cs 3,cs 4最後在mac層形成的packet都是456bit,可以剛好填到4個ts裡面。ms從4個ts接受的資料形成mac層的包,得到rlc層的block 這些block組成llc的llc sndcp segmented pdu fcs。去掉llc頭,就交給sndc...
接受過胎教的孩子
接受過胎教的孩子,他們會 游泳 戶外散步 孕婦可去戶外散步,每天早上早點起來散步,或者晚上到環境優美的地方溜達一段時間,這些活動,尤其在孕晚期可以促進胎頭的下降,增進自然分娩的機會,防止體重增長過快。孕婦瑜伽 孕婦瑜珈,這是對分娩非常有好處的胎教活動,還可以使孕婦心境平和,但要注意做動作時可以完成就...
我接受過的有關Blog的網上採訪
1 您有自己的blog嗎?有 2 您對blog在中國的應用狀況怎麼看?我覺得blog在國內的應用剛剛開始,有影響力的部落格 還很少,部落格還沒有成為有影響力的 blog還沒有被大眾理解與接受,很多人還沒認識到blog與傳統論壇的區別。很多人使用blog是出於新鮮,並沒有理解blog的真正價值。但隨著...