Esempio n. 1
0
/* 释放一个socket结构,并唤醒socket_wait_free队列 */
static void sock_release(struct socket *sock)
{
  int oldstate;
  struct inode *inode;
  struct socket *peersock, *nextsock;

  DPRINTF((net_debug, "NET: sock_release: socket 0x%x, inode 0x%x\n",
						sock, SOCK_INODE(sock)));
  /* 设置socket的状态为正在关闭连接 */
  if ((oldstate = sock->state) != SS_UNCONNECTED)
			sock->state = SS_DISCONNECTING;

  /* Wake up anyone waiting for connections. */
  for (peersock = sock->iconn; peersock; peersock = nextsock) {
	nextsock = peersock->next;
	sock_release_peer(peersock);
  }

  /*
   * Wake up anyone we're connected to. First, we release the
   * protocol, to give it a chance to flush data, etc.
   */
  peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
  if (sock->ops) sock->ops->release(sock, peersock);
  if (peersock) sock_release_peer(peersock);
  inode = SOCK_INODE(sock);
  sock->state = SS_FREE;		/* this really releases us */
  wake_up_interruptible(&socket_wait_free);

  /* We need to do this. If sock alloc was called we already have an inode. */
  iput(inode);
}
Esempio n. 2
0
static struct socket *
sock_alloc(int wait)
{
	struct socket *sock;

	while (1) {
		cli();
		for (sock = sockets; sock <= last_socket; ++sock)
			if (sock->state == SS_FREE) {
				sock->state = SS_UNCONNECTED;
				sti();
				sock->flags = 0;
				sock->ops = NULL;
				sock->data = NULL;
				sock->conn = NULL;
				sock->iconn = NULL;
				/*
				 * this really shouldn't be necessary, but
				 * everything else depends on inodes, so we
				 * grab it.
				 * sleeps are also done on the i_wait member
				 * of this inode.
				 * the close system call will iput this inode
				 * for us.
				 */
				if (!(SOCK_INODE(sock) = get_empty_inode())) {
					printk("sock_alloc: no more inodes\n");
					sock->state = SS_FREE;
					return NULL;
				}
				SOCK_INODE(sock)->i_mode = S_IFSOCK;
				sock->wait = &SOCK_INODE(sock)->i_wait;
				PRINTK("sock_alloc: socket 0x%x, inode 0x%x\n",
				       sock, SOCK_INODE(sock));
				return sock;
			}
		sti();
		if (!wait)
			return NULL;
		PRINTK("sock_alloc: no free sockets, sleeping...\n");
		interruptible_sleep_on(&socket_wait_free);
		if (current->signal & ~current->blocked) {
			PRINTK("sock_alloc: sleep was interrupted\n");
			return NULL;
		}
		PRINTK("sock_alloc: wakeup... trying again...\n");
	}
}
Esempio n. 3
0
static int x25_seq_socket_show(struct seq_file *seq, void *v)
{
	struct sock *s;
	struct x25_sock *x25;
	struct net_device *dev;
	const char *devname;

	if (v == SEQ_START_TOKEN) {
		seq_printf(seq, "dest_addr  src_addr   dev   lci st vs vr "
				"va   t  t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
		goto out;
	}

	s = sk_entry(v);
	x25 = x25_sk(s);

	if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
		devname = "???";
	else
		devname = x25->neighbour->dev->name;

	seq_printf(seq, "%-10s %-10s %-5s %3.3X  %d  %d  %d  %d %3lu %3lu "
			"%3lu %3lu %3lu %5d %5d %ld\n",
		   !x25->dest_addr.x25_addr[0] ? "*" : x25->dest_addr.x25_addr,
		   !x25->source_addr.x25_addr[0] ? "*" : x25->source_addr.x25_addr,
		   devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr,
		   x25->va, x25_display_timer(s) / HZ, x25->t2  / HZ,
		   x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ,
		   sk_wmem_alloc_get(s),
		   sk_rmem_alloc_get(s),
		   s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L);
out:
	return 0;
}
Esempio n. 4
0
unsigned int hook_func(unsigned int hooknum,
                       struct sk_buff *skb,
                       const struct net_device *in,
                       const struct net_device *out,
                       int (*okfn)(struct sk_buff *)) {
	int uid = -1;
	int index = 0;
	if (!skb->sk) {
		 //printk(KERN_ERR "hook_func skb->sk = NULL");
		 return NF_ACCEPT; 
	} else if(!skb->sk->sk_socket) {
		//printk(KERN_ERR "hook_func skb->sk->sk_socket = NULL");
		return NF_ACCEPT; 
	} else {
		struct inode *inode = SOCK_INODE(skb->sk->sk_socket);
		if (inode) {
			uid = inode->i_uid;
			if (10000 > uid) {
			    return NF_ACCEPT;
			}
			//printk(KERN_ERR "hook_func, -----inode->i_uid = %d---------", uid);
			if (clientPid <= 0 ) {
				printk(KERN_ERR "hook_func, clientPid=%d", clientPid);
				return NF_ACCEPT;
		    }
			index = uid - 10000;
			if (index >= 0 && index <= 9999 && uidArray[index] == 0) {
				uidArray[index] = 1;
				send_network_msg(uid);
			}
		}
	}
    return NF_ACCEPT; 
}
Esempio n. 5
0
static void
sock_release(struct socket *sock)
{
	int oldstate;
	struct socket *peersock, *nextsock;

	PRINTK("sock_release: socket 0x%x, inode 0x%x\n", sock,
	       SOCK_INODE(sock));
	if ((oldstate = sock->state) != SS_UNCONNECTED)
		sock->state = SS_DISCONNECTING;
	/*
	 * wake up anyone waiting for connections
	 */
	for (peersock = sock->iconn; peersock; peersock = nextsock) {
		nextsock = peersock->next;
		sock_release_peer(peersock);
	}
	/*
	 * wake up anyone we're connected to. first, we release the
	 * protocol, to give it a chance to flush data, etc.
	 */
	peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
	if (sock->ops)
		sock->ops->release(sock, peersock);
	if (peersock)
		sock_release_peer(peersock);
	sock->state = SS_FREE;		/* this really releases us */
	wake_up(&socket_wait_free);
}
Esempio n. 6
0
/*
 * Get__netinfo returns the length of that string.
 *
 * KNOWN BUGS
 *  As in get_unix_netinfo, the buffer might be too small. If this
 *  happens, get__netinfo returns only part of the available infos.
 */
static int
get__netinfo(struct proto *pro, char *buffer, int format)
{
  struct sock **s_array;
  struct sock *sp;
  char *pos=buffer;
  int i;
  int timer_active;
  unsigned long  dest, src;
  unsigned short destp, srcp;

  s_array = pro->sock_array;
  pos+=sprintf(pos, "sl  local_address rem_address   st tx_queue rx_queue tr tm->when uid\n");
/*
 *	This was very pretty but didn't work when a socket is destroyed at the wrong moment
 *	(eg a syn recv socket getting a reset), or a memory timer destroy. Instead of playing
 *	with timers we just concede defeat and cli().
 */
  for(i = 0; i < SOCK_ARRAY_SIZE; i++) {
  	cli();
	sp = s_array[i];
	while(sp != NULL) {
		dest  = sp->daddr;
		src   = sp->saddr;
		destp = sp->dummy_th.dest;
		srcp  = sp->dummy_th.source;

		/* Since we are Little Endian we need to swap the bytes :-( */
		destp = ntohs(destp);
		srcp  = ntohs(srcp);
		timer_active = del_timer(&sp->timer);
		if (!timer_active)
			sp->timer.expires = 0;
		pos+=sprintf(pos, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d\n",
			i, src, srcp, dest, destp, sp->state, 
			format==0?sp->write_seq-sp->rcv_ack_seq:sp->rmem_alloc, 
			format==0?sp->acked_seq-sp->copied_seq:sp->wmem_alloc,
			timer_active, sp->timer.expires, (unsigned) sp->retransmits,
			SOCK_INODE(sp->socket)->i_uid);
		if (timer_active)
			add_timer(&sp->timer);
		/* Is place in buffer too rare? then abort. */
		if (pos > buffer+PAGE_SIZE-80) {
			printk("oops, too many %s sockets for netinfo.\n",
					pro->name);
			return(strlen(buffer));
		}

		/*
		 * All sockets with (port mod SOCK_ARRAY_SIZE) = i
		 * are kept in sock_array[i], so we must follow the
		 * 'next' link to get them all.
		 */
		sp = sp->next;
	}
	sti();	/* We only turn interrupts back on for a moment, but because the interrupt queues anything built up
		   before this will clear before we jump back and cli, so its not as bad as it looks */
  }
  return(strlen(buffer));
} 
Esempio n. 7
0
/* 创建一个socket的套接字,一般会根据type的类型来确定protocol的类型,
 * protocol的类型一般默认为IPPROTO_IP
 */
static int sock_socket(int family, int type, int protocol)
{
  int i, fd;
  struct socket *sock;
  struct proto_ops *ops;

  DPRINTF((net_debug,
	"NET: sock_socket: family = %d, type = %d, protocol = %d\n",
						family, type, protocol));

  /* Locate the correct protocol family. */
  /* 找到协议族的操作函数 */
  for (i = 0; i < NPROTO; ++i) {
	if (pops[i] == NULL) continue;
	if (pops[i]->family == family) break;
  }
  if (i == NPROTO) {
	DPRINTF((net_debug, "NET: sock_socket: family not found\n"));
	return(-EINVAL);
  }
  ops = pops[i];

  /*
   * Check that this is a type that we know how to manipulate and
   * the protocol makes sense here. The family can still reject the
   * protocol later.
   */
  if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
       type != SOCK_SEQPACKET && type != SOCK_RAW &&
       type != SOCK_PACKET) || protocol < 0)
							return(-EINVAL);

  /*
   * allocate the socket and allow the family to set things up. if
   * the protocol is 0, the family is instructed to select an appropriate
   * default.
   */
  if (!(sock = sock_alloc(1))) {
	printk("sock_socket: no more sockets\n");
	return(-EAGAIN);
  }
  sock->type = type;
  sock->ops = ops;
  /* 根据不同的协议族函数集来创建socket,
    * 因此在不同协议的proto_ops结构当中是没有socket调用的, 
    * 只有create函数 
    */
  if ((i = sock->ops->create(sock, protocol)) < 0) {
	sock_release(sock);
	return(i);
  }

  if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
	sock_release(sock);
	return(-EINVAL);
  }

  return(fd);
}
Esempio n. 8
0
struct socket *
socki_lookup(struct inode *inode)
{
  struct socket *sock;

  if ((sock = inode->i_socket) != NULL) {
	if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
		return sock;
	printk("socket.c: uhhuh. stale inode->i_socket pointer\n");
  }
  for (sock = sockets; sock <= last_socket; ++sock)
	if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) {
		printk("socket.c: uhhuh. Found socket despite no inode->i_socket pointer\n");
		return(sock);
	}
  return(NULL);
}
Esempio n. 9
0
/*
 * perform the socket system call. we locate the appropriate family, then
 * create a fresh socket.
 */
