utils.c revision 50476
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: head/libexec/rbootd/utils.c 50476 1999-08-28 00:22:10Z peter $";
531592Srgrimes#endif /* not lint */
541592Srgrimes
551592Srgrimes#include <sys/param.h>
5627077Ssteve#include <sys/time.h>
571592Srgrimes
581592Srgrimes#include <fcntl.h>
591592Srgrimes#include <signal.h>
601592Srgrimes#include <stdio.h>
611592Srgrimes#include <stdlib.h>
621592Srgrimes#include <string.h>
631592Srgrimes#include <syslog.h>
641592Srgrimes#include <time.h>
651592Srgrimes#include <unistd.h>
661592Srgrimes#include "defs.h"
671592Srgrimes
681592Srgrimes/*
691592Srgrimes**  DispPkt -- Display the contents of an RMPCONN packet.
701592Srgrimes**
711592Srgrimes**	Parameters:
721592Srgrimes**		rconn - packet to be displayed.
731592Srgrimes**		direct - direction packet is going (DIR_*).
741592Srgrimes**
751592Srgrimes**	Returns:
761592Srgrimes**		Nothing.
771592Srgrimes**
781592Srgrimes**	Side Effects:
791592Srgrimes**		None.
801592Srgrimes*/
811592Srgrimesvoid
821592SrgrimesDispPkt(rconn, direct)
831592Srgrimes	RMPCONN *rconn;
841592Srgrimes	int direct;
851592Srgrimes{
861592Srgrimes	static char BootFmt[] = "\t\tRetCode:%u SeqNo:%lx SessID:%x Vers:%u";
871592Srgrimes	static char ReadFmt[] = "\t\tRetCode:%u Offset:%lx SessID:%x\n";
881592Srgrimes
891592Srgrimes	struct tm *tmp;
9027079Ssteve	struct rmp_packet *rmp;
911592Srgrimes	int i, omask;
9227074Ssteve	u_int32_t t;
931592Srgrimes
941592Srgrimes	/*
951592Srgrimes	 *  Since we will be working with RmpConns as well as DbgFp, we
961592Srgrimes	 *  must block signals that can affect either.
971592Srgrimes	 */
981592Srgrimes	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2));
991592Srgrimes
1001592Srgrimes	if (DbgFp == NULL) {			/* sanity */
1011592Srgrimes		(void) sigsetmask(omask);
1021592Srgrimes		return;
1031592Srgrimes	}
1041592Srgrimes
1051592Srgrimes	/* display direction packet is going using '>>>' or '<<<' */
1061592Srgrimes	fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp);
1071592Srgrimes
1081592Srgrimes	/* display packet timestamp */
1091592Srgrimes	tmp = localtime((time_t *)&rconn->tstamp.tv_sec);
1101592Srgrimes	fprintf(DbgFp, "%02d:%02d:%02d.%06ld   ", tmp->tm_hour, tmp->tm_min,
1111592Srgrimes	        tmp->tm_sec, rconn->tstamp.tv_usec);
1121592Srgrimes
1131592Srgrimes	/* display src or dst addr and information about network interface */
1141592Srgrimes	fprintf(DbgFp, "Addr: %s   Intf: %s\n", EnetStr(rconn), IntfName);
1151592Srgrimes
1161592Srgrimes	rmp = &rconn->rmp;
1171592Srgrimes
1181592Srgrimes	/* display IEEE 802.2 Logical Link Control header */
1191592Srgrimes	(void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n",
12027074Ssteve               rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl));
1211592Srgrimes
1221592Srgrimes	/* display HP extensions to 802.2 Logical Link Control header */
1231592Srgrimes	(void) fprintf(DbgFp, "\tHP Ext:    DXSAP:%x SXSAP:%x\n",
12427074Ssteve	               ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap));
1251592Srgrimes
1261592Srgrimes	/*
1271592Srgrimes	 *  Display information about RMP packet using type field to
1281592Srgrimes	 *  determine what kind of packet this is.
1291592Srgrimes	 */
1301592Srgrimes	switch(rmp->r_type) {
1311592Srgrimes		case RMP_BOOT_REQ:		/* boot request */
1321592Srgrimes			(void) fprintf(DbgFp, "\tBoot Request:");
1331592Srgrimes			GETWORD(rmp->r_brq.rmp_seqno, t);
13427074Ssteve			if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) {
1351592Srgrimes				if (WORDZE(rmp->r_brq.rmp_seqno))
1361592Srgrimes					fputs(" (Send Server ID)", DbgFp);
1371592Srgrimes				else
1381592Srgrimes					fprintf(DbgFp," (Send Filename #%u)",t);
1391592Srgrimes			}
1401592Srgrimes			(void) fputc('\n', DbgFp);
1411592Srgrimes			(void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode,
14227074Ssteve			        t, ntohs(rmp->r_brq.rmp_session),
14327074Ssteve			        ntohs(rmp->r_brq.rmp_version));
1441592Srgrimes			(void) fprintf(DbgFp, "\n\t\tMachine Type: ");
1451592Srgrimes			for (i = 0; i < RMP_MACHLEN; i++)
1461592Srgrimes				(void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp);
1471592Srgrimes			DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm);
1481592Srgrimes			break;
1491592Srgrimes		case RMP_BOOT_REPL:		/* boot reply */
1501592Srgrimes			fprintf(DbgFp, "\tBoot Reply:\n");
1511592Srgrimes			GETWORD(rmp->r_brpl.rmp_seqno, t);
1521592Srgrimes			(void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode,
15327074Ssteve			        t, ntohs(rmp->r_brpl.rmp_session),
15427074Ssteve			        ntohs(rmp->r_brpl.rmp_version));
1551592Srgrimes			DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm);
1561592Srgrimes			break;
1571592Srgrimes		case RMP_READ_REQ:		/* read request */
1581592Srgrimes			(void) fprintf(DbgFp, "\tRead Request:\n");
1591592Srgrimes			GETWORD(rmp->r_rrq.rmp_offset, t);
1601592Srgrimes			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode,
16127074Ssteve			        t, ntohs(rmp->r_rrq.rmp_session));
1621592Srgrimes			(void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n",
16327074Ssteve			        ntohs(rmp->r_rrq.rmp_size));
1641592Srgrimes			break;
1651592Srgrimes		case RMP_READ_REPL:		/* read reply */
1661592Srgrimes			(void) fprintf(DbgFp, "\tRead Reply:\n");
1671592Srgrimes			GETWORD(rmp->r_rrpl.rmp_offset, t);
1681592Srgrimes			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode,
16927074Ssteve			        t, ntohs(rmp->r_rrpl.rmp_session));
1701592Srgrimes			(void) fprintf(DbgFp, "\t\tNoOfBytesSent: %d\n",
1711592Srgrimes			        rconn->rmplen - RMPREADSIZE(0));
1721592Srgrimes			break;
1731592Srgrimes		case RMP_BOOT_DONE:		/* boot complete */
1741592Srgrimes			(void) fprintf(DbgFp, "\tBoot Complete:\n");
1751592Srgrimes			(void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n",
1761592Srgrimes			        rmp->r_done.rmp_retcode,
17727074Ssteve			        ntohs(rmp->r_done.rmp_session));
1781592Srgrimes			break;
1791592Srgrimes		default:			/* ??? */
1801592Srgrimes			(void) fprintf(DbgFp, "\tUnknown Type:(%d)\n",
1811592Srgrimes				rmp->r_type);
1821592Srgrimes	}
1831592Srgrimes	(void) fputc('\n', DbgFp);
1841592Srgrimes	(void) fflush(DbgFp);
1851592Srgrimes
1861592Srgrimes	(void) sigsetmask(omask);		/* reset old signal mask */
1871592Srgrimes}
1881592Srgrimes
1891592Srgrimes
1901592Srgrimes/*
1911592Srgrimes**  GetEtherAddr -- convert an RMP (Ethernet) address into a string.
1921592Srgrimes**
1931592Srgrimes**	An RMP BOOT packet has been received.  Look at the type field
1941592Srgrimes**	and process Boot Requests, Read Requests, and Boot Complete
1951592Srgrimes**	packets.  Any other type will be dropped with a warning msg.
1961592Srgrimes**
1971592Srgrimes**	Parameters:
1981592Srgrimes**		addr - array of RMP_ADDRLEN bytes.
1991592Srgrimes**
2001592Srgrimes**	Returns:
2011592Srgrimes**		Pointer to static string representation of `addr'.
2021592Srgrimes**
2031592Srgrimes**	Side Effects:
2041592Srgrimes**		None.
2051592Srgrimes**
2061592Srgrimes**	Warnings:
2071592Srgrimes**		- The return value points to a static buffer; it must
2081592Srgrimes**		  be copied if it's to be saved.
2091592Srgrimes*/
2101592Srgrimeschar *
2111592SrgrimesGetEtherAddr(addr)
21227074Ssteve	u_int8_t *addr;
2131592Srgrimes{
2141592Srgrimes	static char Hex[] = "0123456789abcdef";
2151592Srgrimes	static char etherstr[RMP_ADDRLEN*3];
21627079Ssteve	int i;
21727079Ssteve	char *cp;
2181592Srgrimes
2191592Srgrimes	/*
2201592Srgrimes	 *  For each byte in `addr', convert it to "<hexchar><hexchar>:".
2211592Srgrimes	 *  The last byte does not get a trailing `:' appended.
2221592Srgrimes	 */
2231592Srgrimes	i = 0;
22427074Ssteve	cp = etherstr;
2251592Srgrimes	for(;;) {
22627074Ssteve		*cp++ = Hex[*addr >> 4 & 0xf];
22727074Ssteve		*cp++ = Hex[*addr++ & 0xf];
2281592Srgrimes		if (++i == RMP_ADDRLEN)
2291592Srgrimes			break;
23027074Ssteve		*cp++ = ':';
2311592Srgrimes	}
23227074Ssteve	*cp = '\0';
2331592Srgrimes
2341592Srgrimes	return(etherstr);
2351592Srgrimes}
2361592Srgrimes
2371592Srgrimes
2381592Srgrimes/*
2391592Srgrimes**  DispFlnm -- Print a string of bytes to DbgFp (often, a file name).
2401592Srgrimes**
2411592Srgrimes**	Parameters:
2421592Srgrimes**		size - number of bytes to print.
2431592Srgrimes**		flnm - address of first byte.
2441592Srgrimes**
2451592Srgrimes**	Returns:
2461592Srgrimes**		Nothing.
2471592Srgrimes**
2481592Srgrimes**	Side Effects:
2491592Srgrimes**		- Characters are sent to `DbgFp'.
2501592Srgrimes*/
2511592Srgrimesvoid
2521592SrgrimesDspFlnm(size, flnm)
25327079Ssteve	u_int size;
25427079Ssteve	char *flnm;
2551592Srgrimes{
25627079Ssteve	int i;
2571592Srgrimes
25827074Ssteve	(void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size);
2591592Srgrimes	for (i = 0; i < size; i++)
2601592Srgrimes		(void) fputc(*flnm++, DbgFp);
2611592Srgrimes	(void) fputs(">\n", DbgFp);
2621592Srgrimes}
2631592Srgrimes
2641592Srgrimes
2651592Srgrimes/*
2661592Srgrimes**  NewClient -- allocate memory for a new CLIENT.
2671592Srgrimes**
2681592Srgrimes**	Parameters:
2691592Srgrimes**		addr - RMP (Ethernet) address of new client.
2701592Srgrimes**
2711592Srgrimes**	Returns:
2721592Srgrimes**		Ptr to new CLIENT or NULL if we ran out of memory.
2731592Srgrimes**
2741592Srgrimes**	Side Effects:
2751592Srgrimes**		- Memory will be malloc'd for the new CLIENT.
2761592Srgrimes**		- If malloc() fails, a log message will be generated.
2771592Srgrimes*/
2781592SrgrimesCLIENT *
2791592SrgrimesNewClient(addr)
28027074Ssteve	u_int8_t *addr;
2811592Srgrimes{
2821592Srgrimes	CLIENT *ctmp;
2831592Srgrimes
2841592Srgrimes	if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) {
2851592Srgrimes		syslog(LOG_ERR, "NewClient: out of memory (%s)",
2861592Srgrimes		       GetEtherAddr(addr));
2871592Srgrimes		return(NULL);
2881592Srgrimes	}
2891592Srgrimes
29027079Ssteve	memset(ctmp, 0, sizeof(CLIENT));
29127079Ssteve	memmove(&ctmp->addr[0], addr, RMP_ADDRLEN);
2921592Srgrimes	return(ctmp);
2931592Srgrimes}
2941592Srgrimes
2951592Srgrimes/*
2961592Srgrimes**  FreeClient -- free linked list of Clients.
2971592Srgrimes**
2981592Srgrimes**	Parameters:
2991592Srgrimes**		None.
3001592Srgrimes**
3011592Srgrimes**	Returns:
3021592Srgrimes**		Nothing.
3031592Srgrimes**
3041592Srgrimes**	Side Effects:
3051592Srgrimes**		- All malloc'd memory associated with the linked list of
3061592Srgrimes**		  CLIENTS will be free'd; `Clients' will be set to NULL.
3071592Srgrimes**
3081592Srgrimes**	Warnings:
3091592Srgrimes**		- This routine must be called with SIGHUP blocked.
3101592Srgrimes*/
3111592Srgrimesvoid
3121592SrgrimesFreeClients()
3131592Srgrimes{
31427079Ssteve	CLIENT *ctmp;
3151592Srgrimes
3161592Srgrimes	while (Clients != NULL) {
3171592Srgrimes		ctmp = Clients;
3181592Srgrimes		Clients = Clients->next;
3191592Srgrimes		FreeClient(ctmp);
3201592Srgrimes	}
3211592Srgrimes}
3221592Srgrimes
3231592Srgrimes/*
3241592Srgrimes**  NewStr -- allocate memory for a character array.
3251592Srgrimes**
3261592Srgrimes**	Parameters:
3271592Srgrimes**		str - null terminated character array.
3281592Srgrimes**
3291592Srgrimes**	Returns:
3301592Srgrimes**		Ptr to new character array or NULL if we ran out of memory.
3311592Srgrimes**
3321592Srgrimes**	Side Effects:
3331592Srgrimes**		- Memory will be malloc'd for the new character array.
3341592Srgrimes**		- If malloc() fails, a log message will be generated.
3351592Srgrimes*/
3361592Srgrimeschar *
3371592SrgrimesNewStr(str)
3381592Srgrimes	char *str;
3391592Srgrimes{
3401592Srgrimes	char *stmp;
3411592Srgrimes
3421592Srgrimes	if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) {
3431592Srgrimes		syslog(LOG_ERR, "NewStr: out of memory (%s)", str);
3441592Srgrimes		return(NULL);
3451592Srgrimes	}
3461592Srgrimes
3471592Srgrimes	(void) strcpy(stmp, str);
3481592Srgrimes	return(stmp);
3491592Srgrimes}
3501592Srgrimes
3511592Srgrimes/*
3521592Srgrimes**  To save time, NewConn and FreeConn maintain a cache of one RMPCONN
3531592Srgrimes**  in `LastFree' (defined below).
3541592Srgrimes*/
3551592Srgrimes
3561592Srgrimesstatic RMPCONN *LastFree = NULL;
3571592Srgrimes
3581592Srgrimes/*
3591592Srgrimes**  NewConn -- allocate memory for a new RMPCONN connection.
3601592Srgrimes**
3611592Srgrimes**	Parameters:
3621592Srgrimes**		rconn - initialization template for new connection.
3631592Srgrimes**
3641592Srgrimes**	Returns:
3651592Srgrimes**		Ptr to new RMPCONN or NULL if we ran out of memory.
3661592Srgrimes**
3671592Srgrimes**	Side Effects:
3681592Srgrimes**		- Memory may be malloc'd for the new RMPCONN (if not cached).
3691592Srgrimes**		- If malloc() fails, a log message will be generated.
3701592Srgrimes*/
3711592SrgrimesRMPCONN *
3721592SrgrimesNewConn(rconn)
3731592Srgrimes	RMPCONN *rconn;
3741592Srgrimes{
3751592Srgrimes	RMPCONN *rtmp;
3761592Srgrimes
3771592Srgrimes	if (LastFree == NULL) {		/* nothing cached; make a new one */
3781592Srgrimes		if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) {
3791592Srgrimes			syslog(LOG_ERR, "NewConn: out of memory (%s)",
3801592Srgrimes			       EnetStr(rconn));
3811592Srgrimes			return(NULL);
3821592Srgrimes		}
3831592Srgrimes	} else {			/* use the cached RMPCONN */
3841592Srgrimes		rtmp = LastFree;
3851592Srgrimes		LastFree = NULL;
3861592Srgrimes	}
3871592Srgrimes
3881592Srgrimes	/*
3891592Srgrimes	 *  Copy template into `rtmp', init file descriptor to `-1' and
3901592Srgrimes	 *  set ptr to next elem NULL.
3911592Srgrimes	 */
39227079Ssteve	memmove((char *)rtmp, (char *)rconn, sizeof(RMPCONN));
3931592Srgrimes	rtmp->bootfd = -1;
3941592Srgrimes	rtmp->next = NULL;
3951592Srgrimes
3961592Srgrimes	return(rtmp);
3971592Srgrimes}
3981592Srgrimes
3991592Srgrimes/*
4001592Srgrimes**  FreeConn -- Free memory associated with an RMPCONN connection.
4011592Srgrimes**
4021592Srgrimes**	Parameters:
4031592Srgrimes**		rtmp - ptr to RMPCONN to be free'd.
4041592Srgrimes**
4051592Srgrimes**	Returns:
4061592Srgrimes**		Nothing.
4071592Srgrimes**
4081592Srgrimes**	Side Effects:
4091592Srgrimes**		- Memory associated with `rtmp' may be free'd (or cached).
4101592Srgrimes**		- File desc associated with `rtmp->bootfd' will be closed.
4111592Srgrimes*/
4121592Srgrimesvoid
4131592SrgrimesFreeConn(rtmp)
41427079Ssteve	RMPCONN *rtmp;
4151592Srgrimes{
4161592Srgrimes	/*
4171592Srgrimes	 *  If the file descriptor is in use, close the file.
4181592Srgrimes	 */
4191592Srgrimes	if (rtmp->bootfd >= 0) {
4201592Srgrimes		(void) close(rtmp->bootfd);
4211592Srgrimes		rtmp->bootfd = -1;
4221592Srgrimes	}
4231592Srgrimes
4241592Srgrimes	if (LastFree == NULL)		/* cache for next time */
4251592Srgrimes		rtmp = LastFree;
4261592Srgrimes	else				/* already one cached; free this one */
4271592Srgrimes		free((char *)rtmp);
4281592Srgrimes}
4291592Srgrimes
4301592Srgrimes/*
4311592Srgrimes**  FreeConns -- free linked list of RMPCONN connections.
4321592Srgrimes**
4331592Srgrimes**	Parameters:
4341592Srgrimes**		None.
4351592Srgrimes**
4361592Srgrimes**	Returns:
4371592Srgrimes**		Nothing.
4381592Srgrimes**
4391592Srgrimes**	Side Effects:
4401592Srgrimes**		- All malloc'd memory associated with the linked list of
4411592Srgrimes**		  connections will be free'd; `RmpConns' will be set to NULL.
4421592Srgrimes**		- If LastFree is != NULL, it too will be free'd & NULL'd.
4431592Srgrimes**
4441592Srgrimes**	Warnings:
4451592Srgrimes**		- This routine must be called with SIGHUP blocked.
4461592Srgrimes*/
4471592Srgrimesvoid
4481592SrgrimesFreeConns()
4491592Srgrimes{
45027079Ssteve	RMPCONN *rtmp;
4511592Srgrimes
4521592Srgrimes	while (RmpConns != NULL) {
4531592Srgrimes		rtmp = RmpConns;
4541592Srgrimes		RmpConns = RmpConns->next;
4551592Srgrimes		FreeConn(rtmp);
4561592Srgrimes	}
4571592Srgrimes
4581592Srgrimes	if (LastFree != NULL) {
4591592Srgrimes		free((char *)LastFree);
4601592Srgrimes		LastFree = NULL;
4611592Srgrimes	}
4621592Srgrimes}
4631592Srgrimes
4641592Srgrimes/*
4651592Srgrimes**  AddConn -- Add a connection to the linked list of connections.
4661592Srgrimes**
4671592Srgrimes**	Parameters:
4681592Srgrimes**		rconn - connection to be added.
4691592Srgrimes**
4701592Srgrimes**	Returns:
4711592Srgrimes**		Nothing.
4721592Srgrimes**
4731592Srgrimes**	Side Effects:
4741592Srgrimes**		- RmpConn will point to new connection.
4751592Srgrimes**
4761592Srgrimes**	Warnings:
4771592Srgrimes**		- This routine must be called with SIGHUP blocked.
4781592Srgrimes*/
4791592Srgrimesvoid
4801592SrgrimesAddConn(rconn)
48127079Ssteve	RMPCONN *rconn;
4821592Srgrimes{
4831592Srgrimes	if (RmpConns != NULL)
4841592Srgrimes		rconn->next = RmpConns;
4851592Srgrimes	RmpConns = rconn;
4861592Srgrimes}
4871592Srgrimes
4881592Srgrimes/*
4891592Srgrimes**  FindConn -- Find a connection in the linked list of connections.
4901592Srgrimes**
4911592Srgrimes**	We use the RMP (Ethernet) address as the basis for determining
4921592Srgrimes**	if this is the same connection.  According to the Remote Maint
4931592Srgrimes**	Protocol, we can only have one connection with any machine.
4941592Srgrimes**
4951592Srgrimes**	Parameters:
4961592Srgrimes**		rconn - connection to be found.
4971592Srgrimes**
4981592Srgrimes**	Returns:
4991592Srgrimes**		Matching connection from linked list or NULL if not found.
5001592Srgrimes**
5011592Srgrimes**	Side Effects:
5021592Srgrimes**		None.
5031592Srgrimes**
5041592Srgrimes**	Warnings:
5051592Srgrimes**		- This routine must be called with SIGHUP blocked.
5061592Srgrimes*/
5071592SrgrimesRMPCONN *
5081592SrgrimesFindConn(rconn)
50927079Ssteve	RMPCONN *rconn;
5101592Srgrimes{
51127079Ssteve	RMPCONN *rtmp;
5121592Srgrimes
5131592Srgrimes	for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
5141592Srgrimes		if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0],
5151592Srgrimes		         (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0)
5161592Srgrimes			break;
5171592Srgrimes
5181592Srgrimes	return(rtmp);
5191592Srgrimes}
5201592Srgrimes
5211592Srgrimes/*
5221592Srgrimes**  RemoveConn -- Remove a connection from the linked list of connections.
5231592Srgrimes**
5241592Srgrimes**	Parameters:
5251592Srgrimes**		rconn - connection to be removed.
5261592Srgrimes**
5271592Srgrimes**	Returns:
5281592Srgrimes**		Nothing.
5291592Srgrimes**
5301592Srgrimes**	Side Effects:
5311592Srgrimes**		- If found, an RMPCONN will cease to exist and it will
5321592Srgrimes**		  be removed from the linked list.
5331592Srgrimes**
5341592Srgrimes**	Warnings:
5351592Srgrimes**		- This routine must be called with SIGHUP blocked.
5361592Srgrimes*/
5371592Srgrimesvoid
5381592SrgrimesRemoveConn(rconn)
53927079Ssteve	RMPCONN *rconn;
5401592Srgrimes{
54127079Ssteve	RMPCONN *thisrconn, *lastrconn;
5421592Srgrimes
5431592Srgrimes	if (RmpConns == rconn) {		/* easy case */
5441592Srgrimes		RmpConns = RmpConns->next;
5451592Srgrimes		FreeConn(rconn);
5461592Srgrimes	} else {				/* must traverse linked list */
5471592Srgrimes		lastrconn = RmpConns;			/* set back ptr */
5481592Srgrimes		thisrconn = lastrconn->next;		/* set current ptr */
5491592Srgrimes		while (thisrconn != NULL) {
5501592Srgrimes			if (rconn == thisrconn) {		/* found it */
5511592Srgrimes				lastrconn->next = thisrconn->next;
5521592Srgrimes				FreeConn(thisrconn);
5531592Srgrimes				break;
5541592Srgrimes			}
5551592Srgrimes			lastrconn = thisrconn;
5561592Srgrimes			thisrconn = thisrconn->next;
5571592Srgrimes		}
5581592Srgrimes	}
5591592Srgrimes}
560