dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fs.d / nfs / nfslog / nfslog_ipaddr.c
blob979de0d2dc73a0cb6fcf78de51bf63fb7a963793
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 #include <stdio.h>
28 #include <ctype.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31 #include <malloc.h>
32 #include <sys/socket.h>
33 #include <sys/sockio.h>
34 #include <arpa/inet.h>
35 #include <net/if.h>
36 #include <netinet/in.h>
37 #include <netinet/in_systm.h>
38 #include <netinet/if_ether.h>
39 #include <netinet/ip.h>
40 #include <netdb.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <setjmp.h>
46 * Note: If making changes to this file, check also the file
47 * cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c
48 * as it has the same functions there.
50 static jmp_buf nisjmp;
52 #define MAXHASH 1024 /* must be a power of 2 */
54 struct hostdata {
55 struct hostdata *h_next;
56 char *h_hostname;
57 int h_pktsout;
58 int h_pktsin;
61 struct hostdata4 {
62 struct hostdata4 *h4_next;
63 char *h4_hostname;
64 int h4_pktsout;
65 int h4_pktsin;
66 struct in_addr h4_addr;
69 struct hostdata6 {
70 struct hostdata6 *h6_next;
71 char *h6_hostname;
72 int h6_pktsout;
73 int h6_pktsin;
74 struct in6_addr h6_addr;
77 static struct hostdata *addhost(int, void *, char *);
79 static struct hostdata4 *h_table4[MAXHASH];
80 static struct hostdata6 *h_table6[MAXHASH];
82 #define iphash(e) ((e) & (MAXHASH-1))
84 /* ARGSUSED */
85 static void
86 wakeup(int n)
88 longjmp(nisjmp, 1);
91 extern char *inet_ntoa();
93 static struct hostdata *
94 iplookup(ipaddr)
95 struct in_addr *ipaddr;
97 register struct hostdata4 *h;
98 struct hostent *hp = NULL;
99 struct netent *np;
100 int error_num;
102 for (h = h_table4[iphash(ipaddr->s_addr)]; h; h = h->h4_next) {
103 if (h->h4_addr.s_addr == ipaddr->s_addr)
104 return ((struct hostdata *)h);
107 /* not found. Put it in */
109 if (ipaddr->s_addr == htonl(INADDR_BROADCAST))
110 return (addhost(AF_INET, ipaddr, "BROADCAST"));
111 if (ipaddr->s_addr == htonl(INADDR_ANY))
112 return (addhost(AF_INET, ipaddr, "OLD-BROADCAST"));
115 * Set an alarm here so we don't get held up by
116 * an unresponsive name server.
117 * Give it 3 sec to do its work.
119 if (setjmp(nisjmp) == 0) {
120 (void) signal(SIGALRM, wakeup);
121 (void) alarm(3);
122 hp = getipnodebyaddr((char *)ipaddr, sizeof (struct in_addr),
123 AF_INET, &error_num);
124 if (hp == NULL && inet_lnaof(*ipaddr) == 0) {
125 np = getnetbyaddr(inet_netof(*ipaddr), AF_INET);
126 if (np)
127 return (addhost(AF_INET, ipaddr, np->n_name));
129 (void) alarm(0);
130 } else {
131 hp = NULL;
134 return (addhost(AF_INET, ipaddr, hp ? hp->h_name : inet_ntoa(*ipaddr)));
137 static struct hostdata *
138 ip6lookup(ip6addr)
139 struct in6_addr *ip6addr;
141 struct hostdata6 *h;
142 struct hostent *hp = NULL;
143 int error_num;
144 char addrstr[INET6_ADDRSTRLEN];
145 char *addname;
146 struct hostdata *retval;
148 for (h = h_table6[iphash(((uint32_t *)ip6addr)[3])]; h;
149 h = h->h6_next) {
150 if (IN6_ARE_ADDR_EQUAL(&h->h6_addr, ip6addr))
151 return ((struct hostdata *)h);
154 /* not in the hash table, put it in */
155 if (IN6_IS_ADDR_UNSPECIFIED(ip6addr))
156 return (addhost(AF_INET6, ip6addr, "UNSPECIFIED"));
159 * Set an alarm here so we don't get held up by
160 * an unresponsive name server.
161 * Give it 3 sec to do its work.
163 if (setjmp(nisjmp) == 0) {
164 (void) signal(SIGALRM, wakeup);
165 (void) alarm(3);
166 hp = getipnodebyaddr(ip6addr, sizeof (struct in6_addr),
167 AF_INET6, &error_num);
168 (void) alarm(0);
169 } else {
170 hp = NULL;
173 if (hp != NULL)
174 addname = hp->h_name;
175 else {
176 (void) inet_ntop(AF_INET6, ip6addr, addrstr, INET6_ADDRSTRLEN);
177 addname = addrstr;
180 retval = addhost(AF_INET6, ip6addr, addname);
181 freehostent(hp);
182 return (retval);
185 static struct hostdata *
186 addhost(family, ipaddr, name)
187 int family;
188 void *ipaddr;
189 char *name;
191 register struct hostdata **hp, *n;
192 int hashval;
194 switch (family) {
195 case AF_INET:
196 n = (struct hostdata *)malloc(sizeof (struct hostdata4));
197 if (n == NULL)
198 goto alloc_failed;
200 (void) memset(n, 0, sizeof (struct hostdata4));
201 n->h_hostname = strdup(name);
202 if (n->h_hostname == NULL)
203 goto alloc_failed;
205 ((struct hostdata4 *)n)->h4_addr = *(struct in_addr *)ipaddr;
206 hashval = ((struct in_addr *)ipaddr)->s_addr;
207 hp = (struct hostdata **)&h_table4[iphash(hashval)];
208 break;
209 case AF_INET6:
210 n = (struct hostdata *)malloc(sizeof (struct hostdata6));
211 if (n == NULL)
212 goto alloc_failed;
214 (void) memset(n, 0, sizeof (struct hostdata6));
215 n->h_hostname = strdup(name);
216 if (n->h_hostname == NULL)
217 goto alloc_failed;
219 (void) memcpy(&((struct hostdata6 *)n)->h6_addr, ipaddr,
220 sizeof (struct in6_addr));
221 hashval = ((int *)ipaddr)[3];
222 hp = (struct hostdata **)&h_table6[iphash(hashval)];
223 break;
224 default:
225 (void) fprintf(stderr,
226 "nfslog: addhost ERROR: Unknown address family: %d",
227 family);
228 return (NULL);
231 n->h_next = *hp;
232 *hp = n;
234 return (n);
236 alloc_failed:
237 (void) fprintf(stderr, "addhost: no mem\n");
238 free(n);
239 return (NULL);
242 char *
243 addrtoname(void *sockp)
245 struct hostdata *hostp;
246 int family = ((struct sockaddr_in *)sockp)->sin_family;
248 switch (family) {
249 case AF_INET:
250 hostp = iplookup(&((struct sockaddr_in *)sockp)->sin_addr);
251 break;
252 case AF_INET6:
253 hostp = ip6lookup(&((struct sockaddr_in6 *)sockp)->sin6_addr);
254 break;
255 default:
256 (void) fprintf(stderr, "nfslog: ERROR: unknown address " \
257 "family: %d\n", family);
258 hostp = NULL;
260 return ((hostp != NULL) ? hostp->h_hostname : NULL);