1331722Seadler/*
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.
21262136Sbrueffer * 3. Neither the name of the University nor the names of its contributors
221592Srgrimes *    may be used to endorse or promote products derived from this software
231592Srgrimes *    without specific prior written permission.
241592Srgrimes *
251592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
261592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
271592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
281592Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
291592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
301592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
311592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
321592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
331592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
341592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
351592Srgrimes * SUCH DAMAGE.
361592Srgrimes *
3727074Ssteve *	from: @(#)utils.c	8.1 (Berkeley) 6/4/93
381592Srgrimes *
3927074Ssteve * From: Utah Hdr: utils.c 3.1 92/07/06
401592Srgrimes * Author: Jeff Forys, University of Utah CSS
411592Srgrimes */
421592Srgrimes
431592Srgrimes#ifndef lint
4431386Scharnier#if 0
4527077Sstevestatic const char sccsid[] = "@(#)utils.c	8.1 (Berkeley) 6/4/93";
4631386Scharnier#endif
4731386Scharnierstatic const char rcsid[] =
4850476Speter  "$FreeBSD$";
491592Srgrimes#endif /* not lint */
501592Srgrimes
511592Srgrimes#include <sys/param.h>
5227077Ssteve#include <sys/time.h>
53129652Sstefanf#include <netinet/in.h>
541592Srgrimes
551592Srgrimes#include <fcntl.h>
561592Srgrimes#include <signal.h>
571592Srgrimes#include <stdio.h>
581592Srgrimes#include <stdlib.h>
591592Srgrimes#include <string.h>
601592Srgrimes#include <syslog.h>
611592Srgrimes#include <time.h>
621592Srgrimes#include <unistd.h>
631592Srgrimes#include "defs.h"
641592Srgrimes
651592Srgrimes/*
661592Srgrimes**  DispPkt -- Display the contents of an RMPCONN packet.
671592Srgrimes**
681592Srgrimes**	Parameters:
691592Srgrimes**		rconn - packet to be displayed.
701592Srgrimes**		direct - direction packet is going (DIR_*).
711592Srgrimes**
721592Srgrimes**	Returns:
731592Srgrimes**		Nothing.
741592Srgrimes**
751592Srgrimes**	Side Effects:
761592Srgrimes**		None.
771592Srgrimes*/
781592Srgrimesvoid
7990377SimpDispPkt(RMPCONN *rconn, int direct)
801592Srgrimes{
81228587Sdim	static const char BootFmt[] = "\t\tRetCode:%u SeqNo:%x SessID:%x Vers:%u";
82228587Sdim	static const char ReadFmt[] = "\t\tRetCode:%u Offset:%x SessID:%x\n";
831592Srgrimes
841592Srgrimes	struct tm *tmp;
8527079Ssteve	struct rmp_packet *rmp;
861592Srgrimes	int i, omask;
8727074Ssteve	u_int32_t t;
881592Srgrimes
891592Srgrimes	/*
901592Srgrimes	 *  Since we will be working with RmpConns as well as DbgFp, we
911592Srgrimes	 *  must block signals that can affect either.
921592Srgrimes	 */
931592Srgrimes	omask = sigblock(sigmask(SIGHUP)|sigmask(SIGUSR1)|sigmask(SIGUSR2));
941592Srgrimes
951592Srgrimes	if (DbgFp == NULL) {			/* sanity */
961592Srgrimes		(void) sigsetmask(omask);
971592Srgrimes		return;
981592Srgrimes	}
991592Srgrimes
1001592Srgrimes	/* display direction packet is going using '>>>' or '<<<' */
1011592Srgrimes	fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp);
1021592Srgrimes
1031592Srgrimes	/* display packet timestamp */
1041592Srgrimes	tmp = localtime((time_t *)&rconn->tstamp.tv_sec);
1051592Srgrimes	fprintf(DbgFp, "%02d:%02d:%02d.%06ld   ", tmp->tm_hour, tmp->tm_min,
1061592Srgrimes	        tmp->tm_sec, rconn->tstamp.tv_usec);
1071592Srgrimes
1081592Srgrimes	/* display src or dst addr and information about network interface */
1091592Srgrimes	fprintf(DbgFp, "Addr: %s   Intf: %s\n", EnetStr(rconn), IntfName);
1101592Srgrimes
1111592Srgrimes	rmp = &rconn->rmp;
1121592Srgrimes
1131592Srgrimes	/* display IEEE 802.2 Logical Link Control header */
1141592Srgrimes	(void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n",
11527074Ssteve               rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl));
1161592Srgrimes
1171592Srgrimes	/* display HP extensions to 802.2 Logical Link Control header */
1181592Srgrimes	(void) fprintf(DbgFp, "\tHP Ext:    DXSAP:%x SXSAP:%x\n",
11927074Ssteve	               ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap));
1201592Srgrimes
1211592Srgrimes	/*
1221592Srgrimes	 *  Display information about RMP packet using type field to
1231592Srgrimes	 *  determine what kind of packet this is.
1241592Srgrimes	 */
1251592Srgrimes	switch(rmp->r_type) {
1261592Srgrimes		case RMP_BOOT_REQ:		/* boot request */
1271592Srgrimes			(void) fprintf(DbgFp, "\tBoot Request:");
1281592Srgrimes			GETWORD(rmp->r_brq.rmp_seqno, t);
12927074Ssteve			if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) {
1301592Srgrimes				if (WORDZE(rmp->r_brq.rmp_seqno))
1311592Srgrimes					fputs(" (Send Server ID)", DbgFp);
1321592Srgrimes				else
1331592Srgrimes					fprintf(DbgFp," (Send Filename #%u)",t);
1341592Srgrimes			}
1351592Srgrimes			(void) fputc('\n', DbgFp);
1361592Srgrimes			(void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode,
13727074Ssteve			        t, ntohs(rmp->r_brq.rmp_session),
13827074Ssteve			        ntohs(rmp->r_brq.rmp_version));
1391592Srgrimes			(void) fprintf(DbgFp, "\n\t\tMachine Type: ");
1401592Srgrimes			for (i = 0; i < RMP_MACHLEN; i++)
1411592Srgrimes				(void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp);
1421592Srgrimes			DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm);
1431592Srgrimes			break;
1441592Srgrimes		case RMP_BOOT_REPL:		/* boot reply */
1451592Srgrimes			fprintf(DbgFp, "\tBoot Reply:\n");
1461592Srgrimes			GETWORD(rmp->r_brpl.rmp_seqno, t);
1471592Srgrimes			(void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode,
14827074Ssteve			        t, ntohs(rmp->r_brpl.rmp_session),
14927074Ssteve			        ntohs(rmp->r_brpl.rmp_version));
1501592Srgrimes			DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm);
1511592Srgrimes			break;
1521592Srgrimes		case RMP_READ_REQ:		/* read request */
1531592Srgrimes			(void) fprintf(DbgFp, "\tRead Request:\n");
1541592Srgrimes			GETWORD(rmp->r_rrq.rmp_offset, t);
1551592Srgrimes			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode,
15627074Ssteve			        t, ntohs(rmp->r_rrq.rmp_session));
1571592Srgrimes			(void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n",
15827074Ssteve			        ntohs(rmp->r_rrq.rmp_size));
1591592Srgrimes			break;
1601592Srgrimes		case RMP_READ_REPL:		/* read reply */
1611592Srgrimes			(void) fprintf(DbgFp, "\tRead Reply:\n");
1621592Srgrimes			GETWORD(rmp->r_rrpl.rmp_offset, t);
1631592Srgrimes			(void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode,
16427074Ssteve			        t, ntohs(rmp->r_rrpl.rmp_session));
165228587Sdim			(void) fprintf(DbgFp, "\t\tNoOfBytesSent: %zu\n",
1661592Srgrimes			        rconn->rmplen - RMPREADSIZE(0));
1671592Srgrimes			break;
1681592Srgrimes		case RMP_BOOT_DONE:		/* boot complete */
1691592Srgrimes			(void) fprintf(DbgFp, "\tBoot Complete:\n");
1701592Srgrimes			(void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n",
1711592Srgrimes			        rmp->r_done.rmp_retcode,
17227074Ssteve			        ntohs(rmp->r_done.rmp_session));
1731592Srgrimes			break;
1741592Srgrimes		default:			/* ??? */
1751592Srgrimes			(void) fprintf(DbgFp, "\tUnknown Type:(%d)\n",
1761592Srgrimes				rmp->r_type);
1771592Srgrimes	}
1781592Srgrimes	(void) fputc('\n', DbgFp);
1791592Srgrimes	(void) fflush(DbgFp);
1801592Srgrimes
1811592Srgrimes	(void) sigsetmask(omask);		/* reset old signal mask */
1821592Srgrimes}
1831592Srgrimes
1841592Srgrimes
1851592Srgrimes/*
1861592Srgrimes**  GetEtherAddr -- convert an RMP (Ethernet) address into a string.
1871592Srgrimes**
1881592Srgrimes**	An RMP BOOT packet has been received.  Look at the type field
1891592Srgrimes**	and process Boot Requests, Read Requests, and Boot Complete
1901592Srgrimes**	packets.  Any other type will be dropped with a warning msg.
1911592Srgrimes**
1921592Srgrimes**	Parameters:
1931592Srgrimes**		addr - array of RMP_ADDRLEN bytes.
1941592Srgrimes**
1951592Srgrimes**	Returns:
1961592Srgrimes**		Pointer to static string representation of `addr'.
1971592Srgrimes**
1981592Srgrimes**	Side Effects:
1991592Srgrimes**		None.
2001592Srgrimes**
2011592Srgrimes**	Warnings:
2021592Srgrimes**		- The return value points to a static buffer; it must
2031592Srgrimes**		  be copied if it's to be saved.
2041592Srgrimes*/
2051592Srgrimeschar *
20690377SimpGetEtherAddr(u_int8_t *addr)
2071592Srgrimes{
2081592Srgrimes	static char Hex[] = "0123456789abcdef";
2091592Srgrimes	static char etherstr[RMP_ADDRLEN*3];
21027079Ssteve	int i;
21127079Ssteve	char *cp;
2121592Srgrimes
2131592Srgrimes	/*
2141592Srgrimes	 *  For each byte in `addr', convert it to "<hexchar><hexchar>:".
2151592Srgrimes	 *  The last byte does not get a trailing `:' appended.
2161592Srgrimes	 */
2171592Srgrimes	i = 0;
21827074Ssteve	cp = etherstr;
2191592Srgrimes	for(;;) {
22027074Ssteve		*cp++ = Hex[*addr >> 4 & 0xf];
22127074Ssteve		*cp++ = Hex[*addr++ & 0xf];
2221592Srgrimes		if (++i == RMP_ADDRLEN)
2231592Srgrimes			break;
22427074Ssteve		*cp++ = ':';
2251592Srgrimes	}
22627074Ssteve	*cp = '\0';
2271592Srgrimes
2281592Srgrimes	return(etherstr);
2291592Srgrimes}
2301592Srgrimes
2311592Srgrimes
2321592Srgrimes/*
2331592Srgrimes**  DispFlnm -- Print a string of bytes to DbgFp (often, a file name).
2341592Srgrimes**
2351592Srgrimes**	Parameters:
2361592Srgrimes**		size - number of bytes to print.
2371592Srgrimes**		flnm - address of first byte.
2381592Srgrimes**
2391592Srgrimes**	Returns:
2401592Srgrimes**		Nothing.
2411592Srgrimes**
2421592Srgrimes**	Side Effects:
2431592Srgrimes**		- Characters are sent to `DbgFp'.
2441592Srgrimes*/
2451592Srgrimesvoid
24690377SimpDspFlnm(u_int size, char *flnm)
2471592Srgrimes{
24827079Ssteve	int i;
2491592Srgrimes
25027074Ssteve	(void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size);
2511592Srgrimes	for (i = 0; i < size; i++)
2521592Srgrimes		(void) fputc(*flnm++, DbgFp);
2531592Srgrimes	(void) fputs(">\n", DbgFp);
2541592Srgrimes}
2551592Srgrimes
2561592Srgrimes
2571592Srgrimes/*
2581592Srgrimes**  NewClient -- allocate memory for a new CLIENT.
2591592Srgrimes**
2601592Srgrimes**	Parameters:
2611592Srgrimes**		addr - RMP (Ethernet) address of new client.
2621592Srgrimes**
2631592Srgrimes**	Returns:
2641592Srgrimes**		Ptr to new CLIENT or NULL if we ran out of memory.
2651592Srgrimes**
2661592Srgrimes**	Side Effects:
2671592Srgrimes**		- Memory will be malloc'd for the new CLIENT.
2681592Srgrimes**		- If malloc() fails, a log message will be generated.
2691592Srgrimes*/
2701592SrgrimesCLIENT *
27190377SimpNewClient(u_int8_t *addr)
2721592Srgrimes{
2731592Srgrimes	CLIENT *ctmp;
2741592Srgrimes
2751592Srgrimes	if ((ctmp = (CLIENT *) malloc(sizeof(CLIENT))) == NULL) {
2761592Srgrimes		syslog(LOG_ERR, "NewClient: out of memory (%s)",
2771592Srgrimes		       GetEtherAddr(addr));
2781592Srgrimes		return(NULL);
2791592Srgrimes	}
2801592Srgrimes
28127079Ssteve	memset(ctmp, 0, sizeof(CLIENT));
28227079Ssteve	memmove(&ctmp->addr[0], addr, RMP_ADDRLEN);
2831592Srgrimes	return(ctmp);
2841592Srgrimes}
2851592Srgrimes
2861592Srgrimes/*
2871592Srgrimes**  FreeClient -- free linked list of Clients.
2881592Srgrimes**
2891592Srgrimes**	Parameters:
2901592Srgrimes**		None.
2911592Srgrimes**
2921592Srgrimes**	Returns:
2931592Srgrimes**		Nothing.
2941592Srgrimes**
2951592Srgrimes**	Side Effects:
2961592Srgrimes**		- All malloc'd memory associated with the linked list of
2971592Srgrimes**		  CLIENTS will be free'd; `Clients' will be set to NULL.
2981592Srgrimes**
2991592Srgrimes**	Warnings:
3001592Srgrimes**		- This routine must be called with SIGHUP blocked.
3011592Srgrimes*/
3021592Srgrimesvoid
30390377SimpFreeClients(void)
3041592Srgrimes{
30527079Ssteve	CLIENT *ctmp;
3061592Srgrimes
3071592Srgrimes	while (Clients != NULL) {
3081592Srgrimes		ctmp = Clients;
3091592Srgrimes		Clients = Clients->next;
3101592Srgrimes		FreeClient(ctmp);
3111592Srgrimes	}
3121592Srgrimes}
3131592Srgrimes
3141592Srgrimes/*
3151592Srgrimes**  NewStr -- allocate memory for a character array.
3161592Srgrimes**
3171592Srgrimes**	Parameters:
3181592Srgrimes**		str - null terminated character array.
3191592Srgrimes**
3201592Srgrimes**	Returns:
3211592Srgrimes**		Ptr to new character array or NULL if we ran out of memory.
3221592Srgrimes**
3231592Srgrimes**	Side Effects:
3241592Srgrimes**		- Memory will be malloc'd for the new character array.
3251592Srgrimes**		- If malloc() fails, a log message will be generated.
3261592Srgrimes*/
3271592Srgrimeschar *
32890377SimpNewStr(char *str)
3291592Srgrimes{
3301592Srgrimes	char *stmp;
3311592Srgrimes
3321592Srgrimes	if ((stmp = (char *)malloc((unsigned) (strlen(str)+1))) == NULL) {
3331592Srgrimes		syslog(LOG_ERR, "NewStr: out of memory (%s)", str);
3341592Srgrimes		return(NULL);
3351592Srgrimes	}
3361592Srgrimes
3371592Srgrimes	(void) strcpy(stmp, str);
3381592Srgrimes	return(stmp);
3391592Srgrimes}
3401592Srgrimes
3411592Srgrimes/*
3421592Srgrimes**  To save time, NewConn and FreeConn maintain a cache of one RMPCONN
3431592Srgrimes**  in `LastFree' (defined below).
3441592Srgrimes*/
3451592Srgrimes
3461592Srgrimesstatic RMPCONN *LastFree = NULL;
3471592Srgrimes
3481592Srgrimes/*
3491592Srgrimes**  NewConn -- allocate memory for a new RMPCONN connection.
3501592Srgrimes**
3511592Srgrimes**	Parameters:
3521592Srgrimes**		rconn - initialization template for new connection.
3531592Srgrimes**
3541592Srgrimes**	Returns:
3551592Srgrimes**		Ptr to new RMPCONN or NULL if we ran out of memory.
3561592Srgrimes**
3571592Srgrimes**	Side Effects:
3581592Srgrimes**		- Memory may be malloc'd for the new RMPCONN (if not cached).
3591592Srgrimes**		- If malloc() fails, a log message will be generated.
3601592Srgrimes*/
3611592SrgrimesRMPCONN *
36290377SimpNewConn(RMPCONN *rconn)
3631592Srgrimes{
3641592Srgrimes	RMPCONN *rtmp;
3651592Srgrimes
3661592Srgrimes	if (LastFree == NULL) {		/* nothing cached; make a new one */
3671592Srgrimes		if ((rtmp = (RMPCONN *) malloc(sizeof(RMPCONN))) == NULL) {
3681592Srgrimes			syslog(LOG_ERR, "NewConn: out of memory (%s)",
3691592Srgrimes			       EnetStr(rconn));
3701592Srgrimes			return(NULL);
3711592Srgrimes		}
3721592Srgrimes	} else {			/* use the cached RMPCONN */
3731592Srgrimes		rtmp = LastFree;
3741592Srgrimes		LastFree = NULL;
3751592Srgrimes	}
3761592Srgrimes
3771592Srgrimes	/*
3781592Srgrimes	 *  Copy template into `rtmp', init file descriptor to `-1' and
3791592Srgrimes	 *  set ptr to next elem NULL.
3801592Srgrimes	 */
38127079Ssteve	memmove((char *)rtmp, (char *)rconn, sizeof(RMPCONN));
3821592Srgrimes	rtmp->bootfd = -1;
3831592Srgrimes	rtmp->next = NULL;
3841592Srgrimes
3851592Srgrimes	return(rtmp);
3861592Srgrimes}
3871592Srgrimes
3881592Srgrimes/*
3891592Srgrimes**  FreeConn -- Free memory associated with an RMPCONN connection.
3901592Srgrimes**
3911592Srgrimes**	Parameters:
3921592Srgrimes**		rtmp - ptr to RMPCONN to be free'd.
3931592Srgrimes**
3941592Srgrimes**	Returns:
3951592Srgrimes**		Nothing.
3961592Srgrimes**
3971592Srgrimes**	Side Effects:
3981592Srgrimes**		- Memory associated with `rtmp' may be free'd (or cached).
3991592Srgrimes**		- File desc associated with `rtmp->bootfd' will be closed.
4001592Srgrimes*/
4011592Srgrimesvoid
40290377SimpFreeConn(RMPCONN *rtmp)
4031592Srgrimes{
4041592Srgrimes	/*
4051592Srgrimes	 *  If the file descriptor is in use, close the file.
4061592Srgrimes	 */
4071592Srgrimes	if (rtmp->bootfd >= 0) {
4081592Srgrimes		(void) close(rtmp->bootfd);
4091592Srgrimes		rtmp->bootfd = -1;
4101592Srgrimes	}
4111592Srgrimes
4121592Srgrimes	if (LastFree == NULL)		/* cache for next time */
4131592Srgrimes		rtmp = LastFree;
4141592Srgrimes	else				/* already one cached; free this one */
4151592Srgrimes		free((char *)rtmp);
4161592Srgrimes}
4171592Srgrimes
4181592Srgrimes/*
4191592Srgrimes**  FreeConns -- free linked list of RMPCONN connections.
4201592Srgrimes**
4211592Srgrimes**	Parameters:
4221592Srgrimes**		None.
4231592Srgrimes**
4241592Srgrimes**	Returns:
4251592Srgrimes**		Nothing.
4261592Srgrimes**
4271592Srgrimes**	Side Effects:
4281592Srgrimes**		- All malloc'd memory associated with the linked list of
4291592Srgrimes**		  connections will be free'd; `RmpConns' will be set to NULL.
4301592Srgrimes**		- If LastFree is != NULL, it too will be free'd & NULL'd.
4311592Srgrimes**
4321592Srgrimes**	Warnings:
4331592Srgrimes**		- This routine must be called with SIGHUP blocked.
4341592Srgrimes*/
4351592Srgrimesvoid
43690377SimpFreeConns(void)
4371592Srgrimes{
43827079Ssteve	RMPCONN *rtmp;
4391592Srgrimes
4401592Srgrimes	while (RmpConns != NULL) {
4411592Srgrimes		rtmp = RmpConns;
4421592Srgrimes		RmpConns = RmpConns->next;
4431592Srgrimes		FreeConn(rtmp);
4441592Srgrimes	}
4451592Srgrimes
4461592Srgrimes	if (LastFree != NULL) {
4471592Srgrimes		free((char *)LastFree);
4481592Srgrimes		LastFree = NULL;
4491592Srgrimes	}
4501592Srgrimes}
4511592Srgrimes
4521592Srgrimes/*
4531592Srgrimes**  AddConn -- Add a connection to the linked list of connections.
4541592Srgrimes**
4551592Srgrimes**	Parameters:
4561592Srgrimes**		rconn - connection to be added.
4571592Srgrimes**
4581592Srgrimes**	Returns:
4591592Srgrimes**		Nothing.
4601592Srgrimes**
4611592Srgrimes**	Side Effects:
4621592Srgrimes**		- RmpConn will point to new connection.
4631592Srgrimes**
4641592Srgrimes**	Warnings:
4651592Srgrimes**		- This routine must be called with SIGHUP blocked.
4661592Srgrimes*/
4671592Srgrimesvoid
46890377SimpAddConn(RMPCONN *rconn)
4691592Srgrimes{
4701592Srgrimes	if (RmpConns != NULL)
4711592Srgrimes		rconn->next = RmpConns;
4721592Srgrimes	RmpConns = rconn;
4731592Srgrimes}
4741592Srgrimes
4751592Srgrimes/*
4761592Srgrimes**  FindConn -- Find a connection in the linked list of connections.
4771592Srgrimes**
4781592Srgrimes**	We use the RMP (Ethernet) address as the basis for determining
4791592Srgrimes**	if this is the same connection.  According to the Remote Maint
4801592Srgrimes**	Protocol, we can only have one connection with any machine.
4811592Srgrimes**
4821592Srgrimes**	Parameters:
4831592Srgrimes**		rconn - connection to be found.
4841592Srgrimes**
4851592Srgrimes**	Returns:
4861592Srgrimes**		Matching connection from linked list or NULL if not found.
4871592Srgrimes**
4881592Srgrimes**	Side Effects:
4891592Srgrimes**		None.
4901592Srgrimes**
4911592Srgrimes**	Warnings:
4921592Srgrimes**		- This routine must be called with SIGHUP blocked.
4931592Srgrimes*/
4941592SrgrimesRMPCONN *
49590377SimpFindConn(RMPCONN *rconn)
4961592Srgrimes{
49727079Ssteve	RMPCONN *rtmp;
4981592Srgrimes
4991592Srgrimes	for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
5001592Srgrimes		if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0],
5011592Srgrimes		         (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0)
5021592Srgrimes			break;
5031592Srgrimes
5041592Srgrimes	return(rtmp);
5051592Srgrimes}
5061592Srgrimes
5071592Srgrimes/*
5081592Srgrimes**  RemoveConn -- Remove a connection from the linked list of connections.
5091592Srgrimes**
5101592Srgrimes**	Parameters:
5111592Srgrimes**		rconn - connection to be removed.
5121592Srgrimes**
5131592Srgrimes**	Returns:
5141592Srgrimes**		Nothing.
5151592Srgrimes**
5161592Srgrimes**	Side Effects:
5171592Srgrimes**		- If found, an RMPCONN will cease to exist and it will
5181592Srgrimes**		  be removed from the linked list.
5191592Srgrimes**
5201592Srgrimes**	Warnings:
5211592Srgrimes**		- This routine must be called with SIGHUP blocked.
5221592Srgrimes*/
5231592Srgrimesvoid
52490377SimpRemoveConn(RMPCONN *rconn)
5251592Srgrimes{
52627079Ssteve	RMPCONN *thisrconn, *lastrconn;
5271592Srgrimes
5281592Srgrimes	if (RmpConns == rconn) {		/* easy case */
5291592Srgrimes		RmpConns = RmpConns->next;
5301592Srgrimes		FreeConn(rconn);
5311592Srgrimes	} else {				/* must traverse linked list */
5321592Srgrimes		lastrconn = RmpConns;			/* set back ptr */
5331592Srgrimes		thisrconn = lastrconn->next;		/* set current ptr */
5341592Srgrimes		while (thisrconn != NULL) {
5351592Srgrimes			if (rconn == thisrconn) {		/* found it */
5361592Srgrimes				lastrconn->next = thisrconn->next;
5371592Srgrimes				FreeConn(thisrconn);
5381592Srgrimes				break;
5391592Srgrimes			}
5401592Srgrimes			lastrconn = thisrconn;
5411592Srgrimes			thisrconn = thisrconn->next;
5421592Srgrimes		}
5431592Srgrimes	}
5441592Srgrimes}
545