1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: stable/12/usr.sbin/ppp/defs.c 326276 2017-11-27 15:37:16Z pfg $
29 */
30
31
32 #include <sys/param.h>
33 #include <netdb.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
36 #include <sys/socket.h>
37
38 #include <ctype.h>
39 #include <errno.h>
40 #include <stdarg.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #if defined(__FreeBSD__) && !defined(NOKLDLOAD)
45 #include <sys/module.h>
46 #endif
47 #include <termios.h>
48 #ifndef __FreeBSD__
49 #include <time.h>
50 #endif
51 #include <unistd.h>
52
53 #if defined(__FreeBSD__) && !defined(NOKLDLOAD)
54 #include "id.h"
55 #include "log.h"
56 #endif
57 #include "defs.h"
58
59 #define issep(c) ((c) == '\t' || (c) == ' ')
60
61 #ifdef __NetBSD__
62 void
randinit()63 randinit()
64 {
65 srandom((time(NULL)^getpid())+random());
66 }
67 #endif
68
69 ssize_t
fullread(int fd,void * v,size_t n)70 fullread(int fd, void *v, size_t n)
71 {
72 size_t got, total;
73
74 for (total = 0; total < n; total += got)
75 switch ((got = read(fd, (char *)v + total, n - total))) {
76 case 0:
77 return total;
78 case -1:
79 if (errno == EINTR)
80 got = 0;
81 else
82 return -1;
83 }
84 return total;
85 }
86
87 static struct {
88 int mode;
89 const char *name;
90 } modes[] = {
91 { PHYS_INTERACTIVE, "interactive" },
92 { PHYS_AUTO, "auto" },
93 { PHYS_DIRECT, "direct" },
94 { PHYS_DEDICATED, "dedicated" },
95 { PHYS_DDIAL, "ddial" },
96 { PHYS_BACKGROUND, "background" },
97 { PHYS_FOREGROUND, "foreground" },
98 { PHYS_ALL, "*" },
99 { 0, 0 }
100 };
101
102 const char *
mode2Nam(int mode)103 mode2Nam(int mode)
104 {
105 int m;
106
107 for (m = 0; modes[m].mode; m++)
108 if (modes[m].mode == mode)
109 return modes[m].name;
110
111 return "unknown";
112 }
113
114 int
Nam2mode(const char * name)115 Nam2mode(const char *name)
116 {
117 int m, got, len;
118
119 len = strlen(name);
120 got = -1;
121 for (m = 0; modes[m].mode; m++)
122 if (!strncasecmp(name, modes[m].name, len)) {
123 if (modes[m].name[len] == '\0')
124 return modes[m].mode;
125 if (got != -1)
126 return 0;
127 got = m;
128 }
129
130 return got == -1 ? 0 : modes[got].mode;
131 }
132
133 struct in_addr
GetIpAddr(const char * cp)134 GetIpAddr(const char *cp)
135 {
136 struct in_addr ipaddr;
137
138 if (!strcasecmp(cp, "default"))
139 ipaddr.s_addr = INADDR_ANY;
140 else if (inet_aton(cp, &ipaddr) == 0) {
141 const char *ptr;
142
143 /* Any illegal characters ? */
144 for (ptr = cp; *ptr != '\0'; ptr++)
145 if (!isalnum(*ptr) && strchr("-.", *ptr) == NULL)
146 break;
147
148 if (*ptr == '\0') {
149 struct hostent *hp;
150
151 hp = gethostbyname(cp);
152 if (hp && hp->h_addrtype == AF_INET)
153 memcpy(&ipaddr, hp->h_addr, hp->h_length);
154 else
155 ipaddr.s_addr = INADDR_NONE;
156 } else
157 ipaddr.s_addr = INADDR_NONE;
158 }
159
160 return ipaddr;
161 }
162
163 static const struct speeds {
164 unsigned nspeed;
165 speed_t speed;
166 } speeds[] = {
167 #ifdef B50
168 { 50, B50, },
169 #endif
170 #ifdef B75
171 { 75, B75, },
172 #endif
173 #ifdef B110
174 { 110, B110, },
175 #endif
176 #ifdef B134
177 { 134, B134, },
178 #endif
179 #ifdef B150
180 { 150, B150, },
181 #endif
182 #ifdef B200
183 { 200, B200, },
184 #endif
185 #ifdef B300
186 { 300, B300, },
187 #endif
188 #ifdef B600
189 { 600, B600, },
190 #endif
191 #ifdef B1200
192 { 1200, B1200, },
193 #endif
194 #ifdef B1800
195 { 1800, B1800, },
196 #endif
197 #ifdef B2400
198 { 2400, B2400, },
199 #endif
200 #ifdef B4800
201 { 4800, B4800, },
202 #endif
203 #ifdef B9600
204 { 9600, B9600, },
205 #endif
206 #ifdef B19200
207 { 19200, B19200, },
208 #endif
209 #ifdef B38400
210 { 38400, B38400, },
211 #endif
212 #ifndef _POSIX_SOURCE
213 #ifdef B7200
214 { 7200, B7200, },
215 #endif
216 #ifdef B14400
217 { 14400, B14400, },
218 #endif
219 #ifdef B28800
220 { 28800, B28800, },
221 #endif
222 #ifdef B57600
223 { 57600, B57600, },
224 #endif
225 #ifdef B76800
226 { 76800, B76800, },
227 #endif
228 #ifdef B115200
229 { 115200, B115200, },
230 #endif
231 #ifdef B230400
232 { 230400, B230400, },
233 #endif
234 #ifdef B460800
235 { 460800, B460800, },
236 #endif
237 #ifdef B921600
238 { 921600, B921600, },
239 #endif
240 #ifdef EXTA
241 { 19200, EXTA, },
242 #endif
243 #ifdef EXTB
244 { 38400, EXTB, },
245 #endif
246 #endif /* _POSIX_SOURCE */
247 { 0, 0 }
248 };
249
250 unsigned
SpeedToUnsigned(speed_t speed)251 SpeedToUnsigned(speed_t speed)
252 {
253 const struct speeds *sp;
254
255 for (sp = speeds; sp->nspeed; sp++) {
256 if (sp->speed == speed) {
257 return sp->nspeed;
258 }
259 }
260 return 0;
261 }
262
263 speed_t
UnsignedToSpeed(unsigned nspeed)264 UnsignedToSpeed(unsigned nspeed)
265 {
266 const struct speeds *sp;
267
268 for (sp = speeds; sp->nspeed; sp++) {
269 if (sp->nspeed == nspeed) {
270 return sp->speed;
271 }
272 }
273 return B0;
274 }
275
276 char *
findblank(char * p,int flags)277 findblank(char *p, int flags)
278 {
279 int instring;
280
281 instring = 0;
282 while (*p) {
283 if (*p == '\\') {
284 if (flags & PARSE_REDUCE) {
285 memmove(p, p + 1, strlen(p));
286 if (!*p)
287 break;
288 } else
289 p++;
290 } else if (*p == '"') {
291 memmove(p, p + 1, strlen(p));
292 instring = !instring;
293 continue;
294 } else if (!instring && (issep(*p) ||
295 (*p == '#' && !(flags & PARSE_NOHASH))))
296 return p;
297 p++;
298 }
299
300 return instring ? NULL : p;
301 }
302
303 int
MakeArgs(char * script,char ** pvect,int maxargs,int flags)304 MakeArgs(char *script, char **pvect, int maxargs, int flags)
305 {
306 int nargs;
307
308 nargs = 0;
309 while (*script) {
310 script += strspn(script, " \t");
311 if (*script == '#' && !(flags & PARSE_NOHASH)) {
312 *script = '\0';
313 break;
314 }
315 if (*script) {
316 if (nargs >= maxargs - 1)
317 break;
318 *pvect++ = script;
319 nargs++;
320 script = findblank(script, flags);
321 if (script == NULL)
322 return -1;
323 else if (!(flags & PARSE_NOHASH) && *script == '#')
324 *script = '\0';
325 else if (*script)
326 *script++ = '\0';
327 }
328 }
329 *pvect = NULL;
330 return nargs;
331 }
332
333 const char *
NumStr(long val,char * buf,size_t sz)334 NumStr(long val, char *buf, size_t sz)
335 {
336 static char result[23]; /* handles 64 bit numbers */
337
338 if (buf == NULL || sz == 0) {
339 buf = result;
340 sz = sizeof result;
341 }
342 snprintf(buf, sz, "<%ld>", val);
343 return buf;
344 }
345
346 const char *
HexStr(long val,char * buf,size_t sz)347 HexStr(long val, char *buf, size_t sz)
348 {
349 static char result[21]; /* handles 64 bit numbers */
350
351 if (buf == NULL || sz == 0) {
352 buf = result;
353 sz = sizeof result;
354 }
355 snprintf(buf, sz, "<0x%lx>", val);
356 return buf;
357 }
358
359 const char *
ex_desc(int ex)360 ex_desc(int ex)
361 {
362 static char num[12]; /* Used immediately if returned */
363 static const char * const desc[] = {
364 "normal", "start", "sock", "modem", "dial", "dead", "done",
365 "reboot", "errdead", "hangup", "term", "nodial", "nologin",
366 "redial", "reconnect"
367 };
368
369 if (ex >= 0 && ex < (int)(sizeof desc / sizeof *desc))
370 return desc[ex];
371 snprintf(num, sizeof num, "%d", ex);
372 return num;
373 }
374
375 void
SetTitle(const char * title)376 SetTitle(const char *title)
377 {
378 if (title == NULL)
379 setproctitle(NULL);
380 else if (title[0] == '-' && title[1] != '\0')
381 setproctitle("-%s", title + 1);
382 else
383 setproctitle("%s", title);
384 }
385
386 fd_set *
mkfdset()387 mkfdset()
388 {
389 return (fd_set *)malloc(howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask));
390 }
391
392 void
zerofdset(fd_set * s)393 zerofdset(fd_set *s)
394 {
395 memset(s, '\0', howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask));
396 }
397
398 void
Concatinate(char * buf,size_t sz,int argc,const char * const * argv)399 Concatinate(char *buf, size_t sz, int argc, const char *const *argv)
400 {
401 int i, n;
402 unsigned pos;
403
404 *buf = '\0';
405 for (pos = i = 0; i < argc; i++) {
406 n = snprintf(buf + pos, sz - pos, "%s%s", i ? " " : "", argv[i]);
407 if (n < 0) {
408 buf[pos] = '\0';
409 break;
410 }
411 if ((pos += n) >= sz)
412 break;
413 }
414 }
415
416 #if defined(__FreeBSD__) && !defined(NOKLDLOAD)
417 int
loadmodules(int how,const char * module,...)418 loadmodules(int how, const char *module, ...)
419 {
420 int loaded = 0;
421 va_list ap;
422
423 va_start(ap, module);
424 while (module != NULL) {
425 if (modfind(module) == -1) {
426 if (ID0kldload(module) == -1) {
427 if (how == LOAD_VERBOSLY)
428 log_Printf(LogWARN, "%s: Cannot load module\n", module);
429 } else
430 loaded++;
431 }
432 module = va_arg(ap, const char *);
433 }
434 va_end(ap);
435 return loaded;
436 }
437 #else
438 int
loadmodules(int how __unused,const char * module __unused,...)439 loadmodules(int how __unused, const char *module __unused, ...)
440 {
441 return 0;
442 }
443 #endif
444