8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / fs.d / nfs / nfslog / nfslog_ipaddr.c
blob4c1890587f2ec122e40601d706d2a4123142e293
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 1991, 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33 #include <malloc.h>
34 #include <sys/socket.h>
35 #include <sys/sockio.h>
36 #include <arpa/inet.h>
37 #include <net/if.h>
38 #include <netinet/in.h>
39 #include <netinet/in_systm.h>
40 #include <netinet/if_ether.h>
41 #include <netinet/ip.h>
42 #include <netdb.h>
43 #include <string.h>
44 #include <signal.h>
45 #include <setjmp.h>
48 * Note: If making changes to this file, check also the file
49 * cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c
50 * as it has the same functions there.
52 static jmp_buf nisjmp;
54 #define MAXHASH 1024 /* must be a power of 2 */
56 struct hostdata {
57 struct hostdata *h_next;
58 char *h_hostname;
59 int h_pktsout;
60 int h_pktsin;
63 struct hostdata4 {
64 struct hostdata4 *h4_next;
65 char *h4_hostname;
66 int h4_pktsout;
67 int h4_pktsin;
68 struct in_addr h4_addr;
71 struct hostdata6 {
72 struct hostdata6 *h6_next;
73 char *h6_hostname;
74 int h6_pktsout;
75 int h6_pktsin;
76 struct in6_addr h6_addr;
79 static struct hostdata *addhost(int, void *, char *);
81 static struct hostdata4 *h_table4[MAXHASH];
82 static struct hostdata6 *h_table6[MAXHASH];
84 #define iphash(e) ((e) & (MAXHASH-1))
86 /* ARGSUSED */
87 static void
88 wakeup(int n)
90 longjmp(nisjmp, 1);
93 extern char *inet_ntoa();
95 static struct hostdata *
96 iplookup(ipaddr)
97 struct in_addr *ipaddr;
99 register struct hostdata4 *h;
100 struct hostent *hp = NULL;
101 struct netent *np;
102 int error_num;
104 for (h = h_table4[iphash(ipaddr->s_addr)]; h; h = h->h4_next) {
105 if (h->h4_addr.s_addr == ipaddr->s_addr)
106 return ((struct hostdata *)h);
109 /* not found. Put it in */
111 if (ipaddr->s_addr == htonl(INADDR_BROADCAST))
112 return (addhost(AF_INET, ipaddr, "BROADCAST"));
113 if (ipaddr->s_addr == htonl(INADDR_ANY))
114 return (addhost(AF_INET, ipaddr, "OLD-BROADCAST"));
117 * Set an alarm here so we don't get held up by
118 * an unresponsive name server.
119 * Give it 3 sec to do its work.
121 if (setjmp(nisjmp) == 0) {
122 (void) signal(SIGALRM, wakeup);
123 (void) alarm(3);
124 hp = getipnodebyaddr((char *)ipaddr, sizeof (struct in_addr),
125 AF_INET, &error_num);
126 if (hp == NULL && inet_lnaof(*ipaddr) == 0) {
127 np = getnetbyaddr(inet_netof(*ipaddr), AF_INET);
128 if (np)
129 return (addhost(AF_INET, ipaddr, np->n_name));
131 (void) alarm(0);
132 } else {
133 hp = NULL;
136 return (addhost(AF_INET, ipaddr, hp ? hp->h_name : inet_ntoa(*ipaddr)));
139 static struct hostdata *
140 ip6lookup(ip6addr)
141 struct in6_addr *ip6addr;
143 struct hostdata6 *h;
144 struct hostent *hp = NULL;
145 int error_num;
146 char addrstr[INET6_ADDRSTRLEN];
147 char *addname;
148 struct hostdata *retval;
150 for (h = h_table6[iphash(((uint32_t *)ip6addr)[3])]; h;
151 h = h->h6_next) {
152 if (IN6_ARE_ADDR_EQUAL(&h->h6_addr, ip6addr))
153 return ((struct hostdata *)h);
156 /* not in the hash table, put it in */
157 if (IN6_IS_ADDR_UNSPECIFIED(ip6addr))
158 return (addhost(AF_INET6, ip6addr, "UNSPECIFIED"));
161 * Set an alarm here so we don't get held up by
162 * an unresponsive name server.
163 * Give it 3 sec to do its work.
165 if (setjmp(nisjmp) == 0) {
166 (void) signal(SIGALRM, wakeup);
167 (void) alarm(3);
168 hp = getipnodebyaddr(ip6addr, sizeof (struct in6_addr),
169 AF_INET6, &error_num);
170 (void) alarm(0);
171 } else {
172 hp = NULL;
175 if (hp != NULL)
176 addname = hp->h_name;
177 else {
178 (void) inet_ntop(AF_INET6, ip6addr, addrstr, INET6_ADDRSTRLEN);
179 addname = addrstr;
182 retval = addhost(AF_INET6, ip6addr, addname);
183 freehostent(hp);
184 return (retval);
187 static struct hostdata *
188 addhost(family, ipaddr, name)
189 int family;
190 void *ipaddr;
191 char *name;
193 register struct hostdata **hp, *n;
194 int hashval;
196 switch (family) {
197 case AF_INET:
198 n = (struct hostdata *)malloc(sizeof (struct hostdata4));
199 if (n == NULL)
200 goto alloc_failed;
202 (void) memset(n, 0, sizeof (struct hostdata4));
203 n->h_hostname = strdup(name);
204 if (n->h_hostname == NULL)
205 goto alloc_failed;
207 ((struct hostdata4 *)n)->h4_addr = *(struct in_addr *)ipaddr;
208 hashval = ((struct in_addr *)ipaddr)->s_addr;
209 hp = (struct hostdata **)&h_table4[iphash(hashval)];
210 break;
211 case AF_INET6:
212 n = (struct hostdata *)malloc(sizeof (struct hostdata6));
213 if (n == NULL)
214 goto alloc_failed;
216 (void) memset(n, 0, sizeof (struct hostdata6));
217 n->h_hostname = strdup(name);
218 if (n->h_hostname == NULL)
219 goto alloc_failed;
221 (void) memcpy(&((struct hostdata6 *)n)->h6_addr, ipaddr,
222 sizeof (struct in6_addr));
223 hashval = ((int *)ipaddr)[3];
224 hp = (struct hostdata **)&h_table6[iphash(hashval)];
225 break;
226 default:
227 (void) fprintf(stderr,
228 "nfslog: addhost ERROR: Unknown address family: %d",
229 family);
230 return (NULL);
233 n->h_next = *hp;
234 *hp = n;
236 return (n);
238 alloc_failed:
239 (void) fprintf(stderr, "addhost: no mem\n");
240 if (n != NULL)
241 free(n);
242 return (NULL);
245 char *
246 addrtoname(void *sockp)
248 struct hostdata *hostp;
249 int family = ((struct sockaddr_in *)sockp)->sin_family;
251 switch (family) {
252 case AF_INET:
253 hostp = iplookup(&((struct sockaddr_in *)sockp)->sin_addr);
254 break;
255 case AF_INET6:
256 hostp = ip6lookup(&((struct sockaddr_in6 *)sockp)->sin6_addr);
257 break;
258 default:
259 (void) fprintf(stderr, "nfslog: ERROR: unknown address " \
260 "family: %d\n", family);
261 hostp = NULL;
263 return ((hostp != NULL) ? hostp->h_hostname : NULL);