Beispiel #1
0
static int
ip_proto_bind (struct socket *sock, struct sockaddr *uaddr,
	       int addr_len)
{
  struct sockaddr_in addr;
  volatile struct sock *sk, *sk2;
  unsigned short snum;
  sk = sock->data;
   if (sk == NULL)
     {
	printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
	return (0);
     }
  /* check this error. */
  if (sk->state != TCP_CLOSE) return (-EIO);
  verify_area (uaddr, addr_len);
  memcpy_fromfs (&addr, uaddr, min (sizeof (addr), addr_len));
  if (addr.sin_family && addr.sin_family != AF_INET)
    return (-EIO); /* this needs to be changed. */
  snum = net16(addr.sin_port);
  PRINTK ("bind sk =%X to port = %d\n", sk, snum);
  print_sk (sk);
  sk = sock->data;

  /* we can't just leave the socket bound wherever it is, it might be bound
     to a priveledged port. However, since there seems to be a bug here,
     we will leave it if the port is not priveledged(sp?) */

  if (snum == 0)
    {
       if ( sk->num > PROT_SOCK) return (0);
       snum = get_new_socknum (sk->prot, 0);
    }

  if (snum <= PROT_SOCK && !suser())
    return (-EPERM);

  if (my_ip_addr(addr.sin_addr.s_addr) || addr.sin_addr.s_addr == 0)
    sk->saddr = addr.sin_addr.s_addr;
  PRINTK ("sock_array[%d] = %X:\n", snum & (SOCK_ARRAY_SIZE -1),
	  sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]);
  print_sk (sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)]);

  /* make sure we are allowed to bind here. */
  for (sk2 = sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)];
       sk2 != NULL;
       sk2 = sk2->next)
    {
       if (sk2->num != snum) continue;
       if (sk2->saddr != sk->saddr) continue;
       if (!sk->reuse) return (-EADDRINUSE);
       if (!sk2->reuse) return (-EADDRINUSE);
    }
  remove_sock (sk);
  put_sock(snum, sk);
  sk->dummy_th.source = net16(sk->num);
  sk->daddr = 0;
  sk->dummy_th.dest = 0;
  return (0);
}
static int inet_autobind(struct sock *sk)
{
	/* 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 0;
}
Beispiel #3
0
/**
 * 如果sock未绑定端口,就给sock绑定随机端口,并添加到协议的管理结构中 
 * inet_connect中会调用到
 **/
static int inet_autobind(struct sock *sk)
{
	/* We may need to bind the socket. */
	/* 检查sock是否绑定了端口,如果没绑定就绑定一个随机端口	*/
	if (sk->num == 0) 
	{
		sk->num = get_new_socknum(sk->prot, 0);
		if (sk->num == 0) 
			return(-EAGAIN);
		put_sock(sk->num, sk);
		/* tcp头部,应该使用网络字节序存放源端口号,此处应该是错了	*/
		// sk->dummy_th.source = ntohs(sk->num);
		sk->dummy_th.source = htons(sk->num);
	}
	return 0;
}
Beispiel #4
0
static int inet_bind(struct socket *sock, struct sockaddr *uaddr,
	       int addr_len)
{
	struct sockaddr_in *addr=(struct sockaddr_in *)uaddr;
	struct sock *sk=(struct sock *)sock->data, *sk2;
	unsigned short snum = 0 /* Stoopid compiler.. this IS ok */;
	int chk_addr_ret;

	/* check this error. */
	if (sk->state != TCP_CLOSE)
		return(-EIO);
	if(addr_len<sizeof(struct sockaddr_in))
		return -EINVAL;
		
	if(sock->type != SOCK_RAW)
	{
		/* 验证sk已经加入到对应传输层协议的管理结构中 */
		if (sk->num != 0) 
			return(-EINVAL);

		snum = ntohs(addr->sin_port);

		/*
		 * We can't just leave the socket bound wherever it is, it might
		 * be bound to a privileged port. However, since there seems to
		 * be a bug here, we will leave it if the port is not privileged.
		 */
		if (snum == 0) 
		{
			snum = get_new_socknum(sk->prot, 0);
		}
		if (snum < PROT_SOCK && !suser()) 
			return(-EACCES);
	}
	
	chk_addr_ret = ip_chk_addr(addr->sin_addr.s_addr);
	if (addr->sin_addr.s_addr != 0 && chk_addr_ret != IS_MYADDR && chk_addr_ret != IS_MULTICAST)
		return(-EADDRNOTAVAIL);	/* Source address MUST be ours! */
	  	
	if (chk_addr_ret || addr->sin_addr.s_addr == 0)
		sk->saddr = addr->sin_addr.s_addr;
	
	if(sock->type != SOCK_RAW)
	{
		/* Make sure we are allowed to bind here. */
		cli();
		for(sk2 = sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)];
					sk2 != NULL; sk2 = sk2->next) 
		{
		/* should be below! */
			if (sk2->num != snum) 
				continue;
			if (!sk->reuse)
			{
				sti();
				return(-EADDRINUSE);
			}
			
			if (sk2->num != snum) 
				continue;		/* more than one */
			if (sk2->saddr != sk->saddr) 
				continue;	/* socket per slot ! -FB */
			if (!sk2->reuse || sk2->state==TCP_LISTEN) 
			{
				sti();
				return(-EADDRINUSE);
			}
		}
		sti();

		remove_sock(sk);
		put_sock(snum, sk);
		sk->dummy_th.source = ntohs(sk->num);
		sk->daddr = 0;
		sk->dummy_th.dest = 0;
	}
	return(0);
}
Beispiel #5
0
static int
ip_proto_create (struct socket *sock, int protocol)
{
  volatile struct sock *sk;
  struct proto *prot;
  int err;

  sk = malloc (sizeof (*sk));
  if (sk == NULL)
    return (-ENOMEM);
  sk->num = 0;


  switch (sock->type)
    {
    case SOCK_STREAM:
    case SOCK_SEQPACKET:
       if (protocol && protocol != IP_TCP)
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPROTONOSUPPORT);
	 }
       sk->no_check = TCP_NO_CHECK;
       prot = &tcp_prot;
       break;

    case SOCK_DGRAM:
       if (protocol && protocol != IP_UDP)
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPROTONOSUPPORT);
	 }
       sk->no_check = UDP_NO_CHECK;
       prot=&udp_prot;
       break;
      
     case SOCK_RAW:
       if (!suser())
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPERM);
	 }

       if (!protocol)
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPROTONOSUPPORT);
	 }
       prot = &raw_prot;
       sk->reuse = 1;
       sk->no_check = 0; /* doesn't matter no checksum is preformed
			    anyway. */
       sk->num = protocol;
       break;

    case SOCK_PACKET:
       if (!suser())
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPERM);
	 }

       if (!protocol)
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPROTONOSUPPORT);
	 }
       prot = &packet_prot;
       sk->reuse = 1;
       sk->no_check = 0; /* doesn't matter no checksum is preformed
			    anyway. */
       sk->num = protocol;
       break;

      
    default:
       free_s ((void *)sk, sizeof (*sk));
       return (-ESOCKTNOSUPPORT);

    }
  sk->protocol = protocol;
  sk->wmem_alloc = 0;
  sk->rmem_alloc = 0;
  sk->pair = NULL;
  sk->opt = NULL;
  sk->send_seq = 0;
  sk->acked_seq = 0;
  sk->copied_seq = 0;
  sk->fin_seq = 0;
  sk->proc = 0;
  sk->rtt = TCP_WRITE_TIME;
  sk->packets_out = 0;
  sk->cong_window = 1; /* start with only sending one packet at a time. */
  sk->exp_growth = 1;  /* if set cong_window grow exponentially every time
			  we get an ack. */
  sk->urginline = 0;
  sk->intr = 0;
  sk->linger = 0;
  sk->destroy = 0;
  sk->reuse = 0;
  sk->priority = 1;
  sk->shutdown = 0;
  sk->urg = 0;
  sk->keepopen = 0;
  sk->done = 0;
  sk->ack_backlog = 0;
  sk->window = 0;
  sk->bytes_rcv = 0;
  sk->state = TCP_CLOSE;
  sk->dead = 0;
  sk->ack_timed = 0;

  /* this is how many unacked bytes we will accept for
     this socket.  */

  sk->max_unacked = 2048; /* needs to be at most 2 full packets. */

  /* how many packets we should send before forcing an ack. 
     if this is set to zero it is the same as sk->delay_acks = 0 */

  sk->max_ack_backlog = MAX_ACK_BACKLOG;
  sk->inuse = 0;
  sk->delay_acks = 1; /* default to waiting a while before sending
			 acks.  */
  sk->wback = NULL;
  sk->wfront = NULL;
  sk->rqueue = NULL;
  sk->mtu = 576;
  sk->prot = prot;
  sk->sleep = sock->wait;
  sk->daddr = 0;
  sk->saddr = MY_IP_ADDR;
  sk->err = 0;
  sk->next = NULL;
  sk->pair = NULL;
  sk->send_tail = NULL;
  sk->send_head = NULL;
  sk->time_wait.len = TCP_CONNECT_TIME;
  sk->time_wait.when = 0;
  sk->time_wait.sk = sk;
  sk->time_wait.next = NULL;
  sk->timeout = 0;
  sk->back_log = NULL;
  sk->blog = 0;
  sock->data =(void *) sk;
  sk->dummy_th.doff = sizeof (sk->dummy_th)/4;
  sk->dummy_th.res1=0;
  sk->dummy_th.res2=0;
  sk->dummy_th.urg_ptr = 0;
  sk->dummy_th.fin = 0;
  sk->dummy_th.syn = 0;
  sk->dummy_th.rst = 0;
  sk->dummy_th.psh = 0;
  sk->dummy_th.ack = 0;
  sk->dummy_th.urg = 0;
  sk->dummy_th.dest = 0;
  if (sk->num)
    {
       put_sock (sk->num, sk);
    }
  else
    {
       sk->num = get_new_socknum(sk->prot, 0);
    }
  /* make sure there was a free socket. */
  if (sk->num == 0)
    {
      destroy_sock(sk);
      return (-EAGAIN);
    }
  put_sock(sk->num, sk);
  sk->dummy_th.source = net16(sk->num);
  if (sk->prot->init)
    {
       err = sk->prot->init(sk);
       if (err != 0)
	 {
	    destroy_sock (sk);
	    return (err);
	 }
    }
  return (0);
}