static int
sock_socket(int family, int type, int protocol)
{
	int i, fd;
	struct socket *sock;
	struct proto_ops *ops;

	PRINTK("sys_socket: family = %d (%s), type = %d, protocol = %d\n",
	       family, family_name(family), type, protocol);

	/*
	 * locate the correct protocol family
	 */
	for (i = 0; i < NPROTO; ++i)
		if (proto_table[i].family == family)
			break;
	if (i == NPROTO) {
		PRINTK("sys_socket: family not found\n");
		return -EINVAL;
	}
	ops = proto_table[i].ops;

	/*
	 * check that this is a type that we know how to manipulate and
	 * the protocol makes sense here. the family can still reject the
	 * protocol later.
	 */
	if ((type != SOCK_STREAM &&
	     type != SOCK_DGRAM &&
	     type != SOCK_SEQPACKET &&
	     type != SOCK_RAW) ||
	    protocol < 0)
		return -EINVAL;

	/*
	 * allocate the socket and allow the family to set things up. if
	 * the protocol is 0, the family is instructed to select an appropriate
	 * default.
	 */
	if (!(sock = sock_alloc(1))) {
		printk("sys_socket: no more sockets\n");
		return -EAGAIN;
	}
	sock->type = type;
	sock->ops = ops;
	if ((i = sock->ops->create(sock, protocol)) < 0) {
		sock_release(sock);
		return i;
	}

	if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
		sock_release(sock);
		return -EINVAL;
	}

	return fd;
}
Esempio n. 10
0
unsigned long sock_i_ino(struct sock *sk)
{
	unsigned long ino;

	read_lock(&sk->sk_callback_lock);
	ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
	read_unlock(&sk->sk_callback_lock);
	return ino;
}
Esempio n. 11
0
int sock_i_uid(struct sock *sk)
{
	int uid;

	read_lock(&sk->sk_callback_lock);
	uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0;
	read_unlock(&sk->sk_callback_lock);
	return uid;
}
Esempio n. 12
0
/* 查找一个空闲的struct socket结构,并初始化相应的关系
 * 如sock中有inode节点指针,inode中有struct socket指针
 * wait表示在获取socket结构的时候,该函数是不是阻塞的,
 * wait>0表示阻塞,=0表示非阻塞
 */
