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