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

📄 output.c

📁 cipe 编程
💻 C
📖 第 1 页 / 共 2 页
字号:
        udph->dest   = tunnel->peerport;        udph->len    = htons(length+sizeof(struct udphdr));        /* Encrypted packets are checksummed already, so we can safely	   ignore the UDP checksum. Provide a means to do it nonetheless */	udph->check  = 0;	if (tunnel->flags&CIPF_DO_CSUM) {	    udph->check=csum_tcpudp_magic(		iph->saddr, iph->daddr,		length+sizeof(struct udphdr), IPPROTO_UDP,		csum_partial((char *)udph, length+sizeof(struct udphdr), 0));	    if (!udph->check)		udph->check=-1;	}        dprintk(DEB_OUT, (KERN_INFO                          "%s: sending %d from %s:%d to %s:%d\n",                          dev->name, skb->len,                          cipe_ntoa(iph->saddr), ntohs(udph->source),                          cipe_ntoa(iph->daddr), ntohs(udph->dest)));	if (tunnel->sockshost)	    dprintk(DEB_OUT, (KERN_INFO "%s: via SOCKS to %s:%d\n", dev->name,			      cipe_ntoa(tunnel->sockshost),			      ntohs(tunnel->socksport)));#if 0        dprintk(DEB_OUT, (KERN_INFO "dst: (%d,%d) %s %d %d\n",                          skb->dst->refcnt, skb->dst->use,                          skb->dst->dev->name, skb->dst->pmtu,                          skb->dst->error));#endif#ifdef DEBUG        if (cipe_debug&DEB_PKOU)            cipe_dump_packet("sending", skb, 0);#endif        nf_conntrack_null(skb);        skb->ip_summed = CHECKSUM_NONE;#ifdef LINUX_24        {            int err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,                              rt->u.dst.dev, do_ip_send);            if (err==NET_XMIT_SUCCESS || err==NET_XMIT_CN) {                tunnel->stat.tx_bytes += skb->len;                tunnel->stat.tx_packets++;            } else {		tunnel->stat.tx_errors++;		tunnel->stat.tx_aborted_errors++;            }        }#else        ip_send(skb);        tunnel->stat.tx_bytes += skb->len;        tunnel->stat.tx_packets++;#endif        tunnel->recursion--;	return 0; tx_error:        ip_rt_put(rt); tx_error_out:	tunnel->stat.tx_errors++;	dev_kfree_skb(skb);	tunnel->recursion--;	return 0;}#else /* LINUX_21 *//* An adapted version of Linux 2.0 drivers/net/new_tunnel.c. */#ifdef SO_BINDTODEVICE  #define iproute(t,o,d) ip_rt_route(t,o,d)#else  #define iproute(t,o,d) ip_rt_route(t,o)#endif#if LINUX_VERSION_CODE < 131102  /* < 2.0.30 */  #include <linux/config.h>  #ifdef CONFIG_IP_FORWARD    #define ipforward(s,d,o,t) ip_forward(s,d,o,t)  #else    #error "Requires IP forwarding enabled in kernel"  #endif#else                            /* >= 2.0.30 */  #define ipforward(s,d,o,t) (sysctl_ip_forward ? ip_forward(s,d,o,t) : -1)#endifint cipe_xmit(struct sk_buff *skb, struct NET_DEVICE *dev){    struct enet_statistics *stats;	/* This device's statistics */    struct rtable *rt;     		/* Route to the other host */    struct NET_DEVICE *tdev;		/* Device to other host */    struct iphdr  *iph;			/* Our new IP header */    struct udphdr *udph;    __u32          target;		/* The other host's IP address */    int      max_headroom;		/* The extra header space needed */    int      max_tailroom;    int tos, ttl, length;    DEVTOCIPE(dev,c,0);    if (skb == NULL || dev == NULL) {	dprintk(DEB_OUT, (KERN_INFO "%s: nothing to do\n", dev->name));	return 0;    }    /*     *	Make sure we are not busy (check lock variable)     */    stats = &(c->stat);    if (dev->tbusy != 0)    {	printk(KERN_WARNING "%s: device timeout (really possible?)\n",	       dev->name);	dev->tbusy=0;	stats->tx_errors++;	return(1);    }#ifdef DEBUG    if (cipe_debug&DEB_PKOU)        cipe_dump_packet("original", skb, 0);#endif    /*     *  First things first.  Look up the destination address in the     *  routing tables     */    target = c->peeraddr;    if ((!target) || (!c->peerport) || (!c->myport)) {	/* unconfigured device */	printk(KERN_INFO "%s: unconfigured\n", dev->name);	goto error;    }    if ((rt = iproute(target, 0, skb->sk?skb->sk->bound_device:NULL)) == NULL)    {	/* No route to host */	printk(KERN_INFO "%s: target unreachable\n", dev->name);	goto error;    }    dprintk(DEB_OUT, (KERN_INFO		      "%s: routing to %08lX from %08lX via %08lX dev %s\n",		      dev->name, ntohl(rt->rt_dst), ntohl(rt->rt_src),		      ntohl(rt->rt_gateway), rt->rt_dev->name));    tdev = rt->rt_dev;    ip_rt_put(rt);    if (tdev == dev)    {	/* Tunnel to ourselves?  -- I don't think so. */	printk ( KERN_INFO "%s: Packet targetted at myself!\n" , dev->name);	goto error;    }    /*     * Okay, now see if we can stuff it in the buffer as-is. We can not.     */    max_headroom = (((tdev->hard_header_len+15)&~15)+cipehdrlen+		    ((c->sockshost) ? sizeof(struct sockshdr) : 0));    max_tailroom = (c->flags&CIPF_HAVE_KEY) ? cipefootlen : 0;    {		struct sk_buff *new_skb;		if ( !(new_skb =		       dev_alloc_skb(skb->len+max_headroom+max_tailroom)) )		{			printk(KERN_INFO "%s: Out of memory, dropped packet\n",			       dev->name);  			dev->tbusy = 0;  			stats->tx_dropped++;			dev_kfree_skb(skb, FREE_WRITE);			return 0;		}		new_skb->free = 1;		/*		 * Reserve space for our header and the lower device header		 */		skb_reserve(new_skb, max_headroom);		/*		 * Copy the old packet to the new buffer.		 * Note that new_skb->h.iph will be our (tunnel driver's) header		 * and new_skb->ip_hdr is the IP header of the old packet.		 */		new_skb->ip_hdr = (struct iphdr *) skb_put(new_skb, skb->len);		new_skb->mac.raw = new_skb->data;		new_skb->dev = skb->dev;		memcpy(new_skb->ip_hdr, skb->data, skb->len);		memset(new_skb->proto_priv, 0, sizeof(skb->proto_priv));		/* Free the old packet, we no longer need it */		dev_kfree_skb(skb, FREE_WRITE);		skb = new_skb;    }#ifdef VER_ETH    if (skb->mac.ethernet->h_proto==htons(ETH_P_IP)) {#endif	tos    = skb->ip_hdr->tos;	ttl    = skb->ip_hdr->ttl;#ifdef VER_ETH    } else {	tos = 0;	ttl = 64;    }#endif        length = skb->len;	if (c->flags&CIPF_HAVE_KEY) {	    /* Add an IV */	    cipe_cryptpad(skb_push(skb, c->cipher->ivsize),                          c->cipher->ivsize);	    length+=c->cipher->ivsize;            if (!c->flags&CIPF_MAY_STKEY && !c->flags&CIPF_HAVE_SKEY)                /* Attempt to encrypt data using invalid static key */                goto error;	    cipe_encrypt(c, skb->data, &length, TW_DATA);	    /* This is incorrect - the tail room gets first used and then	       reserved. Doesn't matter in the current (2.0.29) implementation	       of skb_put though. Alternative solution would ruin the nice	       module separation - we don't need to know the real amount	       of padding here. */	    (void) skb_put(skb, length-skb->len);	} else if (!c->flags&CIPF_MAY_CLEAR) {	    goto error;	}        if (c->sockshost) {	    /* Install a SOCKS header */	    struct sockshdr *sh = (struct sockshdr *)		skb_push(skb, sizeof(struct sockshdr));	    memset(sh, 0, 4);	    sh->atyp=1;	    /* sockshost and socksport contain the real peer's address	       and the configured/guessed peer is really the socks relayer! */	    sh->dstaddr=c->sockshost;	    sh->dstport=c->socksport;	    length+=sizeof(struct sockshdr);	}        /* Install our new headers */        udph = (struct udphdr *) skb_push(skb, sizeof(struct udphdr));        skb->h.iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr));	/*	 *	Push down and install the CIPE/UDP header.	 */	iph 			=	skb->h.iph;	iph->version		= 	4;	iph->tos		=	tos;	/* In new_tunnel.c, we use the original packet's TTL here.	   Setting a new TTL behaves better to the user, and RFC2003	   recommends it too. But this doesn't fully protect against	   routing loops. So make it configurable via an argument:	   "cttl" gives the TTL value; if 0 use the packet's	   value. Default should be 64, as with the other protocols	   (ip_statistics.IpDefaultTTL, but this variable is not	   available for modules). */	iph->ttl 		=	c->cttl ? c->cttl : ttl;	iph->frag_off		=	0;	iph->daddr		=	target;	iph->saddr		=	c->myaddr; /* tdev->pa_addr; */	iph->protocol		=	IPPROTO_UDP;	iph->ihl		=	5;	iph->tot_len		=	htons(skb->len);	iph->id			=	htons(ip_id_count++);	/* Race condition here? */	ip_send_check(iph);        udph->source = c->myport;        udph->dest   = c->peerport;        udph->len    = htons(length+sizeof(struct udphdr));        /* Encrypted packets are checksummed already, so we can safely	   ignore the UDP checksum. Provide a means to do it nonetheless */	udph->check  = 0;	if (c->flags&CIPF_DO_CSUM) {	    udph->check=csum_tcpudp_magic(		iph->saddr, iph->daddr,		length+sizeof(struct udphdr), IPPROTO_UDP,		csum_partial((char *)udph, length+sizeof(struct udphdr), 0));	    if (!udph->check)		udph->check=-1;	}	skb->ip_hdr 		= skb->h.iph;	skb->protocol		=	htons(ETH_P_IP);	/*	 *	Send the packet on its way!	 *	Note that dev_queue_xmit() will eventually free the skb.	 *	If ip_forward() made a copy, it will return 1 so we can free.	 */	dprintk(DEB_OUT, (KERN_INFO "%s: send to %s via %s\n",			  dev->name, cipe_ntoa(target), tdev->name));#ifdef DEBUG    if (cipe_debug&DEB_PKOU)        cipe_dump_packet("sending", skb, 0);#endif	switch (ipforward(skb, dev, IPFWD_NOTTLDEC, target)) {	case -1:	    printk(KERN_INFO "%s: forwarding failed\n", dev->name);	    /* fall thru */	case 1:	    dev_kfree_skb(skb, FREE_WRITE);	    /* Does it really need dev_ here? I think so. */	    break;	default:	    /* nothing to do */	}	/*	 *	Clean up:  We're done with the route and the packet	 */	/* Record statistics and return */	stats->tx_packets++;	dev->tbusy=0;	return 0;    error:	stats->tx_errors++;	dev_kfree_skb(skb, FREE_WRITE);	dev->tbusy=0;	return 0;}#endif /* LINUX_21 */

⌨️ 快捷键说明

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