Libinfo-89.tar.gz
[apple/libinfo.git] / netinfo.subproj / sys_interfaces.c
1 /*
2 * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.1 (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.
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,
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.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include "sys_interfaces.h"
29
30 __private_extern__ interface_list_t *
31 sys_interfaces(void)
32 {
33 struct ifconf ifc;
34 struct ifreq *ifr;
35 char buf[1024]; /* XXX */
36 int offset, addrlen, extra, delta;
37 int sock;
38 interface_t *iface;
39 interface_list_t *my_interfaces;
40
41 sock = socket(AF_INET, SOCK_DGRAM, 0);
42
43 if (sock < 0) return NULL;
44
45 ifc.ifc_len = sizeof(buf);
46 ifc.ifc_buf = buf;
47
48 if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
49 {
50 close(sock);
51 return NULL;
52 }
53
54 my_interfaces = (interface_list_t *)malloc(sizeof(interface_list_t));
55 my_interfaces->count = 0;
56 my_interfaces->interface = NULL;
57
58 delta = sizeof(struct ifreq);
59 addrlen = delta - IFNAMSIZ;
60 extra = 0;
61
62 offset = 0;
63
64 while (offset <= ifc.ifc_len)
65 {
66 ifr = (struct ifreq *)(ifc.ifc_buf + offset);
67
68 #ifndef _NO_SOCKADDR_LENGTH_
69 extra = ifr->ifr_addr.sa_len - addrlen;
70 if (extra < 0) extra = 0;
71 #endif
72
73 offset = offset + delta + extra;
74
75 if (ifr->ifr_addr.sa_family != AF_INET) continue;
76 if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue;
77
78 my_interfaces->count++;
79 if (my_interfaces->count == 1)
80 {
81 my_interfaces->interface = (interface_t *)malloc(sizeof(interface_t));
82 }
83 else
84 {
85 my_interfaces->interface = (interface_t *)realloc(my_interfaces->interface, my_interfaces->count * sizeof(interface_t));
86 }
87
88 iface = &(my_interfaces->interface[my_interfaces->count - 1]);
89 memset(iface, 0, sizeof(interface_t));
90
91 memmove(iface->name, ifr->ifr_name, IFNAMSIZ);
92 iface->flags = ifr->ifr_ifru.ifru_flags;
93 iface->addr.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
94 ioctl(sock, SIOCGIFNETMASK, (char *)ifr);
95 iface->mask.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
96 iface->netaddr.s_addr = iface->addr.s_addr & iface->mask.s_addr;
97 iface->bcast.s_addr = iface->netaddr.s_addr | (~iface->mask.s_addr);
98 }
99
100 close(sock);
101 return my_interfaces;
102 }
103
104 __private_extern__ void
105 sys_interfaces_release(interface_list_t *l)
106 {
107 if (l == NULL) return;
108
109 if (l->interface != NULL) free(l->interface);
110 free(l);
111 }
112
113 __private_extern__ int
114 sys_is_my_address(interface_list_t *l, struct in_addr *a)
115 {
116 int i;
117
118 if (l == NULL) return 0;
119
120 for (i = 0; i < l->count; i++)
121 {
122 if (a->s_addr == l->interface[i].addr.s_addr) return 1;
123 }
124 return 0;
125 }
126
127 __private_extern__ int
128 sys_is_my_network(interface_list_t *l, struct in_addr *a)
129 {
130 int i;
131
132 if (l == NULL) return 0;
133
134 for (i = 0; i < l->count; i++)
135 {
136 if ((a->s_addr & l->interface[i].mask.s_addr) ==
137 l->interface[i].netaddr.s_addr) return 1;
138
139 }
140 return 0;
141 }