xref: /freebsd/usr.sbin/ppp/defs.c (revision c30797873f663df5fc45ba0db943393f611bd24e)
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$
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
63 randinit()
64 {
65   srandom((time(NULL)^getpid())+random());
66 }
67 #endif
68 
69 ssize_t
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 *
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
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
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
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
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 *
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
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 *
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 *
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 *
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
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 *
387 mkfdset()
388 {
389   return (fd_set *)malloc(howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask));
390 }
391 
392 void
393 zerofdset(fd_set *s)
394 {
395   memset(s, '\0', howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask));
396 }
397 
398 void
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
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
439 loadmodules(int how __unused, const char *module __unused, ...)
440 {
441   return 0;
442 }
443 #endif
444