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