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

📄 output.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   CIPE - encrypted IP over UDP tunneling   output.c - the sending part of the CIPE device   Copyright 1996 Olaf Titz <olaf@bigred.inka.de>   This program is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public License   as published by the Free Software Foundation; either version   2 of the License, or (at your option) any later version.*//* $Id: linux-2.4.0-cipe-1.4.5.patch,v 1.6 2001/04/17 18:50:11 arjanv Exp $ */#include "cipe.h"#include <net/ip.h>#include <net/icmp.h>#include <linux/if_arp.h>#include <linux/socket.h>#include <linux/version.h>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)#include <linux/netfilter_ipv4.h>#else#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)#endif#ifdef DEBUGstatic void cipe_hexdump(const unsigned char *bp, unsigned int len){    static const __u16 p[16]={0,2,5,7,10,12,15,17,21,23,26,28,31,33,36,38};    static const char h[16]="0123456789abcdef";    short i=0, j=0;    static /*?*/ char b[58];    printk(KERN_DEBUG "(cipe_hexdump %p %x)\n", bp, len);    if (len>1024)	len=1024; /* sanity */    memset(b, ' ', sizeof(b));    while (len-->0) {	if (i>15) {	    b[sizeof(b)-1]=0;	    printk(KERN_DEBUG " %04x:  %s\n", j, b);	    memset(b, ' ', sizeof(b));	    i=0; j+=16;	}	b[p[i]]=h[*bp>>4]; b[p[i]+1]=h[*bp&15];	b[i+42]=(((*bp)&0x60)==0||*bp==127)?'.':*bp;	++bp; ++i;    }    b[sizeof(b)-1]=0;    printk(KERN_DEBUG " %04x:  %s\n", j, b);}void cipe_dump_packet(char *title, struct sk_buff *skb, int dumpskb){    LOCK_PRINTK;    if (dumpskb) {	printk(KERN_DEBUG "SKB:\n");	cipe_hexdump((unsigned char *)skb, sizeof(*skb));    }    printk(KERN_DEBUG#ifdef LINUX_21           "%s: packet len=%x dev=%s\n",#else           "%s: packet len=%lx dev=%s\n",#endif           title, skb->len, skb->dev?skb->dev->name:"<none>");    cipe_hexdump((unsigned char *)skb->data, skb->tail-skb->data);    UNLOCK_PRINTK;}#endif#ifdef LINUX_21/* An adapted version of Linux 2.1 net/ipv4/ipip.c output routine. */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,37)#define ip_select_ident(h,d) (h)->id=htons(ip_id_count++)#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,36)/* this is not exactly the newer kernel's routine, it just does what we need */struct sk_buff *skb_copy_expand(struct sk_buff *skb, int max_headroom,				int max_tailroom, int gfp){    struct sk_buff *n=alloc_skb(skb->len+max_headroom+max_tailroom, gfp);    if (n) {	skb_reserve(n, max_headroom);	skb_put(n,skb->len);	memcpy(n->data,skb->data,skb->len);	n->priority=skb->priority;	n->protocol=skb->protocol;	n->dev=skb->dev;	n->dst=dst_clone(skb->dst);	memcpy(n->cb, skb->cb, sizeof(skb->cb));	n->used=skb->used;	n->is_clone=0;	atomic_set(&n->users, 1);	n->pkt_type=skb->pkt_type;	n->stamp=skb->stamp;	n->security=skb->security;#ifdef CONFIG_IP_FIREWALL	n->fwmark = skb->fwmark;#endif    }    return n;}#endif/* Need this wrapper because NF_HOOK takes the function address, and   ip_send was declared "extern inline" in the vague past. --RR */static inline int do_ip_send(struct sk_buff *skb){	return ip_send(skb);}int cipe_xmit(struct sk_buff *skb, struct NET_DEVICE *dev){        struct cipe *tunnel = (struct cipe*)(dev->priv);	struct rtable *rt = NULL;			/* Route to the other host */	struct NET_DEVICE *tdev;			/* Device to other host */	struct iphdr  *old_iph = skb->nh.iph;	u8     	tos = old_iph->tos;	u16	df = old_iph->frag_off&__constant_htons(IP_DF);	u8	ttl = tunnel->cttl ? tunnel->cttl : old_iph->ttl;	struct iphdr  *iph;			/* Our new IP header */        struct udphdr *udph;	int    	max_headroom;			/* The extra header space needed */	int    	max_tailroom;	u32    	dst = tunnel->peeraddr;	int    	mtu;        int     length = ntohs(skb->nh.iph->tot_len);       	dprintk(DEB_OUT, (KERN_DEBUG "%s: cipe_xmit len=%d(%d)\n", dev->name,                          length, skb->len));	if (length!=skb->len) {	    printk(KERN_ERR "%s: cipe_xmit packet length problem\n",		   dev->name);	    goto tx_error_out;	}        if (tunnel->magic!=CIPE_MAGIC) {            printk(KERN_ERR DEVNAME                   ": cipe_xmit called with wrong struct\n");            return 0;        }        if (tunnel->recursion++) {        	printk(KERN_ERR "%s: cipe_xmit reentrance\n", dev->name);		tunnel->stat.collisions++;		goto tx_error_out;	}	if (skb->protocol != __constant_htons(ETH_P_IP))		goto tx_error_out;	/* Tell the netfilter framework that this packet is not the           same as the one before! */#ifdef CONFIG_NETFILTER	nf_conntrack_put(skb->nfct);	skb->nfct = NULL;#ifdef CONFIG_NETFILTER_DEBUG	skb->nf_debug = 0;#endif#endif#if 0        dprintk(DEB_OUT, (KERN_DEBUG "routing dst=%s src=%s tos=%x oif=%d\n",                          cipe_ntoa(0, dst), cipe_ntoa(1, tunnel->myaddr),                          RT_TOS(tos), tunnel->sock->bound_dev_if));#endif	if (ip_route_output(&rt, dst, tunnel->sock->rcv_saddr, RT_TOS(tos),                            tunnel->sock->bound_dev_if)) {            dprintk(DEB_OUT, (KERN_NOTICE "%s: no route\n", dev->name));            tunnel->stat.tx_carrier_errors++;            dst_link_failure(skb);            goto tx_error_out;        }        if (rt->rt_src!=tunnel->myaddr) {            printk(KERN_NOTICE "%s: changing my address: %s\n", dev->name,                   cipe_ntoa(rt->rt_src));            tunnel->myaddr=tunnel->sock->saddr=rt->rt_src;	}	tdev = rt->u.dst.dev;        dprintk(DEB_OUT, (KERN_DEBUG "route dev=%s flags=%x type=%x\n",                          tdev->name, rt->rt_flags, rt->rt_type));	if (tdev == dev) {        	printk(KERN_ERR "%s: looped route\n", dev->name);		tunnel->stat.collisions++;		goto tx_error;	}        mtu = rt->u.dst.pmtu - (cipehdrlen+cipefootlen);        if (tunnel->sockshost)            mtu -= sizeof(struct sockshdr);        dprintk(DEB_OUT, (KERN_DEBUG "pmtu=%d dmtu=%d size=%d\n",                          mtu, tdev->mtu, skb->len));	if (mtu < 68) {        	printk(KERN_ERR "%s: MTU too small\n", dev->name);		tunnel->stat.collisions++;		goto tx_error;	}	if (skb->dst && mtu < skb->dst->pmtu) {		skb->dst->pmtu = mtu;        	dprintk(DEB_OUT, (KERN_NOTICE "%s: adjusting PMTU\n", dev->name));#if 0                /* TEST: is this OK? */		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));                goto tx_error;#endif        }	if ((old_iph->frag_off&__constant_htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {        	dprintk(DEB_OUT, (KERN_NOTICE "%s: fragmentation needed\n", dev->name));		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));		goto tx_error;	}#ifdef DEBUG        if (cipe_debug&DEB_PKOU)            cipe_dump_packet("original", skb, 0);#endif        max_headroom = ((tdev->hard_header_len+cipehdrlen+			 ((tunnel->sockshost) ? sizeof(struct sockshdr) : 0)	                )+16)&(~15);        max_tailroom = (tunnel->flags&CIPF_HAVE_KEY) ? cipefootlen : 0;	{	    struct sk_buff *n= skb_copy_expand(skb, max_headroom,                                               max_tailroom, GFP_ATOMIC);            if (!n) {                printk(KERN_INFO "%s: Out of memory, dropped packet\n",                       dev->name);                goto tx_error;            }            if (skb->sk)                    skb_set_owner_w(n, skb->sk);	    dev_kfree_skb(skb);            skb = n;        }	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));	dst_release(skb->dst);	skb->dst = &rt->u.dst;	skb->protocol = htons(ETH_P_IP);	if (tunnel->flags&CIPF_HAVE_KEY) {#ifndef VER_SHORT	    /* Add an IV */	    cipe_cryptpad(skb_push(skb, blockSize));	    length+=blockSize;#endif            if (!tunnel->flags&CIPF_MAY_STKEY && !tunnel->flags&CIPF_HAVE_SKEY)                /* Attempt to encrypt data using invalid static key */                goto tx_error;	    cipe_encrypt(tunnel, 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. */	    if (length-skb->len > skb->end-skb->tail) {		printk(KERN_ERR "%s: tailroom problem %d %d %d\n",		       dev->name, length, skb->len, skb->end-skb->tail);		goto tx_error;	    }	    (void) skb_put(skb, length-skb->len);	} else if (!tunnel->flags&CIPF_MAY_CLEAR) {	    goto tx_error;	}        if (tunnel->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=tunnel->sockshost;	    sh->dstport=tunnel->socksport;	    length+=sizeof(struct sockshdr);	}        /* Install our new headers */        udph = skb->h.uh = (struct udphdr *) skb_push(skb, sizeof(struct udphdr));	skb->mac.raw = skb_push(skb, sizeof(struct iphdr));        iph = skb->nh.iph = (struct iphdr *) skb->mac.raw;	/*	 *	Push down and install the CIPE/UDP header.	 */	iph->version    =	4;	iph->ihl        =	sizeof(struct iphdr)>>2;	iph->tos        =	tos;	iph->tot_len    =	htons(skb->len);	ip_select_ident(iph, &rt->u.dst, tunnel->sock);

⌨️ 快捷键说明

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