bind.c

Go to the documentation of this file.
00001 #include <errno.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <sys/ioctl.h>
00005 #include <sys/socket.h>
00006 #include <netinet/in.h>
00007 
00008 #include <net/gen/in.h>
00009 #include <net/gen/tcp.h>
00010 #include <net/gen/tcp_io.h>
00011 #include <net/gen/udp.h>
00012 #include <net/gen/udp_io.h>
00013 
00014 #define DEBUG 0
00015 
00016 static int _tcp_bind(int socket, const struct sockaddr *address,
00017         socklen_t address_len, nwio_tcpconf_t *tcpconfp);
00018 static int _udp_bind(int socket, const struct sockaddr *address,
00019         socklen_t address_len, nwio_udpopt_t *udpoptp);
00020 
00021 int bind(int socket, const struct sockaddr *address, socklen_t address_len)
00022 {
00023         int r;
00024         nwio_tcpconf_t tcpconf;
00025         nwio_udpopt_t udpopt;
00026 
00027         r= ioctl(socket, NWIOGTCPCONF, &tcpconf);
00028         if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
00029         {
00030                 if (r == -1)
00031                         return r;
00032                 r= _tcp_bind(socket, address, address_len, &tcpconf);
00033 #if DEBUG
00034                 if (r == -1)
00035                 {
00036                         int t_errno= errno;
00037                         fprintf(stderr, "bind(tcp) failed: %s\n",
00038                                 strerror(errno));
00039                         errno= t_errno;
00040                 }
00041 #endif
00042                 return r;
00043         }
00044 
00045         r= ioctl(socket, NWIOGUDPOPT, &udpopt);
00046         if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
00047         {
00048                 if (r == -1)
00049                         return r;
00050                 return _udp_bind(socket, address, address_len, &udpopt);
00051         }
00052 
00053 #if DEBUG
00054         fprintf(stderr, "bind: not implemented for fd %d\n", socket);
00055 #endif
00056         errno= ENOSYS;
00057         return -1;
00058 }
00059 
00060 static int _tcp_bind(int socket, const struct sockaddr *address,
00061         socklen_t address_len, nwio_tcpconf_t *tcpconfp)
00062 {
00063         int r;
00064         nwio_tcpconf_t tcpconf;
00065         struct sockaddr_in *sinp;
00066 
00067         sinp= (struct sockaddr_in *)address;
00068         if (sinp->sin_family != AF_INET || address_len != sizeof(*sinp))
00069         {
00070 #if DEBUG
00071                 fprintf(stderr, "bind(tcp): sin_family = %d, len = %d\n",
00072                         sinp->sin_family, address_len);
00073 #endif
00074                 errno= EAFNOSUPPORT;
00075                 return -1;
00076         }
00077 
00078         if (sinp->sin_addr.s_addr != INADDR_ANY &&
00079                 sinp->sin_addr.s_addr != tcpconfp->nwtc_locaddr)
00080         {
00081                 errno= EADDRNOTAVAIL;
00082                 return -1;
00083         }
00084 
00085         tcpconf.nwtc_flags= 0;
00086 
00087         if (sinp->sin_port == 0)
00088                 tcpconf.nwtc_flags |= NWTC_LP_SEL;
00089         else
00090         {
00091                 tcpconf.nwtc_flags |= NWTC_LP_SET;
00092                 tcpconf.nwtc_locport= sinp->sin_port;
00093         }
00094 
00095         r= ioctl(socket, NWIOSTCPCONF, &tcpconf);
00096         return r;
00097 }
00098 
00099 static int _udp_bind(int socket, const struct sockaddr *address,
00100         socklen_t address_len, nwio_udpopt_t *udpoptp)
00101 {
00102         int r;
00103         unsigned long curr_flags;
00104         nwio_udpopt_t udpopt;
00105         struct sockaddr_in *sinp;
00106 
00107         sinp= (struct sockaddr_in *)address;
00108         if (sinp->sin_family != AF_INET || address_len != sizeof(*sinp))
00109         {
00110 #if DEBUG
00111                 fprintf(stderr, "bind(udp): sin_family = %d, len = %d\n",
00112                         sinp->sin_family, address_len);
00113 #endif
00114                 errno= EAFNOSUPPORT;
00115                 return -1;
00116         }
00117 
00118         if (sinp->sin_addr.s_addr != INADDR_ANY &&
00119                 sinp->sin_addr.s_addr != udpoptp->nwuo_locaddr)
00120         {
00121                 errno= EADDRNOTAVAIL;
00122                 return -1;
00123         }
00124 
00125         udpopt.nwuo_flags= 0;
00126 
00127         if (sinp->sin_port == 0)
00128                 udpopt.nwuo_flags |= NWUO_LP_SEL;
00129         else
00130         {
00131                 udpopt.nwuo_flags |= NWUO_LP_SET;
00132                 udpopt.nwuo_locport= sinp->sin_port;
00133         }
00134 
00135         curr_flags= udpoptp->nwuo_flags;
00136         if (!(curr_flags & NWUO_ACC_MASK))
00137                 udpopt.nwuo_flags |= NWUO_EXCL;
00138         if (!(curr_flags & (NWUO_EN_LOC|NWUO_DI_LOC)))
00139                 udpopt.nwuo_flags |= NWUO_EN_LOC;
00140         if (!(curr_flags & (NWUO_EN_BROAD|NWUO_DI_BROAD)))
00141                 udpopt.nwuo_flags |= NWUO_EN_BROAD;
00142         if (!(curr_flags & (NWUO_RP_SET|NWUO_RP_ANY)))
00143                 udpopt.nwuo_flags |= NWUO_RP_ANY;
00144         if (!(curr_flags & (NWUO_RA_SET|NWUO_RA_ANY)))
00145                 udpopt.nwuo_flags |= NWUO_RA_ANY;
00146         if (!(curr_flags & (NWUO_RWDATONLY|NWUO_RWDATALL)))
00147                 udpopt.nwuo_flags |= NWUO_RWDATALL;
00148         if (!(curr_flags & (NWUO_EN_IPOPT|NWUO_DI_IPOPT)))
00149                 udpopt.nwuo_flags |= NWUO_DI_IPOPT;
00150 
00151         r= ioctl(socket, NWIOSUDPOPT, &udpopt);
00152         return r;
00153 }

Generated on Fri Apr 14 22:57:26 2006 for minix by  doxygen 1.4.6