devip-posix.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       devip-posix.c (3551B)
       ---
            1 #include "u.h"
            2 #include <sys/types.h>
            3 #include <sys/socket.h>
            4 #include <netinet/in.h>
            5 #include <netinet/tcp.h>
            6 #include <netdb.h>
            7 #include <signal.h>
            8 #include "lib.h"
            9 #include "mem.h"
           10 #include "dat.h"
           11 #include "fns.h"
           12 #include "error.h"
           13 #include "devip.h"
           14 
           15 #undef listen
           16 #undef accept
           17 #undef bind
           18 
           19 void
           20 osipinit(void)
           21 {
           22         char buf[1024];
           23         
           24         signal(SIGPIPE, SIG_IGN);
           25         gethostname(buf, sizeof(buf));
           26         kstrdup(&sysname, buf);
           27 }
           28 
           29 int
           30 so_socket(int type)
           31 {
           32         int fd, one;
           33 
           34         switch(type) {
           35         default:
           36                 error("bad protocol type");
           37         case S_TCP:
           38                 type = SOCK_STREAM;
           39                 break;
           40         case S_UDP:
           41                 type = SOCK_DGRAM;
           42                 break;
           43         }
           44 
           45         fd = socket(AF_INET, type, 0);
           46         if(fd < 0)
           47                 oserror();
           48 
           49         one = 1;
           50         if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){
           51                 oserrstr();
           52                 print("setsockopt: %r");
           53         }
           54 
           55         return fd;
           56 }
           57 
           58 
           59 void
           60 so_connect(int fd, unsigned long raddr, unsigned short rport)
           61 {
           62         struct sockaddr_in sin;
           63 
           64         memset(&sin, 0, sizeof(sin));
           65         sin.sin_family = AF_INET;
           66         hnputs(&sin.sin_port, rport);
           67         hnputl(&sin.sin_addr.s_addr, raddr);
           68 
           69         if(connect(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
           70                 oserror();
           71 }
           72 
           73 void
           74 so_getsockname(int fd, unsigned long *laddr, unsigned short *lport)
           75 {
           76         socklen_t len;
           77         struct sockaddr_in sin;
           78 
           79         len = sizeof(sin);
           80         if(getsockname(fd, (struct sockaddr*)&sin, &len) < 0)
           81                 oserror();
           82 
           83         if(sin.sin_family != AF_INET || len != sizeof(sin))
           84                 error("not AF_INET");
           85 
           86         *laddr = nhgetl(&sin.sin_addr.s_addr);
           87         *lport = nhgets(&sin.sin_port);
           88 }
           89 
           90 void
           91 so_listen(int fd)
           92 {
           93         if(listen(fd, 5) < 0)
           94                 oserror();
           95 }
           96 
           97 int
           98 so_accept(int fd, unsigned long *raddr, unsigned short *rport)
           99 {
          100         int nfd;
          101         socklen_t len;
          102         struct sockaddr_in sin;
          103 
          104         len = sizeof(sin);
          105         nfd = accept(fd, (struct sockaddr*)&sin, &len);
          106         if(nfd < 0)
          107                 oserror();
          108 
          109         if(sin.sin_family != AF_INET || len != sizeof(sin))
          110                 error("not AF_INET");
          111 
          112         *raddr = nhgetl(&sin.sin_addr.s_addr);
          113         *rport = nhgets(&sin.sin_port);
          114         return nfd;
          115 }
          116 
          117 void
          118 so_bind(int fd, int su, unsigned short port)
          119 {
          120         int i, one;
          121         struct sockaddr_in sin;
          122 
          123         one = 1;
          124         if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){
          125                 oserrstr();
          126                 print("setsockopt: %r");
          127         }
          128 
          129         if(su) {
          130                 for(i = 600; i < 1024; i++) {
          131                         memset(&sin, 0, sizeof(sin));
          132                         sin.sin_family = AF_INET;
          133                         sin.sin_port = i;
          134 
          135                         if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) >= 0)        
          136                                 return;
          137                 }
          138                 oserror();
          139         }
          140 
          141         memset(&sin, 0, sizeof(sin));
          142         sin.sin_family = AF_INET;
          143         hnputs(&sin.sin_port, port);
          144 
          145         if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
          146                 oserror();
          147 }
          148 
          149 int
          150 so_gethostbyname(char *host, char**hostv, int n)
          151 {
          152         int i;
          153         char buf[32];
          154         unsigned char *p;
          155         struct hostent *hp;
          156 
          157         hp = gethostbyname(host);
          158         if(hp == 0)
          159                 return 0;
          160 
          161         for(i = 0; hp->h_addr_list[i] && i < n; i++) {
          162                 p = (unsigned char*)hp->h_addr_list[i];
          163                 sprint(buf, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
          164                 hostv[i] = strdup(buf);
          165                 if(hostv[i] == 0)
          166                         break;
          167         }
          168         return i;
          169 }
          170 
          171 char*
          172 hostlookup(char *host)
          173 {
          174         char buf[100];
          175         uchar *p;
          176         struct hostent *he;
          177 
          178         he = gethostbyname(host);
          179         if(he != 0 && he->h_addr_list[0]) {
          180                 p = (uchar*)he->h_addr_list[0];
          181                 sprint(buf, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]);
          182         } else
          183                 strcpy(buf, host);
          184 
          185         return strdup(buf);
          186 }
          187 
          188 int
          189 so_getservbyname(char *service, char *net, char *port)
          190 {
          191         struct servent *s;
          192 
          193         s = getservbyname(service, net);
          194         if(s == 0)
          195                 return -1;
          196 
          197         sprint(port, "%d", nhgets(&s->s_port));
          198         return 0;
          199 }
          200 
          201 int
          202 so_send(int fd, void *d, int n, int f)
          203 {
          204         return send(fd, d, n, f);
          205 }
          206 
          207 int
          208 so_recv(int fd, void *d, int n, int f)
          209 {
          210         return recv(fd, d, n, f);
          211 }