home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / lan / soss.arj / SRC / SOCK.C < prev    next >
C/C++ Source or Header  |  1991-02-22  |  7KB  |  298 lines

  1. /*
  2.  *  sock.c --
  3.  *      Socket interface for PC NFS file server.  This module provides
  4.  *      one level of abstraction above the socket libraries and socket driver
  5.  *      functions perculiar to different PC Ethernet cards.
  6.  *      Note:  this version for pcip only.
  7.  *
  8.  *  Author:
  9.  *      Tony G. Thomas 4/2/90
  10.  */
  11.  
  12. #include "sock.h"
  13. #include "debug.h"
  14.  
  15. #define    bool_t    int
  16. #define    enum_t    int
  17. #define u_int unsigned int 
  18. #define u_short unsigned short 
  19. #define u_long unsigned long 
  20. #define  u_char  unsigned char 
  21. #define __dontcare__    -1
  22. #define caddr_t char *
  23. #include "in.h"
  24.  
  25. extern NET nets[];
  26. extern long cticks;
  27. extern bcopy_fn();
  28. extern bcopy_nf();
  29. extern bcopy_ff();
  30. void far *_fmalloc();
  31.  
  32. /* templates for local types 
  33. static struct sockproto UDP_PROTO = { PF_INET, IPPROTO_UDP };
  34. static struct sockproto TCP_PROTO = { PF_INET, IPPROTO_TCP }; */
  35.  
  36. struct sockaddr_in *laddr[8], *raddr[8];
  37. char far *p_pkts[8];
  38. int ready_packs[8], used_socks[8];
  39. UDPCONN con[8];
  40. int handler();
  41.  
  42.  
  43. /*
  44.  *  int sock_create(int type, int protocol, struct sockaddr_in *addr) --
  45.  *      Creates a socket of type using protocol, bound to address *addr on the
  46.  *      local PC.  Returns the socket descriptor or -1 if an error
  47.  *      occurred.
  48.  */
  49. int sock_create(type, protocol, addr)
  50.     int type, protocol;
  51.     struct sockaddr_in *addr;
  52. {
  53.     if (type == SOCK_DGRAM && protocol == IPPROTO_UDP)
  54.         return sock_udpcreate(addr);
  55.  
  56.     /* if (type == SOCK_STREAM && protocol == IPPROTO_TCP)
  57.         return sock_tcpcreate(addr); */
  58.  
  59.     (void) fprintf(stderr, "Protocol not supported\n");
  60.     return -1;
  61. }
  62.  
  63. /*
  64.  *  int sock_udpcreate(struct sockaddr_in addr) --
  65.  *      Creates a UDP socket on the local host using address specified.
  66.  *      If port == 0 then an arbitrary port is assigned.
  67.  */
  68. int sock_udpcreate(addr)
  69.     struct sockaddr_in *addr;
  70. {
  71.     int sock;
  72.     unsigned port;
  73.  
  74.     DBGPRT0 (nfsdebug, "creating socket");
  75.  
  76.     for (sock = 0; sock < 8; sock++ )  {
  77.         if (used_socks[sock] == 0) break;
  78.         if (sock == 7) {
  79.             (void) fprintf(stderr, "sock_udpcreate: too many sockets;");
  80.             return -1;
  81.         }
  82.     }
  83.     port = (unsigned) ( addr->sin_port ? addr->sin_port : udp_socket() );
  84.     ready_packs[sock] = 0;
  85.  
  86.     con[sock] = udp_open(0L, 0, port, handler, (unsigned) sock);
  87.     if (con[sock] == NULL) {
  88.         (void) fprintf(stderr, "sock_udpcreate: error opening socket;");
  89.         return -1;
  90.     }
  91.     laddr[sock] = (struct sockaddr_in *) calloc(1, sizeof(struct sockaddr_in));
  92.     raddr[sock] = (struct sockaddr_in *) calloc(1, sizeof(struct sockaddr_in));
  93.  
  94.     laddr[sock]->sin_family = addr->sin_family;
  95.     raddr[sock]->sin_family = addr->sin_family;
  96.  
  97.     laddr[sock]->sin_port = (unsigned) (port);
  98.     (laddr[sock]->sin_addr).s_addr = (addr->sin_addr).s_addr;
  99.  
  100.     used_socks[sock] = 1;
  101.     return sock;
  102. }
  103.  
  104. /*
  105.  * Udp Packet Handler
  106.  */
  107. handler(p, len, host, sock)
  108.     PACKET p;
  109.     unsigned len;
  110.     in_name host;
  111.     unsigned sock;
  112. {
  113.     if (ready_packs[sock] == 1) {
  114.         (void) fprintf(stderr, "UDP: discarding packet\n");
  115.         udp_free(p);
  116.         return;
  117.     }
  118.     p_pkts[sock] = (char far *) _fmalloc(len);
  119.     bcopy_nf(udp_data(udp_head(in_head(p))), p_pkts[sock], len);
  120.     ready_packs[sock] = 1;
  121.  
  122.     raddr[sock]->sin_port = (unsigned) ((udp_head(in_head(p)))->ud_srcp);
  123.     (raddr[sock]->sin_addr).s_addr = host;
  124.     udp_free(p);
  125.     return;
  126. }
  127.  
  128. /*
  129.  *  void sock_close(int sock) --
  130.  *      Closes the socket descriptor sock.
  131.  */
  132. void sock_close(sock)
  133.     int sock;
  134. {
  135.     used_socks[sock] = 0;
  136.     free(laddr[sock]);
  137.     free(raddr[sock]);
  138.     udp_close(con[sock]);
  139.     return;
  140. }
  141.  
  142.  
  143. /*
  144.  *  int sock_select(int *rfds, int *wfds) --
  145.  *      Returns the number of descriptors readable corresponding to
  146.  *      the bit masks in *rfds, or writable in *wfds.
  147.  *      *rfds and *wfds are changed to reflect the readable sockets.
  148.  */
  149. int sock_select(rfds, wfds)
  150.     long *rfds, *wfds;
  151. {
  152.     /* should use soselect, but the function seems to be buggy */
  153.     int sock, nd;        /* socket and # of descriptors */
  154.     long mask, count;
  155.  
  156.     tk_yield();
  157.  
  158.     for(mask = 0, sock = 0, nd = 0; rfds != NULL && *rfds != 0; 
  159.         sock++, *rfds >>= 1) {
  160.         if (*rfds & 1 != 0) {
  161.             /* soioctl(sock, FIONREAD, &count);
  162.             if (count != 0) */
  163.             if( ready_packs[sock] == 1)
  164.                 mask |= 1 << sock, nd++;
  165.         }
  166.     }
  167.     *rfds = mask;
  168.  
  169.     for(mask = 0, sock = 0; wfds != NULL && *wfds != 0; 
  170.         sock++, *wfds >>= 1) {
  171.         if (*wfds & 1 != 0) {
  172.             /* soioctl(sock, FIONREAD, &count);
  173.             if (count != 0) */
  174.             if (used_socks[sock] = 1)
  175.                 mask |= 1 << sock, nd++;
  176.         }
  177.     }
  178.     *wfds = mask;
  179.  
  180.     return nd;
  181. }
  182.  
  183. /*
  184.  *  int sock_recv(int sock, char far *buf, int bufsiz, struct sockaddr_in *from) --
  185.  *      Recevies message from socket and puts it into buffer.  The from address
  186.  *      is placed in *from.  Returns the size of the message.
  187.  */
  188. int sock_recv(sock, buf, bufsiz, from)
  189.     int sock;
  190.     char far *buf;
  191.     int bufsiz;
  192.     struct sockaddr_in *from;
  193. {
  194.     int recvlen; 
  195.  
  196.     /* struct sockaddr_in f; */
  197.  
  198.     if (ready_packs[sock] == 0) return (0);
  199.     recvlen= (int) _fmsize(p_pkts[sock]);
  200.     if (recvlen < 0 ) (void) fprintf(stderr, "--> recv err\n");
  201.     *from = *raddr[sock];
  202.  
  203.     bcopy_ff(p_pkts[sock], buf, (unsigned) bufsiz);
  204.     _ffree(p_pkts[sock]);
  205.     ready_packs[sock] = 0;
  206.     return recvlen;
  207. }
  208.     
  209. /*
  210.  * int sock_send(int sock, struct sockaddr_in *addr, char far *msg, int len) --
  211.  *      Transmits a message msg using sock to host at *addr of length len.
  212.  *      Assumed to be a UDP socket.  Returns the number of bytes sent, or -1
  213.  *      if an error occurred.
  214.  */
  215. int sock_send(sock, addr, msg, len)
  216.     int sock;
  217.     struct sockaddr_in *addr;
  218.     char far *msg;
  219.     int len;
  220. {
  221.     unsigned paclen = 1000;
  222.     PACKET p;
  223.  
  224.     if (len < 1000) paclen = (unsigned) len;
  225.     /* printf("room %u: paclen %u: stack %u\n", _memavl(), paclen, stackavail()); */
  226.     if ((p = udp_alloc(paclen, 0))== NULL) return -1;
  227.     bcopy_fn(msg, udp_data(udp_head(in_head(p))), paclen);
  228.     if ( udp_send_to(addr->sin_addr.s_addr, addr->sin_port, 
  229.          (unsigned) (laddr[sock]->sin_port), p, paclen) < 0) {
  230.          udp_free(p);
  231.          return -1;
  232.     }
  233.     udp_free(p);
  234.     return (int) paclen;
  235. }
  236.  
  237. /*
  238.  *  int sock_getsockaddr(int sock, struct sockaddr_in *addr) --]
  239.  *      Returns socket address in *addr.  Returns -1 if an error
  240.  *      occurred.
  241.  */
  242. int sock_getsockaddr(sock, addr)
  243.     int sock;
  244.     struct sockaddr_in *addr;
  245. {
  246.     *addr = *laddr[sock];
  247.     return;
  248. }
  249.  
  250.  
  251. /*
  252.  *  long sock_gethostbyname(char *name) --
  253.  *      Returns host IP address given host name.  Returns -1 for error.
  254.  */
  255.  
  256. long sock_gethostbyname(modename)
  257.     char *modename; 
  258. {
  259.     in_name fhost;
  260.     
  261.     fhost = resolve_name(modename);
  262.     if(fhost == 0) {
  263.         printf("Couldn't resolve hostname %s.\n", modename);
  264.         return -1;    }
  265.  
  266.     if(fhost == NAMETMO) {
  267.         printf("name servers not responding.\n");
  268.         return -1;
  269.         }
  270.     return fhost;
  271.  
  272. }
  273.  
  274.  
  275. /*
  276.  *  char *sock_gethostbyaddr(struct sockaddr_in addr) --
  277.  *      Returns a character pointer to the hostname
  278.  *    Needs entry in hosts file
  279.  */
  280. char *sock_gethostbyaddr(addr)
  281.     struct sockaddr_in addr;
  282. {
  283.     char *s;
  284.     FILE *fp;
  285.  
  286.     s = (char *) malloc(40);
  287.     if ((fp = fopen("hosts", "r")) == NULL) return NULL;
  288.     while ( fgets(s, 40, fp) != NULL) {
  289.         if ( addr.sin_addr.s_addr == resolve_name(s)) {
  290.             fclose(fp);
  291.             return s;
  292.         }
  293.     }
  294.     fclose(fp);
  295.     s = "no_hosts_entry";
  296.     return s;
  297. }
  298.