static struct socket *sock_alloc(int wait)
{
  struct socket *sock;

  while (1) {
	cli();
	for (sock = sockets; sock <= last_socket; ++sock) {
		if (sock->state == SS_FREE) {
			/* 注意在socket系统调用完成后struct socket的状态为SS_UNCONNECTED */
			sock->state = SS_UNCONNECTED;
			sti();
			sock->flags = 0;
			sock->ops = NULL;
			sock->data = NULL;
			sock->conn = NULL;
			sock->iconn = NULL;

			/*
			 * This really shouldn't be necessary, but everything
			 * else depends on inodes, so we grab it.
			 * Sleeps are also done on the i_wait member of this
			 * inode.  The close system call will iput this inode
			 * for us.
			 */
			/* 此处给socket分配了一个inode,但是inode是空的,
			 * 并没有包含有效数据的 
			 */
			if (!(SOCK_INODE(sock) = get_empty_inode())) {
				printk("NET: sock_alloc: no more inodes\n");
				sock->state = SS_FREE;
				return(NULL);
			}
			/* 此时设置inode和socket之间的关系,
			 * S_IFSOCK指明inode指向的时socket文件 
			 */
			SOCK_INODE(sock)->i_mode = S_IFSOCK;
			SOCK_INODE(sock)->i_uid = current->euid;
			SOCK_INODE(sock)->i_gid = current->egid;
			SOCK_INODE(sock)->i_socket = sock;

			sock->wait = &SOCK_INODE(sock)->i_wait;
			DPRINTF((net_debug,
				"NET: sock_alloc: sk 0x%x, ino 0x%x\n",
				       			sock, SOCK_INODE(sock)));
			return(sock);
		}
	}
	sti();
	if (!wait) return(NULL);
	DPRINTF((net_debug, "NET: sock_alloc: no free sockets, sleeping...\n"));
	/* 如果没找到,则在socket_wait_free队列中睡眠,当有释放时,则唤醒该进程 */
	interruptible_sleep_on(&socket_wait_free);
	if (current->signal & ~current->blocked) {
		DPRINTF((net_debug, "NET: sock_alloc: sleep was interrupted\n"));
		return(NULL);
	}
	DPRINTF((net_debug, "NET: sock_alloc: wakeup... trying again...\n"));
  }
}
Esempio n. 13
0
/* fd是监听的套接字,该函数的执行过程为,首先在sockets数组当中申请一个
 * struct socket,在申请struct socket的过程中就给socket分配了inode节点,
 * 然后在分配一个struct file结构,最后就返回一个新的文件描述符,该过程是一个
 * 反向的过程
 */
