1*97f0f8b4Sguenther /* $OpenBSD: utils.c,v 1.15 2016/05/29 02:19:02 guenther Exp $ */ 2540eaef7Sderaadt /* $NetBSD: utils.c,v 1.5.2.1 1995/11/14 08:45:46 thorpej Exp $ */ 3df930be7Sderaadt 4df930be7Sderaadt /* 5df930be7Sderaadt * Copyright (c) 1988, 1992 The University of Utah and the Center 6df930be7Sderaadt * for Software Science (CSS). 7df930be7Sderaadt * Copyright (c) 1992, 1993 8df930be7Sderaadt * The Regents of the University of California. All rights reserved. 9df930be7Sderaadt * 10df930be7Sderaadt * This code is derived from software contributed to Berkeley by 11df930be7Sderaadt * the Center for Software Science of the University of Utah Computer 12df930be7Sderaadt * Science Department. CSS requests users of this software to return 13df930be7Sderaadt * to css-dist@cs.utah.edu any improvements that they make and grant 14df930be7Sderaadt * CSS redistribution rights. 15df930be7Sderaadt * 16df930be7Sderaadt * Redistribution and use in source and binary forms, with or without 17df930be7Sderaadt * modification, are permitted provided that the following conditions 18df930be7Sderaadt * are met: 19df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright 20df930be7Sderaadt * notice, this list of conditions and the following disclaimer. 21df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 22df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the 23df930be7Sderaadt * documentation and/or other materials provided with the distribution. 2429295d1cSmillert * 3. Neither the name of the University nor the names of its contributors 25df930be7Sderaadt * may be used to endorse or promote products derived from this software 26df930be7Sderaadt * without specific prior written permission. 27df930be7Sderaadt * 28df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38df930be7Sderaadt * SUCH DAMAGE. 39df930be7Sderaadt * 40df930be7Sderaadt * from: @(#)utils.c 8.1 (Berkeley) 6/4/93 41df930be7Sderaadt * 42df930be7Sderaadt * From: Utah Hdr: utils.c 3.1 92/07/06 43df930be7Sderaadt * Author: Jeff Forys, University of Utah CSS 44df930be7Sderaadt */ 45df930be7Sderaadt 46df930be7Sderaadt #include <stdio.h> 47df930be7Sderaadt #include <stdlib.h> 48df930be7Sderaadt #include <string.h> 49df930be7Sderaadt #include <syslog.h> 50df930be7Sderaadt #include <time.h> 51df930be7Sderaadt #include <unistd.h> 52df930be7Sderaadt #include "defs.h" 53df930be7Sderaadt 54df930be7Sderaadt /* 55df930be7Sderaadt ** DispPkt -- Display the contents of an RMPCONN packet. 56df930be7Sderaadt ** 57df930be7Sderaadt ** Parameters: 58df930be7Sderaadt ** rconn - packet to be displayed. 59df930be7Sderaadt ** direct - direction packet is going (DIR_*). 60df930be7Sderaadt ** 61df930be7Sderaadt ** Returns: 62df930be7Sderaadt ** Nothing. 63df930be7Sderaadt ** 64df930be7Sderaadt ** Side Effects: 65df930be7Sderaadt ** None. 66df930be7Sderaadt */ 67df930be7Sderaadt void 6839883a76Sderaadt DispPkt(RMPCONN *rconn, int direct) 69df930be7Sderaadt { 7082ff3630Sguenther static const char BootFmt[] = 7182ff3630Sguenther "\t\tRetCode:%u SeqNo:%x SessID:%x Vers:%u"; 7282ff3630Sguenther static const char ReadFmt[] = 7382ff3630Sguenther "\t\tRetCode:%u Offset:%x SessID:%x\n"; 74df930be7Sderaadt struct tm *tmp; 750ac0d02eSmpech struct rmp_packet *rmp; 76*97f0f8b4Sguenther int i; 77df930be7Sderaadt u_int32_t t; 78d48c07c0Sderaadt time_t tim; 79df930be7Sderaadt 80df930be7Sderaadt /* display direction packet is going using '>>>' or '<<<' */ 81df930be7Sderaadt fputs((direct==DIR_RCVD)?"<<< ":(direct==DIR_SENT)?">>> ":"", DbgFp); 82df930be7Sderaadt 83df930be7Sderaadt /* display packet timestamp */ 84d48c07c0Sderaadt 85d48c07c0Sderaadt tim = rconn->tstamp.tv_sec; 86d48c07c0Sderaadt tmp = localtime(&tim); 87df930be7Sderaadt fprintf(DbgFp, "%02d:%02d:%02d.%06ld ", tmp->tm_hour, tmp->tm_min, 88df930be7Sderaadt tmp->tm_sec, rconn->tstamp.tv_usec); 89df930be7Sderaadt 90df930be7Sderaadt /* display src or dst addr and information about network interface */ 91df930be7Sderaadt fprintf(DbgFp, "Addr: %s Intf: %s\n", EnetStr(rconn), IntfName); 92df930be7Sderaadt 93df930be7Sderaadt rmp = &rconn->rmp; 94df930be7Sderaadt 95df930be7Sderaadt /* display IEEE 802.2 Logical Link Control header */ 96df930be7Sderaadt (void) fprintf(DbgFp, "\t802.2 LLC: DSAP:%x SSAP:%x CTRL:%x\n", 97df930be7Sderaadt rmp->hp_llc.dsap, rmp->hp_llc.ssap, ntohs(rmp->hp_llc.cntrl)); 98df930be7Sderaadt 99df930be7Sderaadt /* display HP extensions to 802.2 Logical Link Control header */ 100df930be7Sderaadt (void) fprintf(DbgFp, "\tHP Ext: DXSAP:%x SXSAP:%x\n", 101df930be7Sderaadt ntohs(rmp->hp_llc.dxsap), ntohs(rmp->hp_llc.sxsap)); 102df930be7Sderaadt 103df930be7Sderaadt /* 104df930be7Sderaadt * Display information about RMP packet using type field to 105df930be7Sderaadt * determine what kind of packet this is. 106df930be7Sderaadt */ 107df930be7Sderaadt switch (rmp->r_type) { 108df930be7Sderaadt case RMP_BOOT_REQ: /* boot request */ 109df930be7Sderaadt (void) fprintf(DbgFp, "\tBoot Request:"); 110df930be7Sderaadt GETWORD(rmp->r_brq.rmp_seqno, t); 111df930be7Sderaadt if (ntohs(rmp->r_brq.rmp_session) == RMP_PROBESID) { 112df930be7Sderaadt if (WORDZE(rmp->r_brq.rmp_seqno)) 113df930be7Sderaadt fputs(" (Send Server ID)", DbgFp); 114df930be7Sderaadt else 115df930be7Sderaadt fprintf(DbgFp," (Send Filename #%u)",t); 116df930be7Sderaadt } 117df930be7Sderaadt (void) fputc('\n', DbgFp); 118df930be7Sderaadt (void) fprintf(DbgFp, BootFmt, rmp->r_brq.rmp_retcode, 119df930be7Sderaadt t, ntohs(rmp->r_brq.rmp_session), 120df930be7Sderaadt ntohs(rmp->r_brq.rmp_version)); 121df930be7Sderaadt (void) fprintf(DbgFp, "\n\t\tMachine Type: "); 122df930be7Sderaadt for (i = 0; i < RMP_MACHLEN; i++) 123df930be7Sderaadt (void) fputc(rmp->r_brq.rmp_machtype[i], DbgFp); 124df930be7Sderaadt DspFlnm(rmp->r_brq.rmp_flnmsize, &rmp->r_brq.rmp_flnm); 125df930be7Sderaadt break; 126df930be7Sderaadt case RMP_BOOT_REPL: /* boot reply */ 127df930be7Sderaadt fprintf(DbgFp, "\tBoot Reply:\n"); 128df930be7Sderaadt GETWORD(rmp->r_brpl.rmp_seqno, t); 129df930be7Sderaadt (void) fprintf(DbgFp, BootFmt, rmp->r_brpl.rmp_retcode, 130df930be7Sderaadt t, ntohs(rmp->r_brpl.rmp_session), 131df930be7Sderaadt ntohs(rmp->r_brpl.rmp_version)); 132df930be7Sderaadt DspFlnm(rmp->r_brpl.rmp_flnmsize,&rmp->r_brpl.rmp_flnm); 133df930be7Sderaadt break; 134df930be7Sderaadt case RMP_READ_REQ: /* read request */ 135df930be7Sderaadt (void) fprintf(DbgFp, "\tRead Request:\n"); 136df930be7Sderaadt GETWORD(rmp->r_rrq.rmp_offset, t); 137df930be7Sderaadt (void) fprintf(DbgFp, ReadFmt, rmp->r_rrq.rmp_retcode, 138df930be7Sderaadt t, ntohs(rmp->r_rrq.rmp_session)); 139df930be7Sderaadt (void) fprintf(DbgFp, "\t\tNoOfBytes: %u\n", 140df930be7Sderaadt ntohs(rmp->r_rrq.rmp_size)); 141df930be7Sderaadt break; 142df930be7Sderaadt case RMP_READ_REPL: /* read reply */ 143df930be7Sderaadt (void) fprintf(DbgFp, "\tRead Reply:\n"); 144df930be7Sderaadt GETWORD(rmp->r_rrpl.rmp_offset, t); 145df930be7Sderaadt (void) fprintf(DbgFp, ReadFmt, rmp->r_rrpl.rmp_retcode, 146df930be7Sderaadt t, ntohs(rmp->r_rrpl.rmp_session)); 147e38ed7b7Sderaadt (void) fprintf(DbgFp, "\t\tNoOfBytesSent: %ld\n", 148e38ed7b7Sderaadt (long)(rconn->rmplen - RMPREADSIZE(0))); 149df930be7Sderaadt break; 150df930be7Sderaadt case RMP_BOOT_DONE: /* boot complete */ 151df930be7Sderaadt (void) fprintf(DbgFp, "\tBoot Complete:\n"); 152df930be7Sderaadt (void) fprintf(DbgFp, "\t\tRetCode:%u SessID:%x\n", 153df930be7Sderaadt rmp->r_done.rmp_retcode, 154df930be7Sderaadt ntohs(rmp->r_done.rmp_session)); 155df930be7Sderaadt break; 156df930be7Sderaadt default: /* ??? */ 157df930be7Sderaadt (void) fprintf(DbgFp, "\tUnknown Type:(%d)\n", 158df930be7Sderaadt rmp->r_type); 15939883a76Sderaadt break; 160df930be7Sderaadt } 161df930be7Sderaadt (void) fputc('\n', DbgFp); 162df930be7Sderaadt (void) fflush(DbgFp); 163df930be7Sderaadt } 164df930be7Sderaadt 165df930be7Sderaadt 166df930be7Sderaadt /* 167df930be7Sderaadt ** GetEtherAddr -- convert an RMP (Ethernet) address into a string. 168df930be7Sderaadt ** 169df930be7Sderaadt ** An RMP BOOT packet has been received. Look at the type field 170df930be7Sderaadt ** and process Boot Requests, Read Requests, and Boot Complete 171df930be7Sderaadt ** packets. Any other type will be dropped with a warning msg. 172df930be7Sderaadt ** 173df930be7Sderaadt ** Parameters: 174df930be7Sderaadt ** addr - array of RMP_ADDRLEN bytes. 175df930be7Sderaadt ** 176df930be7Sderaadt ** Returns: 177df930be7Sderaadt ** Pointer to static string representation of `addr'. 178df930be7Sderaadt ** 179df930be7Sderaadt ** Side Effects: 180df930be7Sderaadt ** None. 181df930be7Sderaadt ** 182df930be7Sderaadt ** Warnings: 183df930be7Sderaadt ** - The return value points to a static buffer; it must 184df930be7Sderaadt ** be copied if it's to be saved. 185df930be7Sderaadt */ 186df930be7Sderaadt char * 18739883a76Sderaadt GetEtherAddr(u_int8_t *addr) 188df930be7Sderaadt { 189df930be7Sderaadt static char Hex[] = "0123456789abcdef"; 190df930be7Sderaadt static char etherstr[RMP_ADDRLEN*3]; 1910ac0d02eSmpech int i; 1920ac0d02eSmpech char *cp; 193df930be7Sderaadt 194df930be7Sderaadt /* 195df930be7Sderaadt * For each byte in `addr', convert it to "<hexchar><hexchar>:". 196df930be7Sderaadt * The last byte does not get a trailing `:' appended. 197df930be7Sderaadt */ 198df930be7Sderaadt i = 0; 199df930be7Sderaadt cp = etherstr; 200df930be7Sderaadt for(;;) { 201df930be7Sderaadt *cp++ = Hex[*addr >> 4 & 0xf]; 202df930be7Sderaadt *cp++ = Hex[*addr++ & 0xf]; 203df930be7Sderaadt if (++i == RMP_ADDRLEN) 204df930be7Sderaadt break; 205df930be7Sderaadt *cp++ = ':'; 206df930be7Sderaadt } 207df930be7Sderaadt *cp = '\0'; 208df930be7Sderaadt 209df930be7Sderaadt return(etherstr); 210df930be7Sderaadt } 211df930be7Sderaadt 212df930be7Sderaadt 213df930be7Sderaadt /* 214df930be7Sderaadt ** DispFlnm -- Print a string of bytes to DbgFp (often, a file name). 215df930be7Sderaadt ** 216df930be7Sderaadt ** Parameters: 217df930be7Sderaadt ** size - number of bytes to print. 218df930be7Sderaadt ** flnm - address of first byte. 219df930be7Sderaadt ** 220df930be7Sderaadt ** Returns: 221df930be7Sderaadt ** Nothing. 222df930be7Sderaadt ** 223df930be7Sderaadt ** Side Effects: 224df930be7Sderaadt ** - Characters are sent to `DbgFp'. 225df930be7Sderaadt */ 226df930be7Sderaadt void 22739883a76Sderaadt DspFlnm(u_int size, char *flnm) 228df930be7Sderaadt { 2290ac0d02eSmpech int i; 230df930be7Sderaadt 231df930be7Sderaadt (void) fprintf(DbgFp, "\n\t\tFile Name (%u): <", size); 232df930be7Sderaadt for (i = 0; i < size; i++) 233df930be7Sderaadt (void) fputc(*flnm++, DbgFp); 234df930be7Sderaadt (void) fputs(">\n", DbgFp); 235df930be7Sderaadt } 236df930be7Sderaadt 237df930be7Sderaadt 238df930be7Sderaadt /* 239df930be7Sderaadt ** NewClient -- allocate memory for a new CLIENT. 240df930be7Sderaadt ** 241df930be7Sderaadt ** Parameters: 242df930be7Sderaadt ** addr - RMP (Ethernet) address of new client. 243df930be7Sderaadt ** 244df930be7Sderaadt ** Returns: 245df930be7Sderaadt ** Ptr to new CLIENT or NULL if we ran out of memory. 246df930be7Sderaadt ** 247df930be7Sderaadt ** Side Effects: 248df930be7Sderaadt ** - Memory will be malloc'd for the new CLIENT. 249df930be7Sderaadt ** - If malloc() fails, a log message will be generated. 250df930be7Sderaadt */ 251df930be7Sderaadt CLIENT * 25239883a76Sderaadt NewClient(u_int8_t *addr) 253df930be7Sderaadt { 254df930be7Sderaadt CLIENT *ctmp; 255df930be7Sderaadt 25635de856eSderaadt if ((ctmp = malloc(sizeof(CLIENT))) == NULL) { 257df930be7Sderaadt syslog(LOG_ERR, "NewClient: out of memory (%s)", 258df930be7Sderaadt GetEtherAddr(addr)); 259df930be7Sderaadt return(NULL); 260df930be7Sderaadt } 261df930be7Sderaadt 262df930be7Sderaadt bzero(ctmp, sizeof(CLIENT)); 263df930be7Sderaadt bcopy(addr, &ctmp->addr[0], RMP_ADDRLEN); 264df930be7Sderaadt return(ctmp); 265df930be7Sderaadt } 266df930be7Sderaadt 267df930be7Sderaadt /* 268df930be7Sderaadt ** FreeClient -- free linked list of Clients. 269df930be7Sderaadt ** 270df930be7Sderaadt ** Parameters: 271df930be7Sderaadt ** None. 272df930be7Sderaadt ** 273df930be7Sderaadt ** Returns: 274df930be7Sderaadt ** Nothing. 275df930be7Sderaadt ** 276df930be7Sderaadt ** Side Effects: 277df930be7Sderaadt ** - All malloc'd memory associated with the linked list of 278df930be7Sderaadt ** CLIENTS will be free'd; `Clients' will be set to NULL. 279df930be7Sderaadt ** 280df930be7Sderaadt ** Warnings: 281df930be7Sderaadt ** - This routine must be called with SIGHUP blocked. 282df930be7Sderaadt */ 283df930be7Sderaadt void 28439883a76Sderaadt FreeClients(void) 285df930be7Sderaadt { 2860ac0d02eSmpech CLIENT *ctmp; 287df930be7Sderaadt 288df930be7Sderaadt while (Clients != NULL) { 289df930be7Sderaadt ctmp = Clients; 290df930be7Sderaadt Clients = Clients->next; 291df930be7Sderaadt FreeClient(ctmp); 292df930be7Sderaadt } 293df930be7Sderaadt } 294df930be7Sderaadt 295df930be7Sderaadt /* 296df930be7Sderaadt ** NewStr -- allocate memory for a character array. 297df930be7Sderaadt ** 298df930be7Sderaadt ** Parameters: 299df930be7Sderaadt ** str - null terminated character array. 300df930be7Sderaadt ** 301df930be7Sderaadt ** Returns: 302df930be7Sderaadt ** Ptr to new character array or NULL if we ran out of memory. 303df930be7Sderaadt ** 304df930be7Sderaadt ** Side Effects: 305df930be7Sderaadt ** - Memory will be malloc'd for the new character array. 306df930be7Sderaadt ** - If malloc() fails, a log message will be generated. 307df930be7Sderaadt */ 308df930be7Sderaadt char * 30939883a76Sderaadt NewStr(char *str) 310df930be7Sderaadt { 311df930be7Sderaadt char *stmp; 312df930be7Sderaadt 3132484043fSderaadt stmp = strdup(str); 3142484043fSderaadt if (stmp == NULL) { 315df930be7Sderaadt syslog(LOG_ERR, "NewStr: out of memory (%s)", str); 316df930be7Sderaadt return(NULL); 317df930be7Sderaadt } 318df930be7Sderaadt return(stmp); 319df930be7Sderaadt } 320df930be7Sderaadt 321df930be7Sderaadt /* 322df930be7Sderaadt ** To save time, NewConn and FreeConn maintain a cache of one RMPCONN 323df930be7Sderaadt ** in `LastFree' (defined below). 324df930be7Sderaadt */ 325df930be7Sderaadt 326df930be7Sderaadt static RMPCONN *LastFree = NULL; 327df930be7Sderaadt 328df930be7Sderaadt /* 329df930be7Sderaadt ** NewConn -- allocate memory for a new RMPCONN connection. 330df930be7Sderaadt ** 331df930be7Sderaadt ** Parameters: 332df930be7Sderaadt ** rconn - initialization template for new connection. 333df930be7Sderaadt ** 334df930be7Sderaadt ** Returns: 335df930be7Sderaadt ** Ptr to new RMPCONN or NULL if we ran out of memory. 336df930be7Sderaadt ** 337df930be7Sderaadt ** Side Effects: 338df930be7Sderaadt ** - Memory may be malloc'd for the new RMPCONN (if not cached). 339df930be7Sderaadt ** - If malloc() fails, a log message will be generated. 340df930be7Sderaadt */ 341df930be7Sderaadt RMPCONN * 34239883a76Sderaadt NewConn(RMPCONN *rconn) 343df930be7Sderaadt { 344df930be7Sderaadt RMPCONN *rtmp; 345df930be7Sderaadt 346df930be7Sderaadt if (LastFree == NULL) { /* nothing cached; make a new one */ 34735de856eSderaadt if ((rtmp = malloc(sizeof(RMPCONN))) == NULL) { 348df930be7Sderaadt syslog(LOG_ERR, "NewConn: out of memory (%s)", 349df930be7Sderaadt EnetStr(rconn)); 350df930be7Sderaadt return(NULL); 351df930be7Sderaadt } 352df930be7Sderaadt } else { /* use the cached RMPCONN */ 353df930be7Sderaadt rtmp = LastFree; 354df930be7Sderaadt LastFree = NULL; 355df930be7Sderaadt } 356df930be7Sderaadt 357df930be7Sderaadt /* 358df930be7Sderaadt * Copy template into `rtmp', init file descriptor to `-1' and 359df930be7Sderaadt * set ptr to next elem NULL. 360df930be7Sderaadt */ 361df930be7Sderaadt bcopy((char *)rconn, (char *)rtmp, sizeof(RMPCONN)); 362df930be7Sderaadt rtmp->bootfd = -1; 363df930be7Sderaadt rtmp->next = NULL; 364df930be7Sderaadt 365df930be7Sderaadt return(rtmp); 366df930be7Sderaadt } 367df930be7Sderaadt 368df930be7Sderaadt /* 369df930be7Sderaadt ** FreeConn -- Free memory associated with an RMPCONN connection. 370df930be7Sderaadt ** 371df930be7Sderaadt ** Parameters: 372df930be7Sderaadt ** rtmp - ptr to RMPCONN to be free'd. 373df930be7Sderaadt ** 374df930be7Sderaadt ** Returns: 375df930be7Sderaadt ** Nothing. 376df930be7Sderaadt ** 377df930be7Sderaadt ** Side Effects: 378df930be7Sderaadt ** - Memory associated with `rtmp' may be free'd (or cached). 379df930be7Sderaadt ** - File desc associated with `rtmp->bootfd' will be closed. 380df930be7Sderaadt */ 381df930be7Sderaadt void 38239883a76Sderaadt FreeConn(RMPCONN *rtmp) 383df930be7Sderaadt { 384df930be7Sderaadt /* 385df930be7Sderaadt * If the file descriptor is in use, close the file. 386df930be7Sderaadt */ 387df930be7Sderaadt if (rtmp->bootfd >= 0) { 388df930be7Sderaadt (void) close(rtmp->bootfd); 389df930be7Sderaadt rtmp->bootfd = -1; 390df930be7Sderaadt } 391df930be7Sderaadt 392df930be7Sderaadt if (LastFree == NULL) /* cache for next time */ 393df930be7Sderaadt rtmp = LastFree; 394df930be7Sderaadt else /* already one cached; free this one */ 395df930be7Sderaadt free((char *)rtmp); 396df930be7Sderaadt } 397df930be7Sderaadt 398df930be7Sderaadt /* 399df930be7Sderaadt ** FreeConns -- free linked list of RMPCONN connections. 400df930be7Sderaadt ** 401df930be7Sderaadt ** Parameters: 402df930be7Sderaadt ** None. 403df930be7Sderaadt ** 404df930be7Sderaadt ** Returns: 405df930be7Sderaadt ** Nothing. 406df930be7Sderaadt ** 407df930be7Sderaadt ** Side Effects: 408df930be7Sderaadt ** - All malloc'd memory associated with the linked list of 409df930be7Sderaadt ** connections will be free'd; `RmpConns' will be set to NULL. 410df930be7Sderaadt ** - If LastFree is != NULL, it too will be free'd & NULL'd. 411df930be7Sderaadt ** 412df930be7Sderaadt ** Warnings: 413df930be7Sderaadt ** - This routine must be called with SIGHUP blocked. 414df930be7Sderaadt */ 415df930be7Sderaadt void 41639883a76Sderaadt FreeConns(void) 417df930be7Sderaadt { 4180ac0d02eSmpech RMPCONN *rtmp; 419df930be7Sderaadt 420df930be7Sderaadt while (RmpConns != NULL) { 421df930be7Sderaadt rtmp = RmpConns; 422df930be7Sderaadt RmpConns = RmpConns->next; 423df930be7Sderaadt FreeConn(rtmp); 424df930be7Sderaadt } 425df930be7Sderaadt 426df930be7Sderaadt if (LastFree != NULL) { 427df930be7Sderaadt free((char *)LastFree); 428df930be7Sderaadt LastFree = NULL; 429df930be7Sderaadt } 430df930be7Sderaadt } 431df930be7Sderaadt 432df930be7Sderaadt /* 433df930be7Sderaadt ** AddConn -- Add a connection to the linked list of connections. 434df930be7Sderaadt ** 435df930be7Sderaadt ** Parameters: 436df930be7Sderaadt ** rconn - connection to be added. 437df930be7Sderaadt ** 438df930be7Sderaadt ** Returns: 439df930be7Sderaadt ** Nothing. 440df930be7Sderaadt ** 441df930be7Sderaadt ** Side Effects: 442df930be7Sderaadt ** - RmpConn will point to new connection. 443df930be7Sderaadt ** 444df930be7Sderaadt ** Warnings: 445df930be7Sderaadt ** - This routine must be called with SIGHUP blocked. 446df930be7Sderaadt */ 447df930be7Sderaadt void 44839883a76Sderaadt AddConn(RMPCONN *rconn) 449df930be7Sderaadt { 450df930be7Sderaadt if (RmpConns != NULL) 451df930be7Sderaadt rconn->next = RmpConns; 452df930be7Sderaadt RmpConns = rconn; 453df930be7Sderaadt } 454df930be7Sderaadt 455df930be7Sderaadt /* 456df930be7Sderaadt ** FindConn -- Find a connection in the linked list of connections. 457df930be7Sderaadt ** 458df930be7Sderaadt ** We use the RMP (Ethernet) address as the basis for determining 459df930be7Sderaadt ** if this is the same connection. According to the Remote Maint 460df930be7Sderaadt ** Protocol, we can only have one connection with any machine. 461df930be7Sderaadt ** 462df930be7Sderaadt ** Parameters: 463df930be7Sderaadt ** rconn - connection to be found. 464df930be7Sderaadt ** 465df930be7Sderaadt ** Returns: 466df930be7Sderaadt ** Matching connection from linked list or NULL if not found. 467df930be7Sderaadt ** 468df930be7Sderaadt ** Side Effects: 469df930be7Sderaadt ** None. 470df930be7Sderaadt ** 471df930be7Sderaadt ** Warnings: 472df930be7Sderaadt ** - This routine must be called with SIGHUP blocked. 473df930be7Sderaadt */ 474df930be7Sderaadt RMPCONN * 47539883a76Sderaadt FindConn(RMPCONN *rconn) 476df930be7Sderaadt { 4770ac0d02eSmpech RMPCONN *rtmp; 478df930be7Sderaadt 479df930be7Sderaadt for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next) 480df930be7Sderaadt if (bcmp((char *)&rconn->rmp.hp_hdr.saddr[0], 481df930be7Sderaadt (char *)&rtmp->rmp.hp_hdr.saddr[0], RMP_ADDRLEN) == 0) 482df930be7Sderaadt break; 483df930be7Sderaadt 484df930be7Sderaadt return(rtmp); 485df930be7Sderaadt } 486df930be7Sderaadt 487df930be7Sderaadt /* 488df930be7Sderaadt ** RemoveConn -- Remove a connection from the linked list of connections. 489df930be7Sderaadt ** 490df930be7Sderaadt ** Parameters: 491df930be7Sderaadt ** rconn - connection to be removed. 492df930be7Sderaadt ** 493df930be7Sderaadt ** Returns: 494df930be7Sderaadt ** Nothing. 495df930be7Sderaadt ** 496df930be7Sderaadt ** Side Effects: 497df930be7Sderaadt ** - If found, an RMPCONN will cease to exist and it will 498df930be7Sderaadt ** be removed from the linked list. 499df930be7Sderaadt ** 500df930be7Sderaadt ** Warnings: 501df930be7Sderaadt ** - This routine must be called with SIGHUP blocked. 502df930be7Sderaadt */ 503df930be7Sderaadt void 50439883a76Sderaadt RemoveConn(RMPCONN *rconn) 505df930be7Sderaadt { 5060ac0d02eSmpech RMPCONN *thisrconn, *lastrconn; 507df930be7Sderaadt 508df930be7Sderaadt if (RmpConns == rconn) { /* easy case */ 509df930be7Sderaadt RmpConns = RmpConns->next; 510df930be7Sderaadt FreeConn(rconn); 511df930be7Sderaadt } else { /* must traverse linked list */ 512df930be7Sderaadt lastrconn = RmpConns; /* set back ptr */ 513df930be7Sderaadt thisrconn = lastrconn->next; /* set current ptr */ 514df930be7Sderaadt while (thisrconn != NULL) { 515df930be7Sderaadt if (rconn == thisrconn) { /* found it */ 516df930be7Sderaadt lastrconn->next = thisrconn->next; 517df930be7Sderaadt FreeConn(thisrconn); 518df930be7Sderaadt break; 519df930be7Sderaadt } 520df930be7Sderaadt lastrconn = thisrconn; 521df930be7Sderaadt thisrconn = thisrconn->next; 522df930be7Sderaadt } 523df930be7Sderaadt } 524df930be7Sderaadt } 525