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