11592Srgrimes/* 21592Srgrimes * Copyright (c) 1988, 1992 The University of Utah and the Center 31592Srgrimes * for Software Science (CSS). 41592Srgrimes * Copyright (c) 1992, 1993 51592Srgrimes * The Regents of the University of California. All rights reserved. 61592Srgrimes * 71592Srgrimes * This code is derived from software contributed to Berkeley by 81592Srgrimes * the Center for Software Science of the University of Utah Computer 91592Srgrimes * Science Department. CSS requests users of this software to return 101592Srgrimes * to css-dist@cs.utah.edu any improvements that they make and grant 111592Srgrimes * CSS redistribution rights. 121592Srgrimes * 131592Srgrimes * Redistribution and use in source and binary forms, with or without 141592Srgrimes * modification, are permitted provided that the following conditions 151592Srgrimes * are met: 161592Srgrimes * 1. Redistributions of source code must retain the above copyright 171592Srgrimes * notice, this list of conditions and the following disclaimer. 181592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 191592Srgrimes * notice, this list of conditions and the following disclaimer in the 201592Srgrimes * documentation and/or other materials provided with the distribution. 211592Srgrimes * 3. All advertising materials mentioning features or use of this software 221592Srgrimes * must display the following acknowledgement: 231592Srgrimes * This product includes software developed by the University of 241592Srgrimes * California, Berkeley and its contributors. 251592Srgrimes * 4. Neither the name of the University nor the names of its contributors 261592Srgrimes * may be used to endorse or promote products derived from this software 271592Srgrimes * without specific prior written permission. 281592Srgrimes * 291592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 301592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 311592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 321592Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 331592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 341592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 351592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 361592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 371592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 381592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 391592Srgrimes * SUCH DAMAGE. 401592Srgrimes * 4127074Ssteve * from: @(#)utils.c 8.1 (Berkeley) 6/4/93 421592Srgrimes * 4327074Ssteve * From: Utah Hdr: utils.c 3.1 92/07/06 441592Srgrimes * Author: Jeff Forys, University of Utah CSS 451592Srgrimes */ 461592Srgrimes 471592Srgrimes#ifndef lint 4831386Scharnier#if 0 4927077Sstevestatic const char sccsid[] = "@(#)utils.c 8.1 (Berkeley) 6/4/93"; 5031386Scharnier#endif 5131386Scharnierstatic const char rcsid[] = 5250476Speter "$FreeBSD$"; 531592Srgrimes#endif /* not lint */ 541592Srgrimes 551592Srgrimes#include <sys/param.h> 5627077Ssteve#include <sys/time.h> 57129652Sstefanf#include <netinet/in.h> 581592Srgrimes 591592Srgrimes#include <fcntl.h> 601592Srgrimes#include <signal.h> 611592Srgrimes#include <stdio.h> 621592Srgrimes#include <stdlib.h> 631592Srgrimes#include <string.h> 641592Srgrimes#include <syslog.h> 651592Srgrimes#include <time.h> 661592Srgrimes#include <unistd.h> 671592Srgrimes#include "defs.h" 681592Srgrimes 691592Srgrimes/* 701592Srgrimes** DispPkt -- Display the contents of an RMPCONN packet. 711592Srgrimes** 721592Srgrimes** Parameters: 731592Srgrimes** rconn - packet to be displayed. 741592Srgrimes** direct - direction packet is going (DIR_*). 751592Srgrimes** 761592Srgrimes** Returns: 771592Srgrimes** Nothing. 781592Srgrimes** 791592Srgrimes** Side Effects: 801592Srgrimes** None. 811592Srgrimes*/ 821592Srgrimesvoid 8390377SimpDispPkt(RMPCONN *rconn, int direct) 841592Srgrimes{ 85229140Sdim static const char BootFmt[] = "\t\tRetCode:%u SeqNo:%x SessID:%x Vers:%u"; 86229140Sdim static const char ReadFmt[] = "\t\tRetCode:%u Offset:%x SessID:%x\n"; 871592Srgrimes 881592Srgrimes struct tm *tmp; 8927079Ssteve struct rmp_packet *rmp; 901592Srgrimes int i, omask; 9127074Ssteve u_int32_t t; 921592Srgrimes 931592Srgrimes /* 941592Srgrimes * Since we will be working with RmpConns as well as DbgFp, we 951592Srgrimes * must block signals that can affect either. 961592Srgrimes */ 971592Srgrimes omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2)); 981592Srgrimes 991592Srgrimes if (DbgFp == NULL) { /* sanity */ 1001592Srgrimes (void) sigsetmask(omask); 1011592Srgrimes return; 1021592Srgrimes } 1031592Srgrimes 1041592Srgrimes /* display direction packet is going using '>>>' or '<<<' */ 1051592Srgrimes fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp); 1061592Srgrimes 1071592Srgrimes /* display packet timestamp */ 1081592Srgrimes tmp = localtime((time_t *)&rconn->tstamp.tv_sec); 1091592Srgrimes fprintf(DbgFp, "%02d:%02d:%02d.%06ld ", tmp->tm_hour, tmp->tm_min, 1101592Srgrimes tmp->tm_sec, rconn->tstamp.tv_usec); 1111592Srgrimes 1121592Srgrimes /* display src or dst addr and information about network interface */ 1131592Srgrimes fprintf(DbgFp, "Addr: %s Intf: %s\n", EnetStr(rconn), IntfName); 1141592Srgrimes 1151592Srgrimes rmp = &rconn->rmp; 1161592Srgrimes 1171592Srgrimes /* display IEEE 802.2 Logical Link Control header */ 1181592Srgrimes (void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n", 11927074Ssteve rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl)); 1201592Srgrimes 1211592Srgrimes /* display HP extensions to 802.2 Logical Link Control header */ 1221592Srgrimes (void) fprintf(DbgFp, "\tHP Ext: DXSAP:%x SXSAP:%x\n", 12327074Ssteve ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap)); 1241592Srgrimes 1251592Srgrimes /* 1261592Srgrimes * Display information about RMP packet using type field to 1271592Srgrimes * determine what kind of packet this is. 1281592Srgrimes */ 1291592Srgrimes switch(rmp->r_type) { 1301592Srgrimes case RMP_BOOT_REQ: /* boot request */ 1311592Srgrimes (void) fprintf(DbgFp, "\tBoot Request:"); 1321592Srgrimes GETWORD(rmp->r_brq.rmp_seqno, t); 13327074Ssteve if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) { 1341592Srgrimes if (WORDZE(rmp->r_brq.rmp_seqno)) 1351592Srgrimes fputs(" (Send Server ID)", DbgFp); 1361592Srgrimes else 1371592Srgrimes fprintf(DbgFp," (Send Filename #%u)",t); 1381592Srgrimes } 1391592Srgrimes (void) fputc('\n', DbgFp); 1401592Srgrimes (void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode, 14127074Ssteve t, ntohs(rmp->r_brq.rmp_session), 14227074Ssteve ntohs(rmp->r_brq.rmp_version)); 1431592Srgrimes (void) fprintf(DbgFp, "\n\t\tMachine Type: "); 1441592Srgrimes for (i = 0; i < RMP_MACHLEN; i++) 1451592Srgrimes (void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp); 1461592Srgrimes DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm); 1471592Srgrimes break; 1481592Srgrimes case RMP_BOOT_REPL: /* boot reply */ 1491592Srgrimes fprintf(DbgFp, "\tBoot Reply:\n"); 1501592Srgrimes GETWORD(rmp->r_brpl.rmp_seqno, t); 1511592Srgrimes (void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode, 15227074Ssteve t, ntohs(rmp->r_brpl.rmp_session), 15327074Ssteve ntohs(rmp->r_brpl.rmp_version)); 1541592Srgrimes DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm); 1551592Srgrimes break; 1561592Srgrimes case RMP_READ_REQ: /* read request */ 1571592Srgrimes (void) fprintf(DbgFp, "\tRead Request:\n"); 1581592Srgrimes GETWORD(rmp->r_rrq.rmp_offset, t); 1591592Srgrimes (void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode, 16027074Ssteve t, ntohs(rmp->r_rrq.rmp_session)); 1611592Srgrimes (void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n", 16227074Ssteve ntohs(rmp->r_rrq.rmp_size)); 1631592Srgrimes break; 1641592Srgrimes case RMP_READ_REPL: /* read reply */ 1651592Srgrimes (void) fprintf(DbgFp, "\tRead Reply:\n"); 1661592Srgrimes GETWORD(rmp->r_rrpl.rmp_offset, t); 1671592Srgrimes (void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode, 16827074Ssteve t, ntohs(rmp->r_rrpl.rmp_session)); 169229140Sdim (void) fprintf(DbgFp, "\t\tNoOfBytesSent: %zu\n", 1701592Srgrimes rconn->rmplen - RMPREADSIZE(0)); 1711592Srgrimes break; 1721592Srgrimes case RMP_BOOT_DONE: /* boot complete */ 1731592Srgrimes (void) fprintf(DbgFp, "\tBoot Complete:\n"); 1741592Srgrimes (void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n", 1751592Srgrimes rmp->r_done.rmp_retcode, 17627074Ssteve ntohs(rmp->r_done.rmp_session)); 1771592Srgrimes break; 1781592Srgrimes default: /* ??? */ 1791592Srgrimes (void) fprintf(DbgFp, "\tUnknown Type:(%d)\n", 1801592Srgrimes rmp->r_type); 1811592Srgrimes } 1821592Srgrimes (void) fputc('\n', DbgFp); 1831592Srgrimes (void) fflush(DbgFp); 1841592Srgrimes 1851592Srgrimes (void) sigsetmask(omask); /* reset old signal mask */ 1861592Srgrimes} 1871592Srgrimes 1881592Srgrimes 1891592Srgrimes/* 1901592Srgrimes** GetEtherAddr -- convert an RMP (Ethernet) address into a string. 1911592Srgrimes** 1921592Srgrimes** An RMP BOOT packet has been received. Look at the type field 1931592Srgrimes** and process Boot Requests, Read Requests, and Boot Complete 1941592Srgrimes** packets. Any other type will be dropped with a warning msg. 1951592Srgrimes** 1961592Srgrimes** Parameters: 1971592Srgrimes** addr - array of RMP_ADDRLEN bytes. 1981592Srgrimes** 1991592Srgrimes** Returns: 2001592Srgrimes** Pointer to static string representation of `addr'. 2011592Srgrimes** 2021592Srgrimes** Side Effects: 2031592Srgrimes** None. 2041592Srgrimes** 2051592Srgrimes** Warnings: 2061592Srgrimes** - The return value points to a static buffer; it must 2071592Srgrimes** be copied if it's to be saved. 2081592Srgrimes*/ 2091592Srgrimeschar * 21090377SimpGetEtherAddr(u_int8_t *addr) 2111592Srgrimes{ 2121592Srgrimes static char Hex[] = "0123456789abcdef"; 2131592Srgrimes static char etherstr[RMP_ADDRLEN*3]; 21427079Ssteve int i; 21527079Ssteve char *cp; 2161592Srgrimes 2171592Srgrimes /* 2181592Srgrimes * For each byte in `addr', convert it to "<hexchar><hexchar>:". 2191592Srgrimes * The last byte does not get a trailing `:' appended. 2201592Srgrimes */ 2211592Srgrimes i = 0; 22227074Ssteve cp = etherstr; 2231592Srgrimes for(;;) { 22427074Ssteve *cp++ = Hex[*addr >> 4 & 0xf]; 22527074Ssteve *cp++ = Hex[*addr++ & 0xf]; 2261592Srgrimes if (++i == RMP_ADDRLEN) 2271592Srgrimes break; 22827074Ssteve *cp++ = ':'; 2291592Srgrimes } 23027074Ssteve *cp = '\0'; 2311592Srgrimes 2321592Srgrimes return(etherstr); 2331592Srgrimes} 2341592Srgrimes 2351592Srgrimes 2361592Srgrimes/* 2371592Srgrimes** DispFlnm -- Print a string of bytes to DbgFp (often, a file name). 2381592Srgrimes** 2391592Srgrimes** Parameters: 2401592Srgrimes** size - number of bytes to print. 2411592Srgrimes** flnm - address of first byte. 2421592Srgrimes** 2431592Srgrimes** Returns: 2441592Srgrimes** Nothing. 2451592Srgrimes** 2461592Srgrimes** Side Effects: 2471592Srgrimes** - Characters are sent to `DbgFp'. 2481592Srgrimes*/ 2491592Srgrimesvoid 25090377SimpDspFlnm(u_int size, char *flnm) 2511592Srgrimes{ 25227079Ssteve int i; 2531592Srgrimes 25427074Ssteve (void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size); 2551592Srgrimes for (i = 0; i < size; i++) 2561592Srgrimes (void) fputc(*flnm++, DbgFp); 2571592Srgrimes (void) fputs(">\n", DbgFp); 2581592Srgrimes} 2591592Srgrimes 2601592Srgrimes 2611592Srgrimes/* 2621592Srgrimes** NewClient -- allocate memory for a new CLIENT. 2631592Srgrimes** 2641592Srgrimes** Parameters: 2651592Srgrimes** addr - RMP (Ethernet) address of new client. 2661592Srgrimes** 2671592Srgrimes** Returns: 2681592Srgrimes** Ptr to new CLIENT or NULL if we ran out of memory. 2691592Srgrimes** 2701592Srgrimes** Side Effects: 2711592Srgrimes** - Memory will be malloc'd for the new CLIENT. 2721592Srgrimes** - If malloc() fails, a log message will be generated. 2731592Srgrimes*/ 2741592SrgrimesCLIENT * 27590377SimpNewClient(u_int8_t *addr) 2761592Srgrimes{ 2771592Srgrimes CLIENT *ctmp; 2781592Srgrimes 2791592Srgrimes if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) { 2801592Srgrimes syslog(LOG_ERR, "NewClient: out of memory (%s)", 2811592Srgrimes GetEtherAddr(addr)); 2821592Srgrimes return(NULL); 2831592Srgrimes } 2841592Srgrimes 28527079Ssteve memset(ctmp, 0, sizeof(CLIENT)); 28627079Ssteve memmove(&ctmp->addr[0], addr, RMP_ADDRLEN); 2871592Srgrimes return(ctmp); 2881592Srgrimes} 2891592Srgrimes 2901592Srgrimes/* 2911592Srgrimes** FreeClient -- free linked list of Clients. 2921592Srgrimes** 2931592Srgrimes** Parameters: 2941592Srgrimes** None. 2951592Srgrimes** 2961592Srgrimes** Returns: 2971592Srgrimes** Nothing. 2981592Srgrimes** 2991592Srgrimes** Side Effects: 3001592Srgrimes** - All malloc'd memory associated with the linked list of 3011592Srgrimes** CLIENTS will be free'd; `Clients' will be set to NULL. 3021592Srgrimes** 3031592Srgrimes** Warnings: 3041592Srgrimes** - This routine must be called with SIGHUP blocked. 3051592Srgrimes*/ 3061592Srgrimesvoid 30790377SimpFreeClients(void) 3081592Srgrimes{ 30927079Ssteve CLIENT *ctmp; 3101592Srgrimes 3111592Srgrimes while (Clients != NULL) { 3121592Srgrimes ctmp = Clients; 3131592Srgrimes Clients = Clients->next; 3141592Srgrimes FreeClient(ctmp); 3151592Srgrimes } 3161592Srgrimes} 3171592Srgrimes 3181592Srgrimes/* 3191592Srgrimes** NewStr -- allocate memory for a character array. 3201592Srgrimes** 3211592Srgrimes** Parameters: 3221592Srgrimes** str - null terminated character array. 3231592Srgrimes** 3241592Srgrimes** Returns: 3251592Srgrimes** Ptr to new character array or NULL if we ran out of memory. 3261592Srgrimes** 3271592Srgrimes** Side Effects: 3281592Srgrimes** - Memory will be malloc'd for the new character array. 3291592Srgrimes** - If malloc() fails, a log message will be generated. 3301592Srgrimes*/ 3311592Srgrimeschar * 33290377SimpNewStr(char *str) 3331592Srgrimes{ 3341592Srgrimes char *stmp; 3351592Srgrimes 3361592Srgrimes if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) { 3371592Srgrimes syslog(LOG_ERR, "NewStr: out of memory (%s)", str); 3381592Srgrimes return(NULL); 3391592Srgrimes } 3401592Srgrimes 3411592Srgrimes (void) strcpy(stmp, str); 3421592Srgrimes return(stmp); 3431592Srgrimes} 3441592Srgrimes 3451592Srgrimes/* 3461592Srgrimes** To save time, NewConn and FreeConn maintain a cache of one RMPCONN 3471592Srgrimes** in `LastFree' (defined below). 3481592Srgrimes*/ 3491592Srgrimes 3501592Srgrimesstatic RMPCONN *LastFree = NULL; 3511592Srgrimes 3521592Srgrimes/* 3531592Srgrimes** NewConn -- allocate memory for a new RMPCONN connection. 3541592Srgrimes** 3551592Srgrimes** Parameters: 3561592Srgrimes** rconn - initialization template for new connection. 3571592Srgrimes** 3581592Srgrimes** Returns: 3591592Srgrimes** Ptr to new RMPCONN or NULL if we ran out of memory. 3601592Srgrimes** 3611592Srgrimes** Side Effects: 3621592Srgrimes** - Memory may be malloc'd for the new RMPCONN (if not cached). 3631592Srgrimes** - If malloc() fails, a log message will be generated. 3641592Srgrimes*/ 3651592SrgrimesRMPCONN * 36690377SimpNewConn(RMPCONN *rconn) 3671592Srgrimes{ 3681592Srgrimes RMPCONN *rtmp; 3691592Srgrimes 3701592Srgrimes if (LastFree == NULL) { /* nothing cached; make a new one */ 3711592Srgrimes if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) { 3721592Srgrimes syslog(LOG_ERR, "NewConn: out of memory (%s)", 3731592Srgrimes EnetStr(rconn)); 3741592Srgrimes return(NULL); 3751592Srgrimes } 3761592Srgrimes } else { /* use the cached RMPCONN */ 3771592Srgrimes rtmp = LastFree; 3781592Srgrimes LastFree = NULL; 3791592Srgrimes } 3801592Srgrimes 3811592Srgrimes /* 3821592Srgrimes * Copy template into `rtmp', init file descriptor to `-1' and 3831592Srgrimes * set ptr to next elem NULL. 3841592Srgrimes */ 38527079Ssteve memmove((char *)rtmp, (char *)rconn, sizeof(RMPCONN)); 3861592Srgrimes rtmp->bootfd = -1; 3871592Srgrimes rtmp->next = NULL; 3881592Srgrimes 3891592Srgrimes return(rtmp); 3901592Srgrimes} 3911592Srgrimes 3921592Srgrimes/* 3931592Srgrimes** FreeConn -- Free memory associated with an RMPCONN connection. 3941592Srgrimes** 3951592Srgrimes** Parameters: 3961592Srgrimes** rtmp - ptr to RMPCONN to be free'd. 3971592Srgrimes** 3981592Srgrimes** Returns: 3991592Srgrimes** Nothing. 4001592Srgrimes** 4011592Srgrimes** Side Effects: 4021592Srgrimes** - Memory associated with `rtmp' may be free'd (or cached). 4031592Srgrimes** - File desc associated with `rtmp->bootfd' will be closed. 4041592Srgrimes*/ 4051592Srgrimesvoid 40690377SimpFreeConn(RMPCONN *rtmp) 4071592Srgrimes{ 4081592Srgrimes /* 4091592Srgrimes * If the file descriptor is in use, close the file. 4101592Srgrimes */ 4111592Srgrimes if (rtmp->bootfd >= 0) { 4121592Srgrimes (void) close(rtmp->bootfd); 4131592Srgrimes rtmp->bootfd = -1; 4141592Srgrimes } 4151592Srgrimes 4161592Srgrimes if (LastFree == NULL) /* cache for next time */ 4171592Srgrimes rtmp = LastFree; 4181592Srgrimes else /* already one cached; free this one */ 4191592Srgrimes free((char *)rtmp); 4201592Srgrimes} 4211592Srgrimes 4221592Srgrimes/* 4231592Srgrimes** FreeConns -- free linked list of RMPCONN connections. 4241592Srgrimes** 4251592Srgrimes** Parameters: 4261592Srgrimes** None. 4271592Srgrimes** 4281592Srgrimes** Returns: 4291592Srgrimes** Nothing. 4301592Srgrimes** 4311592Srgrimes** Side Effects: 4321592Srgrimes** - All malloc'd memory associated with the linked list of 4331592Srgrimes** connections will be free'd; `RmpConns' will be set to NULL. 4341592Srgrimes** - If LastFree is != NULL, it too will be free'd & NULL'd. 4351592Srgrimes** 4361592Srgrimes** Warnings: 4371592Srgrimes** - This routine must be called with SIGHUP blocked. 4381592Srgrimes*/ 4391592Srgrimesvoid 44090377SimpFreeConns(void) 4411592Srgrimes{ 44227079Ssteve RMPCONN *rtmp; 4431592Srgrimes 4441592Srgrimes while (RmpConns != NULL) { 4451592Srgrimes rtmp = RmpConns; 4461592Srgrimes RmpConns = RmpConns->next; 4471592Srgrimes FreeConn(rtmp); 4481592Srgrimes } 4491592Srgrimes 4501592Srgrimes if (LastFree != NULL) { 4511592Srgrimes free((char *)LastFree); 4521592Srgrimes LastFree = NULL; 4531592Srgrimes } 4541592Srgrimes} 4551592Srgrimes 4561592Srgrimes/* 4571592Srgrimes** AddConn -- Add a connection to the linked list of connections. 4581592Srgrimes** 4591592Srgrimes** Parameters: 4601592Srgrimes** rconn - connection to be added. 4611592Srgrimes** 4621592Srgrimes** Returns: 4631592Srgrimes** Nothing. 4641592Srgrimes** 4651592Srgrimes** Side Effects: 4661592Srgrimes** - RmpConn will point to new connection. 4671592Srgrimes** 4681592Srgrimes** Warnings: 4691592Srgrimes** - This routine must be called with SIGHUP blocked. 4701592Srgrimes*/ 4711592Srgrimesvoid 47290377SimpAddConn(RMPCONN *rconn) 4731592Srgrimes{ 4741592Srgrimes if (RmpConns != NULL) 4751592Srgrimes rconn->next = RmpConns; 4761592Srgrimes RmpConns = rconn; 4771592Srgrimes} 4781592Srgrimes 4791592Srgrimes/* 4801592Srgrimes** FindConn -- Find a connection in the linked list of connections. 4811592Srgrimes** 4821592Srgrimes** We use the RMP (Ethernet) address as the basis for determining 4831592Srgrimes** if this is the same connection. According to the Remote Maint 4841592Srgrimes** Protocol, we can only have one connection with any machine. 4851592Srgrimes** 4861592Srgrimes** Parameters: 4871592Srgrimes** rconn - connection to be found. 4881592Srgrimes** 4891592Srgrimes** Returns: 4901592Srgrimes** Matching connection from linked list or NULL if not found. 4911592Srgrimes** 4921592Srgrimes** Side Effects: 4931592Srgrimes** None. 4941592Srgrimes** 4951592Srgrimes** Warnings: 4961592Srgrimes** - This routine must be called with SIGHUP blocked. 4971592Srgrimes*/ 4981592SrgrimesRMPCONN * 49990377SimpFindConn(RMPCONN *rconn) 5001592Srgrimes{ 50127079Ssteve RMPCONN *rtmp; 5021592Srgrimes 5031592Srgrimes for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next) 5041592Srgrimes if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0], 5051592Srgrimes (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0) 5061592Srgrimes break; 5071592Srgrimes 5081592Srgrimes return(rtmp); 5091592Srgrimes} 5101592Srgrimes 5111592Srgrimes/* 5121592Srgrimes** RemoveConn -- Remove a connection from the linked list of connections. 5131592Srgrimes** 5141592Srgrimes** Parameters: 5151592Srgrimes** rconn - connection to be removed. 5161592Srgrimes** 5171592Srgrimes** Returns: 5181592Srgrimes** Nothing. 5191592Srgrimes** 5201592Srgrimes** Side Effects: 5211592Srgrimes** - If found, an RMPCONN will cease to exist and it will 5221592Srgrimes** be removed from the linked list. 5231592Srgrimes** 5241592Srgrimes** Warnings: 5251592Srgrimes** - This routine must be called with SIGHUP blocked. 5261592Srgrimes*/ 5271592Srgrimesvoid 52890377SimpRemoveConn(RMPCONN *rconn) 5291592Srgrimes{ 53027079Ssteve RMPCONN *thisrconn, *lastrconn; 5311592Srgrimes 5321592Srgrimes if (RmpConns == rconn) { /* easy case */ 5331592Srgrimes RmpConns = RmpConns->next; 5341592Srgrimes FreeConn(rconn); 5351592Srgrimes } else { /* must traverse linked list */ 5361592Srgrimes lastrconn = RmpConns; /* set back ptr */ 5371592Srgrimes thisrconn = lastrconn->next; /* set current ptr */ 5381592Srgrimes while (thisrconn != NULL) { 5391592Srgrimes if (rconn == thisrconn) { /* found it */ 5401592Srgrimes lastrconn->next = thisrconn->next; 5411592Srgrimes FreeConn(thisrconn); 5421592Srgrimes break; 5431592Srgrimes } 5441592Srgrimes lastrconn = thisrconn; 5451592Srgrimes thisrconn = thisrconn->next; 5461592Srgrimes } 5471592Srgrimes } 5481592Srgrimes} 549