4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / usr.bin / netstat / route.c
CommitLineData
5ff67f98 1/*
2839532b
KB
2 * Copyright (c) 1983, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
ee3f90a5 4 *
42841feb 5 * %sccs.include.redist.c%
5ff67f98
DF
6 */
7
3537c4ea 8#ifndef lint
2839532b 9static char sccsid[] = "@(#)route.c 8.1 (Berkeley) %G%";
b36fc510 10#endif /* not lint */
3537c4ea 11
6c5bed6c 12#include <sys/param.h>
6e549c8f 13#include <sys/protosw.h>
3537c4ea
SL
14#include <sys/socket.h>
15#include <sys/mbuf.h>
44906619 16
3537c4ea 17#include <net/if.h>
a6dd7faa
MK
18#include <net/if_dl.h>
19#include <net/if_types.h>
4b68c469 20#define KERNEL
3537c4ea 21#include <net/route.h>
4b68c469 22#undef KERNEL
44906619
SL
23#include <netinet/in.h>
24
f1fbb01b
KS
25#include <netns/ns.h>
26
ab2a5ff0 27#include <sys/sysctl.h>
3537c4ea 28
6e549c8f 29#include <netdb.h>
42841feb 30#include <stdio.h>
6e549c8f 31#include <stdlib.h>
42841feb 32#include <string.h>
27788811 33#include <unistd.h>
6e549c8f 34#include "netstat.h"
42841feb 35
d1cfb820 36#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d)))
3537c4ea
SL
37
38/*
39 * Definitions for showing gateway flags.
40 */
41struct bits {
42 short b_mask;
43 char b_val;
44} bits[] = {
45 { RTF_UP, 'U' },
46 { RTF_GATEWAY, 'G' },
47 { RTF_HOST, 'H' },
27788811 48 { RTF_REJECT, 'R' },
6c5bed6c 49 { RTF_DYNAMIC, 'D' },
3273bd86 50 { RTF_MODIFIED, 'M' },
27788811
KS
51 { RTF_DONE, 'd' }, /* Completed -- for routing messages only */
52 { RTF_MASK, 'm' }, /* Mask Present -- for routing messages only */
56492e5a 53 { RTF_CLONING, 'C' },
b8442d18 54 { RTF_XRESOLVE, 'X' },
56492e5a 55 { RTF_LLINFO, 'L' },
4e64fa9b 56 { RTF_STATIC, 'S' },
27788811
KS
57 { RTF_PROTO1, '1' },
58 { RTF_PROTO2, '2' },
3537c4ea
SL
59 { 0 }
60};
61
a6dd7faa
MK
62static union {
63 struct sockaddr u_sa;
64 u_short u_data[128];
65} pt_u;
66
67int do_rtent = 0;
68struct rtentry rtentry;
69struct radix_node rnode;
70struct radix_mask rmask;
71
72int NewTree = 0;
73
6e549c8f
KS
74static struct sockaddr *kgetsa __P((struct sockaddr *));
75static void p_tree __P((struct radix_node *));
76static void p_rtnode __P(());
77static void ntreestuff __P(());
78static void np_rtentry __P((struct rt_msghdr *));
79static void p_sockaddr __P((struct sockaddr *, int, int));
80static void p_flags __P((int, char *));
81static void p_rtentry __P((struct rtentry *));
82
3537c4ea
SL
83/*
84 * Print routing tables.
85 */
6e549c8f 86void
a6dd7faa 87routepr(rtree)
d1cfb820 88 u_long rtree;
3537c4ea 89{
a6dd7faa 90 struct radix_node_head *rnh, head;
4e64fa9b 91 int i;
3537c4ea 92
4b68c469 93 printf("Routing tables\n");
a6dd7faa
MK
94
95 if (Aflag == 0 && NewTree)
96 ntreestuff();
97 else {
98 if (rtree == 0) {
4e64fa9b 99 printf("rt_tables: symbol not in namelist\n");
a6dd7faa
MK
100 return;
101 }
102
4e64fa9b
KS
103 kget(rtree, rt_tables);
104 for (i = 0; i <= AF_MAX; i++) {
105 if ((rnh = rt_tables[i]) == 0)
106 continue;
a6dd7faa 107 kget(rnh, head);
4e64fa9b 108 if (i == AF_UNSPEC) {
6e549c8f 109 if (Aflag && af == 0) {
a6dd7faa
MK
110 printf("Netmasks:\n");
111 p_tree(head.rnh_treetop);
112 }
4e64fa9b
KS
113 } else if (af == AF_UNSPEC || af == i) {
114 pr_family(i);
a6dd7faa
MK
115 do_rtent = 1;
116 pr_rthdr();
117 p_tree(head.rnh_treetop);
118 }
3537c4ea
SL
119 }
120 }
4b68c469
MK
121}
122
a6dd7faa
MK
123/*
124 * Print address family header before a section of the routing table.
125 */
6e549c8f 126void
a6dd7faa
MK
127pr_family(af)
128 int af;
4b68c469 129{
a6dd7faa 130 char *afname;
56492e5a 131
a6dd7faa
MK
132 switch (af) {
133 case AF_INET:
134 afname = "Internet";
135 break;
136 case AF_NS:
137 afname = "XNS";
138 break;
139 case AF_ISO:
140 afname = "ISO";
141 break;
4e64fa9b
KS
142 case AF_CCITT:
143 afname = "X.25";
144 break;
a6dd7faa
MK
145 default:
146 afname = NULL;
147 break;
4b68c469 148 }
a6dd7faa
MK
149 if (afname)
150 printf("\n%s:\n", afname);
151 else
152 printf("\nProtocol Family %d:\n", af);
153}
154
155/* column widths; each followed by one space */
156#define WID_DST 16 /* width of destination column */
157#define WID_GW 18 /* width of gateway column */
158
159/*
160 * Print header for routing table columns.
161 */
6e549c8f 162void
a6dd7faa
MK
163pr_rthdr()
164{
165
166 if (Aflag)
167 printf("%-8.8s ","Address");
168 printf("%-*.*s %-*.*s %-6.6s %6.6s%8.8s %s\n",
169 WID_DST, WID_DST, "Destination",
170 WID_GW, WID_GW, "Gateway",
171 "Flags", "Refs", "Use", "Interface");
4b68c469
MK
172}
173
6e549c8f 174static struct sockaddr *
4d9e18da 175kgetsa(dst)
a6dd7faa 176 register struct sockaddr *dst;
4d9e18da 177{
a6dd7faa 178
4d9e18da 179 kget(dst, pt_u.u_sa);
a6dd7faa 180 if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa))
d1cfb820 181 kread((u_long)dst, (char *)pt_u.u_data, pt_u.u_sa.sa_len);
4d9e18da
KS
182 return (&pt_u.u_sa);
183}
184
6e549c8f 185static void
b8442d18 186p_tree(rn)
a6dd7faa 187 struct radix_node *rn;
4b68c469 188{
4b68c469
MK
189
190again:
191 kget(rn, rnode);
192 if (rnode.rn_b < 0) {
b8442d18
KS
193 if (Aflag)
194 printf("%-8.8x ", rn);
a6dd7faa
MK
195 if (rnode.rn_flags & RNF_ROOT) {
196 if (Aflag)
197 printf("(root node)%s",
b8442d18 198 rnode.rn_dupedkey ? " =>\n" : "\n");
a6dd7faa 199 } else if (do_rtent) {
4b68c469
MK
200 kget(rn, rtentry);
201 p_rtentry(&rtentry);
b8442d18
KS
202 if (Aflag)
203 p_rtnode();
4b68c469 204 } else {
4d9e18da 205 p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key),
a6dd7faa 206 0, 44);
4b68c469
MK
207 putchar('\n');
208 }
209 if (rn = rnode.rn_dupedkey)
210 goto again;
211 } else {
b8442d18
KS
212 if (Aflag && do_rtent) {
213 printf("%-8.8x ", rn);
214 p_rtnode();
215 }
216 rn = rnode.rn_r;
217 p_tree(rnode.rn_l);
218 p_tree(rn);
219 }
220}
a6dd7faa
MK
221
222char nbuf[20];
b8442d18 223
6e549c8f 224static void
b8442d18
KS
225p_rtnode()
226{
b8442d18 227 struct radix_mask *rm = rnode.rn_mklist;
a6dd7faa 228
b8442d18
KS
229 if (rnode.rn_b < 0) {
230 if (rnode.rn_mask) {
231 printf("\t mask ");
232 p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask),
233 0, -1);
234 } else if (rm == 0)
235 return;
236 } else {
237 sprintf(nbuf, "(%d)", rnode.rn_b);
238 printf("%6.6s %8.8x : %8.8x", nbuf, rnode.rn_l, rnode.rn_r);
4b68c469 239 }
b8442d18
KS
240 while (rm) {
241 kget(rm, rmask);
242 sprintf(nbuf, " %d refs, ", rmask.rm_refs);
243 printf(" mk = %8.8x {(%d),%s",
244 rm, -1 - rmask.rm_b, rmask.rm_refs ? nbuf : " ");
245 p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), 0, -1);
246 putchar('}');
247 if (rm = rmask.rm_mklist)
248 printf(" ->");
249 }
250 putchar('\n');
4b68c469
MK
251}
252
6e549c8f 253static void
4d9e18da 254ntreestuff()
4b68c469 255{
ab2a5ff0
KM
256 size_t needed;
257 int mib[6];
4d9e18da
KS
258 char *buf, *next, *lim;
259 register struct rt_msghdr *rtm;
260
ab2a5ff0
KM
261 mib[0] = CTL_NET;
262 mib[1] = PF_ROUTE;
263 mib[2] = 0;
264 mib[3] = 0;
265 mib[4] = NET_RT_DUMP;
266 mib[5] = 0;
267 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
268 { perror("route-sysctl-estimate"); exit(1);}
4d9e18da 269 if ((buf = malloc(needed)) == 0)
56492e5a 270 { printf("out of space\n"); exit(1);}
ab2a5ff0
KM
271 if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
272 { perror("sysctl of routing table"); exit(1);}
4d9e18da
KS
273 lim = buf + needed;
274 for (next = buf; next < lim; next += rtm->rtm_msglen) {
275 rtm = (struct rt_msghdr *)next;
276 np_rtentry(rtm);
4b68c469 277 }
4b68c469
MK
278}
279
6e549c8f 280static void
4d9e18da 281np_rtentry(rtm)
a6dd7faa 282 register struct rt_msghdr *rtm;
4b68c469 283{
4d9e18da 284 register struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
6e549c8f
KS
285#ifdef notdef
286 static int masks_done, banner_printed;
287#endif
288 static int old_af;
4d9e18da 289 int af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST;
4b68c469 290
4d9e18da
KS
291#ifdef notdef
292 /* for the moment, netmasks are skipped over */
293 if (!banner_printed) {
294 printf("Netmasks:\n");
295 banner_printed = 1;
296 }
297 if (masks_done == 0) {
298 if (rtm->rtm_addrs != RTA_DST ) {
299 masks_done = 1;
300 af = sa->sa_family;
301 }
302 } else
303#endif
304 af = sa->sa_family;
305 if (af != old_af) {
a6dd7faa 306 pr_family(af);
4d9e18da
KS
307 old_af = af;
308 }
309 if (rtm->rtm_addrs == RTA_DST)
56492e5a 310 p_sockaddr(sa, 0, 36);
4d9e18da 311 else {
56492e5a 312 p_sockaddr(sa, rtm->rtm_flags, 16);
4d9e18da
KS
313 if (sa->sa_len == 0)
314 sa->sa_len = sizeof(long);
315 sa = (struct sockaddr *)(sa->sa_len + (char *)sa);
56492e5a 316 p_sockaddr(sa, 0, 18);
4d9e18da
KS
317 }
318 p_flags(rtm->rtm_flags & interesting, "%-6.6s ");
319 putchar('\n');
320}
321
6e549c8f 322static void
56492e5a 323p_sockaddr(sa, flags, width)
a6dd7faa
MK
324 struct sockaddr *sa;
325 int flags, width;
4d9e18da 326{
6e549c8f 327 char workbuf[128], *cplim;
a6dd7faa 328 register char *cp = workbuf;
4d9e18da
KS
329
330 switch(sa->sa_family) {
4b68c469 331 case AF_INET:
4d9e18da
KS
332 {
333 register struct sockaddr_in *sin = (struct sockaddr_in *)sa;
334
335 cp = (sin->sin_addr.s_addr == 0) ? "default" :
336 ((flags & RTF_HOST) ?
6e549c8f
KS
337 routename(sin->sin_addr.s_addr) :
338 netname(sin->sin_addr.s_addr, 0L));
4b68c469 339 break;
a6dd7faa 340 }
4d9e18da 341
4b68c469 342 case AF_NS:
6e549c8f 343 cp = ns_print(sa);
4b68c469 344 break;
4d9e18da 345
a6dd7faa
MK
346 case AF_LINK:
347 {
348 register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
a6dd7faa
MK
349
350 if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 &&
351 sdl->sdl_slen == 0)
352 (void) sprintf(workbuf, "link#%d", sdl->sdl_index);
353 else switch (sdl->sdl_type) {
354 case IFT_ETHER:
355 {
356 register int i;
357 register u_char *lla = (u_char *)sdl->sdl_data +
358 sdl->sdl_nlen;
359
360 cplim = "";
361 for (i = 0; i < sdl->sdl_alen; i++, lla++) {
362 cp += sprintf(cp, "%s%x", cplim, *lla);
363 cplim = ":";
364 }
365 cp = workbuf;
366 break;
367 }
368 default:
369 cp = link_ntoa(sdl);
370 break;
371 }
372 break;
373 }
374
4b68c469 375 default:
4d9e18da 376 {
b8442d18 377 register u_short *s = ((u_short *)sa->sa_data), *slim;
4d9e18da 378
b8442d18
KS
379 slim = (u_short *) sa + ((sa->sa_len + sizeof(u_short) - 1) /
380 sizeof(u_short));
4d9e18da
KS
381 cplim = cp + sizeof(workbuf) - 6;
382 cp += sprintf(cp, "(%d)", sa->sa_family);
383 while (s < slim && cp < cplim)
b8442d18 384 cp += sprintf(cp, " %x", *s++);
4d9e18da
KS
385 cp = workbuf;
386 }
4b68c469 387 }
b8442d18
KS
388 if (width < 0 )
389 printf("%s ", cp);
390 else {
391 if (nflag)
392 printf("%-*s ", width, cp);
393 else
394 printf("%-*.*s ", width, width, cp);
395 }
4d9e18da
KS
396}
397
6e549c8f 398static void
4d9e18da 399p_flags(f, format)
a6dd7faa
MK
400 register int f;
401 char *format;
4d9e18da
KS
402{
403 char name[33], *flags;
404 register struct bits *p = bits;
a6dd7faa 405
4d9e18da
KS
406 for (flags = name; p->b_mask; p++)
407 if (p->b_mask & f)
4b68c469
MK
408 *flags++ = p->b_val;
409 *flags = '\0';
4d9e18da
KS
410 printf(format, name);
411}
412
6e549c8f 413static void
4d9e18da 414p_rtentry(rt)
6e549c8f 415 register struct rtentry *rt;
4d9e18da 416{
a6dd7faa
MK
417 static struct ifnet ifnet, *lastif;
418 static char name[16];
4d9e18da 419
a6dd7faa 420 p_sockaddr(kgetsa(rt_key(rt)), rt->rt_flags, WID_DST);
dfacc100 421 p_sockaddr(kgetsa(rt->rt_gateway), RTF_HOST, WID_GW);
4d9e18da
KS
422 p_flags(rt->rt_flags, "%-6.6s ");
423 printf("%6d %8d ", rt->rt_refcnt, rt->rt_use);
a6dd7faa
MK
424 if (rt->rt_ifp) {
425 if (rt->rt_ifp != lastif) {
426 kget(rt->rt_ifp, ifnet);
d1cfb820 427 kread((u_long)ifnet.if_name, name, 16);
a6dd7faa
MK
428 lastif = rt->rt_ifp;
429 }
430 printf(" %.15s%d%s", name, ifnet.if_unit,
431 rt->rt_nodes[0].rn_dupedkey ? " =>" : "");
4b68c469 432 }
a6dd7faa 433 putchar('\n');
3537c4ea
SL
434}
435
436char *
437routename(in)
6e549c8f 438 u_long in;
3537c4ea 439{
6b9930b0 440 register char *cp;
cb646d4b 441 static char line[MAXHOSTNAMELEN + 1];
40f48772 442 struct hostent *hp;
6c5bed6c
MK
443 static char domain[MAXHOSTNAMELEN + 1];
444 static int first = 1;
3537c4ea 445
6c5bed6c
MK
446 if (first) {
447 first = 0;
448 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
449 (cp = index(domain, '.')))
450 (void) strcpy(domain, cp + 1);
451 else
452 domain[0] = 0;
453 }
6b9930b0 454 cp = 0;
3537c4ea 455 if (!nflag) {
f7c99b06 456 hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),
cab3a575 457 AF_INET);
6c5bed6c
MK
458 if (hp) {
459 if ((cp = index(hp->h_name, '.')) &&
460 !strcmp(cp + 1, domain))
461 *cp = 0;
cab3a575 462 cp = hp->h_name;
6c5bed6c 463 }
3537c4ea
SL
464 }
465 if (cp)
cb646d4b 466 strncpy(line, cp, sizeof(line) - 1);
3537c4ea 467 else {
cab3a575 468#define C(x) ((x) & 0xff)
6e549c8f
KS
469 in = ntohl(in);
470 sprintf(line, "%u.%u.%u.%u",
471 C(in >> 24), C(in >> 16), C(in >> 8), C(in));
cab3a575
MK
472 }
473 return (line);
474}
475
476/*
477 * Return the name of the network whose address is given.
478 * The address is assumed to be that of a net or subnet, not a host.
479 */
480char *
481netname(in, mask)
6e549c8f 482 u_long in, mask;
cab3a575
MK
483{
484 char *cp = 0;
cb646d4b 485 static char line[MAXHOSTNAMELEN + 1];
cab3a575
MK
486 struct netent *np = 0;
487 u_long net;
6e549c8f 488 register int i;
6c5bed6c 489 int subnetshift;
cab3a575 490
6e549c8f 491 i = ntohl(in);
a83ade01 492 if (!nflag && i) {
6c5bed6c
MK
493 if (mask == 0) {
494 if (IN_CLASSA(i)) {
495 mask = IN_CLASSA_NET;
496 subnetshift = 8;
497 } else if (IN_CLASSB(i)) {
498 mask = IN_CLASSB_NET;
499 subnetshift = 8;
500 } else {
501 mask = IN_CLASSC_NET;
502 subnetshift = 4;
503 }
cab3a575 504 /*
6c5bed6c
MK
505 * If there are more bits than the standard mask
506 * would suggest, subnets must be in use.
507 * Guess at the subnet mask, assuming reasonable
508 * width subnet fields.
cab3a575 509 */
a83ade01 510 while (i &~ mask)
6c5bed6c 511 mask = (long)mask >> subnetshift;
cab3a575 512 }
a83ade01 513 net = i & mask;
6c5bed6c
MK
514 while ((mask & 1) == 0)
515 mask >>= 1, net >>= 1;
516 np = getnetbyaddr(net, AF_INET);
cab3a575
MK
517 if (np)
518 cp = np->n_name;
6e549c8f 519 }
cab3a575 520 if (cp)
cb646d4b 521 strncpy(line, cp, sizeof(line) - 1);
a83ade01
MK
522 else if ((i & 0xffffff) == 0)
523 sprintf(line, "%u", C(i >> 24));
524 else if ((i & 0xffff) == 0)
525 sprintf(line, "%u.%u", C(i >> 24) , C(i >> 16));
526 else if ((i & 0xff) == 0)
527 sprintf(line, "%u.%u.%u", C(i >> 24), C(i >> 16), C(i >> 8));
cab3a575 528 else
a83ade01
MK
529 sprintf(line, "%u.%u.%u.%u", C(i >> 24),
530 C(i >> 16), C(i >> 8), C(i));
3537c4ea
SL
531 return (line);
532}
6c5bed6c 533
bbd2d21e
SL
534/*
535 * Print routing statistics
536 */
6e549c8f 537void
bbd2d21e 538rt_stats(off)
d1cfb820 539 u_long off;
bbd2d21e
SL
540{
541 struct rtstat rtstat;
542
543 if (off == 0) {
544 printf("rtstat: symbol not in namelist\n");
545 return;
546 }
6e549c8f 547 kread(off, (char *)&rtstat, sizeof (rtstat));
bbd2d21e 548 printf("routing:\n");
bd91d3f9 549 printf("\t%u bad routing redirect%s\n",
bbd2d21e 550 rtstat.rts_badredirect, plural(rtstat.rts_badredirect));
bd91d3f9 551 printf("\t%u dynamically created route%s\n",
bbd2d21e 552 rtstat.rts_dynamic, plural(rtstat.rts_dynamic));
bd91d3f9 553 printf("\t%u new gateway%s due to redirects\n",
bbd2d21e 554 rtstat.rts_newgateway, plural(rtstat.rts_newgateway));
bd91d3f9 555 printf("\t%u destination%s found unreachable\n",
bbd2d21e 556 rtstat.rts_unreach, plural(rtstat.rts_unreach));
bd91d3f9 557 printf("\t%u use%s of a wildcard route\n",
bbd2d21e
SL
558 rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
559}
2ff355d6 560short ns_nullh[] = {0,0,0};
f1fbb01b
KS
561short ns_bh[] = {-1,-1,-1};
562
563char *
6e549c8f
KS
564ns_print(sa)
565 register struct sockaddr *sa;
f1fbb01b 566{
6e549c8f 567 register struct sockaddr_ns *sns = (struct sockaddr_ns*)sa;
2ff355d6
MK
568 struct ns_addr work;
569 union { union ns_net net_e; u_long long_e; } net;
570 u_short port;
571 static char mybuf[50], cport[10], chost[25];
572 char *host = "";
f7c99b06 573 register char *p; register u_char *q;
f1fbb01b 574
2ff355d6
MK
575 work = sns->sns_addr;
576 port = ntohs(work.x_port);
577 work.x_port = 0;
578 net.net_e = work.x_net;
579 if (ns_nullhost(work) && net.long_e == 0) {
580 if (port ) {
581 sprintf(mybuf, "*.%xH", port);
582 upHex(mybuf);
583 } else
584 sprintf(mybuf, "*.*");
585 return (mybuf);
586 }
f1fbb01b 587
56492e5a 588 if (bcmp(ns_bh, work.x_host.c_host, 6) == 0) {
2ff355d6
MK
589 host = "any";
590 } else if (bcmp(ns_nullh, work.x_host.c_host, 6) == 0) {
591 host = "*";
592 } else {
593 q = work.x_host.c_host;
594 sprintf(chost, "%02x%02x%02x%02x%02x%02xH",
595 q[0], q[1], q[2], q[3], q[4], q[5]);
6e549c8f
KS
596 for (p = chost; *p == '0' && p < chost + 12; p++)
597 continue;
2ff355d6 598 host = p;
f1fbb01b 599 }
2ff355d6
MK
600 if (port)
601 sprintf(cport, ".%xH", htons(port));
602 else
603 *cport = 0;
604
605 sprintf(mybuf,"%xH.%s%s", ntohl(net.long_e), host, cport);
606 upHex(mybuf);
f1fbb01b
KS
607 return(mybuf);
608}
2ff355d6 609
f1fbb01b 610char *
6e549c8f
KS
611ns_phost(sa)
612 struct sockaddr *sa;
f1fbb01b 613{
6e549c8f 614 register struct sockaddr_ns *sns = (struct sockaddr_ns *)sa;
2ff355d6
MK
615 struct sockaddr_ns work;
616 static union ns_net ns_zeronet;
617 char *p;
6e549c8f 618
2ff355d6
MK
619 work = *sns;
620 work.sns_addr.x_port = 0;
621 work.sns_addr.x_net = ns_zeronet;
622
6e549c8f 623 p = ns_print((struct sockaddr *)&work);
2ff355d6
MK
624 if (strncmp("0H.", p, 3) == 0) p += 3;
625 return(p);
626}
6e549c8f
KS
627
628void
2ff355d6 629upHex(p0)
6e549c8f 630 char *p0;
2ff355d6
MK
631{
632 register char *p = p0;
633 for (; *p; p++) switch (*p) {
634
635 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
636 *p += ('A' - 'a');
637 }
f1fbb01b 638}