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

📄 sock.c

📁 完整的1.0代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* Check this error. */  if (len < sizeof(sin)) return(-EINVAL);  sin.sin_family = AF_INET;  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  if (peer) {	if (!tcp_connected(sk->state)) return(-ENOTCONN);	sin.sin_port = sk->dummy_th.dest;	sin.sin_addr.s_addr = sk->daddr;  } else {	sin.sin_port = sk->dummy_th.source;	if (sk->saddr == 0) sin.sin_addr.s_addr = my_addr();	  else sin.sin_addr.s_addr = sk->saddr;  }  len = sizeof(sin);/*  verify_area(VERIFY_WRITE, uaddr, len); NOW DONE ABOVE */  memcpy_tofs(uaddr, &sin, sizeof(sin));/*  verify_area(VERIFY_WRITE, uaddr_len, sizeof(len)); NOW DONE ABOVE */  put_fs_long(len, uaddr_len);  return(0);}static intinet_read(struct socket *sock, char *ubuf, int size, int noblock){  struct sock *sk;  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  /* We may need to bind the socket. */  if (sk->num == 0) {	sk->num = get_new_socknum(sk->prot, 0);	if (sk->num == 0) return(-EAGAIN);	put_sock(sk->num, sk);	sk->dummy_th.source = ntohs(sk->num);  }  return(sk->prot->read(sk, (unsigned char *) ubuf, size, noblock,0));}static intinet_recv(struct socket *sock, void *ubuf, int size, int noblock,	  unsigned flags){  struct sock *sk;  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  /* We may need to bind the socket. */  if (sk->num == 0) {	sk->num = get_new_socknum(sk->prot, 0);	if (sk->num == 0) return(-EAGAIN);	put_sock(sk->num, sk);	sk->dummy_th.source = ntohs(sk->num);  }  return(sk->prot->read(sk, (unsigned char *) ubuf, size, noblock, flags));}static intinet_write(struct socket *sock, char *ubuf, int size, int noblock){  struct sock *sk;  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  if (sk->shutdown & SEND_SHUTDOWN) {	send_sig(SIGPIPE, current, 1);	return(-EPIPE);  }  /* We may need to bind the socket. */  if (sk->num == 0) {	sk->num = get_new_socknum(sk->prot, 0);	if (sk->num == 0) return(-EAGAIN);	put_sock(sk->num, sk);	sk->dummy_th.source = ntohs(sk->num);  }  return(sk->prot->write(sk, (unsigned char *) ubuf, size, noblock, 0));}static intinet_send(struct socket *sock, void *ubuf, int size, int noblock, 	       unsigned flags){  struct sock *sk;  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  if (sk->shutdown & SEND_SHUTDOWN) {	send_sig(SIGPIPE, current, 1);	return(-EPIPE);  }  /* We may need to bind the socket. */  if (sk->num == 0) {	sk->num = get_new_socknum(sk->prot, 0);	if (sk->num == 0) return(-EAGAIN);	put_sock(sk->num, sk);	sk->dummy_th.source = ntohs(sk->num);  }  return(sk->prot->write(sk, (unsigned char *) ubuf, size, noblock, flags));}static intinet_sendto(struct socket *sock, void *ubuf, int size, int noblock, 	    unsigned flags, struct sockaddr *sin, int addr_len){  struct sock *sk;  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  if (sk->shutdown & SEND_SHUTDOWN) {	send_sig(SIGPIPE, current, 1);	return(-EPIPE);  }  if (sk->prot->sendto == NULL) return(-EOPNOTSUPP);  /* We may need to bind the socket. */  if (sk->num == 0) {	sk->num = get_new_socknum(sk->prot, 0);	if (sk->num == 0) return(-EAGAIN);	put_sock(sk->num, sk);	sk->dummy_th.source = ntohs(sk->num);  }  return(sk->prot->sendto(sk, (unsigned char *) ubuf, size, noblock, flags, 			   (struct sockaddr_in *)sin, addr_len));}static intinet_recvfrom(struct socket *sock, void *ubuf, int size, int noblock, 		   unsigned flags, struct sockaddr *sin, int *addr_len ){  struct sock *sk;  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  if (sk->prot->recvfrom == NULL) return(-EOPNOTSUPP);  /* We may need to bind the socket. */  if (sk->num == 0) {	sk->num = get_new_socknum(sk->prot, 0);	if (sk->num == 0) return(-EAGAIN);	put_sock(sk->num, sk);	sk->dummy_th.source = ntohs(sk->num);  }  return(sk->prot->recvfrom(sk, (unsigned char *) ubuf, size, noblock, flags,			     (struct sockaddr_in*)sin, addr_len));}static intinet_shutdown(struct socket *sock, int how){  struct sock *sk;  /*   * This should really check to make sure   * the socket is a TCP socket.   */  how++; /* maps 0->1 has the advantage of making bit 1 rcvs and		       1->2 bit 2 snds.		       2->3 */  if (how & ~SHUTDOWN_MASK) return(-EINVAL);  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  if (sock->state == SS_CONNECTING && sk->state == TCP_ESTABLISHED)						sock->state = SS_CONNECTED;  if (!tcp_connected(sk->state)) return(-ENOTCONN);  sk->shutdown |= how;  if (sk->prot->shutdown) sk->prot->shutdown(sk, how);  return(0);}static intinet_select(struct socket *sock, int sel_type, select_table *wait ){  struct sock *sk;  sk = (struct sock *) sock->data;  if (sk == NULL) {	printk("Warning: sock->data = NULL: %d\n" ,__LINE__);	return(0);  }  if (sk->prot->select == NULL) {	DPRINTF((DBG_INET, "select on non-selectable socket.\n"));	return(0);  }  return(sk->prot->select(sk, sel_type, wait));}static intinet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg){  struct sock *sk;  int err;  DPRINTF((DBG_INET, "INET: in inet_ioctl\n"));  sk = NULL;  if (sock && (sk = (struct sock *) sock->data) == NULL) {	printk("AF_INET: Warning: sock->data = NULL: %d\n" , __LINE__);	return(0);  }  switch(cmd) {	case FIOSETOWN:	case SIOCSPGRP:		err=verify_area(VERIFY_READ,(int *)arg,sizeof(long));		if(err)			return err;		if (sk)			sk->proc = get_fs_long((int *) arg);		return(0);	case FIOGETOWN:	case SIOCGPGRP:		if (sk) {			err=verify_area(VERIFY_WRITE,(void *) arg, sizeof(long));			if(err)				return err;			put_fs_long(sk->proc,(int *)arg);		}		return(0);#if 0	/* FIXME: */	case SIOCATMARK:		printk("AF_INET: ioctl(SIOCATMARK, 0x%08X)\n",(void *) arg);		return(-EINVAL);#endif	case DDIOCSDBG:		return(dbg_ioctl((void *) arg, DBG_INET));	case SIOCADDRT: case SIOCADDRTOLD:	case SIOCDELRT: case SIOCDELRTOLD:		return(rt_ioctl(cmd,(void *) arg));	case SIOCDARP:	case SIOCGARP:	case SIOCSARP:		return(arp_ioctl(cmd,(void *) arg));	case IP_SET_DEV:	case SIOCGIFCONF:	case SIOCGIFFLAGS:	case SIOCSIFFLAGS:	case SIOCGIFADDR:	case SIOCSIFADDR:	case SIOCGIFDSTADDR:	case SIOCSIFDSTADDR:	case SIOCGIFBRDADDR:	case SIOCSIFBRDADDR:	case SIOCGIFNETMASK:	case SIOCSIFNETMASK:	case SIOCGIFMETRIC:	case SIOCSIFMETRIC:	case SIOCGIFMEM:	case SIOCSIFMEM:	case SIOCGIFMTU:	case SIOCSIFMTU:	case SIOCSIFLINK:	case SIOCGIFHWADDR:		return(dev_ioctl(cmd,(void *) arg));	default:		if (!sk || !sk->prot->ioctl) return(-EINVAL);		return(sk->prot->ioctl(sk, cmd, arg));  }  /*NOTREACHED*/  return(0);}struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,	     int priority){  if (sk) {	if (sk->wmem_alloc + size < sk->sndbuf || force) {		struct sk_buff * c = alloc_skb(size, priority);		if (c) {			cli();			sk->wmem_alloc+= size;			sti();		}		return c;	}	DPRINTF((DBG_INET, "sock_wmalloc(%X,%d,%d,%d) returning NULL\n",						sk, size, force, priority));	return(NULL);  }  return(alloc_skb(size, priority));}struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority){  if (sk) {	if (sk->rmem_alloc + size < sk->rcvbuf || force) {		struct sk_buff *c = alloc_skb(size, priority);		if (c) {			cli();			sk->rmem_alloc += size;			sti();		}		return(c);	}	DPRINTF((DBG_INET, "sock_rmalloc(%X,%d,%d,%d) returning NULL\n",						sk,size,force, priority));	return(NULL);  }  return(alloc_skb(size, priority));}unsigned longsock_rspace(struct sock *sk){  int amt;  if (sk != NULL) {	if (sk->rmem_alloc >= sk->rcvbuf-2*MIN_WINDOW) return(0);	amt = min((sk->rcvbuf-sk->rmem_alloc)/2-MIN_WINDOW, MAX_WINDOW);	if (amt < 0) return(0);	return(amt);  }  return(0);}unsigned longsock_wspace(struct sock *sk){  if (sk != NULL) {	if (sk->shutdown & SEND_SHUTDOWN) return(0);	if (sk->wmem_alloc >= sk->sndbuf) return(0);	return(sk->sndbuf-sk->wmem_alloc );  }  return(0);}voidsock_wfree(struct sock *sk, void *mem, unsigned long size){  DPRINTF((DBG_INET, "sock_wfree(sk=%X, mem=%X, size=%d)\n", sk, mem, size));  IS_SKB(mem);  kfree_skbmem(mem, size);  if (sk) {	sk->wmem_alloc -= size;	/* In case it might be waiting for more memory. */	if (!sk->dead) sk->write_space(sk);	if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) {		DPRINTF((DBG_INET,			"recovered lost memory, sock = %X\n", sk));	}	return;  }}voidsock_rfree(struct sock *sk, void *mem, unsigned long size){  DPRINTF((DBG_INET, "sock_rfree(sk=%X, mem=%X, size=%d)\n", sk, mem, size));  IS_SKB(mem);  kfree_skbmem(mem, size);  if (sk) {	sk->rmem_alloc -= size;	if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) {		DPRINTF((DBG_INET,			"recovered lot memory, sock = %X\n", sk));	}  }}/* * This routine must find a socket given a TCP or UDP header. * Everyhting is assumed to be in net order. */struct sock *get_sock(struct proto *prot, unsigned short num,				unsigned long raddr,				unsigned short rnum, unsigned long laddr){  struct sock *s;  unsigned short hnum;  hnum = ntohs(num);  DPRINTF((DBG_INET, "get_sock(prot=%X, num=%d, raddr=%X, rnum=%d, laddr=%X)\n",	  prot, num, raddr, rnum, laddr));  /*   * SOCK_ARRAY_SIZE must be a power of two.  This will work better   * than a prime unless 3 or more sockets end up using the same   * array entry.  This should not be a problem because most   * well known sockets don't overlap that much, and for   * the other ones, we can just be careful about picking our   * socket number when we choose an arbitrary one.   */  for(s = prot->sock_array[hnum & (SOCK_ARRAY_SIZE - 1)];      s != NULL; s = s->next)   {	if (s->num != hnum) 		continue;	if(s->dead && (s->state == TCP_CLOSE))		continue;	if(prot == &udp_prot)		return s;	if(ip_addr_match(s->daddr,raddr)==0)		continue;	if (s->dummy_th.dest != rnum && s->dummy_th.dest != 0) 		continue;	if(ip_addr_match(s->saddr,laddr) == 0)		continue;	return(s);  }  return(NULL);}void release_sock(struct sock *sk){  if (!sk) {	printk("sock.c: release_sock sk == NULL\n");	return;  }  if (!sk->prot) {/*	printk("sock.c: release_sock sk->prot == NULL\n"); */	return;  }  if (sk->blog) return;  /* See if we have any packets built up. */  cli();  sk->inuse = 1;  while(sk->back_log != NULL) {	struct sk_buff *skb;	sk->blog = 1;	skb =(struct sk_buff *)sk->back_log;	DPRINTF((DBG_INET, "release_sock: skb = %X:\n", skb));	if (skb->next != skb) {		sk->back_log = skb->next;		skb->prev->next = skb->next;		skb->next->prev = skb->prev;	} else {		sk->back_log = NULL;	}	sti();	DPRINTF((DBG_INET, "sk->back_log = %X\n", sk->back_log));	if (sk->prot->rcv) sk->prot->rcv(skb, skb->dev, sk->opt,					 skb->saddr, skb->len, skb->daddr, 1,	/* Only used for/by raw sockets. */	(struct inet_protocol *)sk->pair); 	cli();  }  sk->blog = 0;  sk->inuse = 0;  sti();  if (sk->dead && sk->state == TCP_CLOSE) {	/* Should be about 2 rtt's */	reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));  }}static intinet_fioctl(struct inode *inode, struct file *file,	 unsigned int cmd, unsigned long arg){  int minor, ret;  /* Extract the minor number on which we work. */  minor = MINOR(inode->i_rdev);  if (minor != 0) return(-ENODEV);  /* Now dispatch on the minor device. */  switch(minor) {	case 0:		/* INET */		ret = inet_ioctl(NULL, cmd, arg);		break;	case 1:		/* IP */		ret = ip_ioctl(NULL, cmd, arg);		break;	case 2:		/* ICMP */		ret = icmp_ioctl(NULL, cmd, arg);		break;	case 3:		/* TCP */		ret = tcp_ioctl(NULL, cmd, arg);		break;	case 4:		/* UDP */		ret = udp_ioctl(NULL, cmd, arg);		break;	default:		ret = -ENODEV;  }  return(ret);}static struct file_operations inet_fops = {  NULL,		/* LSEEK	*/  NULL,		/* READ		*/  NULL,		/* WRITE	*/  NULL,		/* READDIR	*/  NULL,		/* SELECT	*/  inet_fioctl,	/* IOCTL	*/  NULL,		/* MMAP		*/  NULL,		/* OPEN		*/  NULL		/* CLOSE	*/};static struct proto_ops inet_proto_ops = {  AF_INET,  inet_create,  inet_dup,  inet_release,  inet_bind,  inet_connect,  inet_socketpair,  inet_accept,  inet_getname,   inet_read,  inet_write,  inet_select,  inet_ioctl,  inet_listen,  inet_send,  inet_recv,  inet_sendto,  inet_recvfrom,  inet_shutdown,  inet_setsockopt,  inet_getsockopt,  inet_fcntl,};extern unsigned long seq_offset;/* Called by ddi.c on kernel startup.  */void inet_proto_init(struct ddi_proto *pro){  struct inet_protocol *p;  int i;  printk("Swansea University Computer Society Net2Debugged [1.30]\n");  /* Set up our UNIX VFS major device. */  if (register_chrdev(AF_INET_MAJOR, "af_inet", &inet_fops) < 0) {	printk("%s: cannot register major device %d!\n",					pro->name, AF_INET_MAJOR);	return;  }  /* Tell SOCKET that we are alive... */  (void) sock_register(inet_proto_ops.family, &inet_proto_ops);  seq_offset = CURRENT_TIME*250;  /* Add all the protocols. */  for(i = 0; i < SOCK_ARRAY_SIZE; i++) {	tcp_prot.sock_array[i] = NULL;	udp_prot.sock_array[i] = NULL;	raw_prot.sock_array[i] = NULL;  }  printk("IP Protocols: ");  for(p = inet_protocol_base; p != NULL;) {	struct inet_protocol *tmp;	tmp = (struct inet_protocol *) p->next;	inet_add_protocol(p);	printk("%s%s",p->name,tmp?", ":"\n");	p = tmp;  }  /* Initialize the DEV module. */  dev_init();  /* Initialize the "Buffer Head" pointers. */  bh_base[INET_BH].routine = inet_bh;}

⌨️ 快捷键说明

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