Home | History | Annotate | Line # | Download | only in netstat
inet.c revision 1.1
      1  1.1  cgd /*
      2  1.1  cgd  * Copyright (c) 1983, 1988 Regents of the University of California.
      3  1.1  cgd  * All rights reserved.
      4  1.1  cgd  *
      5  1.1  cgd  * Redistribution and use in source and binary forms, with or without
      6  1.1  cgd  * modification, are permitted provided that the following conditions
      7  1.1  cgd  * are met:
      8  1.1  cgd  * 1. Redistributions of source code must retain the above copyright
      9  1.1  cgd  *    notice, this list of conditions and the following disclaimer.
     10  1.1  cgd  * 2. Redistributions in binary form must reproduce the above copyright
     11  1.1  cgd  *    notice, this list of conditions and the following disclaimer in the
     12  1.1  cgd  *    documentation and/or other materials provided with the distribution.
     13  1.1  cgd  * 3. All advertising materials mentioning features or use of this software
     14  1.1  cgd  *    must display the following acknowledgement:
     15  1.1  cgd  *	This product includes software developed by the University of
     16  1.1  cgd  *	California, Berkeley and its contributors.
     17  1.1  cgd  * 4. Neither the name of the University nor the names of its contributors
     18  1.1  cgd  *    may be used to endorse or promote products derived from this software
     19  1.1  cgd  *    without specific prior written permission.
     20  1.1  cgd  *
     21  1.1  cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  1.1  cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  1.1  cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  1.1  cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  1.1  cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  1.1  cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  1.1  cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  1.1  cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  1.1  cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  1.1  cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  1.1  cgd  * SUCH DAMAGE.
     32  1.1  cgd  */
     33  1.1  cgd 
     34  1.1  cgd #ifndef lint
     35  1.1  cgd static char sccsid[] = "@(#)inet.c	5.15 (Berkeley) 6/18/90";
     36  1.1  cgd #endif /* not lint */
     37  1.1  cgd 
     38  1.1  cgd #include <sys/param.h>
     39  1.1  cgd #include <sys/socket.h>
     40  1.1  cgd #include <sys/socketvar.h>
     41  1.1  cgd #include <sys/mbuf.h>
     42  1.1  cgd #include <sys/protosw.h>
     43  1.1  cgd 
     44  1.1  cgd #include <net/route.h>
     45  1.1  cgd #include <netinet/in.h>
     46  1.1  cgd #include <netinet/in_systm.h>
     47  1.1  cgd #include <netinet/ip.h>
     48  1.1  cgd #include <netinet/in_pcb.h>
     49  1.1  cgd #include <netinet/ip_icmp.h>
     50  1.1  cgd #include <netinet/icmp_var.h>
     51  1.1  cgd #include <netinet/ip_var.h>
     52  1.1  cgd #include <netinet/tcp.h>
     53  1.1  cgd #include <netinet/tcpip.h>
     54  1.1  cgd #include <netinet/tcp_seq.h>
     55  1.1  cgd #define TCPSTATES
     56  1.1  cgd #include <netinet/tcp_fsm.h>
     57  1.1  cgd #include <netinet/tcp_timer.h>
     58  1.1  cgd #include <netinet/tcp_var.h>
     59  1.1  cgd #include <netinet/tcp_debug.h>
     60  1.1  cgd #include <netinet/udp.h>
     61  1.1  cgd #include <netinet/udp_var.h>
     62  1.1  cgd 
     63  1.1  cgd #include <netdb.h>
     64  1.1  cgd 
     65  1.1  cgd #include <stdio.h>
     66  1.1  cgd #include <string.h>
     67  1.1  cgd 
     68  1.1  cgd struct	inpcb inpcb;
     69  1.1  cgd struct	tcpcb tcpcb;
     70  1.1  cgd struct	socket sockb;
     71  1.1  cgd extern	int Aflag;
     72  1.1  cgd extern	int aflag;
     73  1.1  cgd extern	int nflag;
     74  1.1  cgd extern	char *plural();
     75  1.1  cgd 
     76  1.1  cgd char	*inetname();
     77  1.1  cgd 
     78  1.1  cgd /*
     79  1.1  cgd  * Print a summary of connections related to an Internet
     80  1.1  cgd  * protocol.  For TCP, also give state of connection.
     81  1.1  cgd  * Listening processes (aflag) are suppressed unless the
     82  1.1  cgd  * -a (all) flag is specified.
     83  1.1  cgd  */
     84  1.1  cgd protopr(off, name)
     85  1.1  cgd 	off_t off;
     86  1.1  cgd 	char *name;
     87  1.1  cgd {
     88  1.1  cgd 	struct inpcb cb;
     89  1.1  cgd 	register struct inpcb *prev, *next;
     90  1.1  cgd 	int istcp;
     91  1.1  cgd 	static int first = 1;
     92  1.1  cgd 
     93  1.1  cgd 	if (off == 0)
     94  1.1  cgd 		return;
     95  1.1  cgd 	istcp = strcmp(name, "tcp") == 0;
     96  1.1  cgd 	kvm_read(off, (char *)&cb, sizeof (struct inpcb));
     97  1.1  cgd 	inpcb = cb;
     98  1.1  cgd 	prev = (struct inpcb *)off;
     99  1.1  cgd 	if (inpcb.inp_next == (struct inpcb *)off)
    100  1.1  cgd 		return;
    101  1.1  cgd 	while (inpcb.inp_next != (struct inpcb *)off) {
    102  1.1  cgd 
    103  1.1  cgd 		next = inpcb.inp_next;
    104  1.1  cgd 		kvm_read((off_t)next, (char *)&inpcb, sizeof (inpcb));
    105  1.1  cgd 		if (inpcb.inp_prev != prev) {
    106  1.1  cgd 			printf("???\n");
    107  1.1  cgd 			break;
    108  1.1  cgd 		}
    109  1.1  cgd 		if (!aflag &&
    110  1.1  cgd 		  inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) {
    111  1.1  cgd 			prev = next;
    112  1.1  cgd 			continue;
    113  1.1  cgd 		}
    114  1.1  cgd 		kvm_read((off_t)inpcb.inp_socket,
    115  1.1  cgd 				(char *)&sockb, sizeof (sockb));
    116  1.1  cgd 		if (istcp) {
    117  1.1  cgd 			kvm_read((off_t)inpcb.inp_ppcb,
    118  1.1  cgd 				(char *)&tcpcb, sizeof (tcpcb));
    119  1.1  cgd 		}
    120  1.1  cgd 		if (first) {
    121  1.1  cgd 			printf("Active Internet connections");
    122  1.1  cgd 			if (aflag)
    123  1.1  cgd 				printf(" (including servers)");
    124  1.1  cgd 			putchar('\n');
    125  1.1  cgd 			if (Aflag)
    126  1.1  cgd 				printf("%-8.8s ", "PCB");
    127  1.1  cgd 			printf(Aflag ?
    128  1.1  cgd 				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
    129  1.1  cgd 				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
    130  1.1  cgd 				"Proto", "Recv-Q", "Send-Q",
    131  1.1  cgd 				"Local Address", "Foreign Address", "(state)");
    132  1.1  cgd 			first = 0;
    133  1.1  cgd 		}
    134  1.1  cgd 		if (Aflag)
    135  1.1  cgd 			if (istcp)
    136  1.1  cgd 				printf("%8x ", inpcb.inp_ppcb);
    137  1.1  cgd 			else
    138  1.1  cgd 				printf("%8x ", next);
    139  1.1  cgd 		printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc,
    140  1.1  cgd 			sockb.so_snd.sb_cc);
    141  1.1  cgd 		inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name);
    142  1.1  cgd 		inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name);
    143  1.1  cgd 		if (istcp) {
    144  1.1  cgd 			if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
    145  1.1  cgd 				printf(" %d", tcpcb.t_state);
    146  1.1  cgd 			else
    147  1.1  cgd 				printf(" %s", tcpstates[tcpcb.t_state]);
    148  1.1  cgd 		}
    149  1.1  cgd 		putchar('\n');
    150  1.1  cgd 		prev = next;
    151  1.1  cgd 	}
    152  1.1  cgd }
    153  1.1  cgd 
    154  1.1  cgd /*
    155  1.1  cgd  * Dump TCP statistics structure.
    156  1.1  cgd  */
    157  1.1  cgd tcp_stats(off, name)
    158  1.1  cgd 	off_t off;
    159  1.1  cgd 	char *name;
    160  1.1  cgd {
    161  1.1  cgd 	struct tcpstat tcpstat;
    162  1.1  cgd 
    163  1.1  cgd 	if (off == 0)
    164  1.1  cgd 		return;
    165  1.1  cgd 	printf ("%s:\n", name);
    166  1.1  cgd 	kvm_read(off, (char *)&tcpstat, sizeof (tcpstat));
    167  1.1  cgd 
    168  1.1  cgd #define	p(f, m)		printf(m, tcpstat.f, plural(tcpstat.f))
    169  1.1  cgd #define	p2(f1, f2, m)	printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
    170  1.1  cgd 
    171  1.1  cgd 	p(tcps_sndtotal, "\t%d packet%s sent\n");
    172  1.1  cgd 	p2(tcps_sndpack,tcps_sndbyte,
    173  1.1  cgd 		"\t\t%d data packet%s (%d byte%s)\n");
    174  1.1  cgd 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
    175  1.1  cgd 		"\t\t%d data packet%s (%d byte%s) retransmitted\n");
    176  1.1  cgd 	p2(tcps_sndacks, tcps_delack,
    177  1.1  cgd 		"\t\t%d ack-only packet%s (%d delayed)\n");
    178  1.1  cgd 	p(tcps_sndurg, "\t\t%d URG only packet%s\n");
    179  1.1  cgd 	p(tcps_sndprobe, "\t\t%d window probe packet%s\n");
    180  1.1  cgd 	p(tcps_sndwinup, "\t\t%d window update packet%s\n");
    181  1.1  cgd 	p(tcps_sndctrl, "\t\t%d control packet%s\n");
    182  1.1  cgd 	p(tcps_rcvtotal, "\t%d packet%s received\n");
    183  1.1  cgd 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%d ack%s (for %d byte%s)\n");
    184  1.1  cgd 	p(tcps_rcvdupack, "\t\t%d duplicate ack%s\n");
    185  1.1  cgd 	p(tcps_rcvacktoomuch, "\t\t%d ack%s for unsent data\n");
    186  1.1  cgd 	p2(tcps_rcvpack, tcps_rcvbyte,
    187  1.1  cgd 		"\t\t%d packet%s (%d byte%s) received in-sequence\n");
    188  1.1  cgd 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
    189  1.1  cgd 		"\t\t%d completely duplicate packet%s (%d byte%s)\n");
    190  1.1  cgd 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
    191  1.1  cgd 		"\t\t%d packet%s with some dup. data (%d byte%s duped)\n");
    192  1.1  cgd 	p2(tcps_rcvoopack, tcps_rcvoobyte,
    193  1.1  cgd 		"\t\t%d out-of-order packet%s (%d byte%s)\n");
    194  1.1  cgd 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
    195  1.1  cgd 		"\t\t%d packet%s (%d byte%s) of data after window\n");
    196  1.1  cgd 	p(tcps_rcvwinprobe, "\t\t%d window probe%s\n");
    197  1.1  cgd 	p(tcps_rcvwinupd, "\t\t%d window update packet%s\n");
    198  1.1  cgd 	p(tcps_rcvafterclose, "\t\t%d packet%s received after close\n");
    199  1.1  cgd 	p(tcps_rcvbadsum, "\t\t%d discarded for bad checksum%s\n");
    200  1.1  cgd 	p(tcps_rcvbadoff, "\t\t%d discarded for bad header offset field%s\n");
    201  1.1  cgd 	p(tcps_rcvshort, "\t\t%d discarded because packet too short\n");
    202  1.1  cgd 	p(tcps_connattempt, "\t%d connection request%s\n");
    203  1.1  cgd 	p(tcps_accepts, "\t%d connection accept%s\n");
    204  1.1  cgd 	p(tcps_connects, "\t%d connection%s established (including accepts)\n");
    205  1.1  cgd 	p2(tcps_closed, tcps_drops,
    206  1.1  cgd 		"\t%d connection%s closed (including %d drop%s)\n");
    207  1.1  cgd 	p(tcps_conndrops, "\t%d embryonic connection%s dropped\n");
    208  1.1  cgd 	p2(tcps_rttupdated, tcps_segstimed,
    209  1.1  cgd 		"\t%d segment%s updated rtt (of %d attempt%s)\n");
    210  1.1  cgd 	p(tcps_rexmttimeo, "\t%d retransmit timeout%s\n");
    211  1.1  cgd 	p(tcps_timeoutdrop, "\t\t%d connection%s dropped by rexmit timeout\n");
    212  1.1  cgd 	p(tcps_persisttimeo, "\t%d persist timeout%s\n");
    213  1.1  cgd 	p(tcps_keeptimeo, "\t%d keepalive timeout%s\n");
    214  1.1  cgd 	p(tcps_keepprobe, "\t\t%d keepalive probe%s sent\n");
    215  1.1  cgd 	p(tcps_keepdrops, "\t\t%d connection%s dropped by keepalive\n");
    216  1.1  cgd #undef p
    217  1.1  cgd #undef p2
    218  1.1  cgd }
    219  1.1  cgd 
    220  1.1  cgd /*
    221  1.1  cgd  * Dump UDP statistics structure.
    222  1.1  cgd  */
    223  1.1  cgd udp_stats(off, name)
    224  1.1  cgd 	off_t off;
    225  1.1  cgd 	char *name;
    226  1.1  cgd {
    227  1.1  cgd 	struct udpstat udpstat;
    228  1.1  cgd 
    229  1.1  cgd 	if (off == 0)
    230  1.1  cgd 		return;
    231  1.1  cgd 	kvm_read(off, (char *)&udpstat, sizeof (udpstat));
    232  1.1  cgd 	printf("%s:\n\t%u incomplete header%s\n", name,
    233  1.1  cgd 		udpstat.udps_hdrops, plural(udpstat.udps_hdrops));
    234  1.1  cgd 	printf("\t%u bad data length field%s\n",
    235  1.1  cgd 		udpstat.udps_badlen, plural(udpstat.udps_badlen));
    236  1.1  cgd 	printf("\t%u bad checksum%s\n",
    237  1.1  cgd 		udpstat.udps_badsum, plural(udpstat.udps_badsum));
    238  1.1  cgd }
    239  1.1  cgd 
    240  1.1  cgd /*
    241  1.1  cgd  * Dump IP statistics structure.
    242  1.1  cgd  */
    243  1.1  cgd ip_stats(off, name)
    244  1.1  cgd 	off_t off;
    245  1.1  cgd 	char *name;
    246  1.1  cgd {
    247  1.1  cgd 	struct ipstat ipstat;
    248  1.1  cgd 
    249  1.1  cgd 	if (off == 0)
    250  1.1  cgd 		return;
    251  1.1  cgd 	kvm_read(off, (char *)&ipstat, sizeof (ipstat));
    252  1.1  cgd 	printf("%s:\n\t%u total packets received\n", name,
    253  1.1  cgd 		ipstat.ips_total);
    254  1.1  cgd 	printf("\t%u bad header checksum%s\n",
    255  1.1  cgd 		ipstat.ips_badsum, plural(ipstat.ips_badsum));
    256  1.1  cgd 	printf("\t%u with size smaller than minimum\n", ipstat.ips_tooshort);
    257  1.1  cgd 	printf("\t%u with data size < data length\n", ipstat.ips_toosmall);
    258  1.1  cgd 	printf("\t%u with header length < data size\n", ipstat.ips_badhlen);
    259  1.1  cgd 	printf("\t%u with data length < header length\n", ipstat.ips_badlen);
    260  1.1  cgd 	printf("\t%u fragment%s received\n",
    261  1.1  cgd 		ipstat.ips_fragments, plural(ipstat.ips_fragments));
    262  1.1  cgd 	printf("\t%u fragment%s dropped (dup or out of space)\n",
    263  1.1  cgd 		ipstat.ips_fragdropped, plural(ipstat.ips_fragdropped));
    264  1.1  cgd 	printf("\t%u fragment%s dropped after timeout\n",
    265  1.1  cgd 		ipstat.ips_fragtimeout, plural(ipstat.ips_fragtimeout));
    266  1.1  cgd 	printf("\t%u packet%s forwarded\n",
    267  1.1  cgd 		ipstat.ips_forward, plural(ipstat.ips_forward));
    268  1.1  cgd 	printf("\t%u packet%s not forwardable\n",
    269  1.1  cgd 		ipstat.ips_cantforward, plural(ipstat.ips_cantforward));
    270  1.1  cgd 	printf("\t%u redirect%s sent\n",
    271  1.1  cgd 		ipstat.ips_redirectsent, plural(ipstat.ips_redirectsent));
    272  1.1  cgd }
    273  1.1  cgd 
    274  1.1  cgd static	char *icmpnames[] = {
    275  1.1  cgd 	"echo reply",
    276  1.1  cgd 	"#1",
    277  1.1  cgd 	"#2",
    278  1.1  cgd 	"destination unreachable",
    279  1.1  cgd 	"source quench",
    280  1.1  cgd 	"routing redirect",
    281  1.1  cgd 	"#6",
    282  1.1  cgd 	"#7",
    283  1.1  cgd 	"echo",
    284  1.1  cgd 	"#9",
    285  1.1  cgd 	"#10",
    286  1.1  cgd 	"time exceeded",
    287  1.1  cgd 	"parameter problem",
    288  1.1  cgd 	"time stamp",
    289  1.1  cgd 	"time stamp reply",
    290  1.1  cgd 	"information request",
    291  1.1  cgd 	"information request reply",
    292  1.1  cgd 	"address mask request",
    293  1.1  cgd 	"address mask reply",
    294  1.1  cgd };
    295  1.1  cgd 
    296  1.1  cgd /*
    297  1.1  cgd  * Dump ICMP statistics.
    298  1.1  cgd  */
    299  1.1  cgd icmp_stats(off, name)
    300  1.1  cgd 	off_t off;
    301  1.1  cgd 	char *name;
    302  1.1  cgd {
    303  1.1  cgd 	struct icmpstat icmpstat;
    304  1.1  cgd 	register int i, first;
    305  1.1  cgd 
    306  1.1  cgd 	if (off == 0)
    307  1.1  cgd 		return;
    308  1.1  cgd 	kvm_read(off, (char *)&icmpstat, sizeof (icmpstat));
    309  1.1  cgd 	printf("%s:\n\t%u call%s to icmp_error\n", name,
    310  1.1  cgd 		icmpstat.icps_error, plural(icmpstat.icps_error));
    311  1.1  cgd 	printf("\t%u error%s not generated 'cuz old message was icmp\n",
    312  1.1  cgd 		icmpstat.icps_oldicmp, plural(icmpstat.icps_oldicmp));
    313  1.1  cgd 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
    314  1.1  cgd 		if (icmpstat.icps_outhist[i] != 0) {
    315  1.1  cgd 			if (first) {
    316  1.1  cgd 				printf("\tOutput histogram:\n");
    317  1.1  cgd 				first = 0;
    318  1.1  cgd 			}
    319  1.1  cgd 			printf("\t\t%s: %u\n", icmpnames[i],
    320  1.1  cgd 				icmpstat.icps_outhist[i]);
    321  1.1  cgd 		}
    322  1.1  cgd 	printf("\t%u message%s with bad code fields\n",
    323  1.1  cgd 		icmpstat.icps_badcode, plural(icmpstat.icps_badcode));
    324  1.1  cgd 	printf("\t%u message%s < minimum length\n",
    325  1.1  cgd 		icmpstat.icps_tooshort, plural(icmpstat.icps_tooshort));
    326  1.1  cgd 	printf("\t%u bad checksum%s\n",
    327  1.1  cgd 		icmpstat.icps_checksum, plural(icmpstat.icps_checksum));
    328  1.1  cgd 	printf("\t%u message%s with bad length\n",
    329  1.1  cgd 		icmpstat.icps_badlen, plural(icmpstat.icps_badlen));
    330  1.1  cgd 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
    331  1.1  cgd 		if (icmpstat.icps_inhist[i] != 0) {
    332  1.1  cgd 			if (first) {
    333  1.1  cgd 				printf("\tInput histogram:\n");
    334  1.1  cgd 				first = 0;
    335  1.1  cgd 			}
    336  1.1  cgd 			printf("\t\t%s: %u\n", icmpnames[i],
    337  1.1  cgd 				icmpstat.icps_inhist[i]);
    338  1.1  cgd 		}
    339  1.1  cgd 	printf("\t%u message response%s generated\n",
    340  1.1  cgd 		icmpstat.icps_reflect, plural(icmpstat.icps_reflect));
    341  1.1  cgd }
    342  1.1  cgd 
    343  1.1  cgd /*
    344  1.1  cgd  * Pretty print an Internet address (net address + port).
    345  1.1  cgd  * If the nflag was specified, use numbers instead of names.
    346  1.1  cgd  */
    347  1.1  cgd inetprint(in, port, proto)
    348  1.1  cgd 	register struct in_addr *in;
    349  1.1  cgd 	u_short port;
    350  1.1  cgd 	char *proto;
    351  1.1  cgd {
    352  1.1  cgd 	struct servent *sp = 0;
    353  1.1  cgd 	char line[80], *cp, *index();
    354  1.1  cgd 	int width;
    355  1.1  cgd 
    356  1.1  cgd 	sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inetname(*in));
    357  1.1  cgd 	cp = index(line, '\0');
    358  1.1  cgd 	if (!nflag && port)
    359  1.1  cgd 		sp = getservbyport((int)port, proto);
    360  1.1  cgd 	if (sp || port == 0)
    361  1.1  cgd 		sprintf(cp, "%.8s", sp ? sp->s_name : "*");
    362  1.1  cgd 	else
    363  1.1  cgd 		sprintf(cp, "%d", ntohs((u_short)port));
    364  1.1  cgd 	width = Aflag ? 18 : 22;
    365  1.1  cgd 	printf(" %-*.*s", width, width, line);
    366  1.1  cgd }
    367  1.1  cgd 
    368  1.1  cgd /*
    369  1.1  cgd  * Construct an Internet address representation.
    370  1.1  cgd  * If the nflag has been supplied, give
    371  1.1  cgd  * numeric value, otherwise try for symbolic name.
    372  1.1  cgd  */
    373  1.1  cgd char *
    374  1.1  cgd inetname(in)
    375  1.1  cgd 	struct in_addr in;
    376  1.1  cgd {
    377  1.1  cgd 	register char *cp;
    378  1.1  cgd 	static char line[50];
    379  1.1  cgd 	struct hostent *hp;
    380  1.1  cgd 	struct netent *np;
    381  1.1  cgd 	static char domain[MAXHOSTNAMELEN + 1];
    382  1.1  cgd 	static int first = 1;
    383  1.1  cgd 
    384  1.1  cgd 	if (first && !nflag) {
    385  1.1  cgd 		first = 0;
    386  1.1  cgd 		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
    387  1.1  cgd 		    (cp = index(domain, '.')))
    388  1.1  cgd 			(void) strcpy(domain, cp + 1);
    389  1.1  cgd 		else
    390  1.1  cgd 			domain[0] = 0;
    391  1.1  cgd 	}
    392  1.1  cgd 	cp = 0;
    393  1.1  cgd 	if (!nflag && in.s_addr != INADDR_ANY) {
    394  1.1  cgd 		int net = inet_netof(in);
    395  1.1  cgd 		int lna = inet_lnaof(in);
    396  1.1  cgd 
    397  1.1  cgd 		if (lna == INADDR_ANY) {
    398  1.1  cgd 			np = getnetbyaddr(net, AF_INET);
    399  1.1  cgd 			if (np)
    400  1.1  cgd 				cp = np->n_name;
    401  1.1  cgd 		}
    402  1.1  cgd 		if (cp == 0) {
    403  1.1  cgd 			hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
    404  1.1  cgd 			if (hp) {
    405  1.1  cgd 				if ((cp = index(hp->h_name, '.')) &&
    406  1.1  cgd 				    !strcmp(cp + 1, domain))
    407  1.1  cgd 					*cp = 0;
    408  1.1  cgd 				cp = hp->h_name;
    409  1.1  cgd 			}
    410  1.1  cgd 		}
    411  1.1  cgd 	}
    412  1.1  cgd 	if (in.s_addr == INADDR_ANY)
    413  1.1  cgd 		strcpy(line, "*");
    414  1.1  cgd 	else if (cp)
    415  1.1  cgd 		strcpy(line, cp);
    416  1.1  cgd 	else {
    417  1.1  cgd 		in.s_addr = ntohl(in.s_addr);
    418  1.1  cgd #define C(x)	((x) & 0xff)
    419  1.1  cgd 		sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
    420  1.1  cgd 			C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
    421  1.1  cgd 	}
    422  1.1  cgd 	return (line);
    423  1.1  cgd }
    424