]>
Commit | Line | Data |
---|---|---|
b7080c8e A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
a2c93a76 A |
6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.0 (the 'License'). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
b7080c8e A |
13 | * |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
a2c93a76 A |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License." | |
b7080c8e A |
21 | * |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | /* | |
25 | * Copyright (c) 1983, 1988, 1993 | |
26 | * The Regents of the University of California. All rights reserved. | |
27 | * | |
28 | * Redistribution and use in source and binary forms, with or without | |
29 | * modification, are permitted provided that the following conditions | |
30 | * are met: | |
31 | * 1. Redistributions of source code must retain the above copyright | |
32 | * notice, this list of conditions and the following disclaimer. | |
33 | * 2. Redistributions in binary form must reproduce the above copyright | |
34 | * notice, this list of conditions and the following disclaimer in the | |
35 | * documentation and/or other materials provided with the distribution. | |
36 | * 3. All advertising materials mentioning features or use of this software | |
37 | * must display the following acknowledgment: | |
38 | * This product includes software developed by the University of | |
39 | * California, Berkeley and its contributors. | |
40 | * 4. Neither the name of the University nor the names of its contributors | |
41 | * may be used to endorse or promote products derived from this software | |
42 | * without specific prior written permission. | |
43 | * | |
44 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
45 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
47 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
48 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
49 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
50 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
51 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
53 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
54 | * SUCH DAMAGE. | |
55 | * | |
56 | * @(#)defs.h 8.1 (Berkeley) 6/5/93 | |
57 | */ | |
58 | ||
59 | ||
60 | /* | |
61 | * Routing Table Management Daemon | |
62 | */ | |
63 | #include "defs.h" | |
64 | #include <sys/ioctl.h> | |
65 | #include <sys/sysctl.h> | |
66 | #include <net/if.h> | |
67 | #include <net/if_dl.h> | |
68 | #include <syslog.h> | |
69 | #include <stdlib.h> | |
70 | #include "pathnames.h" | |
71 | ||
72 | struct interface *ifnet; | |
73 | struct interface **ifnext = &ifnet; | |
74 | int lookforinterfaces = 1; | |
75 | int externalinterfaces = 0; /* # of remote and local interfaces */ | |
76 | int foundloopback; /* valid flag for loopaddr */ | |
77 | struct sockaddr loopaddr; /* our address on loopback */ | |
78 | ||
79 | ||
80 | void | |
81 | quit(s) | |
82 | char *s; | |
83 | { | |
84 | extern int errno; | |
85 | int sverrno = errno; | |
86 | ||
87 | (void) fprintf(stderr, "route: "); | |
88 | if (s) | |
89 | (void) fprintf(stderr, "%s: ", s); | |
90 | (void) fprintf(stderr, "%s\n", strerror(sverrno)); | |
91 | exit(1); | |
92 | /* NOTREACHED */ | |
93 | } | |
94 | ||
95 | struct rt_addrinfo info; | |
96 | /* Sleazy use of local variables throughout file, warning!!!! */ | |
97 | #define netmask info.rti_info[RTAX_NETMASK] | |
98 | #define ifaaddr info.rti_info[RTAX_IFA] | |
99 | #define brdaddr info.rti_info[RTAX_BRD] | |
100 | ||
101 | #define ROUNDUP(a) \ | |
102 | ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) | |
103 | #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) | |
104 | ||
105 | void | |
106 | rt_xaddrs(cp, cplim, rtinfo) | |
107 | register caddr_t cp, cplim; | |
108 | register struct rt_addrinfo *rtinfo; | |
109 | { | |
110 | register struct sockaddr *sa; | |
111 | register int i; | |
112 | ||
113 | memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info)); | |
114 | for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { | |
115 | if ((rtinfo->rti_addrs & (1 << i)) == 0) | |
116 | continue; | |
117 | rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; | |
118 | ADVANCE(cp, sa); | |
119 | } | |
120 | } | |
121 | ||
122 | /* | |
123 | * Find the network interfaces which have configured themselves. | |
124 | * If the interface is present but not yet up (for example an | |
125 | * ARPANET IMP), set the lookforinterfaces flag so we'll | |
126 | * come back later and look again. | |
127 | */ | |
128 | ifinit() | |
129 | { | |
130 | struct interface ifs, *ifp; | |
131 | size_t needed; | |
132 | int mib[6], no_ipaddr = 0, flags = 0; | |
133 | char *buf, *cplim, *cp; | |
134 | register struct if_msghdr *ifm; | |
135 | register struct ifa_msghdr *ifam; | |
136 | struct sockaddr_dl *sdl; | |
137 | struct sockaddr_in *sin; | |
138 | u_long i; | |
139 | ||
140 | mib[0] = CTL_NET; | |
141 | mib[1] = PF_ROUTE; | |
142 | mib[2] = 0; | |
143 | mib[3] = AF_INET; | |
144 | mib[4] = NET_RT_IFLIST; | |
145 | mib[5] = 0; | |
146 | if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) | |
147 | quit("route-sysctl-estimate"); | |
148 | if ((buf = malloc(needed)) == NULL) | |
149 | quit("malloc"); | |
150 | if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) | |
151 | quit("actual retrieval of interface table"); | |
152 | lookforinterfaces = 0; | |
153 | cplim = buf + needed; | |
154 | for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) { | |
155 | ifm = (struct if_msghdr *)cp; | |
156 | if (ifm->ifm_type == RTM_IFINFO) { | |
157 | memset(&ifs, 0, sizeof(ifs)); | |
158 | ifs.int_flags = flags = (0xffff & ifm->ifm_flags) | IFF_INTERFACE; | |
159 | if ((flags & IFF_UP) == 0 || no_ipaddr) | |
160 | lookforinterfaces = 1; | |
161 | sdl = (struct sockaddr_dl *) (ifm + 1); | |
162 | sdl->sdl_data[sdl->sdl_nlen] = 0; | |
163 | no_ipaddr = 1; | |
164 | continue; | |
165 | } | |
166 | if (ifm->ifm_type != RTM_NEWADDR) | |
167 | quit("ifinit: out of sync"); | |
168 | if ((flags & IFF_UP) == 0) | |
169 | continue; | |
170 | ifam = (struct ifa_msghdr *)ifm; | |
171 | info.rti_addrs = ifam->ifam_addrs; | |
172 | rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info); | |
173 | if (ifaaddr == 0) { | |
174 | syslog(LOG_ERR, "%s: (get addr)", sdl->sdl_data); | |
175 | continue; | |
176 | } | |
177 | ifs.int_addr = *ifaaddr; | |
178 | if (ifs.int_addr.sa_family != AF_INET) | |
179 | continue; | |
180 | no_ipaddr = 0; | |
181 | if (ifs.int_flags & IFF_POINTOPOINT) { | |
182 | if (brdaddr == 0) { | |
183 | syslog(LOG_ERR, "%s: (get dstaddr)", | |
184 | sdl->sdl_data); | |
185 | continue; | |
186 | } | |
187 | if (brdaddr->sa_family == AF_UNSPEC) { | |
188 | lookforinterfaces = 1; | |
189 | continue; | |
190 | } | |
191 | ifs.int_dstaddr = *brdaddr; | |
192 | } | |
193 | /* | |
194 | * already known to us? | |
195 | * This allows multiple point-to-point links | |
196 | * to share a source address (possibly with one | |
197 | * other link), but assumes that there will not be | |
198 | * multiple links with the same destination address. | |
199 | */ | |
200 | if (ifs.int_flags & IFF_POINTOPOINT) { | |
201 | if (if_ifwithdstaddr(&ifs.int_dstaddr)) | |
202 | continue; | |
203 | } else if (if_ifwithaddr(&ifs.int_addr)) | |
204 | continue; | |
205 | if (ifs.int_flags & IFF_LOOPBACK) { | |
206 | ifs.int_flags |= IFF_PASSIVE; | |
207 | foundloopback = 1; | |
208 | loopaddr = ifs.int_addr; | |
209 | for (ifp = ifnet; ifp; ifp = ifp->int_next) | |
210 | if (ifp->int_flags & IFF_POINTOPOINT) | |
211 | add_ptopt_localrt(ifp); | |
212 | } | |
213 | if (ifs.int_flags & IFF_BROADCAST) { | |
214 | if (brdaddr == 0) { | |
215 | syslog(LOG_ERR, "%s: (get broadaddr)", | |
216 | sdl->sdl_data); | |
217 | continue; | |
218 | } | |
219 | ifs.int_dstaddr = *brdaddr; | |
220 | } | |
221 | /* | |
222 | * Use a minimum metric of one; | |
223 | * treat the interface metric (default 0) | |
224 | * as an increment to the hop count of one. | |
225 | */ | |
226 | ifs.int_metric = ifam->ifam_metric + 1; | |
227 | if (netmask == 0) { | |
228 | syslog(LOG_ERR, "%s: (get netmask)", | |
229 | sdl->sdl_data); | |
230 | continue; | |
231 | } | |
232 | sin = (struct sockaddr_in *)netmask; | |
233 | ifs.int_subnetmask = ntohl(sin->sin_addr.s_addr); | |
234 | sin = (struct sockaddr_in *)&ifs.int_addr; | |
235 | i = ntohl(sin->sin_addr.s_addr); | |
236 | if (IN_CLASSA(i)) | |
237 | ifs.int_netmask = IN_CLASSA_NET; | |
238 | else if (IN_CLASSB(i)) | |
239 | ifs.int_netmask = IN_CLASSB_NET; | |
240 | else | |
241 | ifs.int_netmask = IN_CLASSC_NET; | |
242 | ifs.int_net = i & ifs.int_netmask; | |
243 | ifs.int_subnet = i & ifs.int_subnetmask; | |
244 | if (ifs.int_subnetmask != ifs.int_netmask) | |
245 | ifs.int_flags |= IFF_SUBNET; | |
246 | ifp = (struct interface *) | |
247 | malloc(sdl->sdl_nlen + 1 + sizeof(ifs)); | |
248 | if (ifp == 0) { | |
249 | printf("routed: out of memory\n"); | |
250 | lookforinterfaces = 1; | |
251 | break; | |
252 | } | |
253 | *ifp = ifs; | |
254 | /* | |
255 | * Count the # of directly connected networks | |
256 | * and point to point links which aren't looped | |
257 | * back to ourself. This is used below to | |
258 | * decide if we should be a routing ``supplier''. | |
259 | */ | |
260 | if ((ifs.int_flags & IFF_LOOPBACK) == 0 && | |
261 | ((ifs.int_flags & IFF_POINTOPOINT) == 0 || | |
262 | if_ifwithaddr(&ifs.int_dstaddr) == 0)) | |
263 | externalinterfaces++; | |
264 | /* | |
265 | * If we have a point-to-point link, we want to act | |
266 | * as a supplier even if it's our only interface, | |
267 | * as that's the only way our peer on the other end | |
268 | * can tell that the link is up. | |
269 | */ | |
270 | if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0) | |
271 | supplier = 1; | |
272 | ifp->int_name = (char *)(ifp + 1); | |
273 | strcpy(ifp->int_name, sdl->sdl_data); | |
274 | *ifnext = ifp; | |
275 | ifnext = &ifp->int_next; | |
276 | traceinit(ifp); | |
277 | addrouteforif(ifp); | |
278 | } | |
279 | if (externalinterfaces > 1 && supplier < 0) | |
280 | supplier = 1; | |
281 | free(buf); | |
282 | } | |
283 | ||
284 | /* | |
285 | * Add route for interface if not currently installed. | |
286 | * Create route to other end if a point-to-point link, | |
287 | * otherwise a route to this (sub)network. | |
288 | * INTERNET SPECIFIC. | |
289 | */ | |
290 | addrouteforif(ifp) | |
291 | register struct interface *ifp; | |
292 | { | |
293 | struct sockaddr_in net; | |
294 | struct sockaddr *dst; | |
295 | int state; | |
296 | register struct rt_entry *rt; | |
297 | ||
298 | if (ifp->int_flags & IFF_POINTOPOINT) | |
299 | dst = &ifp->int_dstaddr; | |
300 | else { | |
301 | memset(&net, 0, sizeof (net)); | |
302 | net.sin_family = AF_INET; | |
303 | net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY); | |
304 | dst = (struct sockaddr *)&net; | |
305 | } | |
306 | rt = rtfind(dst); | |
307 | if (rt && | |
308 | (rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE) | |
309 | return; | |
310 | if (rt) | |
311 | rtdelete(rt); | |
312 | /* | |
313 | * If interface on subnetted network, | |
314 | * install route to network as well. | |
315 | * This is meant for external viewers. | |
316 | */ | |
317 | if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) { | |
318 | struct in_addr subnet; | |
319 | ||
320 | subnet = net.sin_addr; | |
321 | net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY); | |
322 | rt = rtfind(dst); | |
323 | if (rt == 0) | |
324 | rtadd(dst, &ifp->int_addr, ifp->int_metric, | |
325 | ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) | | |
326 | RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET)); | |
327 | else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) == | |
328 | (RTS_INTERNAL|RTS_SUBNET) && | |
329 | ifp->int_metric < rt->rt_metric) | |
330 | rtchange(rt, &rt->rt_router, ifp->int_metric); | |
331 | net.sin_addr = subnet; | |
332 | } | |
333 | if (ifp->int_transitions++ > 0) | |
334 | syslog(LOG_ERR, "re-installing interface %s", ifp->int_name); | |
335 | state = ifp->int_flags & | |
336 | (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET); | |
337 | if (ifp->int_flags & IFF_POINTOPOINT && | |
338 | (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) & | |
339 | ifp->int_netmask) != ifp->int_net) | |
340 | state &= ~RTS_SUBNET; | |
341 | if (ifp->int_flags & IFF_LOOPBACK) | |
342 | state |= RTS_EXTERNAL; | |
343 | rtadd(dst, &ifp->int_addr, ifp->int_metric, state); | |
344 | if (ifp->int_flags & IFF_POINTOPOINT && foundloopback) | |
345 | add_ptopt_localrt(ifp); | |
346 | } | |
347 | ||
348 | /* | |
349 | * Add route to local end of point-to-point using loopback. | |
350 | * If a route to this network is being sent to neighbors on other nets, | |
351 | * mark this route as subnet so we don't have to propagate it too. | |
352 | */ | |
353 | add_ptopt_localrt(ifp) | |
354 | register struct interface *ifp; | |
355 | { | |
356 | struct rt_entry *rt; | |
357 | struct sockaddr *dst; | |
358 | struct sockaddr_in net; | |
359 | int state; | |
360 | ||
361 | state = RTS_INTERFACE | RTS_PASSIVE; | |
362 | ||
363 | /* look for route to logical network */ | |
364 | memset(&net, 0, sizeof (net)); | |
365 | net.sin_family = AF_INET; | |
366 | net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY); | |
367 | dst = (struct sockaddr *)&net; | |
368 | rt = rtfind(dst); | |
369 | if (rt && rt->rt_state & RTS_INTERNAL) | |
370 | state |= RTS_SUBNET; | |
371 | ||
372 | dst = &ifp->int_addr; | |
373 | if (rt = rtfind(dst)) { | |
374 | if (rt && rt->rt_state & RTS_INTERFACE) | |
375 | return; | |
376 | rtdelete(rt); | |
377 | } | |
378 | rtadd(dst, &loopaddr, 1, state); | |
379 | } | |
380 | ||
381 | /* | |
382 | * As a concession to the ARPANET we read a list of gateways | |
383 | * from /etc/gateways and add them to our tables. This file | |
384 | * exists at each ARPANET gateway and indicates a set of ``remote'' | |
385 | * gateways (i.e. a gateway which we can't immediately determine | |
386 | * if it's present or not as we can do for those directly connected | |
387 | * at the hardware level). If a gateway is marked ``passive'' | |
388 | * in the file, then we assume it doesn't have a routing process | |
389 | * of our design and simply assume it's always present. Those | |
390 | * not marked passive are treated as if they were directly | |
391 | * connected -- they're added into the interface list so we'll | |
392 | * send them routing updates. | |
393 | * | |
394 | * PASSIVE ENTRIES AREN'T NEEDED OR USED ON GATEWAYS RUNNING EGP. | |
395 | */ | |
396 | gwkludge() | |
397 | { | |
398 | struct sockaddr_in dst, gate; | |
399 | FILE *fp; | |
400 | char *type, *dname, *gname, *qual, buf[BUFSIZ]; | |
401 | struct interface *ifp; | |
402 | int metric, n; | |
403 | struct rt_entry route; | |
404 | ||
405 | fp = fopen(_PATH_GATEWAYS, "r"); | |
406 | if (fp == NULL) | |
407 | return; | |
408 | qual = buf; | |
409 | dname = buf + 64; | |
410 | gname = buf + ((BUFSIZ - 64) / 3); | |
411 | type = buf + (((BUFSIZ - 64) * 2) / 3); | |
412 | memset(&dst, 0, sizeof (dst)); | |
413 | memset(&gate, 0, sizeof (gate)); | |
414 | memset(&route, 0, sizeof(route)); | |
415 | /* format: {net | host} XX gateway XX metric DD [passive | external]\n */ | |
416 | #define readentry(fp) \ | |
417 | fscanf((fp), "%s %s gateway %s metric %d %s\n", \ | |
418 | type, dname, gname, &metric, qual) | |
419 | for (;;) { | |
420 | if ((n = readentry(fp)) == EOF) | |
421 | break; | |
422 | if (!getnetorhostname(type, dname, &dst)) | |
423 | continue; | |
424 | if (!gethostnameornumber(gname, &gate)) | |
425 | continue; | |
426 | if (metric == 0) /* XXX */ | |
427 | metric = 1; | |
428 | if (strcmp(qual, "passive") == 0) { | |
429 | /* | |
430 | * Passive entries aren't placed in our tables, | |
431 | * only the kernel's, so we don't copy all of the | |
432 | * external routing information within a net. | |
433 | * Internal machines should use the default | |
434 | * route to a suitable gateway (like us). | |
435 | */ | |
436 | route.rt_dst = *(struct sockaddr *) &dst; | |
437 | route.rt_router = *(struct sockaddr *) &gate; | |
438 | route.rt_flags = RTF_UP; | |
439 | if (strcmp(type, "host") == 0) | |
440 | route.rt_flags |= RTF_HOST; | |
441 | if (metric) | |
442 | route.rt_flags |= RTF_GATEWAY; | |
443 | (void) rtioctl(ADD, &route.rt_rt); | |
444 | continue; | |
445 | } | |
446 | if (strcmp(qual, "external") == 0) { | |
447 | /* | |
448 | * Entries marked external are handled | |
449 | * by other means, e.g. EGP, | |
450 | * and are placed in our tables only | |
451 | * to prevent overriding them | |
452 | * with something else. | |
453 | */ | |
454 | rtadd(&dst, &gate, metric, RTS_EXTERNAL|RTS_PASSIVE); | |
455 | continue; | |
456 | } | |
457 | /* assume no duplicate entries */ | |
458 | externalinterfaces++; | |
459 | ifp = (struct interface *)malloc(sizeof (*ifp)); | |
460 | memset(ifp, 0, sizeof (*ifp)); | |
461 | ifp->int_flags = IFF_REMOTE; | |
462 | /* can't identify broadcast capability */ | |
463 | ifp->int_net = inet_netof(dst.sin_addr); | |
464 | if (strcmp(type, "host") == 0) { | |
465 | ifp->int_flags |= IFF_POINTOPOINT; | |
466 | ifp->int_dstaddr = *((struct sockaddr *)&dst); | |
467 | } | |
468 | ifp->int_addr = *((struct sockaddr *)&gate); | |
469 | ifp->int_metric = metric; | |
470 | ifp->int_next = ifnet; | |
471 | ifnet = ifp; | |
472 | addrouteforif(ifp); | |
473 | } | |
474 | fclose(fp); | |
475 | } | |
476 | ||
477 | getnetorhostname(type, name, sin) | |
478 | char *type, *name; | |
479 | struct sockaddr_in *sin; | |
480 | { | |
481 | ||
482 | if (strcmp(type, "net") == 0) { | |
483 | struct netent *np = getnetbyname(name); | |
484 | int n; | |
485 | ||
486 | if (np == 0) | |
487 | n = inet_network(name); | |
488 | else { | |
489 | if (np->n_addrtype != AF_INET) | |
490 | return (0); | |
491 | n = np->n_net; | |
492 | /* | |
493 | * getnetbyname returns right-adjusted value. | |
494 | */ | |
495 | if (n < 128) | |
496 | n <<= IN_CLASSA_NSHIFT; | |
497 | else if (n < 65536) | |
498 | n <<= IN_CLASSB_NSHIFT; | |
499 | else | |
500 | n <<= IN_CLASSC_NSHIFT; | |
501 | } | |
502 | sin->sin_family = AF_INET; | |
503 | sin->sin_addr = inet_makeaddr(n, INADDR_ANY); | |
504 | return (1); | |
505 | } | |
506 | if (strcmp(type, "host") == 0) { | |
507 | struct hostent *hp = gethostbyname(name); | |
508 | ||
509 | if (hp == 0) | |
510 | sin->sin_addr.s_addr = inet_addr(name); | |
511 | else { | |
512 | if (hp->h_addrtype != AF_INET) | |
513 | return (0); | |
514 | memmove(&sin->sin_addr, hp->h_addr, hp->h_length); | |
515 | } | |
516 | sin->sin_family = AF_INET; | |
517 | return (1); | |
518 | } | |
519 | return (0); | |
520 | } | |
521 | ||
522 | gethostnameornumber(name, sin) | |
523 | char *name; | |
524 | struct sockaddr_in *sin; | |
525 | { | |
526 | struct hostent *hp; | |
527 | ||
528 | hp = gethostbyname(name); | |
529 | if (hp) { | |
530 | memmove(&sin->sin_addr, hp->h_addr, hp->h_length); | |
531 | sin->sin_family = hp->h_addrtype; | |
532 | return (1); | |
533 | } | |
534 | sin->sin_addr.s_addr = inet_addr(name); | |
535 | sin->sin_family = AF_INET; | |
536 | return (sin->sin_addr.s_addr != -1); | |
537 | } |