]> git.saurik.com Git - apple/libinfo.git/blame - lookup.subproj/lu_bootp.c
Libinfo-129.4.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_bootp.c
CommitLineData
03fb6eb0 1/*
3b7c7bd7 2 * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
03fb6eb0
A
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 * Bootp lookup - netinfo only
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28#include <mach/mach.h>
29#include <stdio.h>
3b7c7bd7 30#include <stdlib.h>
03fb6eb0 31#include <string.h>
03fb6eb0
A
32#include <rpc/types.h>
33#include <rpc/xdr.h>
03fb6eb0
A
34#include <sys/socket.h>
35#include <netinet/in.h>
36#include <arpa/inet.h>
37#include <net/if.h>
38#include <netinet/if_ether.h>
3b7c7bd7
A
39#include <pthread.h>
40
41#include "_lu_types.h"
42#include "lookup.h"
43#include "lu_utils.h"
44
45extern struct ether_addr *ether_aton(char *);
46
47static pthread_mutex_t _bootp_lock = PTHREAD_MUTEX_INITIALIZER;
48
49struct bootpent
50{
51 char *b_name;
52 struct ether_addr b_enaddr;
53 struct in_addr b_ipaddr;
54 char *b_bootfile;
55};
56
57static void
58free_bootp(struct bootpent *b)
59{
60 if (b == NULL) return;
61
62 if (b->b_name != NULL) free(b->b_name);
63 if (b->b_bootfile != NULL) free(b->b_bootfile);
64
65 free(b);
66}
67
68static struct bootpent *
69extract_bootp(XDR *xdr)
70{
71 struct bootpent *b;
72 struct ether_addr *e;
73 int i, j, nvals, nkeys, status;
74 char *key, **vals;
75
76 if (xdr == NULL) return NULL;
77
78 if (!xdr_int(xdr, &nkeys)) return NULL;
79
80 b = (struct bootpent *)calloc(1, sizeof(struct bootpent));
81
82 for (i = 0; i < nkeys; i++)
83 {
84 key = NULL;
85 vals = NULL;
86 nvals = 0;
87
88 status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
89 if (status < 0)
90 {
91 free_bootp(b);
92 return NULL;
93 }
94
95 if (nvals == 0)
96 {
97 free(key);
98 continue;
99 }
100
101 j = 0;
102
103 if ((b->b_name == NULL) && (!strcmp("name", key)))
104 {
105 b->b_name = vals[0];
106 j = 1;
107 }
108 if ((b->b_name == NULL) && (!strcmp("bootfile", key)))
109 {
110 b->b_bootfile = vals[0];
111 j = 1;
112 }
113 else if (!strcmp("ip_address", key))
114 {
115 b->b_ipaddr.s_addr = inet_addr(vals[0]);
116 }
117 else if (!strcmp("en_address", key))
118 {
119 pthread_mutex_lock(&_bootp_lock);
120 e = ether_aton(vals[0]);
121 if (e != NULL) memcpy(&(b->b_enaddr), e, sizeof(struct ether_addr));
122 pthread_mutex_unlock(&_bootp_lock);
123 j = 1;
124 }
125
126 free(key);
127 if (vals != NULL)
128 {
129 for (; j < nvals; j++) free(vals[j]);
130 free(vals);
131 }
132 }
133
134 if (b->b_name == NULL) b->b_name = strdup("");
135 if (b->b_bootfile == NULL) b->b_bootfile = strdup("");
136
137 return b;
138}
03fb6eb0
A
139
140static int
141lu_bootp_getbyether(struct ether_addr *enaddr, char **name,
142 struct in_addr *ipaddr, char **bootfile)
143{
144 unsigned datalen;
3b7c7bd7
A
145 XDR inxdr;
146 struct bootpent *b;
03fb6eb0 147 static int proc = -1;
3b7c7bd7
A
148 char *lookup_buf;
149 int count;
150
03fb6eb0
A
151 if (proc < 0)
152 {
153 if (_lookup_link(_lu_port, "bootp_getbyether", &proc) != KERN_SUCCESS)
154 {
3b7c7bd7 155 return 0;
03fb6eb0
A
156 }
157 }
158
3b7c7bd7
A
159 datalen = 0;
160 lookup_buf = NULL;
161
162 if (_lookup_all(_lu_port, proc, (unit *)enaddr, ((sizeof(*enaddr) + sizeof(unit) - 1) / sizeof(unit)), &lookup_buf, &datalen) != KERN_SUCCESS)
03fb6eb0 163 {
3b7c7bd7 164 return 0;
03fb6eb0
A
165 }
166
167 datalen *= BYTES_PER_XDR_UNIT;
3b7c7bd7
A
168 if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
169
170 xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
171
172 count = 0;
173 if (!xdr_int(&inxdr, &count))
03fb6eb0 174 {
3b7c7bd7
A
175 xdr_destroy(&inxdr);
176 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
177 return 0;
03fb6eb0
A
178 }
179
3b7c7bd7
A
180 if (count == 0)
181 {
182 xdr_destroy(&inxdr);
183 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
184 return 0;
185 }
03fb6eb0 186
3b7c7bd7
A
187 b = extract_bootp(&inxdr);
188 xdr_destroy(&inxdr);
189
190 *name = b->b_name;
191 *bootfile = b->b_bootfile;
192 ipaddr->s_addr = b->b_ipaddr.s_addr;
193
194 free(b);
195 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
196
197 return 1;
03fb6eb0
A
198}
199
200static int
201lu_bootp_getbyip(struct ether_addr *enaddr, char **name,
202 struct in_addr *ipaddr, char **bootfile)
203{
204 unsigned datalen;
3b7c7bd7
A
205 XDR inxdr;
206 struct bootpent *b;
03fb6eb0 207 static int proc = -1;
3b7c7bd7
A
208 char *lookup_buf;
209 int count;
03fb6eb0
A
210
211 if (proc < 0)
212 {
213 if (_lookup_link(_lu_port, "bootp_getbyip", &proc) != KERN_SUCCESS)
214 {
3b7c7bd7 215 return 0;
03fb6eb0
A
216 }
217 }
218
3b7c7bd7
A
219 datalen = 0;
220 lookup_buf = NULL;
221
222 if (_lookup_all(_lu_port, proc, (unit *)ipaddr, ((sizeof(*ipaddr) + sizeof(unit) - 1) / sizeof(unit)), &lookup_buf, &datalen) != KERN_SUCCESS)
03fb6eb0 223 {
3b7c7bd7 224 return 0;
03fb6eb0
A
225 }
226
227 datalen *= BYTES_PER_XDR_UNIT;
3b7c7bd7
A
228 if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
229
230 xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
231
232 count = 0;
233 if (!xdr_int(&inxdr, &count))
234 {
235 xdr_destroy(&inxdr);
236 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
237 return 0;
238 }
239
240 if (count == 0)
03fb6eb0 241 {
3b7c7bd7
A
242 xdr_destroy(&inxdr);
243 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
244 return 0;
03fb6eb0
A
245 }
246
3b7c7bd7
A
247 b = extract_bootp(&inxdr);
248 xdr_destroy(&inxdr);
03fb6eb0 249
3b7c7bd7
A
250 *name = b->b_name;
251 *bootfile = b->b_bootfile;
252 memcpy(enaddr, &(b->b_enaddr), sizeof(struct ether_addr));
253
254 free(b);
255 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
256
257 return 1;
03fb6eb0
A
258}
259
260int
3b7c7bd7 261bootp_getbyether(struct ether_addr *enaddr, char **name,struct in_addr *ipaddr, char **bootfile)
03fb6eb0
A
262{
263 if (_lu_running())
3b7c7bd7 264 {
03fb6eb0 265 return (lu_bootp_getbyether(enaddr, name, ipaddr, bootfile));
3b7c7bd7
A
266 }
267 return 0;
03fb6eb0
A
268}
269
270int
3b7c7bd7 271bootp_getbyip(struct ether_addr *enaddr, char **name, struct in_addr *ipaddr, char **bootfile)
03fb6eb0
A
272{
273 if (_lu_running())
3b7c7bd7 274 {
03fb6eb0 275 return (lu_bootp_getbyip(enaddr, name, ipaddr, bootfile));
3b7c7bd7
A
276 }
277 return 0;
03fb6eb0
A
278}
279