2 * Copyright (c) 2000-2002 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@
24 * Modification History
26 * Feb 28, 2002 Christophe Allie <callie@apple.com>
29 * Feb 10, 2001 Allan Nathanson <ajn@apple.com>
32 * Feb 2000 Christophe Allie <callie@apple.com>
33 * - initial revision (as ppplib.c)
38 #include <sys/types.h>
39 #include <sys/errno.h>
40 #include <sys/socket.h>
42 #include <CoreFoundation/CoreFoundation.h>
44 #include <SystemConfiguration/SystemConfiguration.h>
45 #include <SystemConfiguration/SCPrivate.h>
52 readn(int ref
, void *data
, int len
)
59 if ((n
= read(ref
, p
, left
)) < 0) {
76 writen(int ref
, void *data
, int len
)
83 if ((n
= write(ref
, p
, left
)) <= 0) {
102 struct sockaddr_un sun
;
104 sock
= socket(AF_LOCAL
, SOCK_STREAM
, 0);
106 bzero(&sun
, sizeof(sun
));
107 sun
.sun_family
= AF_LOCAL
;
108 strncpy(sun
.sun_path
, PPP_PATH
, sizeof(sun
.sun_path
));
110 status
= connect(sock
, (struct sockaddr
*)&sun
, sizeof(sun
));
124 if (close(ref
) < 0) {
141 struct ppp_msg_hdr msg
;
145 bzero(&msg
, sizeof(msg
));
148 msg
.m_len
= ((request
!= NULL
) && (requestLen
> 0)) ? requestLen
: 0;
151 if (writen(ref
, &msg
, sizeof(msg
)) < 0) {
152 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec write() failed: %s"), strerror(errno
));
156 if ((request
!= NULL
) && (requestLen
> 0)) {
157 if (writen(ref
, request
, requestLen
) < 0) {
158 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec write() failed: %s"), strerror(errno
));
163 // always expect a reply
164 n
= readn(ref
, &msg
, sizeof(msg
));
166 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec readn() failed: error=%s"), strerror(errno
));
168 } else if (n
!= sizeof(msg
)) {
169 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec readn() failed: insufficent data, read=%d"), n
);
174 buf
= CFAllocatorAllocate(NULL
, msg
.m_len
, 0);
177 n
= readn(ref
, buf
, msg
.m_len
);
179 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec readn() failed: error=%s"), strerror(errno
));
180 CFAllocatorDeallocate(NULL
, buf
);
182 } else if (n
!= msg
.m_len
) {
183 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec readn() failed: insufficent data, read=%d"), n
);
184 CFAllocatorDeallocate(NULL
, buf
);
190 if (reply
&& replyLen
) {
192 *replyLen
= msg
.m_len
;
194 // if additional returned data is unwanted
195 CFAllocatorDeallocate(NULL
, buf
);
204 PPPConnect(int ref
, u_long link
)
208 status
= PPPExec(ref
,
216 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec(PPP_CONNECT) failed: status = %d"), status
);
225 PPPDisconnect(int ref
, u_long link
)
229 status
= PPPExec(ref
,
237 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec(PPP_DISCONNECT) failed: status = %d"), status
);
243 #endif /* NOT_NEEDED */
248 PPPGetNumberOfLinks(int ref
, u_long
*nLinks
)
250 void *replyBuf
= NULL
;
251 u_long replyBufLen
= 0;
254 status
= PPPExec(ref
,
262 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec(PPP_GETNBLINKS) failed: status = %d"), status
);
266 *nLinks
= (replyBufLen
== sizeof(u_long
)) ? *(u_long
*)replyBuf
: 0;
267 if (replyBuf
) CFAllocatorDeallocate(NULL
, replyBuf
);
275 PPPGetLinkByIndex(int ref
, int index
, u_int32_t
*link
)
278 void *replyBuf
= NULL
;
279 u_long replyBufLen
= 0;
282 status
= PPPExec(ref
,
290 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec(PPP_GETLINKBYINDEX) failed: status = %d"), status
);
294 if (replyBuf
&& (replyBufLen
== sizeof(u_int32_t
))) {
295 *link
= *(u_int32_t
*)replyBuf
;
297 status
= -2; /* if not found */
299 if (replyBuf
) CFAllocatorDeallocate(NULL
, replyBuf
);
307 PPPGetLinkByServiceID(int ref
, CFStringRef serviceID
, u_int32_t
*link
)
314 sID
= CFStringCreateExternalRepresentation(NULL
,
316 kCFStringEncodingMacRoman
,
319 status
= PPPGetNumberOfLinks(ref
, &nLinks
);
321 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPGetNumberOfLinks() failed: %d"), status
);
325 status
= -2; /* assume no link */
327 for (i
=0; i
<nLinks
; i
++) {
332 status
= PPPGetLinkByIndex(ref
, i
, &iLink
);
334 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPGetLinkByIndex() failed: %d"), status
);
338 status
= PPPGetOption(ref
,
344 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPGetOption(PPP_OPT_SERVICEID) failed: %d"), status
);
348 if ((dataLen
!= CFDataGetLength(sID
)) ||
349 (strncmp(data
, CFDataGetBytePtr(sID
), dataLen
) != 0)) {
350 /* if link not found */
354 CFAllocatorDeallocate(NULL
, data
);
370 PPPGetOption(int ref
, u_long link
, u_long option
, void **data
, u_long
*dataLen
)
372 struct ppp_opt_hdr opt
;
373 void *replyBuf
= NULL
;
374 u_long replyBufLen
= 0;
377 bzero(&opt
, sizeof(opt
));
380 status
= PPPExec(ref
,
388 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec(PPP_GETOPTION) failed: status = %d"), status
);
394 if (replyBuf
&& (replyBufLen
> sizeof(struct ppp_opt_hdr
))) {
395 *dataLen
= replyBufLen
- sizeof(struct ppp_opt_hdr
);
396 *data
= CFAllocatorAllocate(NULL
, *dataLen
, 0);
397 bcopy(((struct ppp_opt
*)replyBuf
)->o_data
, *data
, *dataLen
);
399 if (replyBuf
) CFAllocatorDeallocate(NULL
, replyBuf
);
408 PPPSetOption(int ref
, u_long link
, u_long option
, void *data
, u_long dataLen
)
414 bufLen
= sizeof(struct ppp_opt_hdr
) + dataLen
;
415 buf
= CFAllocatorAllocate(NULL
, bufLen
, 0);
417 bzero((struct ppp_opt_hdr
*)buf
, sizeof(struct ppp_opt_hdr
));
418 ((struct ppp_opt_hdr
*)buf
)->o_type
= option
;
419 bcopy(data
, ((struct ppp_opt
*)buf
)->o_data
, dataLen
);
421 status
= PPPExec(ref
,
429 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec(PPP_SETOPTION) failed: status = %d"), status
);
432 CFAllocatorDeallocate(NULL
, buf
);
436 #endif /* NOT_NEEDED */
441 PPPStatus(int ref
, u_long link
, struct ppp_status
**stat
)
443 void *replyBuf
= NULL
;
444 u_long replyBufLen
= 0;
447 status
= PPPExec(ref
,
455 SCLog(_sc_verbose
, LOG_ERR
, CFSTR("PPPExec(PPP_STATUS) failed: status = %d"), status
);
459 if (replyBuf
&& (replyBufLen
== sizeof(struct ppp_status
))) {
460 *stat
= (struct ppp_status
*)replyBuf
;
462 if (replyBuf
) CFAllocatorDeallocate(NULL
, replyBuf
);
474 PPPEnableEvents(int ref
, u_long link
, u_char enable
)
478 status
= PPPExec(ref
,
480 enable
? PPP_ENABLE_EVENT
: PPP_DISABLE_EVENT
,
488 CFSTR("PPPExec(%s) failed: status = %d"),
489 enable
? "PPP_ENABLE_EVENT" : "PPP_DISABLE_EVENT",
496 #endif /* NOT_NEEDED */