static int sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
{
  struct file *file;
  struct socket *sock, *newsock;
  int i;

  DPRINTF((net_debug, "NET: sock_accept: fd = %d\n", fd));
  if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
								return(-EBADF);

  /* 找到监听fd的socket结构 */
  if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
  if (sock->state != SS_UNCONNECTED) {
	DPRINTF((net_debug, "NET: sock_accept: socket isn't unconnected\n"));
	return(-EINVAL);
  }
  if (!(sock->flags & SO_ACCEPTCON)) {
	DPRINTF((net_debug,
		"NET: sock_accept: socket not accepting connections!\n"));
	return(-EINVAL);
  }

	/* 非阻塞的获取一个socket结构 */
  if (!(newsock = sock_alloc(0))) {
	printk("NET: sock_accept: no more sockets\n");
	return(-EAGAIN);
  }
  /* 两个socket的类型,协议族操作函数相同 */
  newsock->type = sock->type;
  newsock->ops = sock->ops;
  if ((i = sock->ops->dup(newsock, sock)) < 0) {
	sock_release(newsock);
	return(i);
  }

  i = newsock->ops->accept(sock, newsock, file->f_flags);
  if ( i < 0) {
	sock_release(newsock);
	return(i);
  }

  /* 给新的socket分配一个文件描述符 */
  if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
	sock_release(newsock);
	return(-EINVAL);
  }

  DPRINTF((net_debug, "NET: sock_accept: connected socket 0x%x via 0x%x\n",
							sock, newsock));

  if (upeer_sockaddr)
	newsock->ops->getname(newsock, upeer_sockaddr, upeer_addrlen, 1);

  /* 返回新的socket文件描述符 */
  return(fd);
}
Esempio n. 14
0
static inline struct socket *
socki_lookup(struct inode *inode)
{
	struct socket *sock;

	for (sock = sockets; sock <= last_socket; ++sock)
		if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
			return sock;
	return NULL;
}
Esempio n. 15
0
/* 根据inode来查找struct socket结构 */
struct socket *socki_lookup(struct inode *inode)
{
  struct socket *sock;

