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; }
/** * 如果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; }
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); }
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); }