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

📄 sock.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   CIPE - encrypted IP over UDP tunneling   sock.c - socket/input interface   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 <linux/config.h>#include <linux/sched.h>#include <net/sock.h>#include <net/ip.h>#include <net/udp.h>#ifdef LINUX_21#include <asm/uaccess.h>#elsetypedef unsigned short mm_segment_t;#endif#ifdef LINUX_21#define kfreeskb(s,t) kfree_skb(s)#define saddr(skb) ((skb)->nh.iph->saddr)#define daddr(skb) ((skb)->nh.iph->daddr)#else#define kfreeskb(s,t) kfree_skb(s,t)#define saddr(skb) ((skb)->saddr)#define daddr(skb) ((skb)->daddr)#endif/* Rewire generic socket operations to our device-specific ones.   We have new routines for close, sendmsg, recvmsg. *//* init struct cipe *c based on struct sock *sk */#ifdef LINUX_21#define SOCKTOC(nam,sk,c,r) \    struct cipe *c=(struct cipe *)sk->user_data; \    if ((!c) || (c->magic!=CIPE_MAGIC)) { \	 printk(KERN_ERR "Ouch: SOCKTOC" nam "\n"); return r; } \    else { \         dprintk(DEB_CALL, (KERN_DEBUG "%s: " nam "\n", c->dev->name)); }#else#define SOCKTOC(nam,sk,c,r) \    struct cipe *c=(struct cipe *)sk->protinfo.af_packet.bound_dev; \    if ((!c) || (c->magic!=CIPE_MAGIC)) { \	 printk(KERN_ERR "Ouch: SOCKTOC" nam "\n"); return r; } \    else { \         dprintk(DEB_CALL, (KERN_DEBUG "%s: " nam "\n", c->dev->name)); }#endif/* Close the socket */void cipe_sock_close(struct sock *sock, timeout_t timeout){    SOCKTOC("sock_close",sock,c,);    c->sock=NULL;    /* Put back the old protocol block and let it do the close */    sock->prot=c->udp_prot;    sock->prot->close(sock, timeout);    if (c->dev->flags&IFF_UP) {	rtnl_LOCK();	dev_close(c->dev);	rtnl_UNLOCK();    } else {	cipe_close(c);    }}/* Anything we send to this socket is in fact a key exchange block.   Encode and encrypt it accordingly.*/int cipe_sendmsg(struct sock *sock, struct msghdr *msg, int len#ifndef LINUX_21                 , int nonblock, int flags#endif    ){    struct msghdr mymsg;    struct iovec myio[2];    struct sockaddr_in sa;    struct sockshdr sh;    int e, n=0;    unsigned char buf[KEYXCHGBLKMAX+blockSize];    SOCKTOC("cipe_sendmsg",sock,c,-ENOSYS);    if (len>KEYXCHGBLKMAX)	return -EMSGSIZE;    cipe_prnpad(buf, sizeof(buf));#ifdef VER_SHORT    memcpy_fromiovec(buf, msg->msg_iov, len);#else    memcpy_fromiovec(buf+blockSize, msg->msg_iov, len);    len+=blockSize;#endif    if (buf[0#ifndef VER_SHORT             +blockSize#endif                       ]>=CT_DUMMY) {        if (!c->flags&CIPF_HAVE_KEY)            return -EINVAL;        buf[KEYXCHGTSPOS-1]='\0';    } else {        if (len<KEYXCHGBLKMIN)            return -EINVAL;    }    (*(__u32 *)(buf+KEYXCHGTSPOS))=htonl(CURRENT_TIME); /* timestamp */    len=KEYXCHGBLKMIN+buf[sizeof(buf)-1]; /* random */    cipe_encrypt(c, buf, &len, TW_NEWKEY);    sa.sin_family=AF_INET;    sa.sin_addr.s_addr=c->peeraddr;    sa.sin_port=c->peerport;    if (c->sockshost) {	/* Prepend a socks header. */	memset(&sh, 0, sizeof(sh));	sh.atyp=1;	sh.dstaddr=c->sockshost;	sh.dstport=c->socksport;	myio[n].iov_base=&sh;	myio[n].iov_len=sizeof(sh);	++n;    }    myio[n].iov_base=&buf;    myio[n].iov_len=len;    /* mymsg=*msg; */    mymsg.msg_name=&sa;    mymsg.msg_namelen=sizeof(sa);    mymsg.msg_iov=myio;    mymsg.msg_iovlen=n+1;    /* just to be sure */    mymsg.msg_control=NULL;    mymsg.msg_controllen=0;    mymsg.msg_flags=0;    /* Call the real thing. Pretend this is user space segment. */    {        mm_segment_t fs=get_fs();        set_fs(get_ds());        if (c->sockshost)            len+=sizeof(struct sockshdr);        dprintk(DEB_KXC, (KERN_DEBUG "%s: real sendmsg len %d text=%04x...\n",                          c->dev->name, len,                          ntohs(*((unsigned short *)(myio[n].iov_base)))));        e=c->udp_prot->sendmsg(sock, &mymsg, len#ifndef LINUX_21                               , nonblock, flags#endif            );        set_fs(fs);    }    return e;}/* Check if we have a new peer */static void checkpeer(struct cipe *c, __u32 saddr, __u16 sport){    if (c->sockshost) {	if (c->sockshost==saddr && c->socksport==sport)	    return;	/* sockshost and socksport contain the real peer's address	   and the configured/guessed peer is really the socks relayer! */	c->sockshost=saddr;	c->socksport=sport;    } else {	if (c->peeraddr==saddr && c->peerport==sport)	    return;	c->peeraddr=saddr;	c->peerport=sport;    }    printk(KERN_NOTICE "%s: new peer %s:%d\n",	   c->dev->name, cipe_ntoa(saddr), ntohs(sport));}/* Decrypt a received packet. Requeue it or return kxc block. *//* On entry the packet starts with the original UDP header,   ip_hdr and h.uh are set to the IP and UDP headers. */struct sk_buff *cipe_decrypt_skb(struct cipe *c, struct sock *sk,				 struct sk_buff *skb, int *offset,                                 int *msgflag){    struct sk_buff *n=NULL;    int length;    __u32 rsaddr;    __u16 rsport;#ifdef DEBUG    if (cipe_debug&DEB_PKIN)        cipe_dump_packet("received", skb, 1);#endif    length = skb->len - sizeof(struct udphdr);    n=alloc_skb(skb->len, GFP_KERNEL);    if (!n) {	printk(KERN_WARNING "%s: cipe_decrypt_skb: out of memory\n",	       c->dev->name);	++c->stat.rx_dropped;	return NULL;    }#if 0 /*def LINUX_21*/    if (skb->sk)	skb_set_owner_r(n, skb->sk);#endif#ifndef LINUX_21    n->free=1;#endif    n->dev=c->dev;    /* Copy the datagram into new buffer, skip IP header */    /* We must copy here because raw sockets get only a clone of the       skbuff, so they would receive the plaintext */    dprintk(DEB_INP, (KERN_DEBUG DEVNAME                      ": sa=%s da=%s us=%d ud=%d ul=%d\n",                      cipe_ntoa(saddr(skb)), cipe_ntoa(daddr(skb)),                      ntohs(skb->h.uh->source), ntohs(skb->h.uh->dest),                      ntohs(skb->h.uh->len)));    /* why did this get swapped?? */#ifdef LINUX_21    rsaddr=saddr(skb);#else    rsaddr=daddr(skb);#endif    rsport=skb->h.uh->source;    skb_put(n,skb->len);#ifdef MAX_SKB_FRAGS    /* Zerocopy version. -DaveM */    skb_copy_bits(skb, (skb->h.raw - skb->data), n->data, skb->len);#else    memcpy(n->data, skb->h.raw, skb->len);#endif    n->h.uh=(struct udphdr *)n->data;    if (c->sockshost) {	/* Pull out the SOCKS header and correct the peer's address. */	struct sockshdr *sh;	sh=(struct sockshdr *)skb_pull(n, sizeof(struct udphdr));	dprintk(DEB_INP, (KERN_DEBUG "socks: fr=%d at=%d da=%s dp=%d\n",                          sh->frag, sh->atyp,                          cipe_ntoa(sh->dstaddr), ntohs(sh->dstport)));	if (sh->frag || (sh->atyp!=1))	    goto error;	/* Pull out UDP header */#ifdef LINUX_21        n->nh.iph=(struct iphdr *)skb_pull(n, sizeof(struct sockshdr));#else	n->ip_hdr=(struct iphdr *)skb_pull(n, sizeof(struct sockshdr));#endif	/***saddr(n)=sh->dstaddr;*/        rsaddr=sh->dstaddr;	rsport=n->h.uh->source=sh->dstport;	length-=sizeof(struct sockshdr);	*offset=sizeof(struct sockshdr)+sizeof(struct udphdr);    } else {	/* Pull out UDP header */#ifdef LINUX_21	n->nh.iph=(struct iphdr *) skb_pull(n, sizeof(struct udphdr));#else	n->ip_hdr=(struct iphdr *) skb_pull(n, sizeof(struct udphdr));#endif	/***saddr(n)=rsaddr;*/	n->h.uh->source=rsport;	*offset=0;    }    n->mac.raw=n->data; /* no hardware header */    if (c->flags&CIPF_HAVE_KEY) {	if (length%blockSize) {	    printk(KERN_DEBUG "%s: got bogus length=%d\n", c->dev->name,		   length);	    goto error;	}        switch (cipe_decrypt(c, n->data, &length)) {	case TW_DATA:            if (!c->flags&CIPF_MAY_STKEY && !c->flags&CIPF_HAVE_RKEY) {                printk(KERN_ERR "%s: got data using invalid static key\n",                       c->dev->name);                goto error;            }	    break;	case TW_CTRL:            /* return it as a control block - out of band datagram */            *msgflag|=MSG_OOB;            /* fall thru */	case TW_NEWKEY:	    /* return it as key exchange block - proper UDP datagram */	    dprintk(DEB_INP, (KERN_DEBUG "TW_NEWKEY data=%p len=%d length=%d\n", n->data, n->len, length));#ifdef LINUX_21	    do_gettimeofday(&n->stamp);#endif	    skb_trim(n, length);	    checkpeer(c, rsaddr, rsport);#if 0	    n->saddr=c->myaddr;	    n->daddr=c->peeraddr;#endif	    n->h.uh->check=0;	    return n;	default:	    /* Bogus packet etc. */	    ++c->stat.rx_crc_errors;	    goto error;	}    } else if (!c->flags&CIPF_MAY_CLEAR) {	goto error;    }    dprintk(DEB_INP, (KERN_DEBUG "TW_DATA data=%p len=%d length=%d\n", n->data, n->len, length));    skb_trim(n, length);    checkpeer(c, rsaddr, rsport);    /* adjust pointers */#ifdef LINUX_21    n->nh.iph=(struct iphdr *)n->data;    memset(&(IPCB(n)->opt), 0, sizeof(IPCB(n)->opt));#else    n->h.iph=(struct iphdr *)n->data;    memset(n->proto_priv, 0, sizeof(struct options));#endif    if (length<cipehdrlen+(c->sockshost?sizeof(struct sockshdr):0)) {        printk(KERN_INFO "%s: got short packet from %s\n", c->dev->name,               cipe_ntoa(saddr(skb)));	goto framerr;    }    n->protocol = __constant_htons(ETH_P_IP);    n->ip_summed = 0;    n->pkt_type = PACKET_HOST;    dprintk(DEB_INP, (KERN_DEBUG "%s: real src %s dst %s len %d\n",                      n->dev->name, cipe_ntoa(saddr(n)),

⌨️ 快捷键说明

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