⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipsec_tunnel.c

📁 ipsec_sha1的C源码。我们已经用于测试SHA1的erilog
💻 C
📖 第 1 页 / 共 5 页
字号:
					  prv->mtu,					  physdev);#endif /* IPSEC_obey_DF */		}		#ifdef MSS_HACK		/*		 * If this is a transport mode TCP packet with		 * SYN set, determine an effective MSS based on 		 * AH/ESP overheads determined above.		 */		if (iph->protocol == IPPROTO_TCP 		    && outgoing_said.proto != IPPROTO_IPIP) {			struct tcphdr *tcph = skb->h.th;			if (tcph->syn && !tcph->ack) {				if(!ipsec_adjust_mss(skb, tcph, prv->mtu)) {					spin_unlock(&tdb_lock);					printk(KERN_WARNING					       "klips_warning:ipsec_tunnel_start_xmit: "					       "ipsec_adjust_mss() failed\n");					stats->tx_errors++;					goto cleanup;				}			}		}#endif /* MSS_HACK */		if(!hard_header_stripped) {			if((saved_header = kmalloc(hard_header_len, GFP_ATOMIC)) == NULL) {				spin_unlock(&tdb_lock);				printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: "				       "Failed, tried to allocate %d bytes for temp hard_header.\n", 				       hard_header_len);				stats->tx_errors++;				goto cleanup;			}			for (i = 0; i < hard_header_len; i++) {				saved_header[i] = skb->data[i];			}			if(skb->len < hard_header_len) {				spin_unlock(&tdb_lock);				printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "				       "tried to skb_pull hhlen=%d, %d available.  This should never happen, please report.\n",				       hard_header_len, (int)(skb->len));				stats->tx_errors++;				goto cleanup;			}			//剥去硬件头,此时data指针指向IP头			skb_pull(skb, hard_header_len);			hard_header_stripped = 1;			/*			iph = (struct iphdr *) (skb->data); */			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,				    "klips_debug:ipsec_tunnel_start_xmit: "				    "head,tailroom: %d,%d after hard_header stripped.\n",				    skb_headroom(skb), skb_tailroom(skb));			KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, iph);		} else {			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,				    "klips_debug:ipsec_tunnel_start_xmit: "				    "hard header already stripped.\n");		}		//此时hard_header_len=16,运算结果为16		//这是为增加两个IP头空间计算长度准备的		ll_headroom = (hard_header_len + 15) & ~15;		if ((skb_headroom(skb) >= max_headroom + 2 * ll_headroom) && 		    (skb_tailroom(skb) >= max_tailroom)#ifndef NET_21			&& skb->free#endif /* !NET_21 */			) {			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,				    "klips_debug:ipsec_tunnel_start_xmit: "				    "data fits in existing skb\n");		} else {			struct sk_buff* tskb = skb;			if(!oskb) {				oskb = skb;			}			//max_headroom+2*ll_headroom = 60 + 2*16 = 92 bytes			//真正扩展skb的空间,使之头部增加长度为max_headroom+2*ll_headroom的空间			//此时头空间已经增加了相应的ipsec头和新、旧ip头空间了			//而尾部则增加长度为max_tailroom的空间			tskb = skb_copy_expand(skb,			/* The reason for 2 * link layer length here still baffles me...RGB */					       max_headroom + 2 * ll_headroom,					       max_tailroom,					       GFP_ATOMIC);#ifdef NET_21			if(tskb && skb->sk) {				skb_set_owner_w(tskb, skb->sk);			}#endif /* NET_21 */			if(!(skb == oskb) ) {				dev_kfree_skb(skb, FREE_WRITE);			}			skb = tskb;			if (!skb) {				spin_unlock(&tdb_lock);				printk(KERN_WARNING				       "klips_debug:ipsec_tunnel_start_xmit: "				       "Failed, tried to allocate %d head and %d tailroom\n", 				       max_headroom, max_tailroom);				stats->tx_errors++;				goto cleanup;			}			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,				    "klips_debug:ipsec_tunnel_start_xmit: "				    "head,tailroom: %d,%d after allocation\n",				    skb_headroom(skb), skb_tailroom(skb));		}				/*		 * Apply grouped transforms to packet		 */		while (tdbp) {#ifdef CONFIG_IPSEC_ESP			struct esp *espp;			__u32 iv[2];			unsigned char *idat, *pad;			int authlen = 0, padlen = 0, i;#endif /* !CONFIG_IPSEC_ESP */#ifdef CONFIG_IPSEC_AH			struct iphdr ipo;			struct ah *ahp;#endif /* CONFIG_IPSEC_AH */#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1)			union {#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5				MD5_CTX md5;#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1				SHA1_CTX sha1;#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */			} tctx;			__u8 hash[AH_AMAX];#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */			int headroom = 0, tailroom = 0, ilen = 0, len = 0;			unsigned char *dat;						iphlen = iph->ihl << 2;			pyldsz = ntohs(iph->tot_len) - iphlen;			sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);			KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,				    "klips_debug:ipsec_tunnel_start_xmit: "				    "calling output for <%s%s%s>, SA:%s\n", 				    IPS_XFORM_NAME(tdbp),				    sa_len ? sa : " (error)");						switch(tdbp->tdb_said.proto) {#ifdef CONFIG_IPSEC_AH			case IPPROTO_AH:				headroom += sizeof(struct ah);				break;#endif /* CONFIG_IPSEC_AH */#ifdef CONFIG_IPSEC_ESP			case IPPROTO_ESP:				switch(tdbp->tdb_encalg) {#ifdef CONFIG_IPSEC_ENC_3DES				case ESP_3DES:					headroom += sizeof(struct esp);					break;#endif /* CONFIG_IPSEC_ENC_3DES */				default:					spin_unlock(&tdb_lock);					stats->tx_errors++;					goto cleanup;				}				switch(tdbp->tdb_authalg) {#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5				case AH_MD5:					authlen = AHHMAC_HASHLEN;					break;#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1				case AH_SHA:					authlen = AHHMAC_HASHLEN;					break;#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */				case AH_NONE:					break;				default:					spin_unlock(&tdb_lock);					stats->tx_errors++;					goto cleanup;				}						tailroom += ((8 - ((pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;				tailroom += authlen;				break;#endif /* !CONFIG_IPSEC_ESP */#ifdef CONFIG_IPSEC_IPIP			case IPPROTO_IPIP:				headroom += sizeof(struct iphdr);				break;#endif /* !CONFIG_IPSEC_IPIP */#ifdef CONFIG_IPSEC_IPCOMP			case IPPROTO_COMP:				break;#endif /* CONFIG_IPSEC_IPCOMP */			default:				spin_unlock(&tdb_lock);				stats->tx_errors++;				goto cleanup;			}						KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,				    "klips_debug:ipsec_tunnel_start_xmit: "				    "pushing %d bytes, putting %d, proto %d.\n", 				    headroom, tailroom, tdbp->tdb_said.proto);			if(skb_headroom(skb) < headroom) {				spin_unlock(&tdb_lock);				printk(KERN_WARNING				       "klips_error:ipsec_tunnel_start_xmit: "				       "tried to skb_push headroom=%d, %d available.  This should never happen, please report.\n",				       headroom, skb_headroom(skb));				stats->tx_errors++;				goto cleanup;			}			//此前的data域已经包含了旧ip头			//添加ipsec头空间或tunnel的IPIP头空间			dat = skb_push(skb, headroom);			ilen = skb->len - tailroom;		//该长度为待处理(加密或认证)的数据的长度			if(skb_tailroom(skb) < tailroom) {				spin_unlock(&tdb_lock);				printk(KERN_WARNING				       "klips_error:ipsec_tunnel_start_xmit: "				       "tried to skb_put %d, %d available.  This should never happen, please report.\n",				       tailroom, skb_tailroom(skb));				stats->tx_errors++;				goto cleanup;			}			//添加ipsec尾空间			skb_put(skb, tailroom);			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,				    "klips_debug:ipsec_tunnel_start_xmit: "				    "head,tailroom: %d,%d before xform.\n",				    skb_headroom(skb), skb_tailroom(skb));			//此长度已经包含了刚才添加的ipsec的头空间			len = skb->len;			if(len > 0xfff0) {				spin_unlock(&tdb_lock);				printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "				       "tot_len (%d) > 65520.  This should never happen, please report.\n",				       len);				stats->tx_errors++;				goto cleanup;			}			//这步是关键!!!!!!!!!!!!!!!!!!!!!!!!!!!			//对于transportMode,则将内部ip头往上移动至刚才添加的ipsec头的前面			//对于tunnelMode,则将IPIP头(外部IP头)往上移动至刚才添加的ipsec头的前面			memmove((void *)dat, (void *)(dat + headroom), iphlen);			//最外部的IP头			iph = (struct iphdr *)dat;			iph->tot_len = htons(skb->len);						switch(tdbp->tdb_said.proto) {#ifdef CONFIG_IPSEC_ESP			case IPPROTO_ESP:				//IP头之后就是ESP头				//前面的memmove和这里的espp的操作就把IPIP(外部IP头)头给挤上去了				espp = (struct esp *)(dat + iphlen);				espp->esp_spi = tdbp->tdb_said.spi;				espp->esp_rpl = htonl(++(tdbp->tdb_replaywin_lastseq));								switch(tdbp->tdb_encalg) {#if defined(CONFIG_IPSEC_ENC_3DES)#ifdef CONFIG_IPSEC_ENC_3DES				case ESP_3DES:#endif /* CONFIG_IPSEC_ENC_3DES */					iv[0] = *((__u32*)&(espp->esp_iv)    ) =						((__u32*)(tdbp->tdb_iv))[0];					iv[1] = *((__u32*)&(espp->esp_iv) + 1) =						((__u32*)(tdbp->tdb_iv))[1];					break;#endif /* defined(CONFIG_IPSEC_ENC_3DES) */				default:					spin_unlock(&tdb_lock);					stats->tx_errors++;					goto cleanup;				}				//idat指向ESP的payload				idat = dat + iphlen + headroom;				//ilen是要加密部分的长度(idat的长度)(不对authenticator进行加密)				ilen = len - (iphlen + headroom + authlen);								/* Self-describing padding */				pad = &dat[len - tailroom];				//-2,其中1个字节存pad length,另外1个字节存next header				padlen = tailroom - 2 - authlen;				for (i = 0; i < padlen; i++) {					pad[i] = i + 1; 		//按照RFC2406的要求,从1开始单向增长进行填充				}				//padLength域				dat[len - authlen - 2] = padlen;								//nextHeader域,为原IP头的下一头类型				dat[len - authlen - 1] = iph->protocol;				//修改外部IP头,使其nextHeader类型标明为此ESP头				iph->protocol = IPPROTO_ESP;								switch(tdbp->tdb_encalg) {#ifdef CONFIG_IPSEC_ENC_3DES				case ESP_3DES:					des_ede3_cbc_encrypt((des_cblock *)idat,							     (des_cblock *)idat,							     ilen,							     ((struct des_eks *)(tdbp->tdb_key_e))[0].ks,							     ((struct des_eks *)(tdbp->tdb_key_e))[1].ks,							     ((struct des_eks *)(tdbp->tdb_key_e))[2].ks,							     (des_cblock *)iv, 1);					break;#endif /* CONFIG_IPSEC_ENC_3DES */				default:					spin_unlock(&tdb_lock);					stats->tx_errors++;					goto cleanup;				}								switch(tdbp->tdb_encalg) {#if defined(CONFIG_IPSEC_ENC_3DES)#ifdef CONFIG_IPSEC_ENC_3DES				case ESP_3DES:#endif /* CONFIG_IPSEC_ENC_3DES */					/* XXX update IV with the last 8 octets of the encryption */					((__u32*)(tdbp->tdb_iv))[0] =						((__u32 *)(idat))[(ilen >> 2) - 2];					((__u32*)(tdbp->tdb_iv))[1] =						((__u32 *)(idat))[(ilen >> 2) - 1];					break;#endif /* defined(CONFIG_IPSEC_ENC_3DES) */				default:					spin_unlock(&tdb_lock);					stats->tx_errors++;					goto cleanup;				}								switch(tdbp->tdb_authalg) {#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5				case AH_MD5:					dmp("espp", (char*)espp, len - iphlen - authlen);					tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;					dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Update(&tctx.md5, (caddr_t)espp, len - iphlen - authlen);					dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Final(hash, &tctx.md5);					dmp("ictx hash", (char*)&hash, sizeof(hash));					tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;					dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Update(&tctx.md5, hash, AHMD596_ALEN);					dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Final(hash, &tctx.md5);					dmp("octx hash", (char*)&hash, sizeof(hash));					memcpy(&(dat[len - authlen]), hash, authlen);					/* paranoid */					memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));					memset((caddr_t)hash, 0, sizeof(*hash));					break;#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1				case AH_SHA:					tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;					SHA1Update(&tctx.sha1, (caddr_t)espp, len - iphlen - authlen);					SHA1Final(hash, &tctx.sha1);					tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;					SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);					SHA1Final(hash, &tctx.sha1);					memcpy(&(dat[len - authlen]), hash, authlen);										/* paranoid */					memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));					memset((caddr_t)hash, 0, sizeof(*hash));					break;#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */				case AH_NONE:					break;				default:					spin_unlock(&tdb_lock);					stats->tx_errors++;					goto cleanup;				}#ifdef NET_21				skb->h.raw = (unsigned char*)espp;#endif /* NET_21 */				break;#endif /* !CONFIG_IPSEC_ESP */#ifdef CONFIG_IPSEC_AH			case IPPROTO_AH:				ahp = (struct ah *)(dat + iphlen);				ahp->ah_spi = tdbp->tdb_said.spi;				ahp->ah_rpl = htonl(++(tdbp->tdb_replaywin_lastseq));				ahp->ah_rv = 0;				ahp->ah_nh = iph->protocol;				ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);				iph->protocol = IPPROTO_AH;				dmp("ahp", (char*)ahp, sizeof(*ahp));								ipo = *iph;				ipo.tos = 0;				ipo.frag_off = 0;				ipo.ttl = 0;				ipo.check = 0;				dmp("ipo", (char*)&ipo, sizeof(ipo));								switch(tdbp->tdb_authalg) {#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5				case AH_MD5:					tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;					dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));					dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));					dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);					dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Update(&tctx.md5,  dat + iphlen + headroom, len - iphlen - headroom);					dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Final(hash, &tctx.md5);					dmp("ictx hash", (char*)&hash, sizeof(hash));					tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;					dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Update(&tctx.md5, hash, AHMD596_ALEN);					dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));					MD5Final(hash, &tctx.md5);					dmp("octx hash", (char*)&hash, sizeof(hash));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -