Пример #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);
}
Пример #2
0
/* this will do terrible things if len + ipheader + devheader > dev->mtu */
static int
packet_sendto (volatile struct sock *sk, unsigned char *from, int len,
	       int noblock,
	       unsigned flags, struct sockaddr_in *usin, int addr_len)
{
   struct sk_buff *skb;
   struct device *dev;
   struct sockaddr saddr;

   /* check the flags. */
   if (flags) return (-EINVAL);
   if (len < 0) return (-EINVAL);

   /* get and verify the address. */
   if (usin)
     {
	if (addr_len < sizeof (saddr))
	  return (-EINVAL);
	verify_area (usin, sizeof (saddr));
	memcpy_fromfs (&saddr, usin, sizeof(saddr));
     }
   else
     return (-EINVAL);

   skb = sk->prot->wmalloc (sk, len+sizeof (*skb) + sk->prot->max_header, 0);
   /* this shouldn't happen, but it could. */
   if (skb == NULL)
     {
	PRINTK ("packet_sendto: write buffer full?\n");
	print_sk (sk);
	return (-EAGAIN);
     }
   skb->mem_addr = skb;
   skb->mem_len = len + sizeof (*skb) +sk->prot->max_header;
   skb->sk = sk;
   skb->free = 1;
   saddr.sa_data[13] = 0;
   dev = get_dev (saddr.sa_data);
   if (dev == NULL)
     {
	sk->prot->wfree (sk, skb->mem_addr, skb->mem_len);
	return (-ENXIO);
     }
   verify_area (from, len);
   memcpy_fromfs (skb+1, from, len);
   skb->len = len;
   skb->next = NULL;
   if (dev->up)
     dev->queue_xmit (skb, dev, sk->priority);
   else
     free_skb (skb, FREE_WRITE);
   return (len);
}
Пример #3
0
static void check_result(void)
{
	struct bpf_tcp_sock srv_tp, cli_tp;
	struct bpf_sock srv_sk, cli_sk;
	__u32 linum, idx0 = 0;
	int err;

	err = bpf_map_lookup_elem(linum_map_fd, &idx0, &linum);
	CHECK(err == -1, "bpf_map_lookup_elem(linum_map_fd)",
	      "err:%d errno:%d", err, errno);

	err = bpf_map_lookup_elem(sk_map_fd, &srv_idx, &srv_sk);
	CHECK(err == -1, "bpf_map_lookup_elem(sk_map_fd, &srv_idx)",
	      "err:%d errno:%d", err, errno);
	err = bpf_map_lookup_elem(tp_map_fd, &srv_idx, &srv_tp);
	CHECK(err == -1, "bpf_map_lookup_elem(tp_map_fd, &srv_idx)",
	      "err:%d errno:%d", err, errno);

	err = bpf_map_lookup_elem(sk_map_fd, &cli_idx, &cli_sk);
	CHECK(err == -1, "bpf_map_lookup_elem(sk_map_fd, &cli_idx)",
	      "err:%d errno:%d", err, errno);
	err = bpf_map_lookup_elem(tp_map_fd, &cli_idx, &cli_tp);
	CHECK(err == -1, "bpf_map_lookup_elem(tp_map_fd, &cli_idx)",
	      "err:%d errno:%d", err, errno);

	printf("srv_sk: ");
	print_sk(&srv_sk);
	printf("\n");

	printf("cli_sk: ");
	print_sk(&cli_sk);
	printf("\n");

	printf("srv_tp: ");
	print_tp(&srv_tp);
	printf("\n");

	printf("cli_tp: ");
	print_tp(&cli_tp);
	printf("\n");

	CHECK(srv_sk.state == 10 ||
	      !srv_sk.state ||
	      srv_sk.family != AF_INET6 ||
	      srv_sk.protocol != IPPROTO_TCP ||
	      memcmp(srv_sk.src_ip6, &in6addr_loopback,
		     sizeof(srv_sk.src_ip6)) ||
	      memcmp(srv_sk.dst_ip6, &in6addr_loopback,
		     sizeof(srv_sk.dst_ip6)) ||
	      srv_sk.src_port != ntohs(srv_sa6.sin6_port) ||
	      srv_sk.dst_port != cli_sa6.sin6_port,
	      "Unexpected srv_sk", "Check srv_sk output. linum:%u", linum);

	CHECK(cli_sk.state == 10 ||
	      !cli_sk.state ||
	      cli_sk.family != AF_INET6 ||
	      cli_sk.protocol != IPPROTO_TCP ||
	      memcmp(cli_sk.src_ip6, &in6addr_loopback,
		     sizeof(cli_sk.src_ip6)) ||
	      memcmp(cli_sk.dst_ip6, &in6addr_loopback,
		     sizeof(cli_sk.dst_ip6)) ||
	      cli_sk.src_port != ntohs(cli_sa6.sin6_port) ||
	      cli_sk.dst_port != srv_sa6.sin6_port,
	      "Unexpected cli_sk", "Check cli_sk output. linum:%u", linum);

	CHECK(srv_tp.data_segs_out != 1 ||
	      srv_tp.data_segs_in ||
	      srv_tp.snd_cwnd != 10 ||
	      srv_tp.total_retrans ||
	      srv_tp.bytes_acked != DATA_LEN,
	      "Unexpected srv_tp", "Check srv_tp output. linum:%u", linum);

	CHECK(cli_tp.data_segs_out ||
	      cli_tp.data_segs_in != 1 ||
	      cli_tp.snd_cwnd != 10 ||
	      cli_tp.total_retrans ||
	      cli_tp.bytes_received != DATA_LEN,
	      "Unexpected cli_tp", "Check cli_tp output. linum:%u", linum);
}
Пример #4
0
void
destroy_sock(volatile struct sock *sk)
{

  struct sk_buff *skb;
  PRINTK ("destroying socket %X\n",sk);
  /* just to be safe. */
  sk->inuse = 1;

  remove_sock (sk);
  /* now we can no longer get new packets. */

  delete_timer((struct timer *)&sk->time_wait);

  /* cleanup up the write buffer. */
  for (skb = sk->wfront; skb != NULL; )
    {
      struct sk_buff *skb2;
      skb2=skb->next;
      free_skb(skb, FREE_WRITE);
      skb=skb2;
    }

  sk->wfront = NULL;

  if (sk->rqueue != NULL)
    {
       skb = sk->rqueue;
       do {
	  struct sk_buff *skb2;
	  skb2=skb->next;
	  /* this will take care of closing sockets that were
	     listening and didn't accept everything. */

	  if (skb->sk != NULL && skb->sk != sk)
	    {
	       skb->sk->dead = 1;
	       skb->sk->prot->close (skb->sk, 0);
	    }
	  free_skb(skb, FREE_READ);
	  skb=skb2;
       } while (skb != sk->rqueue);
    }

  sk->rqueue = NULL;

  /* now we need to clean up the send head. */
  for (skb = sk->send_head; skb != NULL; )
    {
      struct sk_buff *skb2;
      /* we need to remove skb from the transmit queue. */
      cli();
      /* see if it's in a transmit queue. */
      if (skb->next != NULL)
	{
	   if (skb->next != skb)
	     {
		skb->next->prev = skb->prev;
		skb->prev->next = skb->next;
	     }
	   else
	     {
		int i;
		for (i = 0; i < DEV_NUMBUFFS; i++)
		  {
		     if (skb->dev && skb->dev->buffs[i] == skb)
		       {
			  skb->dev->buffs[i]= NULL;
			  break;
		       }
		  }
	     }
	}
      sti();
      skb2=skb->link3;
      free_skb(skb, FREE_WRITE);
      skb=skb2;
    }

  sk->send_head = NULL;

  /* and now the backlog. */

  if (sk->back_log != NULL)
    {
       /* this should never happen. */
       printk ("cleaning back_log. \n");
       cli();
       skb = sk->back_log;
       do {
	  struct sk_buff *skb2;
	  skb2=skb->next;
	  free_skb(skb, FREE_READ);
	  skb=skb2;
       } while (skb != sk->back_log);
       sti();
    }

  sk->back_log = NULL;

  /* now if everything is gone we can free the socket structure, 
     otherwise we need to keep it around until everything is gone. */
  if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0)
    {
       free_s ((void *)sk,sizeof (*sk));
    }
  else
    {
       /* this should never happen. */
       /* actually it can if an ack has just been sent. */
       PRINTK ("possible memory leak in socket = %X\n", sk);
       print_sk (sk);
       sk->destroy = 1;
       sk->ack_backlog = 0;
       sk->inuse = 0;
       sk->time_wait.len = SOCK_DESTROY_TIME;
       sk->timeout = TIME_DESTROY;
       reset_timer ((struct timer *)&sk->time_wait);
    }
  
}