源路徑選項

1. V4,V6頭部差異
IP源路徑選項:
對於IPV4,由於IP頭部長度字段爲4位,最大可以表示15,那麼限制了IPV4的頭部總長度爲15*4 = 60字節。前10字節爲固定的頭部部分,所以最多有40個字節用來填充選項字段。
對於IPV6,固定長度的40字節的IPV6頭部和傳輸層頭部之間可以有擴展頭部。
2. V4,6頭部選項字段填充和獲取使用setsockopt和getsockopt,傳入參數level,optname,buf,buf長度。
用setsockopt來設置IP選項後,在該套接口上發送所有IP數據報都將包含這些選項。
清除選項用setsockopt,第四個參數設置成NULL,或者第五個參數設置成0.
4.	注意區分寬鬆和嚴格源路徑選項。
5.	填充選項時,傳送給setsockopt的緩衝區格式爲:len = 3+IP地址長度(包括dstip)
|NOP + CODE + LEN +PTR +ip1 + ip2 。。。 +ip9+ dstip|  共44字節,最多有10個地址,不過ip1在IP數據報即將發送出去的時候,由內核移動到IP數據報的宿地址字段。
dstip爲IP數據報的最終宿地址。
CODE指定源路徑是寬鬆還是嚴格的。
LEN指定選項的字節長度,包括3字節的選項頭部和dstip,這就已經有了7個字節了。
對於由一個IP地址構成的源路徑,len = 7 +4 =11;
對於由二個IP地址構成的源路徑,len = 7 +4 +4 =15;最多可以有9個IP,故最大可以爲43.
ptr是一個指針(有點類似計數指針,並不是代表內存中的某個區域),表示下一個待處理IP的偏移量,初始值爲4,表示指向第一個IP地址;
distip和NOP不屬於源路徑;
/*建立一個源路徑選項,初始化還沒有加入IP進去*/
u_char *creat_src_route(int type){
	optr = (u_char *)malloc(44);
	bzero(optr, 44);
	*optr++ = IPOPT_NOP;
	*optr++ = type ? 0x83 : 0x889;
	lenptr = optr++;
	*lenptr = 3;
	*optr++ = 4;
	return (optr-4);
}
/*添加地址到源路徑,並更新選項中的len,並且optr指針指向下一個需要添加IP的位置*/
int add_src_route(const char *host){
	struct addrinfo hints, *addrinfo;
	struct sockaddr_in *addr;
	bzero(&hints, sizeof(hints));
	hints.ai_family = AF_INET;
	if(getaddrinfo(host, NULL, &hints, &addrinfo) < 0 ){
		err_sys("getaddrinfo");
	memcpy(addr,(struct sockaddr_in *)addrinfo->ai_addr, sizeof(struct sockaddr_in));
	*optr = addr->sin_addr;
	optr ++= sizeof(struct in_addr);
	*lenptr += sizeof(struct in_addr);
	return (*lenptr+1);
}
6獲取選項時,得到以下格式:
 	|ip1 + NOP+CODE+LEN+PTR+ip2+ip3+...+ip9+dstip|,會根據5中的源路徑進行逆轉。
	getsockopt返回的buf指向第一個字節


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章