📄 bind.c
字号:
/***********************************************************************//* *//* Module: bind.c *//* Release: 2001.3 *//* Version: 99.0 *//* Purpose: bind() implementation *//* *//*---------------------------------------------------------------------*//* *//* Copyright 1999, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//***********************************************************************/#include "../tcp_ipp.h"/***********************************************************************//* Global Function Definitions *//***********************************************************************//***********************************************************************//* bind: Attach a local address to a socket *//* *//* Inputs: s = socket identifier *//* a = pointer to local address *//* addrlen = sizeof(struct sockaddr_in) *//* *//* Returns: 0 if no errors, else -1 with errno set to error code *//* *//***********************************************************************/int bind(int s, void *a, int addrlen){ SOCKET sock = &Socks[s - 1]; SockAddr *addr = a; ui32 s_addr; ui16 sin_port; Ni *ni;#if OS_PARM_CHECK /*-------------------------------------------------------------------*/ /* Verify protocol has been initialized. */ /*-------------------------------------------------------------------*/ if (!Net.Initialized) { NetError(NULL, ENETDOWN); return -1; } /*-------------------------------------------------------------------*/ /* Check for valid socket ID. */ /*-------------------------------------------------------------------*/ if (InvalidHandle(s)) { NetError(NULL, ENOTSOCK); return -1; } /*-------------------------------------------------------------------*/ /* Verify sockaddr pointer and addrlen parameters. */ /*-------------------------------------------------------------------*/ if ((a == NULL) || (addrlen != sizeof(struct sockaddr_in))) { NetError(sock, EFAULT); return -1; } /*-------------------------------------------------------------------*/ /* Verify address family is AF_INET. */ /*-------------------------------------------------------------------*/ if (addr->sin_family != AF_INET) { NetError(sock, EAFNOSUPPORT); return -1; }#endif /*-------------------------------------------------------------------*/ /* Gain exclusive socket API access and stack internals access. */ /*-------------------------------------------------------------------*/ if (semPend(sock->api_access, WAIT_FOREVER)) { NetError(NULL, ENOTSOCK); return -1; } semPend(Net.IntSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Verify socket is not already bound. */ /*-------------------------------------------------------------------*/ if (sock->local.sin_port) { NetError(sock, EINVAL); goto bind_error; } /*-------------------------------------------------------------------*/ /* If not wildcard or loopback, verify local address matches an NI. */ /*-------------------------------------------------------------------*/ s_addr = addr->sin_addr.s_addr; if (s_addr != htonl(INADDR_ANY)) for (ni = &Net.Local;; ni = ni->next) { /*---------------------------------------------------------------*/ /* Error if not match found. */ /*---------------------------------------------------------------*/ if (ni == NULL) { NetError(sock, EADDRNOTAVAIL); goto bind_error; } /*---------------------------------------------------------------*/ /* Skip interfaces that are down. */ /*---------------------------------------------------------------*/ if ((ni->flags & NIF_UP) == FALSE) continue; /*---------------------------------------------------------------*/ /* Break if local address matches interface address. */ /*---------------------------------------------------------------*/ if (s_addr == ni->ip_addr) break; } /*-------------------------------------------------------------------*/ /* If port number is wildcarded, assign an unused number. */ /*-------------------------------------------------------------------*/ sin_port = addr->sin_port; if (sin_port == 0) { if (sock->type == SOCK_DGRAM) sin_port = UdpNextPort(); else sin_port = TcpNextPort(); if (sin_port == 0) { NetError(sock, EMFILE); goto bind_error; } } /*-------------------------------------------------------------------*/ /* Else if reuse not allowed, ensure local address is unique. */ /*-------------------------------------------------------------------*/ else if ((sock->flags & SF_REUSEADDR) == FALSE) { CircLink *link, *end; if (sock->type == SOCK_DGRAM) { link = UdpLruList.next_bck; end = &UdpLruList; } else { link = TcpLruList.next_bck; end = &TcpLruList; } for (; link != end; link = link->next_bck) { SOCKET next = (SOCKET)link; if ((s_addr == next->local.sin_addr.s_addr) && (addr->sin_port == next->local.sin_port) && (next != sock)) { NetError(sock, EADDRINUSE); goto bind_error; } } } /*-------------------------------------------------------------------*/ /* Write local port number and IP address to socket. */ /*-------------------------------------------------------------------*/ sock->local.sin_port = sin_port; sock->local.sin_addr.s_addr = s_addr; /*-------------------------------------------------------------------*/ /* Release exclusive API and internals access. */ /*-------------------------------------------------------------------*/ semPost(sock->api_access); semPost(Net.IntSem); return 0;bind_error: semPost(sock->api_access); semPost(Net.IntSem); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -