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

📄 ipsec_tunnel.c

📁 网上下到的一个很详细介绍VPN基础知识的资料
💻 C
📖 第 1 页 / 共 5 页
字号:
			}			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", 				    TDB_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;			}			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;			}			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));			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;			}			memmove((void *)dat, (void *)(dat + headroom), iphlen);			iph = (struct iphdr *)dat;			iph->tot_len = htons(skb->len);						switch(tdbp->tdb_said.proto) {#ifdef CONFIG_IPSEC_ESP			case IPPROTO_ESP:				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 = dat + iphlen + headroom;				ilen = len - (iphlen + headroom + authlen);								/* Self-describing padding */				pad = &dat[len - tailroom];				padlen = tailroom - 2 - authlen;				for (i = 0; i < padlen; i++) {					pad[i] = i + 1; 				}				dat[len - authlen - 2] = padlen;								dat[len - authlen - 1] = iph->protocol;				iph->protocol = IPPROTO_ESP;								switch(tdbp->tdb_encalg) {#ifdef CONFIG_IPSEC_ENC_3DES				case ESP_3DES:					des_ede3_cbc_encrypt(idat, idat, ilen,							     (caddr_t)(&((struct des_eks*)(tdbp->tdb_key_e))[0]),							     (caddr_t)(&((struct des_eks*)(tdbp->tdb_key_e))[1]),							     (caddr_t)(&((struct des_eks*)(tdbp->tdb_key_e))[2]),							     (caddr_t)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));										memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);										/* 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, (unsigned char *)&ipo, sizeof (struct iphdr));					SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));					SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);					SHA1Update(&tctx.sha1,  dat + iphlen + headroom, len - iphlen - headroom);					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(ahp->ah_data, hash, AHHMAC_HASHLEN);										/* paranoid */					memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));					memset((caddr_t)hash, 0, sizeof(hash));					break;#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */				default:					spin_unlock(&tdb_lock);					stats->tx_errors++;					goto cleanup;				}#ifdef NET_21				skb->h.raw = (unsigned char*)ahp;#endif /* NET_21 */				break;#endif /* CONFIG_IPSEC_AH */#ifdef CONFIG_IPSEC_IPIP			case IPPROTO_IPIP:				iph->version  = 4;				switch(sysctl_ipsec_tos) {				case 0:#ifdef NET_21					iph->tos = skb->nh.iph->tos;#else /* NET_21 */					iph->tos = skb->ip_hdr->tos;#endif /* NET_21 */					break;				case 1:					iph->tos = 0;					break;				default:				}#ifdef NET_21#ifdef NETDEV_23				iph->ttl      = sysctl_ip_default_ttl;#else /* NETDEV_23 */				iph->ttl      = ip_statistics.IpDefaultTTL;#endif /* NETDEV_23 */#else /* NET_21 */				iph->ttl      = 64; /* ip_statistics.IpDefaultTTL; */#endif /* NET_21 */				iph->frag_off = 0;				iph->saddr    = ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr;				iph->daddr    = ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr.s_addr;				iph->protocol = IPPROTO_IPIP;				iph->ihl      = sizeof(struct iphdr) >> 2 /* 5 */;#ifdef IP_SELECT_IDENT				/* XXX use of skb->dst below is a questionable				   substitute for &rt->u.dst which is only				   available later-on */#ifdef IP_SELECT_IDENT_NEW				ip_select_ident(iph, skb->dst, NULL);#else /* IP_SELECT_IDENT_NEW */                                ip_select_ident(iph, skb->dst);#endif /* IP_SELECT_IDENT_NEW */#else /* IP_SELECT_IDENT */				iph->id       = htons(ip_id_count++);   /* Race condition here? */#endif /* IP_SELECT_IDENT */				newdst = (__u32)iph->daddr;				newsrc = (__u32)iph->saddr;		#ifdef NET_21				skb->h.ipiph = skb->nh.iph;#endif /* NET_21 */				break;#endif /* !CONFIG_IPSEC_IPIP */#ifdef CONFIG_IPSEC_IPCOMP			case IPPROTO_COMP:				{					unsigned int flags = 0;#ifdef CONFIG_IPSEC_DEBUG					unsigned int old_tot_len = ntohs(iph->tot_len);#endif /* CONFIG_IPSEC_DEBUG */					tdbp->tdb_comp_ratio_dbytes += ntohs(iph->tot_len);					skb = skb_compress(skb, tdbp, &flags);#ifdef NET_21					iph = skb->nh.iph;#else /* NET_21 */					iph = skb->ip_hdr;#endif /* NET_21 */					tdbp->tdb_comp_ratio_cbytes += ntohs(iph->tot_len);#ifdef CONFIG_IPSEC_DEBUG					if (debug_tunnel & DB_TN_CROUT)					{						if (old_tot_len > ntohs(iph->tot_len))							KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,								    "klips_debug:ipsec_tunnel_start_xmit: "								    "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",								    old_tot_len, ntohs(iph->tot_len),								    ntohs(((struct ipcomphdr*)(((char*)iph) + ((iph->ihl) << 2)))->ipcomp_cpi),								    ntohl(tdbp->tdb_said.spi),								    (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff));						else							KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,								    "klips_debug:ipsec_tunnel_start_xmit: "								    "packet did not compress (flags = %d).\n",								    flags);					}#endif /* CONFIG_IPSEC_DEBUG */				}				break;#endif /* CONFIG_IPSEC_IPCOMP */			default:				spin_unlock(&tdb_lock);

⌨️ 快捷键说明

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