10559b331SSteve Price /* 20559b331SSteve Price * Copyright (c) 1988, 1992 The University of Utah and the Center 30559b331SSteve Price * for Software Science (CSS). 40559b331SSteve Price * Copyright (c) 1992, 1993 50559b331SSteve Price * The Regents of the University of California. All rights reserved. 60559b331SSteve Price * 70559b331SSteve Price * This code is derived from software contributed to Berkeley by 80559b331SSteve Price * the Center for Software Science of the University of Utah Computer 90559b331SSteve Price * Science Department. CSS requests users of this software to return 100559b331SSteve Price * to css-dist@cs.utah.edu any improvements that they make and grant 110559b331SSteve Price * CSS redistribution rights. 120559b331SSteve Price * 130559b331SSteve Price * Redistribution and use in source and binary forms, with or without 140559b331SSteve Price * modification, are permitted provided that the following conditions 150559b331SSteve Price * are met: 160559b331SSteve Price * 1. Redistributions of source code must retain the above copyright 170559b331SSteve Price * notice, this list of conditions and the following disclaimer. 180559b331SSteve Price * 2. Redistributions in binary form must reproduce the above copyright 190559b331SSteve Price * notice, this list of conditions and the following disclaimer in the 200559b331SSteve Price * documentation and/or other materials provided with the distribution. 210559b331SSteve Price * 3. All advertising materials mentioning features or use of this software 220559b331SSteve Price * must display the following acknowledgement: 230559b331SSteve Price * This product includes software developed by the University of 240559b331SSteve Price * California, Berkeley and its contributors. 250559b331SSteve Price * 4. Neither the name of the University nor the names of its contributors 260559b331SSteve Price * may be used to endorse or promote products derived from this software 270559b331SSteve Price * without specific prior written permission. 280559b331SSteve Price * 290559b331SSteve Price * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 300559b331SSteve Price * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 310559b331SSteve Price * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 320559b331SSteve Price * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 330559b331SSteve Price * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 340559b331SSteve Price * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 350559b331SSteve Price * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 360559b331SSteve Price * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 370559b331SSteve Price * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 380559b331SSteve Price * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 390559b331SSteve Price * SUCH DAMAGE. 400559b331SSteve Price * 410559b331SSteve Price * from: @(#)utils.c 8.1 (Berkeley) 6/4/93 420559b331SSteve Price * 430559b331SSteve Price * From: Utah Hdr: utils.c 3.1 92/07/06 440559b331SSteve Price * Author: Jeff Forys, University of Utah CSS 450559b331SSteve Price */ 460559b331SSteve Price 470559b331SSteve Price #ifndef lint 48eb0b8290SPhilippe Charnier #if 0 495c8709fdSSteve Price static const char sccsid[] = "@(#)utils.c 8.1 (Berkeley) 6/4/93"; 50eb0b8290SPhilippe Charnier #endif 51eb0b8290SPhilippe Charnier static const char rcsid[] = 527f3dea24SPeter Wemm "$FreeBSD$"; 530559b331SSteve Price #endif /* not lint */ 540559b331SSteve Price 550559b331SSteve Price #include <sys/param.h> 565c8709fdSSteve Price #include <sys/time.h> 5740905e90SStefan Farfeleder #include <netinet/in.h> 580559b331SSteve Price 590559b331SSteve Price #include <fcntl.h> 600559b331SSteve Price #include <signal.h> 610559b331SSteve Price #include <stdio.h> 620559b331SSteve Price #include <stdlib.h> 630559b331SSteve Price #include <string.h> 640559b331SSteve Price #include <syslog.h> 650559b331SSteve Price #include <time.h> 660559b331SSteve Price #include <unistd.h> 670559b331SSteve Price #include "defs.h" 680559b331SSteve Price 690559b331SSteve Price /* 700559b331SSteve Price ** DispPkt -- Display the contents of an RMPCONN packet. 710559b331SSteve Price ** 720559b331SSteve Price ** Parameters: 730559b331SSteve Price ** rconn - packet to be displayed. 740559b331SSteve Price ** direct - direction packet is going (DIR_*). 750559b331SSteve Price ** 760559b331SSteve Price ** Returns: 770559b331SSteve Price ** Nothing. 780559b331SSteve Price ** 790559b331SSteve Price ** Side Effects: 800559b331SSteve Price ** None. 810559b331SSteve Price */ 820559b331SSteve Price void 83266ebcd3SWarner Losh DispPkt(RMPCONN *rconn, int direct) 840559b331SSteve Price { 85b63695f3SKris Kennaway static const char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u"; 86b63695f3SKris Kennaway static const char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n"; 870559b331SSteve Price 880559b331SSteve Price struct tm *tmp; 8911fe7d5eSSteve Price struct rmp_packet *rmp; 900559b331SSteve Price int i, omask; 910559b331SSteve Price u_int32_t t; 920559b331SSteve Price 930559b331SSteve Price /* 940559b331SSteve Price * Since we will be working with RmpConns as well as DbgFp, we 950559b331SSteve Price * must block signals that can affect either. 960559b331SSteve Price */ 970559b331SSteve Price omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2)); 980559b331SSteve Price 990559b331SSteve Price if (DbgFp == NULL) { /* sanity */ 1000559b331SSteve Price (void) sigsetmask(omask); 1010559b331SSteve Price return; 1020559b331SSteve Price } 1030559b331SSteve Price 1040559b331SSteve Price /* display direction packet is going using '>>>' or '<<<' */ 1050559b331SSteve Price fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp); 1060559b331SSteve Price 1070559b331SSteve Price /* display packet timestamp */ 1080559b331SSteve Price tmp = localtime((time_t *)&rconn->tstamp.tv_sec); 1090559b331SSteve Price fprintf(DbgFp, "%02d:%02d:%02d.%06ld ", tmp->tm_hour, tmp->tm_min, 1100559b331SSteve Price tmp->tm_sec, rconn->tstamp.tv_usec); 1110559b331SSteve Price 1120559b331SSteve Price /* display src or dst addr and information about network interface */ 1130559b331SSteve Price fprintf(DbgFp, "Addr: %s Intf: %s\n", EnetStr(rconn), IntfName); 1140559b331SSteve Price 1150559b331SSteve Price rmp = &rconn->rmp; 1160559b331SSteve Price 1170559b331SSteve Price /* display IEEE 802.2 Logical Link Control header */ 1180559b331SSteve Price (void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n", 1190559b331SSteve Price rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl)); 1200559b331SSteve Price 1210559b331SSteve Price /* display HP extensions to 802.2 Logical Link Control header */ 1220559b331SSteve Price (void) fprintf(DbgFp, "\tHP Ext: DXSAP:%x SXSAP:%x\n", 1230559b331SSteve Price ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap)); 1240559b331SSteve Price 1250559b331SSteve Price /* 1260559b331SSteve Price * Display information about RMP packet using type field to 1270559b331SSteve Price * determine what kind of packet this is. 1280559b331SSteve Price */ 1290559b331SSteve Price switch(rmp->r_type) { 1300559b331SSteve Price case RMP_BOOT_REQ: /* boot request */ 1310559b331SSteve Price (void) fprintf(DbgFp, "\tBoot Request:"); 1320559b331SSteve Price GETWORD(rmp->r_brq.rmp_seqno, t); 1330559b331SSteve Price if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) { 1340559b331SSteve Price if (WORDZE(rmp->r_brq.rmp_seqno)) 1350559b331SSteve Price fputs(" (Send Server ID)", DbgFp); 1360559b331SSteve Price else 1370559b331SSteve Price fprintf(DbgFp," (Send Filename #%u)",t); 1380559b331SSteve Price } 1390559b331SSteve Price (void) fputc('\n', DbgFp); 1400559b331SSteve Price (void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode, 1410559b331SSteve Price t, ntohs(rmp->r_brq.rmp_session), 1420559b331SSteve Price ntohs(rmp->r_brq.rmp_version)); 1430559b331SSteve Price (void) fprintf(DbgFp, "\n\t\tMachine Type: "); 1440559b331SSteve Price for (i = 0; i < RMP_MACHLEN; i++) 1450559b331SSteve Price (void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp); 1460559b331SSteve Price DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm); 1470559b331SSteve Price break; 1480559b331SSteve Price case RMP_BOOT_REPL: /* boot reply */ 1490559b331SSteve Price fprintf(DbgFp, "\tBoot Reply:\n"); 1500559b331SSteve Price GETWORD(rmp->r_brpl.rmp_seqno, t); 1510559b331SSteve Price (void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode, 1520559b331SSteve Price t, ntohs(rmp->r_brpl.rmp_session), 1530559b331SSteve Price ntohs(rmp->r_brpl.rmp_version)); 1540559b331SSteve Price DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm); 1550559b331SSteve Price break; 1560559b331SSteve Price case RMP_READ_REQ: /* read request */ 1570559b331SSteve Price (void) fprintf(DbgFp, "\tRead Request:\n"); 1580559b331SSteve Price GETWORD(rmp->r_rrq.rmp_offset, t); 1590559b331SSteve Price (void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode, 1600559b331SSteve Price t, ntohs(rmp->r_rrq.rmp_session)); 1610559b331SSteve Price (void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n", 1620559b331SSteve Price ntohs(rmp->r_rrq.rmp_size)); 1630559b331SSteve Price break; 1640559b331SSteve Price case RMP_READ_REPL: /* read reply */ 1650559b331SSteve Price (void) fprintf(DbgFp, "\tRead Reply:\n"); 1660559b331SSteve Price GETWORD(rmp->r_rrpl.rmp_offset, t); 1670559b331SSteve Price (void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode, 1680559b331SSteve Price t, ntohs(rmp->r_rrpl.rmp_session)); 1690559b331SSteve Price (void) fprintf(DbgFp, "\t\tNoOfBytesSent: %d\n", 1700559b331SSteve Price rconn->rmplen - RMPREADSIZE(0)); 1710559b331SSteve Price break; 1720559b331SSteve Price case RMP_BOOT_DONE: /* boot complete */ 1730559b331SSteve Price (void) fprintf(DbgFp, "\tBoot Complete:\n"); 1740559b331SSteve Price (void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n", 1750559b331SSteve Price rmp->r_done.rmp_retcode, 1760559b331SSteve Price ntohs(rmp->r_done.rmp_session)); 1770559b331SSteve Price break; 1780559b331SSteve Price default: /* ??? */ 1790559b331SSteve Price (void) fprintf(DbgFp, "\tUnknown Type:(%d)\n", 1800559b331SSteve Price rmp->r_type); 1810559b331SSteve Price } 1820559b331SSteve Price (void) fputc('\n', DbgFp); 1830559b331SSteve Price (void) fflush(DbgFp); 1840559b331SSteve Price 1850559b331SSteve Price (void) sigsetmask(omask); /* reset old signal mask */ 1860559b331SSteve Price } 1870559b331SSteve Price 1880559b331SSteve Price 1890559b331SSteve Price /* 1900559b331SSteve Price ** GetEtherAddr -- convert an RMP (Ethernet) address into a string. 1910559b331SSteve Price ** 1920559b331SSteve Price ** An RMP BOOT packet has been received. Look at the type field 1930559b331SSteve Price ** and process Boot Requests, Read Requests, and Boot Complete 1940559b331SSteve Price ** packets. Any other type will be dropped with a warning msg. 1950559b331SSteve Price ** 1960559b331SSteve Price ** Parameters: 1970559b331SSteve Price ** addr - array of RMP_ADDRLEN bytes. 1980559b331SSteve Price ** 1990559b331SSteve Price ** Returns: 2000559b331SSteve Price ** Pointer to static string representation of `addr'. 2010559b331SSteve Price ** 2020559b331SSteve Price ** Side Effects: 2030559b331SSteve Price ** None. 2040559b331SSteve Price ** 2050559b331SSteve Price ** Warnings: 2060559b331SSteve Price ** - The return value points to a static buffer; it must 2070559b331SSteve Price ** be copied if it's to be saved. 2080559b331SSteve Price */ 2090559b331SSteve Price char * 210266ebcd3SWarner Losh GetEtherAddr(u_int8_t *addr) 2110559b331SSteve Price { 2120559b331SSteve Price static char Hex[] = "0123456789abcdef"; 2130559b331SSteve Price static char etherstr[RMP_ADDRLEN*3]; 21411fe7d5eSSteve Price int i; 21511fe7d5eSSteve Price char *cp; 2160559b331SSteve Price 2170559b331SSteve Price /* 2180559b331SSteve Price * For each byte in `addr', convert it to "<hexchar><hexchar>:". 2190559b331SSteve Price * The last byte does not get a trailing `:' appended. 2200559b331SSteve Price */ 2210559b331SSteve Price i = 0; 2220559b331SSteve Price cp = etherstr; 2230559b331SSteve Price for(;;) { 2240559b331SSteve Price *cp++ = Hex[*addr >> 4 & 0xf]; 2250559b331SSteve Price *cp++ = Hex[*addr++ & 0xf]; 2260559b331SSteve Price if (++i == RMP_ADDRLEN) 2270559b331SSteve Price break; 2280559b331SSteve Price *cp++ = ':'; 2290559b331SSteve Price } 2300559b331SSteve Price *cp = '\0'; 2310559b331SSteve Price 2320559b331SSteve Price return(etherstr); 2330559b331SSteve Price } 2340559b331SSteve Price 2350559b331SSteve Price 2360559b331SSteve Price /* 2370559b331SSteve Price ** DispFlnm -- Print a string of bytes to DbgFp (often, a file name). 2380559b331SSteve Price ** 2390559b331SSteve Price ** Parameters: 2400559b331SSteve Price ** size - number of bytes to print. 2410559b331SSteve Price ** flnm - address of first byte. 2420559b331SSteve Price ** 2430559b331SSteve Price ** Returns: 2440559b331SSteve Price ** Nothing. 2450559b331SSteve Price ** 2460559b331SSteve Price ** Side Effects: 2470559b331SSteve Price ** - Characters are sent to `DbgFp'. 2480559b331SSteve Price */ 2490559b331SSteve Price void 250266ebcd3SWarner Losh DspFlnm(u_int size, char *flnm) 2510559b331SSteve Price { 25211fe7d5eSSteve Price int i; 2530559b331SSteve Price 2540559b331SSteve Price (void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size); 2550559b331SSteve Price for (i = 0; i < size; i++) 2560559b331SSteve Price (void) fputc(*flnm++, DbgFp); 2570559b331SSteve Price (void) fputs(">\n", DbgFp); 2580559b331SSteve Price } 2590559b331SSteve Price 2600559b331SSteve Price 2610559b331SSteve Price /* 2620559b331SSteve Price ** NewClient -- allocate memory for a new CLIENT. 2630559b331SSteve Price ** 2640559b331SSteve Price ** Parameters: 2650559b331SSteve Price ** addr - RMP (Ethernet) address of new client. 2660559b331SSteve Price ** 2670559b331SSteve Price ** Returns: 2680559b331SSteve Price ** Ptr to new CLIENT or NULL if we ran out of memory. 2690559b331SSteve Price ** 2700559b331SSteve Price ** Side Effects: 2710559b331SSteve Price ** - Memory will be malloc'd for the new CLIENT. 2720559b331SSteve Price ** - If malloc() fails, a log message will be generated. 2730559b331SSteve Price */ 2740559b331SSteve Price CLIENT * 275266ebcd3SWarner Losh NewClient(u_int8_t *addr) 2760559b331SSteve Price { 2770559b331SSteve Price CLIENT *ctmp; 2780559b331SSteve Price 2790559b331SSteve Price if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) { 2800559b331SSteve Price syslog(LOG_ERR, "NewClient: out of memory (%s)", 2810559b331SSteve Price GetEtherAddr(addr)); 2820559b331SSteve Price return(NULL); 2830559b331SSteve Price } 2840559b331SSteve Price 28511fe7d5eSSteve Price memset(ctmp, 0, sizeof(CLIENT)); 28611fe7d5eSSteve Price memmove(&ctmp->addr[0], addr, RMP_ADDRLEN); 2870559b331SSteve Price return(ctmp); 2880559b331SSteve Price } 2890559b331SSteve Price 2900559b331SSteve Price /* 2910559b331SSteve Price ** FreeClient -- free linked list of Clients. 2920559b331SSteve Price ** 2930559b331SSteve Price ** Parameters: 2940559b331SSteve Price ** None. 2950559b331SSteve Price ** 2960559b331SSteve Price ** Returns: 2970559b331SSteve Price ** Nothing. 2980559b331SSteve Price ** 2990559b331SSteve Price ** Side Effects: 3000559b331SSteve Price ** - All malloc'd memory associated with the linked list of 3010559b331SSteve Price ** CLIENTS will be free'd; `Clients' will be set to NULL. 3020559b331SSteve Price ** 3030559b331SSteve Price ** Warnings: 3040559b331SSteve Price ** - This routine must be called with SIGHUP blocked. 3050559b331SSteve Price */ 3060559b331SSteve Price void 307266ebcd3SWarner Losh FreeClients(void) 3080559b331SSteve Price { 30911fe7d5eSSteve Price CLIENT *ctmp; 3100559b331SSteve Price 3110559b331SSteve Price while (Clients != NULL) { 3120559b331SSteve Price ctmp = Clients; 3130559b331SSteve Price Clients = Clients->next; 3140559b331SSteve Price FreeClient(ctmp); 3150559b331SSteve Price } 3160559b331SSteve Price } 3170559b331SSteve Price 3180559b331SSteve Price /* 3190559b331SSteve Price ** NewStr -- allocate memory for a character array. 3200559b331SSteve Price ** 3210559b331SSteve Price ** Parameters: 3220559b331SSteve Price ** str - null terminated character array. 3230559b331SSteve Price ** 3240559b331SSteve Price ** Returns: 3250559b331SSteve Price ** Ptr to new character array or NULL if we ran out of memory. 3260559b331SSteve Price ** 3270559b331SSteve Price ** Side Effects: 3280559b331SSteve Price ** - Memory will be malloc'd for the new character array. 3290559b331SSteve Price ** - If malloc() fails, a log message will be generated. 3300559b331SSteve Price */ 3310559b331SSteve Price char * 332266ebcd3SWarner Losh NewStr(char *str) 3330559b331SSteve Price { 3340559b331SSteve Price char *stmp; 3350559b331SSteve Price 3360559b331SSteve Price if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) { 3370559b331SSteve Price syslog(LOG_ERR, "NewStr: out of memory (%s)", str); 3380559b331SSteve Price return(NULL); 3390559b331SSteve Price } 3400559b331SSteve Price 3410559b331SSteve Price (void) strcpy(stmp, str); 3420559b331SSteve Price return(stmp); 3430559b331SSteve Price } 3440559b331SSteve Price 3450559b331SSteve Price /* 3460559b331SSteve Price ** To save time, NewConn and FreeConn maintain a cache of one RMPCONN 3470559b331SSteve Price ** in `LastFree' (defined below). 3480559b331SSteve Price */ 3490559b331SSteve Price 3500559b331SSteve Price static RMPCONN *LastFree = NULL; 3510559b331SSteve Price 3520559b331SSteve Price /* 3530559b331SSteve Price ** NewConn -- allocate memory for a new RMPCONN connection. 3540559b331SSteve Price ** 3550559b331SSteve Price ** Parameters: 3560559b331SSteve Price ** rconn - initialization template for new connection. 3570559b331SSteve Price ** 3580559b331SSteve Price ** Returns: 3590559b331SSteve Price ** Ptr to new RMPCONN or NULL if we ran out of memory. 3600559b331SSteve Price ** 3610559b331SSteve Price ** Side Effects: 3620559b331SSteve Price ** - Memory may be malloc'd for the new RMPCONN (if not cached). 3630559b331SSteve Price ** - If malloc() fails, a log message will be generated. 3640559b331SSteve Price */ 3650559b331SSteve Price RMPCONN * 366266ebcd3SWarner Losh NewConn(RMPCONN *rconn) 3670559b331SSteve Price { 3680559b331SSteve Price RMPCONN *rtmp; 3690559b331SSteve Price 3700559b331SSteve Price if (LastFree == NULL) { /* nothing cached; make a new one */ 3710559b331SSteve Price if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) { 3720559b331SSteve Price syslog(LOG_ERR, "NewConn: out of memory (%s)", 3730559b331SSteve Price EnetStr(rconn)); 3740559b331SSteve Price return(NULL); 3750559b331SSteve Price } 3760559b331SSteve Price } else { /* use the cached RMPCONN */ 3770559b331SSteve Price rtmp = LastFree; 3780559b331SSteve Price LastFree = NULL; 3790559b331SSteve Price } 3800559b331SSteve Price 3810559b331SSteve Price /* 3820559b331SSteve Price * Copy template into `rtmp', init file descriptor to `-1' and 3830559b331SSteve Price * set ptr to next elem NULL. 3840559b331SSteve Price */ 38511fe7d5eSSteve Price memmove((char *)rtmp, (char *)rconn, sizeof(RMPCONN)); 3860559b331SSteve Price rtmp->bootfd = -1; 3870559b331SSteve Price rtmp->next = NULL; 3880559b331SSteve Price 3890559b331SSteve Price return(rtmp); 3900559b331SSteve Price } 3910559b331SSteve Price 3920559b331SSteve Price /* 3930559b331SSteve Price ** FreeConn -- Free memory associated with an RMPCONN connection. 3940559b331SSteve Price ** 3950559b331SSteve Price ** Parameters: 3960559b331SSteve Price ** rtmp - ptr to RMPCONN to be free'd. 3970559b331SSteve Price ** 3980559b331SSteve Price ** Returns: 3990559b331SSteve Price ** Nothing. 4000559b331SSteve Price ** 4010559b331SSteve Price ** Side Effects: 4020559b331SSteve Price ** - Memory associated with `rtmp' may be free'd (or cached). 4030559b331SSteve Price ** - File desc associated with `rtmp->bootfd' will be closed. 4040559b331SSteve Price */ 4050559b331SSteve Price void 406266ebcd3SWarner Losh FreeConn(RMPCONN *rtmp) 4070559b331SSteve Price { 4080559b331SSteve Price /* 4090559b331SSteve Price * If the file descriptor is in use, close the file. 4100559b331SSteve Price */ 4110559b331SSteve Price if (rtmp->bootfd >= 0) { 4120559b331SSteve Price (void) close(rtmp->bootfd); 4130559b331SSteve Price rtmp->bootfd = -1; 4140559b331SSteve Price } 4150559b331SSteve Price 4160559b331SSteve Price if (LastFree == NULL) /* cache for next time */ 4170559b331SSteve Price rtmp = LastFree; 4180559b331SSteve Price else /* already one cached; free this one */ 4190559b331SSteve Price free((char *)rtmp); 4200559b331SSteve Price } 4210559b331SSteve Price 4220559b331SSteve Price /* 4230559b331SSteve Price ** FreeConns -- free linked list of RMPCONN connections. 4240559b331SSteve Price ** 4250559b331SSteve Price ** Parameters: 4260559b331SSteve Price ** None. 4270559b331SSteve Price ** 4280559b331SSteve Price ** Returns: 4290559b331SSteve Price ** Nothing. 4300559b331SSteve Price ** 4310559b331SSteve Price ** Side Effects: 4320559b331SSteve Price ** - All malloc'd memory associated with the linked list of 4330559b331SSteve Price ** connections will be free'd; `RmpConns' will be set to NULL. 4340559b331SSteve Price ** - If LastFree is != NULL, it too will be free'd & NULL'd. 4350559b331SSteve Price ** 4360559b331SSteve Price ** Warnings: 4370559b331SSteve Price ** - This routine must be called with SIGHUP blocked. 4380559b331SSteve Price */ 4390559b331SSteve Price void 440266ebcd3SWarner Losh FreeConns(void) 4410559b331SSteve Price { 44211fe7d5eSSteve Price RMPCONN *rtmp; 4430559b331SSteve Price 4440559b331SSteve Price while (RmpConns != NULL) { 4450559b331SSteve Price rtmp = RmpConns; 4460559b331SSteve Price RmpConns = RmpConns->next; 4470559b331SSteve Price FreeConn(rtmp); 4480559b331SSteve Price } 4490559b331SSteve Price 4500559b331SSteve Price if (LastFree != NULL) { 4510559b331SSteve Price free((char *)LastFree); 4520559b331SSteve Price LastFree = NULL; 4530559b331SSteve Price } 4540559b331SSteve Price } 4550559b331SSteve Price 4560559b331SSteve Price /* 4570559b331SSteve Price ** AddConn -- Add a connection to the linked list of connections. 4580559b331SSteve Price ** 4590559b331SSteve Price ** Parameters: 4600559b331SSteve Price ** rconn - connection to be added. 4610559b331SSteve Price ** 4620559b331SSteve Price ** Returns: 4630559b331SSteve Price ** Nothing. 4640559b331SSteve Price ** 4650559b331SSteve Price ** Side Effects: 4660559b331SSteve Price ** - RmpConn will point to new connection. 4670559b331SSteve Price ** 4680559b331SSteve Price ** Warnings: 4690559b331SSteve Price ** - This routine must be called with SIGHUP blocked. 4700559b331SSteve Price */ 4710559b331SSteve Price void 472266ebcd3SWarner Losh AddConn(RMPCONN *rconn) 4730559b331SSteve Price { 4740559b331SSteve Price if (RmpConns != NULL) 4750559b331SSteve Price rconn->next = RmpConns; 4760559b331SSteve Price RmpConns = rconn; 4770559b331SSteve Price } 4780559b331SSteve Price 4790559b331SSteve Price /* 4800559b331SSteve Price ** FindConn -- Find a connection in the linked list of connections. 4810559b331SSteve Price ** 4820559b331SSteve Price ** We use the RMP (Ethernet) address as the basis for determining 4830559b331SSteve Price ** if this is the same connection. According to the Remote Maint 4840559b331SSteve Price ** Protocol, we can only have one connection with any machine. 4850559b331SSteve Price ** 4860559b331SSteve Price ** Parameters: 4870559b331SSteve Price ** rconn - connection to be found. 4880559b331SSteve Price ** 4890559b331SSteve Price ** Returns: 4900559b331SSteve Price ** Matching connection from linked list or NULL if not found. 4910559b331SSteve Price ** 4920559b331SSteve Price ** Side Effects: 4930559b331SSteve Price ** None. 4940559b331SSteve Price ** 4950559b331SSteve Price ** Warnings: 4960559b331SSteve Price ** - This routine must be called with SIGHUP blocked. 4970559b331SSteve Price */ 4980559b331SSteve Price RMPCONN * 499266ebcd3SWarner Losh FindConn(RMPCONN *rconn) 5000559b331SSteve Price { 50111fe7d5eSSteve Price RMPCONN *rtmp; 5020559b331SSteve Price 5030559b331SSteve Price for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next) 5040559b331SSteve Price if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0], 5050559b331SSteve Price (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0) 5060559b331SSteve Price break; 5070559b331SSteve Price 5080559b331SSteve Price return(rtmp); 5090559b331SSteve Price } 5100559b331SSteve Price 5110559b331SSteve Price /* 5120559b331SSteve Price ** RemoveConn -- Remove a connection from the linked list of connections. 5130559b331SSteve Price ** 5140559b331SSteve Price ** Parameters: 5150559b331SSteve Price ** rconn - connection to be removed. 5160559b331SSteve Price ** 5170559b331SSteve Price ** Returns: 5180559b331SSteve Price ** Nothing. 5190559b331SSteve Price ** 5200559b331SSteve Price ** Side Effects: 5210559b331SSteve Price ** - If found, an RMPCONN will cease to exist and it will 5220559b331SSteve Price ** be removed from the linked list. 5230559b331SSteve Price ** 5240559b331SSteve Price ** Warnings: 5250559b331SSteve Price ** - This routine must be called with SIGHUP blocked. 5260559b331SSteve Price */ 5270559b331SSteve Price void 528266ebcd3SWarner Losh RemoveConn(RMPCONN *rconn) 5290559b331SSteve Price { 53011fe7d5eSSteve Price RMPCONN *thisrconn, *lastrconn; 5310559b331SSteve Price 5320559b331SSteve Price if (RmpConns == rconn) { /* easy case */ 5330559b331SSteve Price RmpConns = RmpConns->next; 5340559b331SSteve Price FreeConn(rconn); 5350559b331SSteve Price } else { /* must traverse linked list */ 5360559b331SSteve Price lastrconn = RmpConns; /* set back ptr */ 5370559b331SSteve Price thisrconn = lastrconn->next; /* set current ptr */ 5380559b331SSteve Price while (thisrconn != NULL) { 5390559b331SSteve Price if (rconn == thisrconn) { /* found it */ 5400559b331SSteve Price lastrconn->next = thisrconn->next; 5410559b331SSteve Price FreeConn(thisrconn); 5420559b331SSteve Price break; 5430559b331SSteve Price } 5440559b331SSteve Price lastrconn = thisrconn; 5450559b331SSteve Price thisrconn = thisrconn->next; 5460559b331SSteve Price } 5470559b331SSteve Price } 5480559b331SSteve Price } 549