/***************************************************************************** * * Copyright 1989, Xylogics, Inc. ALL RIGHTS RESERVED. * * ALL RIGHTS RESERVED. Licensed Material - Property of Xylogics, Inc. * This software is made available solely pursuant to the terms of a * software license agreement which governs its use. * Unauthorized duplication, distribution or sale are strictly prohibited. * * Module Function: * * SL/IP layer of Xenix UDP SL/IP * * Original Author: Paul Mattes Created on: 01/04/88 * * Revision Control Information: * * $Header: /annex/common/src/./libannex/RCS/slip_layer.c,v 1.7 1994/08/04 10:58:46 sasson Exp $ * * This file created by RCS from: * $Source: /annex/common/src/./libannex/RCS/slip_layer.c,v $ * * Revision History: * * $Log: slip_layer.c,v $ * Revision 1.7 1994/08/04 10:58:46 sasson * SPR 3211: "debug" variable defined in multiple places. * * Revision 1.6 1993/12/30 13:14:13 carlson * SPR 2084 -- made compatible with 64 bit machines. * * Revision 1.5 1989/04/11 00:59:28 loverso * fix extern declarations, inet_addr is u_long, remove extern htonl et al * * Revision 1.4 89/04/05 12:40:21 loverso * Changed copyright notice * * Revision 1.3 88/05/31 17:12:25 parker * fixes to get XENIX/SLIP to build again * * Revision 1.2 88/05/24 18:35:57 parker * Changes for new install-annex script * * Revision 1.1 88/04/15 11:58:47 mattes * Initial revision * * * This file is currently under revision by: * * $Locker: $ * *****************************************************************************/ #define RCSDATE $Date: 1994/08/04 10:58:46 $ #define RCSREV $Revision: 1.7 $ #define RCSID "$Header: /annex/common/src/./libannex/RCS/slip_layer.c,v 1.7 1994/08/04 10:58:46 sasson Exp $" #ifndef lint static char rcsid[] = RCSID; #endif /***************************************************************************** * * * Include files * * * *****************************************************************************/ #include #include "../inc/config.h" #include "port/port.h" #include #include #include #include #include #include #include "../inc/slip/slip_user.h" #include "../inc/slip/slip_system.h" #include "../inc/slip/BSDslip.h" /***************************************************************************** * * * Local defines and macros * * * *****************************************************************************/ #undef read #undef write #undef close /***************************************************************************** * * * Structure and union definitions * * * *****************************************************************************/ /***************************************************************************** * * * External data * * * *****************************************************************************/ extern int debug; extern int errno; /***************************************************************************** * * * Global data * * * *****************************************************************************/ UINT32 _my_inet_address; /***************************************************************************** * * * Static data * * * *****************************************************************************/ static int ports_in_use = 0; static int portlock = -1; /***************************************************************************** * * * Forward definitions * * * *****************************************************************************/ int _net_init(mtu, buffersize) int *mtu; int *buffersize; { FILE *f; int n_scanned; char addr[32], tty[32]; /* look for the configuration file and pick it apart */ f = fopen(CFGFILE, "r"); if(!f) { perror(CFGFILE); return(errno); } /* we want "addr tty [stty ...] */ n_scanned = fscanf(f, "%s %s", addr, tty); if(n_scanned == EOF || n_scanned < 2) { fprintf(stderr, "Illegal configuration file\n"); return(errno); } /* parse the inet address */ _my_inet_address = inet_addr(addr); if(!_my_inet_address) { fprintf(stderr, "Illegal internet address in %s: %s\n", CFGFILE, addr); } if(debug) printf("My IP address is %lx\n", _my_inet_address); /* grab the port lock file */ if(portlock == -1) { portlock = open(PORTLOCK, O_RDWR); if(portlock == -1) { perror(PORTLOCK); return(errno); } } /* return the MTU and go home */ *mtu = SLMTU; *buffersize = SLMTU + sizeof(u_short); return(0); } int _try_to_reserve(port) int port; { char pn[32]; int fd; struct flock lock; /* try for the lock */ lock.l_type = F_WRLCK; lock.l_whence = 0; lock.l_start = ntohs(port); lock.l_len = 1; if(fcntl(portlock, F_SETLK, &lock) == -1) { if(errno == EAGAIN) return(EADDRINUSE); else return(errno); } /* create a named pipe to hold the incoming data */ sprintf(pn, SLIPDATA, ntohs(port)); if(mknod(pn, S_IFIFO | 0666, 0) == -1) { if(errno == EEXIST) errno = 0; else { perror(pn); exit(1); } } else (void)chmod(pn, 0666); ++ports_in_use; return(0); } u_short _pick_a_random_port() { int i; for(i = 7000; ; ++i) if(!_try_to_reserve(htons(i))) return(htons(i)); } int _close_port(port, last_close) int port; int last_close; { char pn[32]; struct flock lock; /* Give up the port lock, if we're really supposed to */ if(last_close) { sprintf(pn, SLIPDATA, ntohs(port)); unlink(pn); lock.l_type = F_UNLCK; lock.l_whence = 0; lock.l_start = ntohs(port); lock.l_len = 1; (void)fcntl(portlock, F_SETLK, &lock); } --ports_in_use; return(0); } int _sl_input(iobuf, cc, buf, port) struct sockiobuf *iobuf; int *cc; char **buf; u_short port; { char fn[32]; FILE *f; int nbytes; int fd; int pkt_len; /* Read fresh data, if necessary */ restart: if(!iobuf->sb_len) { sprintf(fn, SLIPDATA, ntohs(port)); fd = open(fn, O_RDONLY); if(fd == -1) { if(errno == EINTR) return(errno); perror("_sl_input: open"); exit(1); } iobuf->sb_curr = iobuf->sb_base; nbytes = read(fd, iobuf->sb_curr, SLMTU + sizeof(u_short)); switch(nbytes) { case 0: /* EOF after other side closed */ if(debug) fprintf(stderr, "_sl_read: EOF\n"); close(fd); goto restart; case -1: /* An error? */ if(errno == EINTR) { close(fd); return(EINTR); } if(debug) perror("_sl_input: read"); exit(1); default: close(fd); iobuf->sb_len = nbytes; break; } } if(iobuf->sb_len < sizeof(u_short)) { iobuf->sb_len = 0; goto restart; } pkt_len = *(u_short *)iobuf->sb_curr; iobuf->sb_len -= 2; iobuf->sb_curr += 2; if(iobuf->sb_len < pkt_len) { iobuf->sb_len = 0; goto restart; } *cc = pkt_len; *buf = iobuf->sb_curr; iobuf->sb_curr += pkt_len; iobuf->sb_curr -= pkt_len; return(0); } int _sl_output(iobuf) struct sockiobuf *iobuf; { int fd; if(iobuf->sb_len > SLMTU) return(EMSGSIZE); /* open the output FIFO */ fd = open(OUTPIPE, O_WRONLY); if(fd < 0) { perror(OUTPIPE); return(errno); } /* glue on the length and do some output */ iobuf->sb_curr -= sizeof(u_short); *(u_short *)(iobuf->sb_curr) = iobuf->sb_len; iobuf->sb_len += sizeof(u_short); (void)write(fd, iobuf->sb_curr, iobuf->sb_len); (void)close(fd); return(0); } int _private_fileno(s) int s; { return(s == portlock); }