Merge branch 'Teaman-ND' into Teaman-RT
[tomato.git] / release / src / router / xl2tpd / file.c
blob9a8cfd62a4a7c1885d8ff41e3f11f46cc15eab7c
1 /*
2 * Layer Two Tunnelling Protocol Daemon
3 * Copyright (C) 1998 Adtran, Inc.
4 * Copyright (C) 2002 Jeff McAdams
6 * Mark Spencer
8 * This software is distributed under the terms
9 * of the GPL, which you should have received
10 * along with this source.
12 * File format handling
16 #include <stdio.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <netdb.h>
21 #include <netinet/in.h>
22 #include <time.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
26 #include "l2tp.h"
28 struct lns *lnslist;
29 struct lac *laclist;
30 struct lns *deflns;
31 struct lac *deflac;
32 struct global gconfig;
33 char filerr[STRLEN];
35 int parse_config (FILE *);
36 struct keyword words[];
38 int init_config ()
40 FILE *f;
41 int returnedValue;
43 gconfig.port = UDP_LISTEN_PORT;
44 gconfig.listenaddr = htonl(INADDR_ANY); /* Default is to bind (listen) to all interfaces */
45 gconfig.debug_avp = 0;
46 gconfig.debug_network = 0;
47 gconfig.packet_dump = 0;
48 gconfig.debug_tunnel = 0;
49 gconfig.debug_state = 0;
50 lnslist = NULL;
51 laclist = NULL;
52 deflac = (struct lac *) calloc (1, sizeof (struct lac));
54 f = fopen (gconfig.configfile, "r");
55 if (!f)
57 f = fopen (gconfig.altconfigfile, "r");
58 if (f)
60 l2tp_log (LOG_WARNING, "%s: Using old style config files %s and %s\n",
61 __FUNCTION__, gconfig.altconfigfile, gconfig.altauthfile);
62 strncpy (gconfig.authfile, gconfig.altauthfile,
63 sizeof (gconfig.authfile));
65 else
67 l2tp_log (LOG_CRIT, "%s: Unable to open config file %s or %s\n",
68 __FUNCTION__, gconfig.configfile, gconfig.altconfigfile);
69 return -1;
73 returnedValue = parse_config (f);
74 fclose (f);
75 return (returnedValue);
76 filerr[0] = 0;
79 struct lns *new_lns ()
81 struct lns *tmp;
82 tmp = (struct lns *) calloc (1, sizeof (struct lns));
83 if (!tmp)
85 l2tp_log (LOG_CRIT, "%s: Unable to allocate memory for new LNS\n",
86 __FUNCTION__);
87 return NULL;
89 tmp->next = NULL;
90 tmp->exclusive = 0;
91 tmp->localaddr = 0;
92 tmp->tun_rws = DEFAULT_RWS_SIZE;
93 tmp->call_rws = DEFAULT_RWS_SIZE;
94 tmp->rxspeed = DEFAULT_RX_BPS;
95 tmp->txspeed = DEFAULT_TX_BPS;
96 tmp->hbit = 0;
97 tmp->lbit = 0;
98 tmp->authpeer = 0;
99 tmp->authself = -1;
100 tmp->authname[0] = 0;
101 tmp->peername[0] = 0;
102 tmp->hostname[0] = 0;
103 tmp->entname[0] = 0;
104 tmp->range = NULL;
105 tmp->assign_ip = 1; /* default to 'yes' */
106 tmp->lacs = NULL;
107 tmp->passwdauth = 0;
108 tmp->pap_require = 0;
109 tmp->pap_refuse = 0;
110 tmp->chap_require = 0;
111 tmp->chap_refuse = 0;
112 tmp->idle = 0;
113 tmp->pridns = 0;
114 tmp->secdns = 0;
115 tmp->priwins = 0;
116 tmp->secwins = 0;
117 tmp->proxyarp = 0;
118 tmp->proxyauth = 0;
119 tmp->challenge = 0;
120 tmp->debug = 0;
121 tmp->pppoptfile[0] = 0;
122 tmp->t = NULL;
123 return tmp;
126 struct lac *new_lac ()
128 struct lac *tmp;
129 tmp = (struct lac *) calloc (1, sizeof (struct lac));
130 if (!tmp)
132 l2tp_log (LOG_CRIT, "%s: Unable to allocate memory for lac entry!\n",
133 __FUNCTION__);
134 return NULL;
136 tmp->next = NULL;
137 tmp->rsched = NULL;
138 tmp->localaddr = 0;
139 tmp->remoteaddr = 0;
140 tmp->lns = 0;
141 tmp->tun_rws = DEFAULT_RWS_SIZE;
142 tmp->call_rws = DEFAULT_RWS_SIZE;
143 tmp->hbit = 0;
144 tmp->lbit = 0;
145 tmp->authpeer = 0;
146 tmp->authself = -1;
147 tmp->authname[0] = 0;
148 tmp->peername[0] = 0;
149 tmp->hostname[0] = 0;
150 tmp->entname[0] = 0;
151 tmp->pap_require = 0;
152 tmp->pap_refuse = 0;
153 tmp->chap_require = 0;
154 tmp->chap_refuse = 0;
155 tmp->t = NULL;
156 tmp->redial = 0;
157 tmp->rtries = 0;
158 tmp->rmax = 0;
159 tmp->challenge = 0;
160 tmp->autodial = 0;
161 tmp->rtimeout = 30;
162 tmp->active = 0;
163 tmp->debug = 0;
164 tmp->pppoptfile[0] = 0;
165 tmp->defaultroute = 0;
166 return tmp;
169 int yesno (char *value)
171 if (!strcasecmp (value, "yes") || !strcasecmp (value, "y") ||
172 !strcasecmp (value, "true"))
173 return 1;
174 else if (!strcasecmp (value, "no") || !strcasecmp (value, "n") ||
175 !strcasecmp (value, "false"))
176 return 0;
177 else
178 return -1;
181 int set_boolean (char *word, char *value, int *ptr)
183 int val;
184 #ifdef DEBUG_FILE
185 l2tp_log (LOG_DEBUG, "set_%s: %s flag to '%s'\n", word, word, value);
186 #endif /* ; */
187 if ((val = yesno (value)) < 0)
189 snprintf (filerr, sizeof (filerr), "%s must be 'yes' or 'no'\n",
190 word);
191 return -1;
193 *ptr = val;
194 return 0;
197 int set_int (char *word, char *value, int *ptr)
199 int val;
200 #ifdef DEBUG_FILE
201 l2tp_log (LOG_DEBUG, "set_%s: %s flag to '%s'\n", word, word, value);
202 #endif /* ; */
203 if ((val = atoi (value)) < 0)
205 snprintf (filerr, sizeof (filerr), "%s must be a number\n", word);
206 return -1;
208 *ptr = val;
209 return 0;
212 int set_string (char *word, char *value, char *ptr, int len)
214 #ifdef DEBUG_FILE
215 l2tp_log (LOG_DEBUG, "set_%s: %s flag to '%s'\n", word, word, value);
216 #endif /* ; */
217 strncpy (ptr, value, len);
218 return 0;
221 int set_port (char *word, char *value, int context, void *item)
223 switch (context & ~CONTEXT_DEFAULT)
225 case CONTEXT_GLOBAL:
226 #ifdef DEBUG_FILE
227 l2tp_log (LOG_DEBUG, "set_port: Setting global port number to %s\n",
228 value);
229 #endif
230 set_int (word, value, &(((struct global *) item)->port));
231 break;
232 default:
233 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
234 word);
235 return -1;
237 return 0;
240 int set_rtimeout (char *word, char *value, int context, void *item)
242 if (atoi (value) < 1)
244 snprintf (filerr, sizeof (filerr),
245 "rtimeout value must be at least 1\n");
246 return -1;
248 switch (context & ~CONTEXT_DEFAULT)
250 case CONTEXT_LAC:
251 #ifdef DEBUG_FILE
252 l2tp_log (LOG_DEBUG, "set_rtimeout: Setting redial timeout to %s\n",
253 value);
254 #endif
255 set_int (word, value, &(((struct lac *) item)->rtimeout));
256 break;
257 default:
258 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
259 word);
260 return -1;
262 return 0;
265 int set_rws (char *word, char *value, int context, void *item)
267 if (atoi (value) < -1)
269 snprintf (filerr, sizeof (filerr),
270 "receive window size must be at least -1\n");
271 return -1;
273 switch (context & ~CONTEXT_DEFAULT)
275 case CONTEXT_LAC:
276 if (word[0] == 'c')
277 set_int (word, value, &(((struct lac *) item)->call_rws));
278 if (word[0] == 't')
280 set_int (word, value, &(((struct lac *) item)->tun_rws));
281 if (((struct lac *) item)->tun_rws < 1)
283 snprintf (filerr, sizeof (filerr),
284 "receive window size for tunnels must be at least 1\n");
285 return -1;
288 break;
289 case CONTEXT_LNS:
290 if (word[0] == 'c')
291 set_int (word, value, &(((struct lns *) item)->call_rws));
292 if (word[0] == 't')
294 set_int (word, value, &(((struct lns *) item)->tun_rws));
295 if (((struct lns *) item)->tun_rws < 1)
297 snprintf (filerr, sizeof (filerr),
298 "receive window size for tunnels must be at least 1\n");
299 return -1;
302 break;
303 default:
304 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
305 word);
306 return -1;
308 return 0;
311 int set_speed (char *word, char *value, int context, void *item)
313 if (atoi (value) < 1 )
315 snprintf (filerr, sizeof (filerr),
316 "bps must be greater than zero\n");
317 return -1;
319 switch (context & ~CONTEXT_DEFAULT)
321 case CONTEXT_LAC:
322 if (word[0] == 't')
323 set_int (word, value, &(((struct lac *) item)->txspeed));
324 else if (word[0] == 'r')
325 set_int (word, value, &(((struct lac *) item)->rxspeed));
326 else
328 set_int (word, value, &(((struct lac *) item)->rxspeed));
329 set_int (word, value, &(((struct lac *) item)->txspeed));
331 break;
332 case CONTEXT_LNS:
333 if (word[0] == 't')
334 set_int (word, value, &(((struct lns *) item)->txspeed));
335 else if (word[0] == 'r')
336 set_int (word, value, &(((struct lns *) item)->rxspeed));
337 else
339 set_int (word, value, &(((struct lns *) item)->rxspeed));
340 set_int (word, value, &(((struct lns *) item)->txspeed));
342 break;
343 default:
344 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
345 word);
346 return -1;
348 return 0;
351 int set_rmax (char *word, char *value, int context, void *item)
353 if (atoi (value) < 1)
355 snprintf (filerr, sizeof (filerr), "rmax value must be at least 1\n");
356 return -1;
358 switch (context & ~CONTEXT_DEFAULT)
360 case CONTEXT_LAC:
361 #ifdef DEBUG_FILE
362 l2tp_log (LOG_DEBUG, "set_rmax: Setting max redials to %s\n", value);
363 #endif
364 set_int (word, value, &(((struct lac *) item)->rmax));
365 break;
366 default:
367 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
368 word);
369 return -1;
371 return 0;
374 int set_authfile (char *word, char *value, int context, void *item)
376 if (!strlen (value))
378 snprintf (filerr, sizeof (filerr),
379 "no filename specified for authentication\n");
380 return -1;
382 switch (context & ~CONTEXT_DEFAULT)
384 case CONTEXT_GLOBAL:
385 #ifdef DEBUG_FILE
386 l2tp_log (LOG_DEBUG, "set_authfile: Setting global auth file to '%s'\n",
387 value);
388 #endif /* ; */
389 strncpy (((struct global *) item)->authfile, value,
390 sizeof (((struct global *)item)->authfile));
391 break;
392 default:
393 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
394 word);
395 return -1;
397 return 0;
400 int set_autodial (char *word, char *value, int context, void *item)
402 switch (context & ~CONTEXT_DEFAULT)
404 case CONTEXT_LAC:
405 if (set_boolean (word, value, &(((struct lac *) item)->autodial)))
406 return -1;
407 break;
408 default:
409 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
410 word);
411 return -1;
413 return 0;
416 int set_flow (char *word, char *value, int context, void *item)
418 int v;
419 set_boolean (word, value, &v);
420 if (v < 0)
421 return -1;
422 switch (context & ~CONTEXT_DEFAULT)
424 case CONTEXT_LAC:
425 if (v)
427 if (((struct lac *) item)->call_rws < 0)
428 ((struct lac *) item)->call_rws = 0;
430 else
432 ((struct lac *) item)->call_rws = -1;
434 break;
435 case CONTEXT_LNS:
436 if (v)
438 if (((struct lns *) item)->call_rws < 0)
439 ((struct lns *) item)->call_rws = 0;
441 else
443 ((struct lns *) item)->call_rws = -1;
445 break;
446 default:
447 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
448 word);
449 return -1;
451 return 0;
454 int set_defaultroute (char *word, char *value, int context, void *item)
456 switch (context & ~CONTEXT_DEFAULT)
458 case CONTEXT_LAC:
459 if (set_boolean (word, value, &(((struct lac *) item)->defaultroute)))
460 return -1;
461 break;
462 default:
463 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
464 word);
465 return -1;
467 return 0;
470 int set_authname (char *word, char *value, int context, void *item)
472 struct lac *l = (struct lac *) item;
473 struct lns *n = (struct lns *) item;
474 switch (context & ~CONTEXT_DEFAULT)
476 case CONTEXT_LNS:
477 if (set_string (word, value, n->authname, sizeof (n->authname)))
478 return -1;
479 break;
480 case CONTEXT_LAC:
481 if (set_string (word, value, l->authname, sizeof (l->authname)))
482 return -1;
483 break;
484 default:
485 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
486 word);
487 return -1;
489 return 0;
492 int set_hostname (char *word, char *value, int context, void *item)
494 struct lac *l = (struct lac *) item;
495 struct lns *n = (struct lns *) item;
496 switch (context & ~CONTEXT_DEFAULT)
498 case CONTEXT_LNS:
499 if (set_string (word, value, n->hostname, sizeof (n->hostname)))
500 return -1;
501 break;
502 case CONTEXT_LAC:
503 if (set_string (word, value, l->hostname, sizeof (l->hostname)))
504 return -1;
505 break;
506 default:
507 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
508 word);
509 return -1;
511 return 0;
514 int set_passwdauth (char *word, char *value, int context, void *item)
516 switch (context & ~CONTEXT_DEFAULT)
518 case CONTEXT_LNS:
519 if (set_boolean (word, value, &(((struct lns *) item)->passwdauth)))
520 return -1;
521 break;
522 default:
523 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
524 word);
525 return -1;
527 return 0;
530 int set_hbit (char *word, char *value, int context, void *item)
532 switch (context & ~CONTEXT_DEFAULT)
534 case CONTEXT_LAC:
535 if (set_boolean (word, value, &(((struct lac *) item)->hbit)))
536 return -1;
537 break;
538 case CONTEXT_LNS:
539 if (set_boolean (word, value, &(((struct lns *) item)->hbit)))
540 return -1;
541 break;
542 default:
543 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
544 word);
545 return -1;
547 return 0;
550 int set_challenge (char *word, char *value, int context, void *item)
552 switch (context & ~CONTEXT_DEFAULT)
554 case CONTEXT_LAC:
555 if (set_boolean (word, value, &(((struct lac *) item)->challenge)))
556 return -1;
557 break;
558 case CONTEXT_LNS:
559 if (set_boolean (word, value, &(((struct lns *) item)->challenge)))
560 return -1;
561 break;
562 default:
563 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
564 word);
565 return -1;
567 return 0;
570 int set_lbit (char *word, char *value, int context, void *item)
572 switch (context & ~CONTEXT_DEFAULT)
574 case CONTEXT_LAC:
575 if (set_boolean (word, value, &(((struct lac *) item)->lbit)))
576 return -1;
577 break;
578 case CONTEXT_LNS:
579 if (set_boolean (word, value, &(((struct lns *) item)->lbit)))
580 return -1;
581 break;
582 default:
583 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
584 word);
585 return -1;
587 return 0;
591 int set_debug (char *word, char *value, int context, void *item)
593 switch (context & ~CONTEXT_DEFAULT)
595 case CONTEXT_LAC:
596 if (set_boolean (word, value, &(((struct lac *) item)->debug)))
597 return -1;
598 break;
599 case CONTEXT_LNS:
600 if (set_boolean (word, value, &(((struct lns *) item)->debug)))
601 return -1;
602 break;
603 default:
604 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
605 word);
606 return -1;
608 return 0;
611 int set_pppoptfile (char *word, char *value, int context, void *item)
613 struct lac *l = (struct lac *) item;
614 struct lns *n = (struct lns *) item;
615 switch (context & ~CONTEXT_DEFAULT)
617 case CONTEXT_LNS:
618 if (set_string (word, value, n->pppoptfile, sizeof (n->pppoptfile)))
619 return -1;
620 break;
621 case CONTEXT_LAC:
622 if (set_string (word, value, l->pppoptfile, sizeof (l->pppoptfile)))
623 return -1;
624 break;
625 default:
626 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
627 word);
628 return -1;
630 return 0;
633 int set_papchap (char *word, char *value, int context, void *item)
635 int result;
636 char *c;
637 struct lac *l = (struct lac *) item;
638 struct lns *n = (struct lns *) item;
639 if (set_boolean (word, value, &result))
640 return -1;
641 c = strchr (word, ' ');
642 c++;
643 switch (context & ~CONTEXT_DEFAULT)
645 case CONTEXT_LAC:
646 if (c[0] == 'p') /* PAP */
647 if (word[2] == 'f')
648 l->pap_refuse = result;
649 else
650 l->pap_require = result;
651 else if (c[0] == 'a') /* Authentication */
652 if (word[2] == 'f')
653 l->authself = !result;
654 else
655 l->authpeer = result;
656 else /* CHAP */ if (word[2] == 'f')
657 l->chap_refuse = result;
658 else
659 l->chap_require = result;
660 break;
661 case CONTEXT_LNS:
662 if (c[0] == 'p') /* PAP */
663 if (word[2] == 'f')
664 n->pap_refuse = result;
665 else
666 n->pap_require = result;
667 else if (c[0] == 'a') /* Authentication */
668 if (word[2] == 'f')
669 n->authself = !result;
670 else
671 n->authpeer = result;
672 else /* CHAP */ if (word[2] == 'f')
673 n->chap_refuse = result;
674 else
675 n->chap_require = result;
676 break;
677 default:
678 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
679 word);
680 return -1;
682 return 0;
685 int set_redial (char *word, char *value, int context, void *item)
687 switch (context & ~CONTEXT_DEFAULT)
689 case CONTEXT_LAC:
690 if (set_boolean (word, value, &(((struct lac *) item)->redial)))
691 return -1;
692 break;
693 default:
694 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
695 word);
696 return -1;
698 return 0;
701 int set_accesscontrol (char *word, char *value, int context, void *item)
703 switch (context & ~CONTEXT_DEFAULT)
705 case CONTEXT_GLOBAL:
706 if (set_boolean
707 (word, value, &(((struct global *) item)->accesscontrol)))
708 return -1;
709 break;
710 default:
711 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
712 word);
713 return -1;
715 return 0;
718 int set_userspace (char *word, char *value, int context, void *item)
720 switch (context & ~CONTEXT_DEFAULT)
722 case CONTEXT_GLOBAL:
723 if (set_boolean
724 (word, value, &(((struct global *) item)->forceuserspace)))
725 return -1;
726 break;
727 default:
728 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
729 word);
730 return -1;
732 return 0;
735 int set_debugavp (char *word, char *value, int context, void *item)
737 switch (context & ~CONTEXT_DEFAULT)
739 case CONTEXT_GLOBAL:
740 if (set_boolean
741 (word, value, &(((struct global *) item)->debug_avp)))
742 return -1;
743 break;
744 default:
745 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
746 word);
747 return -1;
749 return 0;
752 int set_debugnetwork (char *word, char *value, int context, void *item)
754 switch (context & ~CONTEXT_DEFAULT)
756 case CONTEXT_GLOBAL:
757 if (set_boolean
758 (word, value, &(((struct global *) item)->debug_network)))
759 return -1;
760 break;
761 default:
762 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
763 word);
764 return -1;
766 return 0;
769 int set_debugpacket (char *word, char *value, int context, void *item)
771 switch (context & ~CONTEXT_DEFAULT)
773 case CONTEXT_GLOBAL:
774 if (set_boolean
775 (word, value, &(((struct global *) item)->packet_dump)))
776 return -1;
777 break;
778 default:
779 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
780 word);
781 return -1;
783 return 0;
786 int set_debugtunnel (char *word, char *value, int context, void *item)
788 switch (context & ~CONTEXT_DEFAULT)
790 case CONTEXT_GLOBAL:
791 if (set_boolean
792 (word, value, &(((struct global *) item)->debug_tunnel)))
793 return -1;
794 break;
795 default:
796 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
797 word);
798 return -1;
800 return 0;
803 int set_debugstate (char *word, char *value, int context, void *item)
805 switch (context & ~CONTEXT_DEFAULT)
807 case CONTEXT_GLOBAL:
808 if (set_boolean
809 (word, value, &(((struct global *) item)->debug_state)))
810 return -1;
811 break;
812 default:
813 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
814 word);
815 return -1;
817 return 0;
820 int set_assignip (char *word, char *value, int context, void *item)
822 switch (context & ~CONTEXT_DEFAULT)
824 case CONTEXT_LNS:
825 if (set_boolean (word, value, &(((struct lns *) item)->assign_ip)))
826 return -1;
827 break;
828 default:
829 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
830 word);
831 return -1;
833 return 0;
836 struct iprange *set_range (char *word, char *value, struct iprange *in)
838 char *c, *d = NULL, *e = NULL;
839 struct iprange *ipr, *p;
840 struct hostent *hp;
841 int count = 0;
842 c = strchr (value, '-');
843 if (c)
845 d = c + 1;
846 *c = 0;
847 while ((c >= value) && (*c < 33))
848 *(c--) = 0;
849 while (*d && (*d < 33))
850 d++;
852 if (!strlen (value) || (c && !strlen (d)))
854 snprintf (filerr, sizeof (filerr),
855 "format is '%s <host or ip> - <host or ip>'\n", word);
856 return NULL;
858 ipr = (struct iprange *) malloc (sizeof (struct iprange));
859 ipr->next = NULL;
860 hp = gethostbyname (value);
861 if (!hp)
863 snprintf (filerr, sizeof (filerr), "Unknown host %s\n", value);
864 free (ipr);
865 return NULL;
867 bcopy (hp->h_addr, &ipr->start, sizeof (unsigned int));
868 if (c)
870 char ip_hi[16];
872 e = d;
873 while(*e != '\0') {
874 if (*e++ == '.')
875 count++;
877 if (count < 3) {
878 strcpy(ip_hi, value);
879 for (e = ip_hi + sizeof(ip_hi); e >= ip_hi; e--) {
880 if (*e == '.') count--;
881 if (count < 0) {
882 e++;
883 break;
886 /* Copy the last field + null terminator */
887 if (ip_hi + sizeof(ip_hi)-e > strlen(d)) {
888 strcpy(e, d);
889 d = ip_hi;
892 hp = gethostbyname (d);
893 if (!hp)
895 snprintf (filerr, sizeof (filerr), "Unknown host %s\n", d);
896 free (ipr);
897 return NULL;
899 bcopy (hp->h_addr, &ipr->end, sizeof (unsigned int));
901 else
902 ipr->end = ipr->start;
903 if (ntohl (ipr->start) > ntohl (ipr->end))
905 snprintf (filerr, sizeof (filerr), "start is greater than end!\n");
906 free (ipr);
907 return NULL;
909 if (word[0] == 'n')
910 ipr->sense = SENSE_DENY;
911 else
912 ipr->sense = SENSE_ALLOW;
913 p = in;
914 if (p)
916 while (p->next)
917 p = p->next;
918 p->next = ipr;
919 return in;
921 else
922 return ipr;
925 int set_iprange (char *word, char *value, int context, void *item)
927 struct lns *lns = (struct lns *) item;
928 switch (context & ~CONTEXT_DEFAULT)
930 case CONTEXT_LNS:
931 break;
932 default:
933 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
934 word);
935 return -1;
937 lns->range = set_range (word, value, lns->range);
938 if (!lns->range)
939 return -1;
940 #ifdef DEBUG_FILE
941 l2tp_log (LOG_DEBUG, "range start = %x, end = %x, sense=%ud\n",
942 ntohl (lns->range->start), ntohl (lns->range->end), lns->range->sense);
943 #endif
944 return 0;
947 int set_lac (char *word, char *value, int context, void *item)
949 struct lns *lns = (struct lns *) item;
950 switch (context & ~CONTEXT_DEFAULT)
952 case CONTEXT_LNS:
953 break;
954 default:
955 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
956 word);
957 return -1;
959 lns->lacs = set_range (word, value, lns->lacs);
960 if (!lns->lacs)
961 return -1;
962 #ifdef DEBUG_FILE
963 l2tp_log (LOG_DEBUG, "lac start = %x, end = %x, sense=%ud\n",
964 ntohl (lns->lacs->start), ntohl (lns->lacs->end), lns->lacs->sense);
965 #endif
966 return 0;
969 int set_exclusive (char *word, char *value, int context, void *item)
971 switch (context & ~CONTEXT_DEFAULT)
973 case CONTEXT_LNS:
974 if (set_boolean (word, value, &(((struct lns *) item)->exclusive)))
975 return -1;
976 break;
977 default:
978 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
979 word);
980 return -1;
982 return 0;
985 int set_ip (char *word, char *value, unsigned int *addr)
987 struct hostent *hp;
988 hp = gethostbyname (value);
989 if (!hp)
991 snprintf (filerr, sizeof (filerr), "%s: host '%s' not found\n",
992 __FUNCTION__, value);
993 return -1;
995 bcopy (hp->h_addr, addr, sizeof (unsigned int));
996 return 0;
999 int set_listenaddr (char *word, char *value, int context, void *item)
1001 switch (context & ~CONTEXT_DEFAULT)
1003 case CONTEXT_GLOBAL:
1004 #ifdef DEBUG_FILE
1005 l2tp_log (LOG_DEBUG, "set_listenaddr: Setting listen address to %s\n",
1006 value);
1007 #endif
1008 if (set_ip (word, value, &(((struct global *) item)->listenaddr)))
1009 return -1;
1010 break;
1011 default:
1012 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
1013 word);
1014 return -1;
1016 return 0;
1019 int set_localaddr (char *word, char *value, int context, void *item)
1021 struct lac *l;
1022 struct lns *n;
1023 switch (context & ~CONTEXT_DEFAULT)
1025 case CONTEXT_LAC:
1026 l = (struct lac *) item;
1027 return set_ip (word, value, &(l->localaddr));
1028 case CONTEXT_LNS:
1029 n = (struct lns *) item;
1030 return set_ip (word, value, &(n->localaddr));
1031 default:
1032 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
1033 word);
1034 return -1;
1036 return 0;
1039 int set_remoteaddr (char *word, char *value, int context, void *item)
1041 struct lac *l;
1042 switch (context & ~CONTEXT_DEFAULT)
1044 case CONTEXT_LAC:
1045 l = (struct lac *) item;
1046 return set_ip (word, value, &(l->remoteaddr));
1047 default:
1048 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
1049 word);
1050 return -1;
1052 return 0;
1055 int set_lns (char *word, char *value, int context, void *item)
1057 #if 0
1058 struct hostent *hp;
1059 #endif
1060 struct lac *l;
1061 struct host *ipr, *pos;
1062 char *d;
1063 switch (context & ~CONTEXT_DEFAULT)
1065 case CONTEXT_LAC:
1066 #ifdef DEBUG_FILE
1067 l2tp_log (LOG_DEBUG, "set_lns: setting LNS to '%s'\n", value);
1068 #endif
1069 l = (struct lac *) item;
1070 d = strchr (value, ':');
1071 if (d)
1073 d[0] = 0;
1074 d++;
1076 #if 0
1077 // why would you want to lookup hostnames at this time?
1078 hp = gethostbyname (value);
1079 if (!hp)
1081 snprintf (filerr, sizeof (filerr), "no such host '%s'\n", value);
1082 return -1;
1084 #endif
1085 ipr = malloc (sizeof (struct host));
1086 ipr->next = NULL;
1087 pos = l->lns;
1088 if (!pos)
1090 l->lns = ipr;
1092 else
1094 while (pos->next)
1095 pos = pos->next;
1096 pos->next = ipr;
1098 strncpy (ipr->hostname, value, sizeof (ipr->hostname));
1099 if (d)
1100 ipr->port = atoi (d);
1101 else
1102 ipr->port = UDP_LISTEN_PORT;
1103 break;
1104 default:
1105 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
1106 word);
1107 return -1;
1109 return 0;
1112 int set_rand_sys ()
1114 l2tp_log(LOG_WARNING, "The \"rand()\" function call is not a very good source"
1115 "of randomness\n");
1116 rand_source = RAND_SYS;
1117 return 0;
1120 int set_ipsec_saref (char *word, char *value, int context, void *item)
1122 struct global *g = ((struct global *) item);
1123 switch (context & ~CONTEXT_DEFAULT)
1125 case CONTEXT_GLOBAL:
1126 if (set_boolean
1127 (word, value, &(g->ipsecsaref)))
1128 return -1;
1129 if(g->ipsecsaref) {
1130 l2tp_log(LOG_WARNING, "Enabling IPsec SAref processing for L2TP transport mode SAs\n");
1132 if(g->forceuserspace != 1) {
1133 l2tp_log(LOG_WARNING, "IPsec SAref does not work with L2TP kernel mode yet, enabling forceuserspace=yes\n");
1135 break;
1136 default:
1137 snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n",
1138 word);
1139 return -1;
1141 return 0;
1144 int set_rand_dev ()
1146 rand_source = RAND_DEV;
1147 return 0;
1150 int set_rand_egd (char *value)
1152 l2tp_log(LOG_WARNING, "%s: not yet implemented!\n", __FUNCTION__);
1153 rand_source = RAND_EGD;
1154 return -1;
1157 int set_rand_source (char *word, char *value, int context, void *item)
1159 time_t seconds;
1161 * We're going to go ahead and seed the rand() function with srand()
1162 * because even if we set the randomness source to dev or egd, they
1163 * can fall back to sys if they fail, so we want to make sure we at
1164 * least have *some* semblance of randomness available from the
1165 * rand() function
1168 * This is a sucky random number seed...just the result from the
1169 * time() call...but...the user requested to use the rand()
1170 * function, which is a pretty sucky source of randomness
1171 * regardless...at least we can get a almost sorta decent seed. If
1172 * you have any better suggestions for creating a seed...lemme know
1173 * :/
1175 seconds = time(NULL);
1176 srand(seconds);
1178 if (context != CONTEXT_GLOBAL)
1180 l2tp_log(LOG_WARNING, "%s: %s not valid in context %d\n",
1181 __FUNCTION__, word, context);
1182 return -1;
1184 /* WORKING HERE */
1185 if (strlen(value) == 0)
1187 snprintf(filerr, sizeof (filerr), "no randomness source specified\n");
1188 return -1;
1190 if (strncmp(value, "egd", 3) == 0)
1192 return set_rand_egd(value);
1194 else if (strncmp(value, "dev", 3) == 0)
1196 return set_rand_dev();
1198 else if (strncmp(value, "sys", 3) == 0)
1200 return set_rand_sys();
1202 else
1204 l2tp_log(LOG_WARNING, "%s: %s is not a valid randomness source\n",
1205 __FUNCTION__, value);
1206 return -1;
1211 int parse_config (FILE * f)
1213 /* Read in the configuration file handed to us */
1214 /* FIXME: I should check for incompatible options */
1215 int context = 0;
1216 char buf[STRLEN];
1217 char *s, *d, *t;
1218 int linenum = 0;
1219 int def = 0;
1220 void *data = NULL;
1221 struct lns *tl;
1222 struct lac *tc;
1223 while (!feof (f))
1225 if (NULL == fgets (buf, sizeof (buf), f))
1227 /* Error or EOL */
1228 break;
1230 linenum++;
1231 s = buf;
1232 /* Strip comments */
1233 while (*s && *s != ';')
1234 s++;
1235 *s = 0;
1236 s = buf;
1237 if (!strlen (buf))
1238 continue;
1239 while ((*s < 33) && *s)
1240 s++; /* Skip over beginning white space */
1241 t = s + strlen (s);
1242 while ((t >= s) && (*t < 33))
1243 *(t--) = 0; /* Ditch trailing white space */
1244 if (!strlen (s))
1245 continue;
1246 if (s[0] == '[')
1248 /* We've got a context description */
1249 if (!(t = strchr (s, ']')))
1251 l2tp_log (LOG_CRIT, "parse_config: line %d: No closing bracket\n",
1252 linenum);
1253 return -1;
1255 t[0] = 0;
1256 s++;
1257 if ((d = strchr (s, ' ')))
1259 /* There's a parameter */
1260 d[0] = 0;
1261 d++;
1263 if (d && !strcasecmp (d, "default"))
1264 def = CONTEXT_DEFAULT;
1265 else
1266 def = 0;
1267 if (!strcasecmp (s, "global"))
1269 context = CONTEXT_GLOBAL;
1270 #ifdef DEBUG_FILE
1271 l2tp_log (LOG_DEBUG,
1272 "parse_config: global context descriptor %s\n",
1273 d ? d : "");
1274 #endif
1275 data = &gconfig;
1277 else if (!strcasecmp (s, "lns"))
1279 context = CONTEXT_LNS;
1280 if (def)
1282 if (!deflns)
1284 deflns = new_lns ();
1285 strncpy (deflns->entname, "default",
1286 sizeof (deflns->entname));
1288 data = deflns;
1289 continue;
1291 data = NULL;
1292 tl = lnslist;
1293 if (d)
1295 while (tl)
1297 if (!strcasecmp (d, tl->entname))
1298 break;
1299 tl = tl->next;
1301 if (tl)
1302 data = tl;
1304 if (!data)
1306 data = new_lns ();
1307 if (!data)
1308 return -1;
1309 ((struct lns *) data)->next = lnslist;
1310 lnslist = (struct lns *) data;
1312 if (d)
1313 strncpy (((struct lns *) data)->entname,
1314 d, sizeof (((struct lns *) data)->entname));
1315 #ifdef DEBUG_FILE
1316 l2tp_log (LOG_DEBUG, "parse_config: lns context descriptor %s\n",
1317 d ? d : "");
1318 #endif
1320 else if (!strcasecmp (s, "lac"))
1322 context = CONTEXT_LAC;
1323 if (def)
1325 if (!deflac)
1327 deflac = new_lac ();
1328 strncpy (deflac->entname, "default",
1329 sizeof (deflac->entname));
1331 data = deflac;
1332 continue;
1334 data = NULL;
1335 tc = laclist;
1336 if (d)
1338 while (tc)
1340 if (!strcasecmp (d, tc->entname))
1341 break;
1342 tc = tc->next;
1344 if (tc)
1345 data = tc;
1347 if (!data)
1349 data = new_lac ();
1350 if (!data)
1351 return -1;
1352 ((struct lac *) data)->next = laclist;
1353 laclist = (struct lac *) data;
1355 if (d)
1356 strncpy (((struct lac *) data)->entname,
1357 d, sizeof (((struct lac *) data)->entname));
1358 #ifdef DEBUG_FILE
1359 l2tp_log (LOG_DEBUG, "parse_config: lac context descriptor %s\n",
1360 d ? d : "");
1361 #endif
1363 else
1365 l2tp_log (LOG_WARNING,
1366 "parse_config: line %d: unknown context '%s'\n", linenum,
1368 return -1;
1371 else
1373 if (!context)
1375 l2tp_log (LOG_WARNING,
1376 "parse_config: line %d: data '%s' occurs with no context\n",
1377 linenum, s);
1378 return -1;
1380 if (!(t = strchr (s, '=')))
1382 l2tp_log (LOG_WARNING, "parse_config: line %d: no '=' in data\n",
1383 linenum);
1384 return -1;
1386 d = t;
1387 d--;
1388 t++;
1389 while ((d >= s) && (*d < 33))
1390 d--;
1391 d++;
1392 *d = 0;
1393 while (*t && (*t < 33))
1394 t++;
1395 #ifdef DEBUG_FILE
1396 l2tp_log (LOG_DEBUG, "parse_config: field is %s, value is %s\n", s, t);
1397 #endif
1398 /* Okay, bit twidling is done. Let's handle this */
1400 switch (parse_one_option (s, t, context | def, data))
1402 case -1:
1403 l2tp_log (LOG_WARNING, "parse_config: line %d: %s", linenum,
1404 filerr);
1405 return -1;
1406 case -2:
1407 l2tp_log (LOG_CRIT, "parse_config: line %d: Unknown field '%s'\n",
1408 linenum, s);
1409 return -1;
1413 return 0;
1416 int parse_one_option(char *word, char *value, int context, void *item)
1418 struct keyword *kw;
1420 for (kw = words; kw->keyword; kw++)
1422 if (!strcasecmp (word, kw->keyword))
1424 if (kw->handler (word, value, context, item))
1426 return -1;
1428 break;
1431 if (!kw->keyword)
1433 return -2;
1435 return 0;
1438 struct keyword words[] = {
1439 {"listen-addr", &set_listenaddr},
1440 {"port", &set_port},
1441 {"rand source", &set_rand_source},
1442 {"auth file", &set_authfile},
1443 {"exclusive", &set_exclusive},
1444 {"autodial", &set_autodial},
1445 {"redial", &set_redial},
1446 {"redial timeout", &set_rtimeout},
1447 {"lns", &set_lns},
1448 {"max redials", &set_rmax},
1449 {"access control", &set_accesscontrol},
1450 {"force userspace", &set_userspace},
1451 {"ip range", &set_iprange},
1452 {"no ip range", &set_iprange},
1453 {"debug avp", &set_debugavp},
1454 {"debug network", &set_debugnetwork},
1455 {"debug packet", &set_debugpacket},
1456 {"debug tunnel", &set_debugtunnel},
1457 {"debug state", &set_debugstate},
1458 {"ipsec saref", &set_ipsec_saref},
1459 {"lac", &set_lac},
1460 {"no lac", &set_lac},
1461 {"assign ip", &set_assignip},
1462 {"local ip", &set_localaddr},
1463 {"remote ip", &set_remoteaddr},
1464 {"defaultroute", &set_defaultroute},
1465 {"length bit", &set_lbit},
1466 {"hidden bit", &set_hbit},
1467 {"require pap", &set_papchap},
1468 {"require chap", &set_papchap},
1469 {"require authentication", &set_papchap},
1470 {"require auth", &set_papchap},
1471 {"refuse pap", &set_papchap},
1472 {"refuse chap", &set_papchap},
1473 {"refuse authentication", &set_papchap},
1474 {"refuse auth", &set_papchap},
1475 {"unix authentication", &set_passwdauth},
1476 {"unix auth", &set_passwdauth},
1477 {"name", &set_authname},
1478 {"hostname", &set_hostname},
1479 {"ppp debug", &set_debug},
1480 {"pppoptfile", &set_pppoptfile},
1481 {"call rws", &set_rws},
1482 {"tunnel rws", &set_rws},
1483 {"flow bit", &set_flow},
1484 {"challenge", &set_challenge},
1485 {"tx bps", &set_speed},
1486 {"rx bps", &set_speed},
1487 {"bps", &set_speed},
1488 {NULL, NULL}