2 * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
27 #include <sys/types.h>
28 #include <sys/errno.h>
29 #include <sys/socket.h>
31 #include <CoreFoundation/CoreFoundation.h>
32 #include <SystemConfiguration/SystemConfiguration.h>
45 struct sockaddr_un sun
;
47 sock
= socket(AF_LOCAL
, SOCK_STREAM
, 0);
49 bzero(&sun
, sizeof(sun
));
50 sun
.sun_family
= AF_LOCAL
;
51 strncpy(sun
.sun_path
, PPP_PATH
, sizeof(sun
.sun_path
));
53 status
= connect(sock
, (struct sockaddr
*)&sun
, sizeof(sun
));
84 struct ppp_msg_hdr msg
;
88 bzero(&msg
, sizeof(msg
));
91 msg
.m_len
= ((request
!= NULL
) && (requestLen
> 0)) ? requestLen
: 0;
94 n
= write(ref
, &msg
, sizeof(msg
));
96 SCDLog(LOG_ERR
, CFSTR("PPPExec write() failed: %s"), strerror(errno
));
98 } else if (n
!= sizeof(msg
)) {
99 SCDLog(LOG_ERR
, CFSTR("PPPExec write() failed: wrote=%d"), n
);
103 if ((request
!= NULL
) && (requestLen
> 0)) {
104 n
= write(ref
, request
, requestLen
);
106 SCDLog(LOG_ERR
, CFSTR("PPPExec write() failed: %s"), strerror(errno
));
108 } else if (n
!= requestLen
) {
109 SCDLog(LOG_ERR
, CFSTR("PPPExec write() failed: wrote=%d"), n
);
114 // always expect a reply
115 n
= read(ref
, &msg
, sizeof(msg
));
117 SCDLog(LOG_ERR
, CFSTR("PPPExec read() failed: error=%s"), strerror(errno
));
119 } else if (n
!= sizeof(msg
)) {
120 SCDLog(LOG_ERR
, CFSTR("PPPExec read() failed: insufficent data, read=%d"), n
);
125 buf
= CFAllocatorAllocate(NULL
, msg
.m_len
, 0);
128 n
= read(ref
, buf
, msg
.m_len
);
130 SCDLog(LOG_ERR
, CFSTR("PPPExec read() failed: error=%s"), strerror(errno
));
131 CFAllocatorDeallocate(NULL
, buf
);
133 } else if (n
!= msg
.m_len
) {
134 SCDLog(LOG_ERR
, CFSTR("PPPExec read() failed: insufficent data, read=%d"), n
);
135 CFAllocatorDeallocate(NULL
, buf
);
141 if (reply
&& replyLen
) {
143 *replyLen
= msg
.m_len
;
145 // if additional returned data is unwanted
146 CFAllocatorDeallocate(NULL
, buf
);
155 PPPGetNumberOfLinks(int ref
, u_long
*nLinks
)
157 void *replyBuf
= NULL
;
158 u_long replyBufLen
= 0;
161 status
= PPPExec(ref
,
169 SCDLog(LOG_ERR
, CFSTR("PPPExec() failed: status = %d"), status
);
173 *nLinks
= (replyBufLen
== sizeof(u_long
)) ? *(u_long
*)replyBuf
: 0;
174 if (replyBuf
) CFAllocatorDeallocate(NULL
, replyBuf
);
182 PPPGetLinkByIndex(int ref
, int index
, u_int32_t
*link
)
185 void *replyBuf
= NULL
;
186 u_long replyBufLen
= 0;
189 status
= PPPExec(ref
,
197 SCDLog(LOG_ERR
, CFSTR("PPPExec() failed: status = %d"), status
);
201 if (replyBuf
&& (replyBufLen
== sizeof(u_int32_t
))) {
202 *link
= *(u_int32_t
*)replyBuf
;
204 status
= -2; /* if not found */
206 if (replyBuf
) CFAllocatorDeallocate(NULL
, replyBuf
);
214 PPPGetLinkByServiceID(int ref
, CFStringRef serviceID
, u_int32_t
*link
)
221 sID
= CFStringCreateExternalRepresentation(NULL
,
223 kCFStringEncodingMacRoman
,
226 status
= PPPGetNumberOfLinks(ref
, &nLinks
);
228 SCDLog(LOG_ERR
, CFSTR("PPPGetNumberOfLinks() failed: %d"), status
);
232 status
= -2; /* assume no link */
234 for (i
=0; i
<nLinks
; i
++) {
239 status
= PPPGetLinkByIndex(ref
, i
, &iLink
);
241 SCDLog(LOG_ERR
, CFSTR("PPPGetLinkByIndex() failed: %d"), status
);
245 status
= PPPGetOption(ref
,
251 SCDLog(LOG_ERR
, CFSTR("PPPGetOption() failed: %d"), status
);
255 if ((dataLen
!= CFDataGetLength(sID
)) ||
256 (strncmp(data
, CFDataGetBytePtr(sID
), dataLen
) != 0)) {
257 /* if link not found */
261 CFAllocatorDeallocate(NULL
, data
);
277 PPPGetOption(int ref
, u_long link
, u_long option
, void **data
, u_long
*dataLen
)
279 struct ppp_opt_hdr opt
;
280 void *replyBuf
= NULL
;
281 u_long replyBufLen
= 0;
284 bzero(&opt
, sizeof(opt
));
287 status
= PPPExec(ref
,
295 SCDLog(LOG_ERR
, CFSTR("PPPExec() failed: status = %d"), status
);
301 if (replyBuf
&& (replyBufLen
> sizeof(struct ppp_opt_hdr
))) {
302 *dataLen
= replyBufLen
- sizeof(struct ppp_opt_hdr
);
303 *data
= CFAllocatorAllocate(NULL
, *dataLen
, 0);
304 bcopy(((struct ppp_opt
*)replyBuf
)->o_data
, *data
, *dataLen
);
306 if (replyBuf
) CFAllocatorDeallocate(NULL
, replyBuf
);
314 PPPStatus(int ref
, u_long link
, struct ppp_status
**stat
)
316 void *replyBuf
= NULL
;
317 u_long replyBufLen
= 0;
320 status
= PPPExec(ref
,
328 SCDLog(LOG_ERR
, CFSTR("PPPExec() failed: status = %d"), status
);
332 if (replyBuf
&& (replyBufLen
== sizeof(struct ppp_status
))) {
333 *stat
= (struct ppp_status
*)replyBuf
;
335 if (replyBuf
) CFAllocatorDeallocate(NULL
, replyBuf
);