home *** CD-ROM | disk | FTP | other *** search
- /*
- * sock.c --
- * Socket interface for PC NFS file server. This module provides
- * one level of abstraction above the socket libraries and socket driver
- * functions perculiar to different PC Ethernet cards.
- * Note: this version for pcip only.
- *
- * Author:
- * Tony G. Thomas 4/2/90
- * Modified by:
- * Rich Braun @ Kronos
- *
- * Revision history:
- *
- * $Log: sock.c_v $
- * Revision 1.3 1991/05/10 21:01:48 richb
- * Boost sock_send limit from 1000 to 1300 to allow 1024-byte replies.
- *
- */
-
- #ifdef RCSID
- static char _rcsid_ = "$Id: sock.c_v 1.3 1991/05/10 21:01:48 richb Exp $";
- #endif
-
- #include "sock.h"
- #include "debug.h"
-
- #define bool_t int
- #define enum_t int
- #define u_int unsigned int
- #define u_short unsigned short
- #define u_long unsigned long
- #define u_char unsigned char
- #define __dontcare__ -1
- #define caddr_t char *
- #include "in.h"
-
- extern NET nets[];
- extern long cticks;
- extern bcopy_fn();
- extern bcopy_nf();
- extern bcopy_ff();
- void far *_fmalloc();
-
- /* templates for local types
- static struct sockproto UDP_PROTO = { PF_INET, IPPROTO_UDP };
- static struct sockproto TCP_PROTO = { PF_INET, IPPROTO_TCP }; */
-
- struct sockaddr_in *laddr[8], *raddr[8];
- char far *p_pkts[8];
- int ready_packs[8], used_socks[8];
- UDPCONN con[8];
- int handler();
-
-
- /*
- * int sock_create(int type, int protocol, struct sockaddr_in *addr) --
- * Creates a socket of type using protocol, bound to address *addr on the
- * local PC. Returns the socket descriptor or -1 if an error
- * occurred.
- */
- int sock_create(type, protocol, addr)
- int type, protocol;
- struct sockaddr_in *addr;
- {
- if (type == SOCK_DGRAM && protocol == IPPROTO_UDP)
- return sock_udpcreate(addr);
-
- /* if (type == SOCK_STREAM && protocol == IPPROTO_TCP)
- return sock_tcpcreate(addr); */
-
- (void) fprintf(stderr, "Protocol not supported\n");
- return -1;
- }
-
- /*
- * int sock_udpcreate(struct sockaddr_in addr) --
- * Creates a UDP socket on the local host using address specified.
- * If port == 0 then an arbitrary port is assigned.
- */
- int sock_udpcreate(addr)
- struct sockaddr_in *addr;
- {
- int sock;
- unsigned port;
-
- DBGPRT0 (nfsdebug, "creating socket");
-
- for (sock = 0; sock < 8; sock++ ) {
- if (used_socks[sock] == 0) break;
- if (sock == 7) {
- (void) fprintf(stderr, "sock_udpcreate: too many sockets;");
- return -1;
- }
- }
- port = (unsigned) ( addr->sin_port ? addr->sin_port : udp_socket() );
- ready_packs[sock] = 0;
-
- con[sock] = udp_open(0L, 0, port, handler, (unsigned) sock);
- if (con[sock] == NULL) {
- (void) fprintf(stderr, "sock_udpcreate: error opening socket;");
- return -1;
- }
- laddr[sock] = (struct sockaddr_in *) calloc(1, sizeof(struct sockaddr_in));
- raddr[sock] = (struct sockaddr_in *) calloc(1, sizeof(struct sockaddr_in));
-
- laddr[sock]->sin_family = addr->sin_family;
- raddr[sock]->sin_family = addr->sin_family;
-
- laddr[sock]->sin_port = (unsigned) (port);
- (laddr[sock]->sin_addr).s_addr = (addr->sin_addr).s_addr;
-
- used_socks[sock] = 1;
- return sock;
- }
-
- /*
- * Udp Packet Handler
- */
- handler(p, len, host, sock)
- PACKET p;
- unsigned len;
- in_name host;
- unsigned sock;
- {
- if (ready_packs[sock] == 1) {
- (void) fprintf(stderr, "UDP: discarding packet\n");
- udp_free(p);
- return;
- }
- p_pkts[sock] = (char far *) _fmalloc(len);
- bcopy_nf(udp_data(udp_head(in_head(p))), p_pkts[sock], len);
- ready_packs[sock] = 1;
-
- raddr[sock]->sin_port = (unsigned) ((udp_head(in_head(p)))->ud_srcp);
- (raddr[sock]->sin_addr).s_addr = host;
- udp_free(p);
- return;
- }
-
- /*
- * void sock_close(int sock) --
- * Closes the socket descriptor sock.
- */
- void sock_close(sock)
- int sock;
- {
- used_socks[sock] = 0;
- free(laddr[sock]);
- free(raddr[sock]);
- udp_close(con[sock]);
- return;
- }
-
-
- /*
- * int sock_select(int *rfds, int *wfds) --
- * Returns the number of descriptors readable corresponding to
- * the bit masks in *rfds, or writable in *wfds.
- * *rfds and *wfds are changed to reflect the readable sockets.
- */
- int sock_select(rfds, wfds)
- long *rfds, *wfds;
- {
- /* should use soselect, but the function seems to be buggy */
- int sock, nd; /* socket and # of descriptors */
- long mask, count;
-
- tk_yield();
-
- for(mask = 0, sock = 0, nd = 0; rfds != NULL && *rfds != 0;
- sock++, *rfds >>= 1) {
- if (*rfds & 1 != 0) {
- /* soioctl(sock, FIONREAD, &count);
- if (count != 0) */
- if( ready_packs[sock] == 1)
- mask |= 1 << sock, nd++;
- }
- }
- *rfds = mask;
-
- for(mask = 0, sock = 0; wfds != NULL && *wfds != 0;
- sock++, *wfds >>= 1) {
- if (*wfds & 1 != 0) {
- /* soioctl(sock, FIONREAD, &count);
- if (count != 0) */
- if (used_socks[sock] = 1)
- mask |= 1 << sock, nd++;
- }
- }
- *wfds = mask;
-
- return nd;
- }
-
- /*
- * int sock_recv(int sock, char far *buf, int bufsiz, struct sockaddr_in *from) --
- * Recevies message from socket and puts it into buffer. The from address
- * is placed in *from. Returns the size of the message.
- */
- int sock_recv(sock, buf, bufsiz, from)
- int sock;
- char far *buf;
- int bufsiz;
- struct sockaddr_in *from;
- {
- int recvlen;
-
- /* struct sockaddr_in f; */
-
- if (ready_packs[sock] == 0) return (0);
- recvlen= (int) _fmsize(p_pkts[sock]);
- if (recvlen < 0 ) (void) fprintf(stderr, "--> recv err\n");
- *from = *raddr[sock];
-
- bcopy_ff(p_pkts[sock], buf, (unsigned) bufsiz);
- _ffree(p_pkts[sock]);
- ready_packs[sock] = 0;
- return recvlen;
- }
-
- /*
- * int sock_send(int sock, struct sockaddr_in *addr, char far *msg, int len) --
- * Transmits a message msg using sock to host at *addr of length len.
- * Assumed to be a UDP socket. Returns the number of bytes sent, or -1
- * if an error occurred.
- */
- int sock_send(sock, addr, msg, len)
- int sock;
- struct sockaddr_in *addr;
- char far *msg;
- int len;
- {
- unsigned paclen = 1300;
- PACKET p;
-
- if (len < 1300) paclen = (unsigned) len;
- /* printf("room %u: paclen %u: stack %u\n", _memavl(), paclen, stackavail()); */
- if ((p = udp_alloc(paclen, 0))== NULL) return -1;
- bcopy_fn(msg, udp_data(udp_head(in_head(p))), paclen);
- if ( udp_send_to(addr->sin_addr.s_addr, addr->sin_port,
- (unsigned) (laddr[sock]->sin_port), p, paclen) < 0) {
- udp_free(p);
- return -1;
- }
- udp_free(p);
- return (int) paclen;
- }
-
- /*
- * int sock_getsockaddr(int sock, struct sockaddr_in *addr) --]
- * Returns socket address in *addr. Returns -1 if an error
- * occurred.
- */
- int sock_getsockaddr(sock, addr)
- int sock;
- struct sockaddr_in *addr;
- {
- *addr = *laddr[sock];
- return;
- }
-
-
- /*
- * long sock_gethostbyname(char *name) --
- * Returns host IP address given host name. Returns -1 for error.
- */
-
- long sock_gethostbyname(modename)
- char *modename;
- {
- in_name fhost;
-
- fhost = resolve_name(modename);
- if(fhost == 0) {
- printf("Couldn't resolve hostname %s.\n", modename);
- return -1; }
-
- if(fhost == NAMETMO) {
- printf("name servers not responding.\n");
- return -1;
- }
- return fhost;
-
- }
-
-
- /*
- * char *sock_gethostbyaddr(struct sockaddr_in addr) --
- * Returns a character pointer to the hostname
- * Needs entry in hosts file
- */
- char *sock_gethostbyaddr(addr)
- struct sockaddr_in addr;
- {
- char *s;
- FILE *fp;
-
- s = (char *) malloc(40);
- if ((fp = fopen("hosts", "r")) == NULL) return NULL;
- while ( fgets(s, 40, fp) != NULL) {
- if ( addr.sin_addr.s_addr == resolve_name(s)) {
- fclose(fp);
- return s;
- }
- }
- fclose(fp);
- s = "no_hosts_entry";
- return s;
- }
-