1119418Sobrien/*	$NetBSD: readmsg.c,v 1.23 2017/08/11 16:47:42 ginsbach Exp $	*/
251694Sroger
351694Sroger/*-
451694Sroger * Copyright (c) 1985, 1993 The Regents of the University of California.
551694Sroger * All rights reserved.
651694Sroger *
751694Sroger * Redistribution and use in source and binary forms, with or without
851694Sroger * modification, are permitted provided that the following conditions
951694Sroger * are met:
1051694Sroger * 1. Redistributions of source code must retain the above copyright
1151694Sroger *    notice, this list of conditions and the following disclaimer.
1251694Sroger * 2. Redistributions in binary form must reproduce the above copyright
1351694Sroger *    notice, this list of conditions and the following disclaimer in the
1451694Sroger *    documentation and/or other materials provided with the distribution.
1551694Sroger * 3. Neither the name of the University nor the names of its contributors
1651694Sroger *    may be used to endorse or promote products derived from this software
1751694Sroger *    without specific prior written permission.
1851694Sroger *
1951694Sroger * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2051694Sroger * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2151694Sroger * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2251694Sroger * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2351694Sroger * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2451694Sroger * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2551694Sroger * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2651694Sroger * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2751694Sroger * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2851694Sroger * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2951694Sroger * SUCH DAMAGE.
3051694Sroger */
3151694Sroger
3251694Sroger#include <sys/cdefs.h>
3351694Sroger#ifndef lint
34119418Sobrien#if 0
35119418Sobrienstatic char sccsid[] = "@(#)readmsg.c	8.1 (Berkeley) 6/6/93";
3651694Sroger#else
37119418Sobrien__RCSID("$NetBSD: readmsg.c,v 1.23 2017/08/11 16:47:42 ginsbach Exp $");
38119418Sobrien#endif
39119418Sobrien#endif /* not lint */
40119418Sobrien
41119418Sobrien#include "globals.h"
42119418Sobrien
43119418Sobrienextern const char * const tsptype[];
44119418Sobrien
45119418Sobrien/*
46119418Sobrien * LOOKAT checks if the message is of the requested type and comes from
47119418Sobrien * the right machine, returning 1 in case of affirmative answer
48119418Sobrien */
4959014Sroger#define LOOKAT(msg, mtype, mfrom, netp, froms) \
5051694Sroger	(((mtype) == TSP_ANY || (mtype) == (msg).tsp_type) &&		\
5151694Sroger	 ((mfrom) == 0 || !strcmp((mfrom), (msg).tsp_name)) &&		\
5251694Sroger	 ((netp) == 0 || 						\
5351694Sroger	  ((netp)->mask & (froms).sin_addr.s_addr) == (netp)->net.s_addr))
5462214Sroger
5562214Srogerstruct timeval rtime, rwait, rtout;
5662214Srogerstruct tsp msgin;
5762214Srogerstatic struct tsplist {
5862214Sroger	struct tsp info;
5962214Sroger	struct timeval when;
6051694Sroger	struct sockaddr_in addr;
6151694Sroger	struct tsplist *p;
6251694Sroger} msgslist;
6351694Srogerstruct sockaddr_in from;
6451694Srogerstruct netinfo *fromnet;
6551694Srogerstruct timeval from_when;
6651694Sroger
6751694Sroger/*
6870834Swollman * `readmsg' returns message `type' sent by `machfrom' if it finds it
6970834Swollman * either in the receive queue, or in a linked list of previously received
7070834Swollman * messages that it maintains.
7151694Sroger * Otherwise it waits to see if the appropriate message arrives within
7270834Swollman * `intvl' seconds. If not, it returns NULL.
7351694Sroger */
7451694Sroger
7551694Srogerstruct tsp *
7651694Srogerreadmsg(int type, char *machfrom, struct timeval *intvl,
7751694Sroger	struct netinfo *netfrom)
7851694Sroger{
7951694Sroger	socklen_t length;
8093023Snsouch	struct pollfd set[1];
8151694Sroger	static struct tsplist *head = &msgslist;
8251694Sroger	static struct tsplist *tail = &msgslist;
8351694Sroger	static int msgcnt = 0;
8459014Sroger	struct tsplist *prev;
8559014Sroger	struct netinfo *ntp;
8659014Sroger	struct tsplist *ptr;
8759014Sroger	ssize_t n;
8859014Sroger
8959014Sroger	if (trace) {
9051694Sroger		fprintf(fd, "readmsg: looking for %s from %s, %s\n",
9151694Sroger			tsptype[type], machfrom == NULL ? "ANY" : machfrom,
9251694Sroger			netfrom == NULL ? "ANYNET" : inet_ntoa(netfrom->net));
9351694Sroger		if (head->p != 0) {
9451694Sroger			length = 1;
9567306Sroger			for (ptr = head->p; ptr != 0; ptr = ptr->p) {
9667306Sroger				/* do not repeat the hundreds of messages */
9751694Sroger				if (++length > 3) {
9851694Sroger					if (ptr == tail) {
99119277Simp						fprintf(fd,"\t ...%d skipped\n",
100119277Simp							length);
101119277Simp					} else {
102119277Simp						continue;
10351694Sroger					}
10451694Sroger				}
10551694Sroger				fprintf(fd, length > 1 ? "\t" : "queue:\t");
10651694Sroger				print(&ptr->info, &ptr->addr);
10751694Sroger			}
10851694Sroger		}
10959014Sroger	}
110118819Salex
111118819Salex	ptr = head->p;
112118819Salex	prev = head;
113118819Salex
114118819Salex	/*
115118819Salex	 * Look for the requested message scanning through the
11651694Sroger	 * linked list. If found, return it and free the space
11751694Sroger	 */
11851694Sroger
11951694Sroger	while (ptr != NULL) {
12051694Sroger		if (LOOKAT(ptr->info, type, machfrom, netfrom, ptr->addr)) {
12151694Srogeragain:
12259014Sroger			msgin = ptr->info;
123118819Salex			from = ptr->addr;
124118819Salex			from_when = ptr->when;
125118819Salex			prev->p = ptr->p;
126118819Salex			if (ptr == tail)
127118819Salex				tail = prev;
12851694Sroger			free(ptr);
12962214Sroger			fromnet = NULL;
13051694Sroger			if (netfrom == NULL)
13162214Sroger			    for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
13262214Sroger				    if ((ntp->mask & from.sin_addr.s_addr) ==
13351694Sroger					ntp->net.s_addr) {
13451694Sroger					    fromnet = ntp;
13551694Sroger					    break;
13651694Sroger				    }
13751694Sroger			    }
13851694Sroger			else
13951694Sroger			    fromnet = netfrom;
14051694Sroger			if (trace) {
14151694Sroger				fprintf(fd, "readmsg: found ");
14251694Sroger				print(&msgin, &from);
14351694Sroger			}
14462214Sroger
14562214Sroger/* The protocol can get far behind.  When it does, it gets
14662214Sroger *	hopelessly confused.  So delete duplicate messages.
14762214Sroger */
14862214Sroger			for (ptr = prev; (ptr = ptr->p) != NULL; prev = ptr) {
14962214Sroger				if (ptr->addr.sin_addr.s_addr
15062214Sroger					== from.sin_addr.s_addr
15162214Sroger				    && ptr->info.tsp_type == msgin.tsp_type) {
15262214Sroger					if (trace)
15362214Sroger						fprintf(fd, "\tdup ");
15462214Sroger					goto again;
15562214Sroger				}
15662214Sroger			}
15762214Sroger			msgcnt--;
15862214Sroger			return(&msgin);
15962214Sroger		} else {
16062214Sroger			prev = ptr;
16162214Sroger			ptr = ptr->p;
16262214Sroger		}
16362214Sroger	}
16459014Sroger
16559014Sroger	/*
16659014Sroger	 * If the message was not in the linked list, it may still be
16759014Sroger	 * coming from the network. Set the timer and wait
16859014Sroger	 * on a select to read the next incoming message: if it is the
16959014Sroger	 * right one, return it, otherwise insert it in the linked list.
17059014Sroger	 */
17159014Sroger
17259014Sroger	(void)gettimeofday(&rtout, 0);
17359014Sroger	timeradd(&rtout, intvl, &rtout);
17459014Sroger	set[0].fd = sock;
17559014Sroger	set[0].events = POLLIN;
17651694Sroger	for (;;) {
17751694Sroger		(void)gettimeofday(&rtime, 0);
17851694Sroger		timersub(&rtout, &rtime, &rwait);
17962214Sroger		if (rwait.tv_sec < 0)
18062214Sroger			rwait.tv_sec = rwait.tv_usec = 0;
18162214Sroger		else if (rwait.tv_sec == 0
18262214Sroger			 && rwait.tv_usec < 1000000/CLK_TCK)
18362214Sroger			rwait.tv_usec = 1000000/CLK_TCK;
18462214Sroger
18562214Sroger		if (trace) {
18662214Sroger			fprintf(fd, "readmsg: wait %ld.%6ld at %s\n",
18762214Sroger			    (long int)rwait.tv_sec, (long int)rwait.tv_usec,
188123291Sobrien			    date());
189123291Sobrien			/* Notice a full disk, as we flush trace info.
19062214Sroger			 * It is better to flush periodically than at
19162214Sroger			 * every line because the tracing consists of bursts
19262214Sroger			 * of many lines.  Without care, tracing slows
19362214Sroger			 * down the code enough to break the protocol.
19462214Sroger			 */
19562214Sroger			if (rwait.tv_sec != 0
19693023Snsouch			    && EOF == fflush(fd))
19765692Sroger				traceoff("Tracing ended for cause");
19865392Speter		}
19993023Snsouch
20093023Snsouch		if (!poll(set, 1, (int)(rwait.tv_sec * 1000 + rwait.tv_usec / 1000))) {
20193023Snsouch			if (rwait.tv_sec == 0 && rwait.tv_usec == 0)
20262214Sroger				return(0);
20365392Speter			continue;
20451694Sroger		}
20562214Sroger		length = sizeof(from);
20651694Sroger		memset(&msgin, 0, sizeof(msgin));
20751694Sroger		if ((n = recvfrom(sock, &msgin, sizeof(struct tsp), 0,
20851694Sroger			     (struct sockaddr*)(void *)&from, &length)) < 0) {
20951694Sroger			syslog(LOG_ERR, "recvfrom: %m");
21051694Sroger			exit(EXIT_FAILURE);
21151694Sroger		}
21251694Sroger		/*
21351694Sroger		 * The 4.3BSD protocol spec had a 32-byte tsp_name field, and
21451694Sroger		 * this is still OS-dependent.  Demand that the packet is at
21551694Sroger		 * least long enough to hold a 4.3BSD packet.
21651694Sroger		 */
21751694Sroger		if (n < (ssize_t)(sizeof(struct tsp) - MAXHOSTNAMELEN + 32)) {
21851694Sroger			syslog(LOG_NOTICE,
21951694Sroger			    "short packet (%lu/%lu bytes) from %s",
22051694Sroger			      (u_long)n,
22151694Sroger			      (u_long)(sizeof(struct tsp) - MAXHOSTNAMELEN + 32),
22251694Sroger			      inet_ntoa(from.sin_addr));
22351694Sroger			continue;
22493023Snsouch		}
22593023Snsouch		(void)gettimeofday(&from_when, (struct timezone *)0);
22693023Snsouch		bytehostorder(&msgin);
22793023Snsouch
22893023Snsouch		if (msgin.tsp_vers > TSPVERSION) {
22993023Snsouch			if (trace) {
23093023Snsouch			    fprintf(fd,"readmsg: version mismatch\n");
23193023Snsouch			    /* should do a dump of the packet */
23293023Snsouch			}
23393023Snsouch			continue;
23493023Snsouch		}
23593023Snsouch
23693023Snsouch		if (memchr(msgin.tsp_name,
23793023Snsouch		    '\0', sizeof msgin.tsp_name) == NULL) {
23893023Snsouch			syslog(LOG_NOTICE, "hostname field not NUL terminated "
23993023Snsouch			    "in packet from %s", inet_ntoa(from.sin_addr));
24051694Sroger			continue;
24151694Sroger		}
24251694Sroger
24351694Sroger		fromnet = NULL;
24451694Sroger		for (ntp = nettab; ntp != NULL; ntp = ntp->next)
24551694Sroger			if ((ntp->mask & from.sin_addr.s_addr) ==
24651694Sroger			    ntp->net.s_addr) {
24751694Sroger				fromnet = ntp;
24851694Sroger				break;
24951694Sroger			}
25051694Sroger
25151694Sroger		/*
25251694Sroger		 * drop packets from nets we are ignoring permanently
25351694Sroger		 */
25451694Sroger		if (fromnet == NULL) {
25551694Sroger			/*
25651694Sroger			 * The following messages may originate on
25751694Sroger			 * this host with an ignored network address
25851694Sroger			 */
25951694Sroger			if (msgin.tsp_type != TSP_TRACEON &&
26051694Sroger			    msgin.tsp_type != TSP_SETDATE &&
261111815Sphk			    msgin.tsp_type != TSP_MSITE &&
262111815Sphk			    msgin.tsp_type != TSP_TEST &&
263111815Sphk			    msgin.tsp_type != TSP_TRACEOFF) {
264111815Sphk				if (trace) {
265111815Sphk				    fprintf(fd,"readmsg: discard null net ");
266111815Sphk				    print(&msgin, &from);
267111815Sphk				}
268111815Sphk				continue;
269111815Sphk			}
27051694Sroger		}
27151694Sroger
27252995Speter		/*
27367306Sroger		 * Throw away messages coming from this machine,
27465728Sroger		 * unless they are of some particular type.
27565728Sroger		 * This gets rid of broadcast messages and reduces
27667306Sroger		 * master processing time.
27751694Sroger		 */
27851694Sroger		if (!strcmp(msgin.tsp_name, hostname)
27951694Sroger		    && msgin.tsp_type != TSP_SETDATE
28051694Sroger		    && msgin.tsp_type != TSP_TEST
28151694Sroger		    && msgin.tsp_type != TSP_MSITE
28251694Sroger		    && msgin.tsp_type != TSP_TRACEON
28351694Sroger		    && msgin.tsp_type != TSP_TRACEOFF
28451694Sroger		    && msgin.tsp_type != TSP_LOOP) {
28551694Sroger			if (trace) {
28651694Sroger				fprintf(fd, "readmsg: discard own ");
28751694Sroger				print(&msgin, &from);
28867306Sroger			}
28967306Sroger			continue;
29067306Sroger		}
29167306Sroger
29267306Sroger		/*
29367306Sroger		 * Send acknowledgements here; this is faster and
29467306Sroger		 * avoids deadlocks that would occur if acks were
29567306Sroger		 * sent from a higher level routine.  Different
29667306Sroger		 * acknowledgements are necessary, depending on
29767306Sroger		 * status.
29867306Sroger		 */
29967306Sroger		if (fromnet == NULL)	/* do not de-reference 0 */
30067306Sroger			ignoreack();
30167306Sroger		else if (fromnet->status == MASTER)
30267306Sroger			masterack();
30367306Sroger		else if (fromnet->status == SLAVE)
30467306Sroger			slaveack();
30567306Sroger		else
30667306Sroger			ignoreack();
30751694Sroger
30851694Sroger		if (LOOKAT(msgin, type, machfrom, netfrom, from)) {
30951694Sroger			if (trace) {
31051694Sroger				fprintf(fd, "readmsg: ");
31151694Sroger				print(&msgin, &from);
31251694Sroger			}
31351694Sroger			return(&msgin);
31451694Sroger		} else if (++msgcnt > NHOSTS*3) {
31551694Sroger
31651694Sroger/* The protocol gets hopelessly confused if it gets too far
31751694Sroger*	behind.  However, it seems able to recover from all cases of lost
31851694Sroger*	packets.  Therefore, if we are swamped, throw everything away.
31951694Sroger*/
32051694Sroger			if (trace)
32151694Sroger				fprintf(fd,
32251694Sroger					"readmsg: discarding %d msgs\n",
32351694Sroger					msgcnt);
32451694Sroger			msgcnt = 0;
32551694Sroger			while ((ptr = head->p) != NULL) {
32651694Sroger				head->p = ptr->p;
32751694Sroger				free(ptr);
32851694Sroger			}
32951694Sroger			tail = head;
33051694Sroger		} else {
33151694Sroger			tail->p = malloc(sizeof(struct tsplist));
33251694Sroger			tail = tail->p;
33362112Sroger			tail->p = NULL;
33462112Sroger			tail->info = msgin;
33562112Sroger			tail->addr = from;
33651694Sroger			/* timestamp msgs so SETTIMEs are correct */
33751694Sroger			tail->when = from_when;
33851694Sroger		}
33951694Sroger	}
34051694Sroger}
34151694Sroger
34251694Sroger/*
34351694Sroger * Send the necessary acknowledgements:
34451694Sroger * only the type ACK is to be sent by a slave
34551694Sroger */
346119690Sjhbvoid
34765049Srogerslaveack(void)
34865049Sroger{
34951694Sroger	switch(msgin.tsp_type) {
35065049Sroger
35151694Sroger	case TSP_ADJTIME:
35251694Sroger	case TSP_SETTIME:
35351694Sroger	case TSP_ACCEPT:
35451694Sroger	case TSP_REFUSE:
35551694Sroger	case TSP_TRACEON:
35659014Sroger	case TSP_TRACEOFF:
35759014Sroger	case TSP_QUIT:
35851694Sroger		if (trace) {
35959014Sroger			fprintf(fd, "Slaveack: ");
36051694Sroger			print(&msgin, &from);
36151694Sroger		}
36251694Sroger		xmit(TSP_ACK,msgin.tsp_seq, &from);
36359014Sroger		break;
36459014Sroger
36551694Sroger	default:
36651694Sroger		if (trace) {
36751694Sroger			fprintf(fd, "Slaveack: no ack: ");
36851694Sroger			print(&msgin, &from);
36951694Sroger		}
37051694Sroger		break;
37151694Sroger	}
37251694Sroger}
37351694Sroger
37451694Sroger/*
37551694Sroger * Certain packets may arrive from this machine on ignored networks.
37651694Sroger * These packets should be acknowledged.
37751694Sroger */
37865049Srogervoid
37965049Srogerignoreack(void)
38065049Sroger{
38151694Sroger	switch(msgin.tsp_type) {
38251694Sroger
38351694Sroger	case TSP_TRACEON:
38451694Sroger	case TSP_TRACEOFF:
38551694Sroger	case TSP_QUIT:
38651694Sroger		if (trace) {
38759250Sroger			fprintf(fd, "Ignoreack: ");
38851694Sroger			print(&msgin, &from);
38951694Sroger		}
39051694Sroger		xmit(TSP_ACK,msgin.tsp_seq, &from);
39151694Sroger		break;
39251694Sroger
39351694Sroger	default:
39451694Sroger		if (trace) {
39551694Sroger			fprintf(fd, "Ignoreack: no ack: ");
39651694Sroger			print(&msgin, &from);
39751694Sroger		}
39851694Sroger		break;
39951694Sroger	}
40051694Sroger}
40151694Sroger
40251694Sroger/*
40351694Sroger * `masterack' sends the necessary acknowledgements
40451694Sroger * to the messages received by a master
40551694Sroger */
40651694Srogervoid
40751694Srogermasterack(void)
40851694Sroger{
40951694Sroger	struct tsp resp;
41051694Sroger
41151694Sroger	resp = msgin;
41251694Sroger	resp.tsp_vers = TSPVERSION;
41365692Sroger	set_tsp_name(&resp, hostname);
41493023Snsouch
41551694Sroger	switch(msgin.tsp_type) {
41651694Sroger
41751694Sroger	case TSP_QUIT:
41851694Sroger	case TSP_TRACEON:
41951694Sroger	case TSP_TRACEOFF:
42051694Sroger	case TSP_MSITEREQ:
42151694Sroger		if (trace) {
42251694Sroger			fprintf(fd, "Masterack: ");
42351694Sroger			print(&msgin, &from);
42451694Sroger		}
42551694Sroger		xmit(TSP_ACK,msgin.tsp_seq, &from);
42651694Sroger		break;
42751694Sroger
42851694Sroger	case TSP_RESOLVE:
42951694Sroger	case TSP_MASTERREQ:
43051694Sroger		if (trace) {
43151694Sroger			fprintf(fd, "Masterack: ");
43251694Sroger			print(&msgin, &from);
43351694Sroger		}
43451694Sroger		xmit(TSP_MASTERACK,msgin.tsp_seq, &from);
43551694Sroger		break;
43651694Sroger
43751694Sroger	default:
43851694Sroger		if (trace) {
43951694Sroger			fprintf(fd,"Masterack: no ack: ");
44051694Sroger			print(&msgin, &from);
44151694Sroger		}
44251694Sroger		break;
44351694Sroger	}
44451694Sroger}
44551694Sroger
44651694Sroger/*
44751694Sroger * Print a TSP message
44851694Sroger */
44967306Srogervoid
45067306Srogerprint(struct tsp *msg, struct sockaddr_in *addr)
45167306Sroger{
45267306Sroger	char tm[26];
45367306Sroger	time_t msgtime;
45467306Sroger
45567306Sroger	if (msg->tsp_type >= TSPTYPENUMBER) {
45651694Sroger		fprintf(fd, "bad type (%u) on packet from %s\n",
45767306Sroger		  msg->tsp_type, inet_ntoa(addr->sin_addr));
45867306Sroger		return;
45967306Sroger	}
46067306Sroger
46167306Sroger	switch (msg->tsp_type) {
46267306Sroger
46367306Sroger	case TSP_LOOP:
46467306Sroger		fprintf(fd, "%s %d %-6u #%d %-15s %s\n",
46567306Sroger			tsptype[msg->tsp_type],
46667306Sroger			msg->tsp_vers,
46767306Sroger			msg->tsp_seq,
46851694Sroger			msg->tsp_hopcnt,
46951694Sroger			inet_ntoa(addr->sin_addr),
47051694Sroger			msg->tsp_name);
47165049Sroger		break;
47265049Sroger
47365049Sroger	case TSP_SETTIME:
47465049Sroger	case TSP_SETDATE:
47551694Sroger	case TSP_SETDATEREQ:
47651694Sroger		msgtime = msg->tsp_time.tv_sec;
47751694Sroger		strlcpy(tm, ctime(&msgtime)+3+1, sizeof(tm));
47851694Sroger		tm[15] = '\0';		/* ugh */
47951694Sroger		fprintf(fd, "%s %d %-6u %s %-15s %s\n",
48051694Sroger			tsptype[msg->tsp_type],
48151694Sroger			msg->tsp_vers,
48251694Sroger			msg->tsp_seq,
48351694Sroger			tm,
48451694Sroger			inet_ntoa(addr->sin_addr),
48551694Sroger			msg->tsp_name);
48651694Sroger		break;
487118819Salex
488118819Salex	case TSP_ADJTIME:
489118819Salex		fprintf(fd, "%s %d %-6u (%ld,%ld) %-15s %s\n",
490118819Salex			tsptype[msg->tsp_type],
491118819Salex			msg->tsp_vers,
492118819Salex			msg->tsp_seq,
49351694Sroger			(long)msg->tsp_time.tv_sec,
49459014Sroger			(long)msg->tsp_time.tv_usec,
49559014Sroger			inet_ntoa(addr->sin_addr),
49651694Sroger			msg->tsp_name);
49793023Snsouch		break;
49893023Snsouch
499115556Sphk	default:
500115556Sphk		fprintf(fd, "%s %d %-6u %-15s %s\n",
50193023Snsouch			tsptype[msg->tsp_type],
502123088Struckman			msg->tsp_vers,
503123088Struckman			msg->tsp_seq,
504123088Struckman			inet_ntoa(addr->sin_addr),
50593023Snsouch			msg->tsp_name);
50667306Sroger		break;
50767306Sroger	}
50867306Sroger}
50951694Sroger