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

📄 sock.c

📁 cipe 编程
💻 C
📖 第 1 页 / 共 2 页
字号:
    n->protocol = htons(ETH_P_IP);    n->pkt_type = PACKET_HOST;#endif#ifdef LINUX_21    n->nh.raw=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    n->ip_summed = 0;    /* this prints nonsense for non-IP packets. Ignore that. */    dprintk(DEB_INP, (KERN_INFO "%s: real src %s dst %s len %d\n",                      n->dev->name, cipe_ntoa(saddr(n)),                      cipe_ntoa(daddr(n)), length));#ifdef DEBUG    if (cipe_debug&DEB_PKIN)        cipe_dump_packet("decrypted", n, 1);#ifdef LINUX_23    dprintk(DEB_INP, (KERN_DEBUG "%s state=%ld refcnt=%d\n", n->dev->name, n->dev->state,		      atomic_read(&n->dev->refcnt)));#endif#endif    nf_conntrack_null(skb);    /* requeue */    netif_rx(n);#ifdef LINUX_24    /* raise a softirq to process the new packet asap */    do_softirq();#endif#ifdef LINUX_21    c->stat.rx_bytes+=skb->len; /* count carrier-level bytes */#endif    c->stat.rx_packets++;    return NULL; framerr:    ++c->stat.rx_frame_errors; /* slightly abuse this */ error:    ++c->stat.rx_errors;    if (n)	kfreeskb(n, FREE_READ);    return NULL;}/* Receive message. If encrypted, put it through the mill.   If decrypted, return it as key exchange block.   This is mostly from net/ipv4/udp.c, but cipe_decrypt_skb pulls the   UDP header.*/int cipe_recvmsg(#ifdef LINUX_25    struct kiocb *iocb,#endif    struct sock *sk, struct msghdr *msg#ifdef LINUX_25    , size_t len#else    , int len#endif    , int noblock, int flags,int *addr_len){  	int copied;  	struct sk_buff *skb, *skn;  	int er=0;  	struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name;	SOCKTOC("cipe_recvmsg",sk,c);	/*	 *	Check any passed addresses	 */  	if (addr_len)  		*addr_len=sizeof(*sin);	/*	 *	From here the generic datagram does a lot of the work. Come	 *	the finished NET3, it will do _ALL_ the work!	 */	do {	    /* CIPE: look if the packet is encrypted, repeat until	       a decrypted one is found */	    skn=NULL;	    skb=skb_recv_datagram(sk,flags,noblock,&er);	    if(skb==NULL) {		dprintk(DEB_KXC, (KERN_INFO "%s: skb_recv_datagram: %d\n",                                  c->dev->name, er));                return er;	    }	    if (!skb->h.uh->source) {		/* Synthetic KXC packets are marked by source port 0.		   Correct this - we know the truth from our structure.		   Perhaps it would be better to not correct it so the		   user level daemon can spot the difference? */		skb->h.uh->source=c->peerport;		skb_pull(skb, sizeof(struct udphdr));		break;	    }	    skn=cipe_decrypt_skb(c, sk, skb, &(msg->msg_flags));	    skb_free_datagram(sk, skb);	    skb=skn;	} while (skb==NULL);	dprintk(DEB_INP, (KERN_INFO "%s: returning " FLEN " flags %04x\n",			  c->dev->name, skb->len, msg->msg_flags));  	copied = skb->len;	if (copied > len)	{		copied = len;#ifdef LINUX_21		msg->msg_flags |= MSG_TRUNC;#endif	}	if (copied<=0) {	    printk(KERN_ERR "cipe_recvmsg: bogus length %d\n", copied);	    goto out_free;	}  	/*  	 *	FIXME : should use udp header size info value  	 */#ifdef LINUX_21	er = memcpy_toiovec(msg->msg_iov, skb->data, copied);	if (er<0)		goto out_free;#else	memcpy_toiovec(msg->msg_iov, skb->data, copied);#endif	sk->sk_stamp=skb->stamp;	/* Copy the address. */	if (sin#ifdef LINUX_21            && skb->nh.iph   /* Fake KXC has no address */#endif	) {		sin->sin_family = AF_INET;		sin->sin_port = skb->h.uh->source;                sin->sin_addr.s_addr = daddr(skb);	}        er=copied; out_free:	if (skb==skn)	    /* the buffer was a copy made by decryption */	    kfreeskb(skb, FREE_READ);	else	    skb_free_datagram(sk, skb);  	return(er);}#ifdef LINUX_21#include <linux/file.h>int cipe_attach(struct NET_DEVICE *dev, struct siocsifcipatt *parm){    struct file *file;    struct inode *inode;    struct socket *sock;    struct sock *sk;#if 0    struct in_device *indev;#endif    struct cipe *c0;    DEVTOCIPE(dev,c,-ENODEV);    if (c->sock)        return -EBUSY;    if (!(file=fget(parm->fd)))        return(-EBADF);    inode = file->f_dentry->d_inode;    if (!inode || !inode->i_sock || !(sock=SOCKET_I(inode))) {        fput(file);        return(-ENOTSOCK);    }    if (sock->file != file) {        printk(KERN_ERR DEVNAME ": socki_lookup: socket file changed!\n");        sock->file = file;    }    fput(file);    if (sock->type!=SOCK_DGRAM)	return(-ESOCKTNOSUPPORT);    if (sock->ops->family!=AF_INET)	return(-EAFNOSUPPORT);    sk=sock->sk;    if (sk->sk_state!=TCP_ESTABLISHED)	return(-ENOTCONN);    if (((c0=(struct cipe *)sk->sk_user_data)) &&	(c0->magic==CIPE_MAGIC))	return(-EBUSY); /* socket is already attached */    if (!cipe_use_module())        return(-ENODEV);    c->owner=current->pid;#ifdef LINUX_25    c->sock=(struct inet_sock*)sk;#else    c->sock=sk;#endif    c->peeraddr=inet_sk(sk)->daddr;    c->peerport=inet_sk(sk)->dport;    c->myaddr=inet_sk(sk)->saddr;    if (c->flags&CIPF_MAY_DYNIP)        inet_sk(sk)->rcv_saddr=0;    c->myport=htons(inet_sk(sk)->num);    /* Disconnect socket, we might receive from somewhere else */    inet_sk(sk)->daddr=0;    inet_sk(sk)->dport=0;    /* Fill an otherwise unused field in the sock struct with this info.       This field is conveniently named and the kernel uses it only for RPC. */    sk->sk_user_data=c;    sk->sk_no_check=(c->flags&CIPF_DO_CSUM) ? 0 : 1;    /* Set up new socket operations */    c->udp_prot=sk->sk_prot;    c->cipe_proto=*sk->sk_prot;    c->cipe_proto.close=cipe_sock_close;    c->cipe_proto.sendmsg=cipe_sendmsg;    c->cipe_proto.recvmsg=cipe_recvmsg;    sk->sk_prot=&c->cipe_proto;#if 0    /* (Try to) Set our dummy hardware address from the IP address. */    /* This does not work, because the IP address is set       _after_ the attach... */    if ((indev=dev->ip_ptr)) {	struct in_ifaddr **ifap = NULL;	struct in_ifaddr *ifa = NULL;	for (ifap=&indev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)	    if (strcmp(dev->name, ifa->ifa_label) == 0)		break;	if (ifa) {	    char *x=(char *)&ifa->ifa_local;	    dev->dev_addr[3]=x[1]|0x80;	    dev->dev_addr[4]=x[2];	    dev->dev_addr[5]=x[3];	}    }#endif    return(0);}#else /* LINUX_21 */#define sreturn(x) {sti(); return((x));}int cipe_attach(struct NET_DEVICE *dev, struct siocsifcipatt *parm){    struct file *file;    struct inode *inode;    struct socket *sock;    struct sock *sk;    int fd=parm->fd;    struct cipe *c0;    DEVTOCIPE(dev,c,-ENODEV);    cli();    if (c->sock)	sreturn(-EBUSY);    if (!c->cipher)        sreturn(-ENXIO);    /* Find the socket (from net/socket.c) */    if (fd < 0 || fd >= NR_OPEN || !(file = current->files->fd[fd]))	sreturn(-EBADF);    inode = file->f_inode;    if (!inode || !inode->i_sock)	sreturn(-ENOTSOCK);    sock=&inode->u.socket_i;    if (sock->type!=SOCK_DGRAM)	sreturn(-ESOCKTNOSUPPORT);    if (sock->ops->family!=AF_INET)	sreturn(-EAFNOSUPPORT);    sk=(struct sock *)sock->data;    if (sk->state!=TCP_ESTABLISHED)	sreturn(-ENOTCONN);    if (((c0=(struct cipe *)sk->protinfo.af_packet.bound_dev)) &&	(c0->magic==CIPE_MAGIC))	sreturn(-EBUSY); /* socket is already attached */    cipe_use_module(); /* cannot fail under 2.0 */    c->owner=current->pid;    c->sock=sk;    c->peeraddr=sk->daddr;    c->peerport=sk->dummy_th.dest;    c->myaddr=sk->saddr;    if (c->flags&CIPF_MAY_DYNIP)        sk->rcv_saddr=0;    c->myport=sk->dummy_th.source;    /* Disconnect socket, we might receive from somewhere else */    sk->daddr=0;    sk->dummy_th.dest=0;    /* Set up new socket operations */    c->udp_prot=sk->prot;    c->cipe_proto=*sk->prot;    c->cipe_proto.close=cipe_sock_close;    c->cipe_proto.sendmsg=cipe_sendmsg;    c->cipe_proto.recvmsg=cipe_recvmsg;    sk->prot=&c->cipe_proto;    /* Fill an otherwise unused field in the sock struct with this info.       Actually, this is very similar to a packet socket!       The ugly cast saves us one deref in the actual ops */    sk->protinfo.af_packet.bound_dev=(struct NET_DEVICE *)c;    sk->no_check=(c->flags&CIPF_DO_CSUM) ? 0 : 1;    sti();    return 0;}#endif/* Build and enqueue a fake UDP packet to receive.   Note that these are neither encrypted nor SOCKSed.*/void cipe_fakenkey(struct cipe *c, char typ){    int len=sizeof(struct udphdr)+KEYXCHGBLKMIN;    struct sk_buff *skb=alloc_skb(len, GFP_ATOMIC);    if (!skb) {        printk(KERN_WARNING "%s: cipe_fakenkey: out of memory\n",               c->dev->name);        return; /* not much we can do */    }    dprintk(DEB_KXC, (KERN_INFO "%s: fake kxc block typ=%d\n",                      c->dev->name, typ));    skb->sk=NULL;    skb->dev=c->dev;    skb->h.uh=(struct udphdr *)skb->data;    skb->len=len;#ifdef LINUX_21    skb->nh.iph=NULL;#else    saddr(skb)=c->myaddr;    daddr(skb)=c->peeraddr;    skb->free=1; /* Discard after use */    skb->ip_hdr=NULL;#endif    skb->h.uh->source=0; /* mark as KXC packet */    skb->h.uh->dest=c->myport;    len-=sizeof(struct udphdr);    skb->h.uh->len=htons(len);    skb->h.uh->check=0;    skb->mac.raw=skb->data; /* no hardware header */    /* All those contortions for just one byte of payload data.       Since we generate only NK_RREQ and NK_REQ it's effectively       one _bit_... */    skb->data[sizeof(struct udphdr)]=typ;    (*(__u32 *)(skb->data+sizeof(struct udphdr)+KEYXCHGTSPOS))=        htonl(CURRENT_TIME_SEC); /* even need timestamp */    if (sock_queue_rcv_skb(SOCK(c), skb)<0) {        printk(KERN_WARNING "%s: cipe_fakenkey: enqueuing failed\n",               c->dev->name);        kfreeskb(skb, FREE_WRITE);    }}

⌨️ 快捷键说明

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