]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/ppp.c
configd-24.1.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / ppp.c
1 /*
2 * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 #include <stdio.h>
24 //#include <stdlib.h>
25 //#include <string.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <sys/errno.h>
29 #include <sys/socket.h>
30 #include <sys/un.h>
31 #include <CoreFoundation/CoreFoundation.h>
32 #include <SystemConfiguration/SystemConfiguration.h>
33
34
35 #include "ppp_msg.h"
36 #include "ppp.h"
37
38
39 __private_extern__
40 int
41 PPPInit(int *ref)
42 {
43 int sock;
44 int status;
45 struct sockaddr_un sun;
46
47 sock = socket(AF_LOCAL, SOCK_STREAM, 0);
48
49 bzero(&sun, sizeof(sun));
50 sun.sun_family = AF_LOCAL;
51 strncpy(sun.sun_path, PPP_PATH, sizeof(sun.sun_path));
52
53 status = connect(sock, (struct sockaddr *)&sun, sizeof(sun));
54 if (status < 0) {
55 return errno;
56 }
57
58 *ref = sock;
59 return 0;
60 }
61
62
63 __private_extern__
64 int
65 PPPDispose(int ref)
66 {
67 if (close(ref) < 0) {
68 return errno;
69 }
70 return 0;
71 }
72
73
74 __private_extern__
75 int
76 PPPExec(int ref,
77 u_long link,
78 u_int32_t cmd,
79 void *request,
80 u_long requestLen,
81 void **reply,
82 u_long *replyLen)
83 {
84 struct ppp_msg_hdr msg;
85 char *buf = NULL;
86 ssize_t n;
87
88 bzero(&msg, sizeof(msg));
89 msg.m_type = cmd;
90 msg.m_link = link;
91 msg.m_len = ((request != NULL) && (requestLen > 0)) ? requestLen : 0;
92
93 // send the command
94 n = write(ref, &msg, sizeof(msg));
95 if (n == -1) {
96 SCDLog(LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
97 return errno;
98 } else if (n != sizeof(msg)) {
99 SCDLog(LOG_ERR, CFSTR("PPPExec write() failed: wrote=%d"), n);
100 return -1;
101 }
102
103 if ((request != NULL) && (requestLen > 0)) {
104 n = write(ref, request, requestLen);
105 if (n == -1) {
106 SCDLog(LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
107 return errno;
108 } else if (n != requestLen) {
109 SCDLog(LOG_ERR, CFSTR("PPPExec write() failed: wrote=%d"), n);
110 return -1;
111 }
112 }
113
114 // always expect a reply
115 n = read(ref, &msg, sizeof(msg));
116 if (n == -1) {
117 SCDLog(LOG_ERR, CFSTR("PPPExec read() failed: error=%s"), strerror(errno));
118 return errno;
119 } else if (n != sizeof(msg)) {
120 SCDLog(LOG_ERR, CFSTR("PPPExec read() failed: insufficent data, read=%d"), n);
121 return -1;
122 }
123
124 if (msg.m_len) {
125 buf = CFAllocatorAllocate(NULL, msg.m_len, 0);
126 if (buf) {
127 // read reply
128 n = read(ref, buf, msg.m_len);
129 if (n == -1) {
130 SCDLog(LOG_ERR, CFSTR("PPPExec read() failed: error=%s"), strerror(errno));
131 CFAllocatorDeallocate(NULL, buf);
132 return errno;
133 } else if (n != msg.m_len) {
134 SCDLog(LOG_ERR, CFSTR("PPPExec read() failed: insufficent data, read=%d"), n);
135 CFAllocatorDeallocate(NULL, buf);
136 return -1;
137 }
138 }
139 }
140
141 if (reply && replyLen) {
142 *reply = buf;
143 *replyLen = msg.m_len;
144 } else if (buf) {
145 // if additional returned data is unwanted
146 CFAllocatorDeallocate(NULL, buf);
147 }
148
149 return msg.m_result;
150 }
151
152
153 __private_extern__
154 int
155 PPPGetNumberOfLinks(int ref, u_long *nLinks)
156 {
157 void *replyBuf = NULL;
158 u_long replyBufLen = 0;
159 int status;
160
161 status = PPPExec(ref,
162 -1,
163 PPP_GETNBLINKS,
164 NULL,
165 0,
166 &replyBuf,
167 &replyBufLen);
168 if (status != 0) {
169 SCDLog(LOG_ERR, CFSTR("PPPExec() failed: status = %d"), status);
170 return status;
171 }
172
173 *nLinks = (replyBufLen == sizeof(u_long)) ? *(u_long *)replyBuf : 0;
174 if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf);
175
176 return status;
177 }
178
179
180 __private_extern__
181 int
182 PPPGetLinkByIndex(int ref, int index, u_int32_t *link)
183 {
184 u_int32_t i = index;
185 void *replyBuf = NULL;
186 u_long replyBufLen = 0;
187 int status;
188
189 status = PPPExec(ref,
190 -1,
191 PPP_GETLINKBYINDEX,
192 (void *)&i,
193 sizeof(i),
194 &replyBuf,
195 &replyBufLen);
196 if (status != 0) {
197 SCDLog(LOG_ERR, CFSTR("PPPExec() failed: status = %d"), status);
198 return status;
199 }
200
201 if (replyBuf && (replyBufLen == sizeof(u_int32_t))) {
202 *link = *(u_int32_t *)replyBuf;
203 } else {
204 status = -2; /* if not found */
205 }
206 if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf);
207
208 return status;
209 }
210
211
212 __private_extern__
213 int
214 PPPGetLinkByServiceID(int ref, CFStringRef serviceID, u_int32_t *link)
215 {
216 int i;
217 u_long nLinks;
218 int status;
219 CFDataRef sID;
220
221 sID = CFStringCreateExternalRepresentation(NULL,
222 serviceID,
223 kCFStringEncodingMacRoman,
224 0);
225
226 status = PPPGetNumberOfLinks(ref, &nLinks);
227 if (status != 0) {
228 SCDLog(LOG_ERR, CFSTR("PPPGetNumberOfLinks() failed: %d"), status);
229 goto done;
230 }
231
232 status = -2; /* assume no link */
233
234 for (i=0; i<nLinks; i++) {
235 u_int32_t iLink;
236 void *data = NULL;
237 u_long dataLen = 0;
238
239 status = PPPGetLinkByIndex(ref, i, &iLink);
240 if (status != 0) {
241 SCDLog(LOG_ERR, CFSTR("PPPGetLinkByIndex() failed: %d"), status);
242 goto done;
243 }
244
245 status = PPPGetOption(ref,
246 iLink,
247 PPP_OPT_SERVICEID,
248 &data,
249 &dataLen);
250 if (status != 0) {
251 SCDLog(LOG_ERR, CFSTR("PPPGetOption() failed: %d"), status);
252 goto done;
253 }
254
255 if ((dataLen != CFDataGetLength(sID)) ||
256 (strncmp(data, CFDataGetBytePtr(sID), dataLen) != 0)) {
257 /* if link not found */
258 status = -2;
259 }
260
261 CFAllocatorDeallocate(NULL, data);
262 if (status == 0) {
263 *link = iLink;
264 goto done;
265 }
266 }
267
268 done :
269
270 CFRelease(sID);
271 return status;
272 }
273
274
275 __private_extern__
276 int
277 PPPGetOption(int ref, u_long link, u_long option, void **data, u_long *dataLen)
278 {
279 struct ppp_opt_hdr opt;
280 void *replyBuf = NULL;
281 u_long replyBufLen = 0;
282 int status;
283
284 bzero(&opt, sizeof(opt));
285 opt.o_type = option;
286
287 status = PPPExec(ref,
288 link,
289 PPP_GETOPTION,
290 (void *)&opt,
291 sizeof(opt),
292 &replyBuf,
293 &replyBufLen);
294 if (status != 0) {
295 SCDLog(LOG_ERR, CFSTR("PPPExec() failed: status = %d"), status);
296 *data = NULL;
297 *dataLen = 0;
298 return status;
299 }
300
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);
305 }
306 if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf);
307
308 return status;
309 }
310
311
312 __private_extern__
313 int
314 PPPStatus(int ref, u_long link, struct ppp_status **stat)
315 {
316 void *replyBuf = NULL;
317 u_long replyBufLen = 0;
318 int status;
319
320 status = PPPExec(ref,
321 link,
322 PPP_STATUS,
323 NULL,
324 0,
325 &replyBuf,
326 &replyBufLen);
327 if (status != 0) {
328 SCDLog(LOG_ERR, CFSTR("PPPExec() failed: status = %d"), status);
329 return status;
330 }
331
332 if (replyBuf && (replyBufLen == sizeof(struct ppp_status))) {
333 *stat = (struct ppp_status *)replyBuf;
334 } else {
335 if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf);
336 *stat = NULL;
337 status = -1;
338 }
339
340 return status;
341 }