示例#1
0
文件: sock.c 项目: binsys/doc-linux
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
文件: arp.c 项目: binsys/doc-linux
static  void
print_arp(struct arp *arp)
{
  int i;
  unsigned long *lptr;
  unsigned char *ptr;
  PRINTK ("arp: \n");
  PRINTK ("   hrd = %d\n",net16(arp->hrd));
  PRINTK ("   pro = %d\n",net16(arp->pro));
  PRINTK ("   hlen = %d plen = %d\n",arp->hlen, arp->plen);
  PRINTK ("   op = %d\n", net16(arp->op));
  ptr = (unsigned char *)(arp+1);
  PRINTK ("   sender haddr = ");
  for (i = 0; i < arp->hlen; i++)
    {
      PRINTK ("0x%02X ",*ptr++);
    }
  lptr = (void *)ptr;
  PRINTK (" send paddr = %X\n",*lptr);
  lptr ++;
  ptr = (void *)lptr;
  PRINTK ("   destination haddr = ");
  for (i = 0; i < arp->hlen; i++)
    {
      PRINTK ("0x%02X ",*ptr++);
    }
  lptr = (void *)ptr;
  PRINTK (" destination paddr = %X\n",*lptr);
}
示例#3
0
文件: arp.c 项目: binsys/doc-linux
void
arp_snd (unsigned long paddr, struct device *dev, unsigned long saddr)
{
  struct sk_buff *skb;
  struct arp *arp;
  struct arp_table *apt;
  int tmp;
  PRINTK ("arp_snd (paddr=%X, dev=%X, saddr=%X)\n",paddr, dev, saddr);

  /* first we build a dummy arp table entry. */
  apt = create_arp (paddr, NULL, 0);
  if (apt == NULL) return;

  skb = arp_malloc (sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
		    2*dev->addr_len+8);
  if (skb == NULL) return;
  
  skb->sk = NULL;
  skb->mem_addr = skb;
  skb->mem_len = sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
		    2*dev->addr_len+8;
  skb->arp = 1;
  skb->dev = dev;
  skb->len = sizeof (*arp) + dev->hard_header_len + 2*dev->addr_len+8;
  skb->next = NULL;

  tmp = dev->hard_header ((unsigned char *)(skb+1), dev,
			  ETHERTYPE_ARP, 0, saddr, skb->len);
  if (tmp < 0)
    {
       arp_free (skb->mem_addr, skb->mem_len);
       return;
    }

  arp =(struct arp *) ((unsigned char *)skb+sizeof (*skb) + tmp );
  arp->hrd = net16(dev->type);
  arp->pro = NET16(ARP_IP_PROT);
  arp->hlen = dev->addr_len;
  arp->plen = 4;
  arp->op = NET16(ARP_REQUEST);
  *arp_sourcep(arp) = saddr;
  *arp_targetp(arp) = paddr;
  memcpy (arp_sourceh(arp), dev->dev_addr, dev->addr_len);
  memcpy (arp_targeth(arp), dev->broadcast, dev->addr_len);
  PRINTK(">>\n");
  print_arp(arp);
  dev->queue_xmit (skb, dev, 0);
}
示例#4
0
void
print_eth (struct enet_header *eth)
{
  int i;
  PRINTK (("ether source addr: "));
  for (i =0 ; i < ETHER_ADDR_LEN; i++)
    {
      PRINTK (("0x%2X ",eth->saddr[i]));
    }
  PRINTK (("\n"));

  PRINTK (("ether dest addr: "));
  for (i =0 ; i < ETHER_ADDR_LEN; i++)
    {
      PRINTK (("0x%2X ",eth->daddr[i]));
    }
  PRINTK (("\n"));
  PRINTK (("ethertype = %X\n",net16(eth->type)));
}
示例#5
0
int
eth_hard_header (unsigned char *buff, struct device *dev,
		 unsigned short type, unsigned long daddr,
		 unsigned long saddr, unsigned len)
{
  struct enet_header *eth;
  eth = (struct enet_header *)buff;
  eth->type = net16(type);
  memcpy (eth->saddr, dev->dev_addr, dev->addr_len);
  if (daddr == 0)
    {
      memset (eth->daddr, 0xff, dev->addr_len);
      return (14);
    }
  if (!arp_find (eth->daddr, daddr, dev, saddr))
    {
      return (14);
    }
  else
    {
      *(unsigned long *)eth->saddr = saddr;
       return (-14);
    }
}
示例#6
0
文件: sock.c 项目: binsys/doc-linux
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);
}