2 * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Bootp lookup - netinfo only
27 * Copyright (C) 1989 by NeXT, Inc.
29 #include <mach/mach.h>
33 #include <rpc/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
39 #include <netinet/if_ether.h>
40 #include <net/ethernet.h>
43 #include "_lu_types.h"
47 extern struct ether_addr
*ether_aton(char *);
49 static pthread_mutex_t _bootp_lock
= PTHREAD_MUTEX_INITIALIZER
;
54 struct ether_addr b_enaddr
;
55 struct in_addr b_ipaddr
;
60 free_bootp(struct bootpent
*b
)
62 if (b
== NULL
) return;
64 if (b
->b_name
!= NULL
) free(b
->b_name
);
65 if (b
->b_bootfile
!= NULL
) free(b
->b_bootfile
);
70 static struct bootpent
*
71 extract_bootp(XDR
*xdr
)
75 int i
, j
, nvals
, nkeys
, status
;
78 if (xdr
== NULL
) return NULL
;
80 if (!xdr_int(xdr
, &nkeys
)) return NULL
;
82 b
= (struct bootpent
*)calloc(1, sizeof(struct bootpent
));
84 for (i
= 0; i
< nkeys
; i
++)
90 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
105 if ((b
->b_name
== NULL
) && (!strcmp("name", key
)))
110 if ((b
->b_name
== NULL
) && (!strcmp("bootfile", key
)))
112 b
->b_bootfile
= vals
[0];
115 else if (!strcmp("ip_address", key
))
117 b
->b_ipaddr
.s_addr
= inet_addr(vals
[0]);
119 else if (!strcmp("en_address", key
))
121 pthread_mutex_lock(&_bootp_lock
);
122 e
= ether_aton(vals
[0]);
123 if (e
!= NULL
) memcpy(&(b
->b_enaddr
), e
, sizeof(struct ether_addr
));
124 pthread_mutex_unlock(&_bootp_lock
);
131 for (; j
< nvals
; j
++) free(vals
[j
]);
136 if (b
->b_name
== NULL
) b
->b_name
= strdup("");
137 if (b
->b_bootfile
== NULL
) b
->b_bootfile
= strdup("");
143 lu_bootp_getbyether(struct ether_addr
*enaddr
, char **name
,
144 struct in_addr
*ipaddr
, char **bootfile
)
149 static int proc
= -1;
155 if (_lookup_link(_lu_port
, "bootp_getbyether", &proc
) != KERN_SUCCESS
)
164 if (_lookup_all(_lu_port
, proc
, (unit
*)enaddr
, ((sizeof(*enaddr
) + sizeof(unit
) - 1) / sizeof(unit
)), &lookup_buf
, &datalen
) != KERN_SUCCESS
)
169 datalen
*= BYTES_PER_XDR_UNIT
;
170 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
172 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
175 if (!xdr_int(&inxdr
, &count
))
178 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
185 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
189 b
= extract_bootp(&inxdr
);
193 *bootfile
= b
->b_bootfile
;
194 ipaddr
->s_addr
= b
->b_ipaddr
.s_addr
;
197 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
203 lu_bootp_getbyip(struct ether_addr
*enaddr
, char **name
,
204 struct in_addr
*ipaddr
, char **bootfile
)
209 static int proc
= -1;
215 if (_lookup_link(_lu_port
, "bootp_getbyip", &proc
) != KERN_SUCCESS
)
224 if (_lookup_all(_lu_port
, proc
, (unit
*)ipaddr
, ((sizeof(*ipaddr
) + sizeof(unit
) - 1) / sizeof(unit
)), &lookup_buf
, &datalen
) != KERN_SUCCESS
)
229 datalen
*= BYTES_PER_XDR_UNIT
;
230 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
232 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
235 if (!xdr_int(&inxdr
, &count
))
238 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
245 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
249 b
= extract_bootp(&inxdr
);
253 *bootfile
= b
->b_bootfile
;
254 memcpy(enaddr
, &(b
->b_enaddr
), sizeof(struct ether_addr
));
257 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
263 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
267 return (lu_bootp_getbyether(enaddr
, name
, ipaddr
, bootfile
));
273 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
277 return (lu_bootp_getbyip(enaddr
, name
, ipaddr
, bootfile
));