  /* 如果当前inode的i_socket不为空,且两者相互指向,则返回 */
  if ((sock = inode->i_socket) != NULL) {
	if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
		return sock;
	printk("socket.c: uhhuh. stale inode->i_socket pointer\n");
  }
  /* 如果inode当中没有struct socket的指针,
    * 则在socket数组中查找socket中inode指向参数inode的项
    * 如果找到了则返回,否则返回为空。
    */
  for (sock = sockets; sock <= last_socket; ++sock)
	if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) {
		printk("socket.c: uhhuh. Found socket despite no inode->i_socket pointer\n");
		return(sock);
	}
  return(NULL);
}
Esempio n. 16
0
/*
 * for accept, we attempt to create a new socket, set up the link with the
 * client, wake up the client, then return the new connected fd.
 */
static int
sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
{
	struct file *file;
	struct socket *sock, *newsock;
	int i;

	PRINTK("sys_accept: fd = %d\n", fd);
	if (!(sock = sockfd_lookup(fd, &file)))
		return -EBADF;
	if (sock->state != SS_UNCONNECTED) {
		PRINTK("sys_accept: socket isn't unconnected\n");
		return -EINVAL;
	}
	if (!(sock->flags & SO_ACCEPTCON)) {
		PRINTK("sys_accept: socket not accepting connections!\n");
		return -EINVAL;
	}

	if (!(newsock = sock_alloc(0))) {
		printk("sys_accept: no more sockets\n");
		return -EAGAIN;
	}
	newsock->type = sock->type;
	newsock->ops = sock->ops;
	if ((i = sock->ops->dup(newsock, sock)) < 0) {
		sock_release(newsock);
		return i;
	}

	if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
		sock_release(newsock);
		return -EINVAL;
	}
	i = newsock->ops->accept(sock, newsock, file->f_flags);

	if ( i < 0)
	  {
	     sys_close (fd);
	     return (i);
	  }

	PRINTK("sys_accept: connected socket 0x%x via 0x%x\n",
	       sock, newsock);

	if (upeer_sockaddr)
		newsock->ops->getname(newsock, upeer_sockaddr,
				      upeer_addrlen, 1);

	return fd;
}
Esempio n. 17
0
int atalk_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{
	atalk_socket *s;
	int len=0;
	off_t pos=0;
	off_t begin=0;

	/*
	 *	Output the appletalk data for the /proc virtual fs.
	 */

	len += sprintf (buffer,"Type local_addr  remote_addr tx_queue rx_queue st uid\n");
	for (s = atalk_socket_list; s != NULL; s = s->next)
	{
		len += sprintf (buffer+len,"%02X   ", s->type);
		len += sprintf (buffer+len,"%04X:%02X:%02X  ",
			ntohs(s->protinfo.af_at.src_net),
			s->protinfo.af_at.src_node,
			s->protinfo.af_at.src_port);
		len += sprintf (buffer+len,"%04X:%02X:%02X  ",
			ntohs(s->protinfo.af_at.dest_net),
			s->protinfo.af_at.dest_node,
			s->protinfo.af_at.dest_port);
		len += sprintf (buffer+len,"%08X:%08X ", s->wmem_alloc, s->rmem_alloc);
		len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
		
		/* Are we still dumping unwanted data then discard the record */
		pos=begin+len;
		
		if(pos<offset)
		{
			len=0;			/* Keep dumping into the buffer start */
			begin=pos;
		}
		if(pos>offset+length)		/* We have dumped enough */
			break;
	}
	
	/* The data in question runs from begin to begin+len */
	*start=buffer+(offset-begin);	/* Start of wanted data */
	len-=(offset-begin);		/* Remove unwanted header data from length */
	if(len>length)
		len=length;		/* Remove unwanted tail data from length */
	
	return len;
}
Esempio n. 18
0
static int atalk_seq_socket_show(struct seq_file *seq, void *v)
{
	struct sock *s;
	struct atalk_sock *at;

	if (v == SEQ_START_TOKEN) {
		seq_printf(seq, "Type Local_addr  Remote_addr Tx_queue "
				"Rx_queue St UID\n");
		goto out;
	}

	s = v;
	at = at_sk(s);

	seq_printf(seq, "%02X   %04X:%02X:%02X  %04X:%02X:%02X  %08X:%08X "
			"%02X %d\n",
		   s->sk_type, ntohs(at->src_net), at->src_node, at->src_port,
		   ntohs(at->dest_net), at->dest_node, at->dest_port,
		   atomic_read(&s->sk_wmem_alloc),
		   atomic_read(&s->sk_rmem_alloc),
		   s->sk_state, SOCK_INODE(s->sk_socket)->i_uid);
out:
	return 0;
}