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

📄 ipsec_xmit.c

📁 openswan
💻 C
📖 第 1 页 / 共 4 页
字号:
					      , "klips_xmit: invalid nat-t type %d"					      , ixs->natt_type);				  bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;				  goto cleanup;					      					break;			}			ixs->tailroom += ixs->natt_head;		}#endif			break;#endif /* !CONFIG_KLIPS_ESP */#ifdef CONFIG_KLIPS_IPIP		case IPPROTO_IPIP:			ixs->headroom += sizeof(struct iphdr);			break;#endif /* !CONFIG_KLIPS_IPIP */		case IPPROTO_COMP:#ifdef CONFIG_KLIPS_IPCOMP			/*			  We can't predict how much the packet will			  shrink without doing the actual compression.			  We could do it here, if we were the first			  encapsulation in the chain.  That might save			  us a skb_copy_expand, since we might fit			  into the existing skb then.  However, this			  would be a bit unclean (and this hack has			  bit us once), so we better not do it. After			  all, the skb_copy_expand is cheap in			  comparison to the actual compression.			  At least we know the packet will not grow.			*/			break;#endif /* CONFIG_KLIPS_IPCOMP */		default:			ixs->stats->tx_errors++;			bundle_stat = IPSEC_XMIT_BADPROTO;			goto cleanup;		}		ixs->ipsp = ixs->ipsp->ips_onext;		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_debug:ipsec_xmit_encap_bundle: "			    "Required head,tailroom: %d,%d\n", 			    ixs->headroom, ixs->tailroom);		ixs->max_headroom += ixs->headroom;		ixs->max_tailroom += ixs->tailroom;		ixs->pyldsz += (ixs->headroom + ixs->tailroom);	}	ixs->ipsp = ixs->ipsq;	/* restore the head of the ipsec_sa chain */			KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,		    "klips_debug:ipsec_xmit_encap_bundle: "		    "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",		    skb_headroom(ixs->skb), skb_tailroom(ixs->skb),		    ixs->max_headroom, ixs->max_tailroom);			ixs->tot_headroom += ixs->max_headroom;	ixs->tot_tailroom += ixs->max_tailroom;	ixs->mtudiff = ixs->cur_mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;	KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,		    "klips_debug:ipsec_xmit_encap_bundle: "		    "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",		    ixs->cur_mtu, ixs->physmtu,		    ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));	if(ixs->mtudiff > 0) {		int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_info:ipsec_xmit_encap_bundle: "			    "dev %s mtu of %d decreased by %d to %d\n",			    ixs->dev ? ixs->dev->name : "ifX",			    ixs->cur_mtu,			    ixs->cur_mtu - newmtu,			    newmtu);		ixs->cur_mtu = newmtu;		/* this would seem to adjust the MTU of the route as well */#if 0		ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */#endif /* 0 */	}	/* 	   If the sender is doing PMTU discovery, and the	   packet doesn't fit within ixs->prv->mtu, notify him	   (unless it was an ICMP packet, or it was not the	   zero-offset packet) and send it anyways.	   Note: buggy firewall configuration may prevent the	   ICMP packet from getting back.	*/	if(sysctl_ipsec_icmp	   && ixs->cur_mtu < ntohs(ixs->iph->tot_len)	   && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {		int notify = ixs->iph->protocol != IPPROTO_ICMP			&& (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;			#ifdef IPSEC_obey_DF		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_debug:ipsec_xmit_encap_bundle: "			    "fragmentation needed and DF set; %sdropping packet\n",			    notify ? "sending ICMP and " : "");		if (notify)			ICMP_SEND(ixs->skb,				  ICMP_DEST_UNREACH,				  ICMP_FRAG_NEEDED,				  ixs->cur_mtu,				  ixs->physdev);		ixs->stats->tx_errors++;		bundle_stat = IPSEC_XMIT_CANNOTFRAG;		goto cleanup;#else /* IPSEC_obey_DF */		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_debug:ipsec_xmit_encap_bundle: "			    "fragmentation needed and DF set; %spassing packet\n",			    notify ? "sending ICMP and " : "");		if (notify)			ICMP_SEND(ixs->skb,				  ICMP_DEST_UNREACH,				  ICMP_FRAG_NEEDED,				  ixs->cur_mtu,				  ixs->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 (ixs->iph->protocol == IPPROTO_TCP 	    && ixs->outgoing_said.proto != IPPROTO_IPIP) {		struct tcphdr *tcph = ixs->skb->h.th;		if (tcph->syn && !tcph->ack) {			if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->cur_mtu)) {				printk(KERN_WARNING				       "klips_warning:ipsec_xmit_encap_bundle: "				       "ipsec_adjust_mss() failed\n");				ixs->stats->tx_errors++;				bundle_stat = IPSEC_XMIT_MSSERR;				goto cleanup;			}		}	}#endif /* MSS_HACK */#ifdef CONFIG_IPSEC_NAT_TRAVERSAL      if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {	      /**	       * NAT-Traversal and Transport Mode:	       *   we need to correct TCP/UDP checksum	       *	       * If we've got NAT-OA, we can fix checksum without recalculation.	       * If we don't we can zero udp checksum.	       */	      __u32 natt_oa = ixs->ipsp->ips_natt_oa ?		      ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;	      __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph;	      __u16 data_len = pkt_len - (ixs->iph->ihl << 2);	      switch (ixs->iph->protocol) {		      case IPPROTO_TCP:			      if (data_len >= sizeof(struct tcphdr)) {				      struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);				      if (natt_oa) {					      __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };					      KLIPS_PRINT(debug_tunnel,						      "klips_debug:ipsec_tunnel_start_xmit: "						      "NAT-T & TRANSPORT: "						      "fix TCP checksum using NAT-OA\n");					      tcp->check = csum_fold(						      csum_partial((unsigned char *)buff, sizeof(buff),						      tcp->check^0xffff));				      }				      else {					      KLIPS_PRINT(debug_tunnel,						      "klips_debug:ipsec_tunnel_start_xmit: "						      "NAT-T & TRANSPORT: do not recalc TCP checksum\n");				      }			      }			      else {				      KLIPS_PRINT(debug_tunnel,					      "klips_debug:ipsec_tunnel_start_xmit: "					      "NAT-T & TRANSPORT: can't fix TCP checksum\n");			      }			      break;		      case IPPROTO_UDP:			      if (data_len >= sizeof(struct udphdr)) {				      struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);				      if (udp->check == 0) {					      KLIPS_PRINT(debug_tunnel,						      "klips_debug:ipsec_tunnel_start_xmit: "						      "NAT-T & TRANSPORT: UDP checksum already 0\n");				      }				      else if (natt_oa) {					      __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };					      KLIPS_PRINT(debug_tunnel,						      "klips_debug:ipsec_tunnel_start_xmit: "						      "NAT-T & TRANSPORT: "						      "fix UDP checksum using NAT-OA\n");					      udp->check = csum_fold(						      csum_partial((unsigned char *)buff, sizeof(buff),						      udp->check^0xffff));				      }				      else {					      KLIPS_PRINT(debug_tunnel,						      "klips_debug:ipsec_tunnel_start_xmit: "						      "NAT-T & TRANSPORT: zero UDP checksum\n");					      udp->check = 0;				      }			      }			      else {				      KLIPS_PRINT(debug_tunnel,					      "klips_debug:ipsec_tunnel_start_xmit: "					      "NAT-T & TRANSPORT: can't fix UDP checksum\n");			      }			      break;		      default:			      KLIPS_PRINT(debug_tunnel,				      "klips_debug:ipsec_tunnel_start_xmit: "				      "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");			      break;	      }      }#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */	if(!ixs->hard_header_stripped && ixs->hard_header_len>0) {		KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,			    "klips_debug:ipsec_xmit_encap_bundle: "			    "allocating %d bytes for hardheader.\n",			    ixs->hard_header_len);		if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {			printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "			       "Failed, tried to allocate %d bytes for temp hard_header.\n", 			       ixs->hard_header_len);			ixs->stats->tx_errors++;			bundle_stat = IPSEC_XMIT_ERRMEMALLOC;			goto cleanup;		}		{			int i;			for (i = 0; i < ixs->hard_header_len; i++) {				ixs->saved_header[i] = ixs->skb->data[i];			}		}		if(ixs->skb->len < ixs->hard_header_len) {			printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "			       "tried to skb_pull hhlen=%d, %d available.  This should never happen, please report.\n",			       ixs->hard_header_len, (int)(ixs->skb->len));			ixs->stats->tx_errors++;			bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;			goto cleanup;		}		skb_pull(ixs->skb, ixs->hard_header_len);		ixs->hard_header_stripped = 1;			/*			ixs->iph = (struct iphdr *) (ixs->skb->data); */		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_debug:ipsec_xmit_encap_bundle: "			    "head,tailroom: %d,%d after hard_header stripped.\n",			    skb_headroom(ixs->skb), skb_tailroom(ixs->skb));		KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);	} else {		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_debug:ipsec_xmit_encap_bundle: "			    "hard header already stripped.\n");	}			ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;	if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) && 	    (skb_tailroom(ixs->skb) >= ixs->max_tailroom)#ifndef NET_21	    && ixs->skb->free#endif /* !NET_21 */		) {		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_debug:ipsec_xmit_encap_bundle: "			    "data fits in existing skb\n");	} else {		struct sk_buff* tskb;		if(!ixs->oskb) {			ixs->oskb = ixs->skb;		}		tskb = skb_copy_expand(ixs->skb,				       /* The need for 2 * link layer length here remains unexplained...RGB */				       ixs->max_headroom + 2 * ixs->ll_headroom,				       ixs->max_tailroom,				       GFP_ATOMIC);		if(tskb && ixs->skb->sk) {			skb_set_owner_w(tskb, ixs->skb->sk);		}		if(ixs->skb != ixs->oskb) {			ipsec_kfree_skb(ixs->skb);		}		ixs->skb = tskb;		if (!ixs->skb) {			printk(KERN_WARNING			       "klips_debug:ipsec_xmit_encap_bundle: "			       "Failed, tried to allocate %d head and %d tailroom\n", 			       ixs->max_headroom, ixs->max_tailroom);			ixs->stats->tx_errors++;			bundle_stat = IPSEC_XMIT_ERRSKBALLOC;			goto cleanup;		}		KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,			    "klips_debug:ipsec_xmit_encap_bundle: "			    "head,tailroom: %d,%d after allocation\n",			    skb_headroom(ixs->skb), skb_tailroom(ixs->skb));	}			if(debug_tunnel & DB_TN_ENCAP) {		ipsec_print_ip(ixs->iph);	}	/*	 * Apply grouped transforms to packet	 */	while (ixs->ipsp) {		enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;		encap_stat = ipsec_xmit_encap_once(ixs);		if(debug_tunnel & DB_TN_ENCAP) {			ipsec_print_ip(ixs->iph);		}		if(encap_stat != IPSEC_XMIT_OK) {			KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,				    "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",				    encap_stat);							bundle_stat = IPSEC_XMIT_ENCAPFAIL;			goto cleanup;		}	}	/* we are done with this SA */	ipsec_sa_put(ixs->ipsp); 	/* end encapsulation loop here XXX */ cleanup:	spin_unlock(&tdb_lock);	return bundle_stat;}/* * $Log: ipsec_xmit.c,v $ * Revision 1.20.2.6  2006/07/07 22:09:49  paul * From: Bart Trojanowski <bart@xelerance.com> * Removing a left over '#else' that split another '#if/#endif' block in two. * * Revision 1.20.2.5  2006/07/07 15:43:17  paul * From: Bart Trojanowski <bart@xelerance.com> * improved protocol detection in ipsec_print_ip() -- a debug aid. * * Revision 1.20.2.4  2006/04/20 16:33:07  mcr * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it. * Fix in-kernel module compilation. Sub-makefiles do not work. * * Revision 1.20.2.3  2005/11/29 21:52:57  ken * Fix for #518 MTU issues * * Revision 1.20.2.2  2005/11/27 21:41:03  paul * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"in for klips as module. * * Revision 1.20.2.1  2005/08/27 23:40:00  paul * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13 * * Revision 1.20  2005/07/12 15:39:27  paul * include asm/uaccess.h for VERIFY_WRITE * * Revision 1.19  2005/05/24 01:02:35  mcr * 	some refactoring/simplification of situation where alg * 	is not found. * * Revision 1.18  2005/05/23 23:52:33  mcr * 	adjust comments, add additional debugging. * * Revision 1.17  2005/05/23 22:57:23  mcr * 	removed explicit 3DES support. * * Revision 1.16  2005/05/21 03:29:15  mcr * 	fixed warning about unused zeroes if AH is off. * * Revision 1.15  2005/05/20 16:47:59  mcr * 	include asm/checksum.h to get ip_fast_csum macro. * * Revision 1.14  2005/05/11 01:43:03  mcr * 	removed "poor-man"s OOP in favour of proper C structures. * * Revision 1.13  2005/04/29 05:10:22  mcr * 	removed from extraenous includes to make unit testing easier. * * Revision 1.12  2005/04/15 01:28:34  mcr * 	use ipsec_dmp_block. * * Revision 1.11  2005/01/26 00:50:35  mcr * 	adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT, * 	and make sure that NAT_TRAVERSAL is set as well to match * 	userspace compiles of code. * * Revision 1.10  2004/09/13 17:55:21  ken * MD5* -> osMD5* * * Revision 1.9  2004/07/10 19:11:18  mcr * 	CONFIG_IPSEC -> CONFIG_KLIPS. * * Revision 1.8  2004/04/06 02:49:26  mcr * 	pullup of algo code from alg-branch. * * Revision 1.7  2004/02/03 03:13:41  mcr * 	mark invalid encapsulation states. * * Revision 1.6.2.1  2003/12/22 15:25:52  jjo *      Merged algo-0.8.1-rc11-test1 into alg-branch * * Revision 1.6  2003/12/10 01:14:27  mcr * 	NAT-traversal patches to KLIPS. * * Revision 1.5  2003/10/31 02:27:55  mcr * 	pulled up port-selector patches and sa_id elimination. * * Revision 1.4.4.2  2003/10/29 01:37:39  mcr * 	when creating %hold from %trap, only make the %hold as * 	specific as the %trap was - so if the protocol and ports * 	were wildcards, then the %hold will be too. * * Revision 1.4.4.1  2003/09/21 13:59:56  mcr * 	pre-liminary X.509 patch - does not yet pass tests. * * Revision 1.4  2003/06/20 02:28:10  mcr * 	misstype of variable name, not detected by module build. * * Revision 1.3  2003/06/20 01:42:21  mcr * 	added counters to measure how many ACQUIREs we send to pluto, * 	and how many are successfully sent. * * Revision 1.2  2003/04/03 17:38:35  rgb * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. * Normalised coding style. * Simplified logic and reduced duplication of code. * * Revision 1.1  2003/02/12 19:31:23  rgb * Refactored from ipsec_tunnel.c * * Local Variables: * c-file-style: "linux" * End: * */

⌨️ 快捷键说明

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