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 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); }
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); }
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))); }
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); } }
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); }