diff -aur l2tpd-0.69_old/aaa.c l2tpd-0.69_new/aaa.c --- l2tpd-0.69_old/aaa.c 2002-04-23 13:50:49.000000000 -0600 +++ l2tpd-0.69_new/aaa.c 2005-09-26 00:56:40.000000000 -0600 @@ -25,7 +25,7 @@ /* FIXME: Accounting? */ -static struct addr_ent *uaddr[ADDR_HASH_SIZE]; +struct addr_ent *uaddr[ADDR_HASH_SIZE]; void init_addr () { @@ -317,10 +317,11 @@ (ntohl (t->peer.sin_addr.s_addr) <= ntohl (ipr->end))) { #ifdef DEBUG_AAA + /* mferd, 29.01.2003: t->addr #ifdef'd out ... */ log (LOG_DEBUG, "get_lns: Rule %s to %s, sense %s matched %s\n", IPADDY (ipr->start), IPADDY (ipr->end), - (ipr->sense ? "allow" : "deny"), IPADDY (t->addr)); + (ipr->sense ? "allow" : "deny"), IPADDY (t->peer.sin_addr.s_addr)); #endif allow = ipr->sense; } diff -aur l2tpd-0.69_old/avp.c l2tpd-0.69_new/avp.c --- l2tpd-0.69_old/avp.c 2002-08-19 09:39:27.000000000 -0600 +++ l2tpd-0.69_new/avp.c 2005-09-26 00:48:20.000000000 -0600 @@ -1596,6 +1596,7 @@ int hidlen; char *data = buf->start + sizeof (struct control_hdr); avp = (struct avp_hdr *) data; + if (debug_avp) log (LOG_DEBUG, "%s: handling avp's for tunnel %d, call %d\n", __FUNCTION__, t->ourtid, c->ourcid); @@ -1608,7 +1609,7 @@ if (AMBIT (avp->length)) { log (LOG_WARN, - "%s: dont know how to handle mandatory attribute %d. Closing %s.\n" + "%s: dont know how to handle mandatory attribute %d. Closing %s.\n", __FUNCTION__, avp->attr, (c != t->self) ? "call" : "tunnel"); set_error (c, VENDOR_ERROR, @@ -1643,7 +1644,7 @@ c->needclose = -1; return -EINVAL; } - if (ALENGTH (avp->length) < sizeof (struct avp_hdr)) + if (ALENGTH (avp->length) < (int) sizeof (struct avp_hdr)) /* mf, 04.05.2004: cast to (int), avoid compiler warning */ { log (LOG_WARN, "%s: AVP with too small of size (%d).\n", __FUNCTION__, ALENGTH (avp->length)); diff -aur l2tpd-0.69_old/avp.h l2tpd-0.69_new/avp.h --- l2tpd-0.69_old/avp.h 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/avp.h 2005-09-26 00:48:20.000000000 -0600 @@ -116,7 +116,8 @@ extern int add_avp_rws (struct buffer *, _u16); extern int add_tunnelid_avp (struct buffer *, _u16); extern int add_vendor_avp (struct buffer *); -extern int add_hostname_avp (struct buffer *); +/* mferd, 30.01.2003: hostname as arg to add_hostname_avp */ +extern int add_hostname_avp (struct buffer *, char *); extern int add_firmware_avp (struct buffer *); extern int add_bearer_caps_avp (struct buffer *buf, _u16 caps); extern int add_frame_caps_avp (struct buffer *buf, _u16 caps); diff -aur l2tpd-0.69_old/avpsend.c l2tpd-0.69_new/avpsend.c --- l2tpd-0.69_old/avpsend.c 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/avpsend.c 2005-09-26 00:48:20.000000000 -0600 @@ -98,15 +98,14 @@ } */ -int add_hostname_avp (struct buffer *buf) +int add_hostname_avp (struct buffer *buf, char *hostname) { - char names[6] = "eriwan"; _u16 *raw = (_u16 *) (buf->start + buf->len); - raw[0] = htons (0xC | MBIT); + raw[0] = htons ((0x6 + strlen(hostname)) | MBIT); raw[1] = htons (VENDOR_ID); raw[2] = htons (0x7); - strcpy ((char *) (&raw[3]), names); - buf->len += 12; + strcpy ((char *) (&raw[3]), hostname); + buf->len += 6 + strlen(hostname); return 0; } diff -aur l2tpd-0.69_old/call.c l2tpd-0.69_new/call.c --- l2tpd-0.69_old/call.c 2002-08-09 18:47:25.000000000 -0600 +++ l2tpd-0.69_new/call.c 2005-09-26 00:48:20.000000000 -0600 @@ -138,7 +138,9 @@ errors++; log (LOG_DEBUG, "%s: Error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); - if (errors > 10) + /* mf, 08.06.2004: if pppd dies, read return EBADF (Bad File Descriptor) + in that case, don't bother repeating */ + if (errors > 10 || errno == EBADF) { log (LOG_DEBUG, "%s: Too many errors. Declaring call dead.\n", @@ -193,8 +195,7 @@ } } /* I should never get here */ - log (LOG_WARN, "%s: You should not see this message. If you do, please - enter a bug report at http://sourceforge.net/projects/l2tpd", __FUNCTION__); + log (LOG_WARN, "%s: You should not see this message. If you do, please enter a bug report at http://sourceforge.net/projects/l2tpd", __FUNCTION__); return -EINVAL; } @@ -313,11 +314,15 @@ call_close (tmp); tmp = tmp2; } + /* mf, 16.04.2003: change log message to show tunneltag */ + //log (LOG_LOG, + // "%s : Connection %d closed to %s, port %d (%s)\n", __FUNCTION__, + // c->container->tid, + // IPADDY (c->container->peer.sin_addr), + // ntohs (c->container->peer.sin_port), c->errormsg); log (LOG_LOG, - "%s : Connection %d closed to %s, port %d (%s)\n", __FUNCTION__, - c->container->tid, - IPADDY (c->container->peer.sin_addr), - ntohs (c->container->peer.sin_port), c->errormsg); + "%s : Connection closed with peer %s, reason: %s\n", + __FUNCTION__, c->container->tunneltag, c->errormsg); } else { @@ -524,6 +529,10 @@ tmp->ourcid = 0x6227; #endif } + else + { log(LOG_DEBUG, "%s: initializing ourcid to 0\n", __FUNCTION__); + tmp->ourcid=0; + } tmp->dialed[0] = 0; tmp->dialing[0] = 0; tmp->subaddy[0] = 0; @@ -536,6 +545,7 @@ /* tmp->rws = -1; */ tmp->fd = -1; tmp->oldptyconf = malloc (sizeof (struct termios)); + tmp->ptyname[0] = '\0'; /* mf, 08.04.2003: no name for pty yet */ tmp->pnu = 0; tmp->cnu = 0; tmp->needclose = 0; diff -aur l2tpd-0.69_old/call.h l2tpd-0.69_new/call.h --- l2tpd-0.69_old/call.h 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/call.h 2005-09-26 00:48:20.000000000 -0600 @@ -70,6 +70,7 @@ struct tunnel *container; /* Tunnel we belong to */ int fd; /* File descriptor for pty */ struct termios *oldptyconf; + char ptyname[6]; /* mf, 08.04.2003: string for ptyname */ int die; int nego; /* Show negotiation? */ int pppd; /* PID of pppd */ @@ -82,12 +83,15 @@ int pnu; /* ditto for payload packet */ char errormsg[MAXSTRLEN]; /* Error message */ /* int rws; Receive window size, or -1 for none */ +/* mferd, 30.01.2003: rws missing? */ int rws; struct timeval lastsent; /* When did we last send something? */ _u16 data_seq_num; /* Sequence for next payload packet */ _u16 data_rec_seq_num; /* Sequence for next received payload packet */ _u16 closeSs; /* What number was in Ns when we started to close? */ int pLr; /* Last packet received by peer */ +/* mferd, 29.01.2003: pSr missing? */ _u16 pSr; +/* mferd, 30.01.2003: pSr missing? */ _u16 pSs; struct lns *lns; /* LNS that owns us */ struct lac *lac; /* LAC that owns us */ char dial_no[128]; /* jz: dialing number for outgoing call */ diff -aur l2tpd-0.69_old/control.c l2tpd-0.69_new/control.c --- l2tpd-0.69_old/control.c 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/control.c 2005-09-26 00:48:20.000000000 -0600 @@ -62,6 +62,8 @@ int global_serno = 1; + + struct buffer *new_outgoing (struct tunnel *t) { /* @@ -161,6 +163,28 @@ udp_xmit (buf); } +/* mferd, 04.02.2003: make sure challenge storage is malloc'd */ +#define MALLOC_CHALLENGE(data,size) \ + { data=malloc(size); \ + if (!(data)) \ + { \ + log (LOG_WARN, "%s: malloc failed\n", __FUNCTION__); \ + set_error (c, VENDOR_ERROR, "malloc failed"); \ + toss (buf); \ + return -EINVAL; \ + } \ + } + +/* mf, 03.04.2003: provide string representation of tunnel in newly malloc'd memory */ +char *get_tunneltag (struct tunnel *t) + { char tag[128]; + + sprintf(tag, "%s:%d/rt=%d/lt=%d", + IPADDY (t->peer.sin_addr), ntohs (t->peer.sin_port), + t->tid, t->ourtid); + return(strdup(tag)); + } + int control_finish (struct tunnel *t, struct call *c) { /* @@ -183,6 +207,9 @@ char ip1[STRLEN]; char ip2[STRLEN]; char dummy_buf[128] = "/var/l2tp/"; /* jz: needed to read /etc/ppp/var.options - just kick it if you dont like */ + char *my_l2tp_hostname; /* mferd, 30.01.2003: use "hostname" set in l2tpd.conf */ + char my_ipparam[STRLEN]; /* mf, 08.04.2003: used to construct ipparam arg to pppd */ + if (c->msgtype < 0) { log (LOG_DEBUG, "%s: Whoa... non-ZLB with no message type!\n", @@ -201,6 +228,24 @@ */ if (t->self == c) { + /* mferd, 30.01.2003: set my_l2tp_hostname to configured lns resp. lac hostname */ + /* use network hostname as fallback */ + /* my_l2tp_hostname=t->lns ? t->lns->hostname : t->lac ? t->lac->hostname : hostname; */ + my_l2tp_hostname="\0"; + if (t->lns) + { log(LOG_WARN, "my configured LNS hostname: %s\n", t->lns->hostname); + my_l2tp_hostname=t->lns->hostname; + } + else if (t->lac) + { log(LOG_WARN, "my configured LAC hostname: %s\n", t->lac->hostname); + my_l2tp_hostname=t->lac->hostname; + } + if (!strlen(my_l2tp_hostname)) + { log(LOG_WARN, "no configured LAC/LNS hostname found, using network hostname %s", + hostname); + my_l2tp_hostname=hostname; + } + if (t->lns) { t->ourrws = t->lns->tun_rws; @@ -225,14 +270,15 @@ add_bearer_caps_avp (buf, t->ourbc); /* FIXME: Tie breaker */ add_firmware_avp (buf); - add_hostname_avp (buf); + add_hostname_avp (buf, my_l2tp_hostname); add_vendor_avp (buf); add_tunnelid_avp (buf, t->ourtid); if (t->ourrws >= 0) add_avp_rws (buf, t->ourrws); if ((t->lac && t->lac->challenge) || (t->lns && t->lns->challenge)) - { + { /* mferd, 04.02.2003: challenge storage needs malloc */ + MALLOC_CHALLENGE(t->chal_them.challenge, MD_SIG_SIZE) mk_challenge (t->chal_them.challenge, MD_SIG_SIZE); add_challenge_avp (buf, t->chal_them.challenge, MD_SIG_SIZE); t->chal_them.state = STATE_CHALLENGED; @@ -357,6 +403,24 @@ c->needclose = -1; return -EINVAL; } + /* mferd, 30.01.2003: set my_l2tp_hostname to configured lns resp. lac hostname */ + /* use network hostname as fallback */ + /* my_l2tp_hostname=t->lns ? t->lns->hostname : t->lac ? t->lac->hostname : hostname; */ + my_l2tp_hostname="\0"; + if (t->lns) + { log(LOG_WARN, "my configured LNS hostname: %s\n", t->lns->hostname); + my_l2tp_hostname=t->lns->hostname; + } + else if (t->lac) + { log(LOG_WARN, "my configured LAC hostname: %s\n", t->lac->hostname); + my_l2tp_hostname=t->lac->hostname; + } + if (!strlen(my_l2tp_hostname)) + { log(LOG_WARN, "no configured LAC/LNS hostname found, using network hostname %s\n", + hostname); + my_l2tp_hostname=hostname; + } + t->ourrws = t->lns->tun_rws; t->hbit = t->lns->hbit; if (t->fc < 0) @@ -425,7 +489,7 @@ add_frame_caps_avp (buf, t->ourfc); add_bearer_caps_avp (buf, t->ourbc); add_firmware_avp (buf); - add_hostname_avp (buf); + add_hostname_avp (buf, my_l2tp_hostname); add_vendor_avp (buf); add_tunnelid_avp (buf, t->ourtid); if (t->ourrws >= 0) @@ -583,10 +647,13 @@ t->ourtid); #endif t->hello = schedule (tv, hello, (void *) t); - log (LOG_LOG, + t->tunneltag = get_tunneltag(t); + /* mf, 03.04.2003: use tunneltag in log message */ + /*log (LOG_LOG, "%s: Connection established to %s, %d. Local: %d, Remote: %d.\n", __FUNCTION__, IPADDY (t->peer.sin_addr), - ntohs (t->peer.sin_port), t->ourtid, t->tid); + ntohs (t->peer.sin_port), t->ourtid, t->tid); */ + log (LOG_LOG, "%s: Connection established to %s\n", t->tunneltag); if (t->lac) { /* This is part of a LAC, so we want to go ahead @@ -619,10 +686,14 @@ } #endif t->state = SCCCN; - log (LOG_LOG, + t->tunneltag = get_tunneltag(t); + /* mf, 03.04.2003: use tunneltag in log message */ + /*log (LOG_LOG, "%s: Connection established to %s, %d. Local: %d, Remote: %d. LNS session is '%s'\n", __FUNCTION__, IPADDY (t->peer.sin_addr), - ntohs (t->peer.sin_port), t->ourtid, t->tid, t->lns->entname); + ntohs (t->peer.sin_port), t->ourtid, t->tid, t->lns->entname);*/ + log (LOG_LOG, "%s: Connection established to %s. LNS session is '%s'\n", + __FUNCTION__, t->tunneltag, t->lns->entname); /* Schedule a HELLO */ tv.tv_sec = HELLO_DELAY; tv.tv_usec = 0; @@ -660,10 +731,13 @@ __FUNCTION__); return -EINVAL; } - log (LOG_LOG, + /* mf, 03.04.2003: use tunneltag in log message */ + /*log (LOG_LOG, "%s: Connection closed to %s, port %d (%s), Local: %d, Remote: %d\n", __FUNCTION__, IPADDY (t->peer.sin_addr), - ntohs (t->peer.sin_port), t->self->errormsg, t->ourtid, t->tid); + ntohs (t->peer.sin_port), t->self->errormsg, t->ourtid, t->tid); */ + log (LOG_LOG, "%s: Connection closed to %s (%s)\n", + __FUNCTION__, t->tunneltag, t->self->errormsg); c->needclose = 0; c->closing = -1; break; @@ -812,14 +886,20 @@ #endif if (debug_state) log (LOG_DEBUG, "%s: Sending ICCN\n", __FUNCTION__); - log (LOG_LOG, + /* mf, 03.04.2003: use tunneltag in log message */ + /* log (LOG_LOG, "%s: Call established with %s, Local: %d, Remote: %d, Serial: %d\n", __FUNCTION__, IPADDY (t->peer.sin_addr), c->ourcid, c->cid, + c->serno); */ + log (LOG_LOG, + "%s: Call established with %s, Local: %d, Remote: %d, Serial: %d\n", + __FUNCTION__, t->tunneltag, c->ourcid, c->cid, c->serno); control_xmit (buf); po = NULL; po = add_opt (po, "passive"); - po = add_opt (po, "-detach"); + po = add_opt (po, "nodetach"); + if (c->lac) { if (c->lac->defaultroute) @@ -911,7 +991,7 @@ strncpy (ip2, IPADDY (c->addr), sizeof (ip2)); po = NULL; po = add_opt (po, "passive"); - po = add_opt (po, "-detach"); + po = add_opt (po, "nodetach"); po = add_opt (po, "%s:%s", c->lns->localaddr ? ip1 : "", ip2); if (c->lns->authself) { @@ -947,11 +1027,30 @@ po = add_opt (po, "file"); po = add_opt (po, c->lns->pppoptfile); } + /* mf, 08.04.2003: setup ipparam arguments */ + my_ipparam[0] = '\0'; + if (c->lns->ipparam[0]) + { strncat(my_ipparam, c->lns->ipparam, sizeof(my_ipparam)-strlen(my_ipparam)-1); } + if (c->lns->ipparamtunneltag) + { if (my_ipparam[0]) + { strncat(my_ipparam, ",l2gw=", sizeof(my_ipparam)-strlen(my_ipparam)-1); } + strncat(my_ipparam, c->container->tunneltag, + sizeof(my_ipparam)-strlen(my_ipparam)-1); + } + if (my_ipparam[0]) + { po = add_opt(po, "ipparam"); + po = add_opt(po, my_ipparam); + } start_pppd (c, po); opt_destroy (po); - log (LOG_LOG, + /* mf, 03.04.2003: use tunneltag in log message */ + /*log (LOG_LOG, "%s: Call established with %s, Local: %d, Remote: %d, Serial: %d\n", __FUNCTION__, IPADDY (t->peer.sin_addr), c->ourcid, c->cid, + c->serno); */ + log (LOG_LOG, + "%s: Call established with %s, Local: %d, Remote: %d, Serial: %d\n", + __FUNCTION__, t->tunneltag, c->ourcid, c->cid, c->serno); break; case OCRP: /* jz: nothing to do for OCRP, waiting for OCCN */ @@ -959,7 +1058,7 @@ case OCCN: /* jz: get OCCN, so the only thing we must do is to start the pppd */ po = NULL; po = add_opt (po, "passive"); - po = add_opt (po, "-detach"); + po = add_opt (po, "nodetach"); po = add_opt (po, "file"); strcat (dummy_buf, c->dial_no); /* jz: use /etc/ppp/dialnumber.options for pppd - kick it if you dont like */ strcat (dummy_buf, ".options"); @@ -1057,9 +1156,13 @@ __FUNCTION__); return -EINVAL; } + /* mf, 03.04.2003: use tunneltag in log message */ + /*log (LOG_LOG, + "%s: Connection closed to %s, serial %d (%s)\n", __FUNCTION__, + IPADDY (t->peer.sin_addr), c->serno, c->errormsg);*/ log (LOG_LOG, "%s: Connection closed to %s, serial %d (%s)\n", __FUNCTION__, - IPADDY (t->peer.sin_addr), c->serno, c->errormsg); + t->tunneltag, c->serno, c->errormsg); c->needclose = 0; c->closing = -1; break; @@ -1085,7 +1188,7 @@ */ struct control_hdr *h = (struct control_hdr *) (buf->start); struct buffer *zlb; - if (buf->len < sizeof (struct control_hdr)) + if (buf->len < (int) sizeof (struct control_hdr)) /* mf, 04.05.2004: cast to (int), avoid compiler warning */ { if (DEBUG) { @@ -1411,7 +1514,8 @@ log (LOG_DEBUG, "%s: payload, cid = %d, Ns = %d, Nr = %d\n", __FUNCTION__, c->cid, new_hdr->Ns, new_hdr->Nr); #endif - if (new_hdr->Ns != c->data_seq_num) + /* if (new_hdr->Ns != c->data_seq_num) */ /* mf, 03.04.2003: should be data_rec_seq_num, I suppose...*/ + if (new_hdr->Ns != c->data_rec_seq_num) { /* RFC1982-esque comparison of serial numbers */ if (((new_hdr->Ns < c->data_rec_seq_num) && @@ -1657,11 +1761,11 @@ } } -inline int handle_packet (struct buffer *buf, struct tunnel *t, +/* mf, 14.06.2004: de-inline function handle_packet */ +/*inline*/ int handle_packet (struct buffer *buf, struct tunnel *t, struct call *c) { int res; - struct timeval tv; if (CTBIT (*((_u16 *) buf->start))) { /* We have a control packet */ @@ -1712,7 +1816,7 @@ { if (!expand_payload (buf, t, c)) { - if (buf->len > sizeof (struct payload_hdr)) + if (buf->len > (int) sizeof (struct payload_hdr)) /* mf, 04.05.2004: cast to (int), avoid compiler warning */ { /* if (c->throttle) { if (c->pSs > c->pLr + c->rws) { diff -aur l2tpd-0.69_old/control.h l2tpd-0.69_new/control.h --- l2tpd-0.69_old/control.h 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/control.h 2005-09-26 00:48:20.000000000 -0600 @@ -63,5 +63,7 @@ extern void hello (void *); extern void send_zlb (void *); extern void dethrottle (void *); +/* mf, 08.06.2004: get_tunneltag also needed in other places */ +char *get_tunneltag (struct tunnel *t); #endif diff -aur l2tpd-0.69_old/file.c l2tpd-0.69_new/file.c --- l2tpd-0.69_old/file.c 2002-08-09 18:55:14.000000000 -0600 +++ l2tpd-0.69_new/file.c 2005-09-26 00:48:20.000000000 -0600 @@ -35,6 +35,11 @@ int parse_config (FILE *); struct keyword words[]; +unsigned int listen_addy=INADDR_ANY; /* Address to listen on */ /* mf, 27.03.2003: moved here from network.c */ +char *l2tpdstatusfile="/var/run/l2tpd.status"; /* mf, 27.03.2003: configurable output file for status dumps (SIGUSR1) */ + + + int init_config () { FILE *f; @@ -109,6 +114,8 @@ tmp->debug = 0; tmp->pppoptfile[0] = 0; tmp->t = NULL; + tmp->ipparam[0] = '\0'; + tmp->ipparamtunneltag = 0; return tmp; } @@ -557,6 +564,41 @@ return 0; } +/* mf, 08.04.2003: option to give tunneltag to pppd via ipparam (l2gw=) */ +int set_ipparamtunneltag(char *word, char *value, int context, void *item) +{ + switch (context & ~CONTEXT_DEFAULT) + { + case CONTEXT_LNS: + if (set_boolean (word, value, &(((struct lns *) item)->ipparamtunneltag))) + return -1; + break; + default: + snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", + word); + return -1; + } + return 0; +} + +/* mf, 08.04.2003: configure static ipparam argument for pppd */ +int set_ipparam(char *word, char *value, int context, void *item) +{ + struct lns *n = (struct lns *) item; + switch (context & ~CONTEXT_DEFAULT) + { + case CONTEXT_LNS: + if (set_string (word, value, n->ipparam, sizeof (n->ipparam))) + return -1; + break; + default: + snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", + word); + return -1; + } + return 0; +} + int set_pppoptfile (char *word, char *value, int context, void *item) { struct lac *l = (struct lac *) item; @@ -599,7 +641,7 @@ l->pap_require = result; else if (c[0] == 'a') /* Authentication */ if (word[2] == 'f') - l->authself = result; + l->authself = !result; /* mferd, 04.02.2003: missing ! */ else l->authpeer = result; else /* CHAP */ if (word[2] == 'f') @@ -763,8 +805,9 @@ if (!lns->range) return -1; #ifdef DEBUG_FILE + /* mferd, 29.01.2003: ipr not defined, give info about lns->range instead */ log (LOG_DEBUG, "range start = %x, end = %x, sense=%ud\n", - ntohl (ipr->start), ntohl (ipr->end), ipr->sense); + ntohl (lns->range->start), ntohl (lns->range->end), lns->range->sense); #endif return 0; } @@ -785,8 +828,9 @@ if (!lns->lacs) return -1; #ifdef DEBUG_FILE + /* mferd, 29.01.2003: ipr undefined, info about lns->lacs instead */ log (LOG_DEBUG, "lac start = %x, end = %x, sense=%ud\n", - ntohl (ipr->start), ntohl (ipr->end), ipr->sense); + ntohl (lns->lacs->start), ntohl (lns->lacs->end), lns->lacs->sense); #endif return 0; } @@ -821,6 +865,61 @@ return 0; } +/* mf, 27.03.2003: set listenaddr */ +int set_listenaddr(char *word, char *value, int context, void *item) +{ + switch (context & ~CONTEXT_DEFAULT) + { + case CONTEXT_GLOBAL: +#ifdef DEBUG_FILE + log (LOG_DEBUG, "set_listenaddr: Setting global listen address to %s\n", + value); +#endif + return set_ip (word, value, &listen_addy); + break; + default: + snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", + word); + return -1; + } + return 0; +} + +/* mf, 27.03.2003: set statusfile (for SIGUSR1 status dumps) */ +int set_statusfile (char *word, char *value, int context, void *item) +{ + char *vdup; + + if (!strlen (value)) + { + snprintf (filerr, sizeof (filerr), + "no filename specified for statusfile\n"); + return -1; + } + switch (context & ~CONTEXT_DEFAULT) + { + case CONTEXT_GLOBAL: +#ifdef DEBUG_FILE + log (LOG_DEBUG, "%s: Setting status file to '%s'\n", + __FUNCTION__, value); +#endif /* ; */ + vdup=strdup(value); + if (!vdup) + { log (LOG_WARN, "%s: cannot duplicate statusfile name", + __FUNCTION__); + return -1; + } + l2tpdstatusfile=vdup; + break; + default: + snprintf (filerr, sizeof (filerr), "'%s' not valid in this context\n", + word); + return -1; + } + return 0; +} + + int set_localaddr (char *word, char *value, int context, void *item) { struct lac *l; @@ -1197,6 +1296,8 @@ struct keyword words[] = { {"port", &set_port}, + {"listenaddr", &set_listenaddr}, /* mf, 27.03.2003: restrict socket to specific address */ + {"statusfile", &set_statusfile}, /* mf, 27.03.2003: configurable file for status dumps (SIGUSR1) */ {"rand source", &set_rand_source}, {"auth file", &set_authfile}, {"exclusive", &set_exclusive}, @@ -1229,6 +1330,8 @@ {"name", &set_authname}, {"hostname", &set_hostname}, {"ppp debug", &set_debug}, + {"ipparam_tunneltag", &set_ipparamtunneltag},/* mf, 08.04.2003: provide tunneltag to pppd in ipparam? */ + {"ipparam", &set_ipparam}, /* mf, 08.04.2003: set ipparam arg to pppd */ {"pppoptfile", &set_pppoptfile}, {"call rws", &set_rws}, {"tunnel rws", &set_rws}, diff -aur l2tpd-0.69_old/file.h l2tpd-0.69_new/file.h --- l2tpd-0.69_old/file.h 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/file.h 2005-09-26 00:48:20.000000000 -0600 @@ -89,6 +89,8 @@ int proxyauth; /* Allow proxy authentication? */ int debug; /* Debug PPP? */ char pppoptfile[STRLEN]; /* File containing PPP options */ + char ipparam[STRLEN]; /* mf, 08.04.2003: ipparam to provide for pppd */ + int ipparamtunneltag; /* mf, 08.04.2003: provide tunneltag to pppd via ipparam? */ struct tunnel *t; /* Tunnel of this, if it's ready */ }; @@ -148,4 +150,7 @@ extern struct lns *deflns; /* Default LNS config */ extern struct lac *deflac; /* Default LAC config */ extern int init_config (); /* Read in the config file */ +extern unsigned int listen_addy; /* Address to listen on */ /* mf, 27.03.2003: moved here from network.c */ +extern char *l2tpdstatusfile; /* mf, 27.03.2003: configurable output file for status dumps (SIGUSR1) */ + #endif diff -aur l2tpd-0.69_old/l2tpd.c l2tpd-0.69_new/l2tpd.c --- l2tpd-0.69_old/l2tpd.c 2002-08-19 08:12:17.000000000 -0600 +++ l2tpd-0.69_new/l2tpd.c 2005-09-26 00:48:20.000000000 -0600 @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -39,6 +40,7 @@ #ifdef USE_KERNEL #include #endif +#include /* mf, 08.05.2003: nanosleep */ #include "l2tp.h" struct tunnel_list tunnels; @@ -129,6 +131,10 @@ entname : (c->lns ? c->lns->entname : "")), c->ourcid, c->cid, c->serno, c->data_seq_num, c->data_rec_seq_num, c->pLr, c->tx_bytes, c->tx_pkts, c->rx_bytes, c->rx_pkts); + /* mf, 27.03.2003: add compact id usable for scripts */ + fprintf (f, " tty=%s, pppd_pid=%d, tag=%d/%d/%u, peer=%s:%d\n", + c->ptyname, c->pppd, c->ourcid, c->cid, c->serno, + IPADDY (t->peer.sin_addr), ntohs (t->peer.sin_port)); c = c->next; } t = t->next; @@ -175,7 +181,13 @@ void status_handler (int sig) { - show_status (1); + /* mf, 27.03.2003: write status info to configured statusfile */ + /* allows to view status info in daemon mode */ + FILE *status; + + status=fopen(l2tpdstatusfile, "w"); + show_status(fileno(status)); + fclose(status); } void child_handler (int signal) @@ -259,7 +271,7 @@ int start_pppd (struct call *c, struct ppp_opts *opts) { - char a, b; + int flags; char tty[80]; char *stropt[80]; struct ppp_opts *p; @@ -271,7 +283,6 @@ #ifdef DEBUG_PPPD int x; #endif - struct termios ptyconf; char *str; p = opts; stropt[0] = strdup (PPPD); @@ -309,23 +320,13 @@ else { #endif - if ((c->fd = getPtyMaster (&a, &b)) < 0) + if (pty_get(&c->fd, &fd2) < 0) { log (LOG_WARN, "%s: unable to allocate pty, abandoning!\n", __FUNCTION__); return -EINVAL; } - /* set fd opened above to not echo so we don't see read our own packets - back of the file descriptor that we just wrote them to */ - tcgetattr (c->fd, &ptyconf); - *(c->oldptyconf) = ptyconf; - ptyconf.c_cflag &= ~(ICANON | ECHO); - tcsetattr (c->fd, TCSANOW, &ptyconf); - - snprintf (tty, sizeof (tty), "/dev/tty%c%c", a, b); - fd2 = open (tty, O_RDWR); - #ifdef USE_KERNEL } #endif @@ -388,9 +389,15 @@ execv (PPPD, stropt); log (LOG_WARN, "%s: Exec of %s failed!\n", __FUNCTION__, PPPD); exit (1); - }; + } + /* mferd, 05.02.2003: race condition? ppp packets received are echoed until pppd comes up; + workaround: lose some time and hope pppd comes up fast enough... */ + else { /* sleep(1); */ struct timespec req, rem; req.tv_sec=0; req.tv_nsec= 300000000L; nanosleep(&req,&rem); } + close (fd2); pos = 0; + flags = fcntl(c->fd, F_GETFL); + if (flags >= 0) fcntl(c->fd, F_SETFL, (long) flags | O_NONBLOCK); while (stropt[pos]) { free (stropt[pos]); @@ -409,6 +416,7 @@ */ struct call *c, *me; + struct call *c2; /* mf, 26.06.2004: needed for walk through list while freeing it */ struct tunnel *p; struct timeval tv; if (!t) @@ -429,8 +437,9 @@ c = t->call_head; while (c) { + c2 = c->next; /* mf, 26.06.2004: can't use c->next after freeing c */ destroy_call (c); - c = c->next; + c = c2; /* mf, 26.06.2004: can't use c->next after freeing c */ }; /* * Remove ourselves from the list of tunnels @@ -483,6 +492,7 @@ */ if (t->lns) t->lns->t = NULL; + if (t->tunneltag) { free(t->tunneltag); } /* mf, 03.04.2003: also free tunnel tag if allocated */ free (t); free (me); } @@ -731,6 +741,9 @@ tmp->hostname[0] = 0; tmp->vendor[0] = 0; tmp->secret[0] = 0; + /* mf, 14.06.2004: valgrind suggested initializing parent->self */ + tmp->self = (struct call *) NULL; + if (!(tmp->self = new_call (tmp))) { free (tmp); @@ -749,6 +762,8 @@ tmp->chal_them.vector = (unsigned char *) malloc (VECTOR_SIZE); tmp->chal_us.vector = NULL; tmp->hbit = 0; + /* mf, 03.04.2003: tunneltag invalid until after connection is established */ + tmp->tunneltag = NULL; return tmp; } @@ -1002,29 +1017,43 @@ /* Read previous pid file. */ if ((i = open(gconfig.pidfile,O_RDONLY)) > 0) { l=read(i,buf,sizeof(buf)-1); - if (i < 0) { + /* mf, 27.03.2003: usage of "i" (filedescr) corrected to "l" (length) */ + if (l < 0) { log(LOG_LOG, "%s: Unable to read pid file [%s]\n", __FUNCTION__, gconfig.pidfile); } - buf[i] = '\0'; + buf[l] = '\0'; pid = atoi(buf); /* If the previous server process is not still running, write a new pid file immediately. */ - if (pid && (pid == getpid () || kill (pid, 0) < 0)) { + /* mf, 27.03.2003: also handle case pid=0 (e.g. empty pid file) */ + if (pid==0 || (pid && (pid == getpid () || kill (pid, 0) < 0))) { unlink (gconfig.pidfile); if ((i = open (gconfig.pidfile, O_WRONLY | O_CREAT, 0640)) >= 0) { snprintf (buf, sizeof(buf), "%d\n", (int)getpid()); - write (i, buf, strlen(buf)); + l=write (i, buf, strlen(buf)); + if (l!=(int)strlen(buf)) /* mf, 04.05.2004: cast to (int), avoid compiler warning */ + { log(LOG_LOG, "%s: error overwriting pid file with %s\n", + __FUNCTION__, buf); + } + else log(LOG_LOG, "overwrote pid file with %s\n", buf); close (i); pidfilewritten = 1; + log(LOG_LOG, "%s: wrote pid to file %s\n", + __FUNCTION__, gconfig.pidfile); } + /* mf, 27.03.2003: cannot write pid file ?!? */ + else + { log(LOG_LOG, "%s: cannot write to pid file %s\n", + __FUNCTION__, gconfig.pidfile); + } } else { - log(LOG_LOG, "%s: There's already a l2tpd server running.\n", - __FUNCTION__); + log(LOG_LOG, "%s: There's already a l2tpd server running (pid=%d).\n", + __FUNCTION__, (int) pid); close(server_socket); exit(1); } @@ -1035,12 +1064,21 @@ if(! pidfilewritten) { unlink(gconfig.pidfile); if ((i = open (gconfig.pidfile, O_WRONLY | O_CREAT, 0640)) >= 0) { - snprintf (buf, strlen(buf), "%d\n", (int)getpid()); - write (i, buf, strlen(buf)); + /* mf, 27.03.2003: correct strlen(buf) => sizeof(buf) */ + snprintf (buf, sizeof(buf), "%d\n", (int)getpid()); + log(LOG_LOG, "pid is %s\n", buf); + l=write (i, buf, strlen(buf)); + if (l!=(int)strlen(buf)) /* mf, 04.05.2004: cast to (int), avoid compiler warning */ + { log(LOG_LOG, "%s: error writing pid file\n", + __FUNCTION__); + } + else log(LOG_LOG, "pid file with %s\n", buf); close (i); pidfilewritten = 1; } } + /* mf, 27.03.2003: log successful daemonization */ + log(LOG_LOG, "daemonize successfully completed\n"); } @@ -1081,7 +1119,7 @@ __FUNCTION__); exit (1); } - log (LOG_LOG, "l2tpd version " SERVER_VERSION " started on %s PID:%d\n", + log (LOG_LOG, "l2tpd version " SERVER_VERSION SPECIAL_VERSION " started on %s PID:%d\n", hostname, getpid ()); log (LOG_LOG, "Written by Mark Spencer, Copyright (C) 1998, Adtran, Inc.\n"); diff -aur l2tpd-0.69_old/l2tp.h l2tpd-0.69_new/l2tp.h --- l2tpd-0.69_old/l2tp.h 2002-08-19 11:26:23.000000000 -0600 +++ l2tpd-0.69_new/l2tp.h 2005-09-26 00:48:20.000000000 -0600 @@ -37,6 +37,9 @@ #define BINARY "l2tpd" #define SERVER_VERSION "0.69" +#ifndef SPECIAL_VERSION +# define SPECIAL_VERSION "" +#endif #define VENDOR_NAME "l2tpd.org" #define PPPD "/usr/sbin/pppd" #define CALL_PPP_OPTS "defaultroute" @@ -88,7 +91,9 @@ #define PAYLOAD_BUF 10 /* Provide 10 expansion bytes so we can "decompress" the payloads and simplify coding */ -#define DEFAULT_MAX_RETRIES 5 /* Recommended value from spec */ +/* mf, 05.10.2003: increased DEFAULT_MAX_RETRIES to avoid breakdowns */ +/* #define DEFAULT_MAX_RETRIES 5 */ /* Recommended value from spec */ +#define DEFAULT_MAX_RETRIES 8 #define DEFAULT_RWS_SIZE 4 /* Default max outstanding control packets in queue */ #define DEFAULT_TX_BPS 10000000 /* For outgoing calls, report this speed */ @@ -156,6 +161,8 @@ struct call *self; struct lns *lns; /* LNS that owns us */ struct lac *lac; /* LAC that owns us */ + char *tunneltag; /* mf, 03.04.2003: string representing tunnel: peer a.b.c.d:p, ltunnelid num, rtunnelid num; + valid only after completing connection! */ }; struct tunnel_list diff -aur l2tpd-0.69_old/Makefile l2tpd-0.69_new/Makefile --- l2tpd-0.69_old/Makefile 2002-08-09 18:42:22.000000000 -0600 +++ l2tpd-0.69_new/Makefile 2005-09-26 00:48:20.000000000 -0600 @@ -27,7 +27,9 @@ # become runtime options) debugging flags # #DFLAGS= -g -O2 -DDEBUG_PPPD -DFLAGS= -g -O2 -DDEBUG_PPPD -DDEBUG_CONTROL -DDEBUG_ENTROPY +#DFLAGS= -g -O2 -DDEBUG_PPPD -DDEBUG_CONTROL -DDEBUG_ENTROPY +#DFLAGS= -g -DDEBUG_PPPD -DDEBUG_CONTROL -DDEBUG_ENTROPY -DDEBUG_HELLO -DDEBUG_CLOSE -DDEBUG_CLOSE -DDEBUG_FLOW -DDEBUG_FILE -DDEBUG_AAA -DDEBUG_HIDDEN -DDEBUG_AUTH -DDEBUG_CONTROL_XMIT -DDEBUG_FLOW_MORE -DDEBUG_MAGIC -DDEBUG_PPPD -DDEBUG_ZLB +DFLAGS= -g -O2 -DDEBUG_PPPD -DDEBUG_CONTROL -DDEBUG_ENTROPY -DDEBUG_HELLO -DDEBUG_CLOSE -DDEBUG_CLOSE -DDEBUG_FLOW -DDEBUG_FILE -DDEBUG_AAA -DDEBUG_HIDDEN -DDEBUG_AUTH -DDEBUG_CONTROL_XMIT -DDEBUG_MAGIC -DDEBUG_PPPD -DDEBUG_ZLB -DSPECIAL_VERSION=$(SPECIAL_VERSION) # # Uncomment the next line for Linux # @@ -69,5 +71,7 @@ clean: rm -f $(OBJS) $(BIN) +$(OBJS): $(HDRS) + $(BIN): $(OBJS) $(HDRS) $(CC) -o $(BIN) $(DFLAGS) $(OBJS) $(LIBS) diff -aur l2tpd-0.69_old/misc.c l2tpd-0.69_new/misc.c --- l2tpd-0.69_old/misc.c 2002-08-09 18:42:22.000000000 -0600 +++ l2tpd-0.69_new/misc.c 2005-09-26 00:48:20.000000000 -0600 @@ -32,16 +32,46 @@ void log (int level, const char *fmt, ...) { + /* mf, 08.06.2004: do openlog only once */ + static int log_opened=0; + /* mf, 12.06.2004: try to avoid re-entering syslog call */ + static int homegrown_syslog_mutex=0; + static int homegrown_syslog_lostmsgcount=0; + char buf[256]; va_list args; va_start (args, fmt); vsnprintf (buf, sizeof (buf), fmt, args); va_end (args); //bk - otherwise ppc segfaults va_start (args, fmt); //bk - vfprintf (stderr, fmt, args); - fflush (stderr); - openlog (BINARY, LOG_PID, LOG_DAEMON); - syslog (level, "%s", buf); + /* mferd, 20.03.2003: avoid logging to stderr as daemon or log messages + will be fed into pppd + (increased error counters in interface stats) + */ + if (!gconfig.daemon) + { vfprintf (stderr, fmt, args); + fflush (stderr); + } + /* mf, 08.06.2004: do openlog only once */ + /* openlog (BINARY, LOG_PID, LOG_DAEMON); */ + if (!log_opened) + { openlog (BINARY, LOG_PID, LOG_DAEMON); + log_opened++; + } + /* mf, 12.06.2004: try to avoid re-entering syslog call */ + if (homegrown_syslog_mutex++) + { /* someone is currently calling syslog and has not exited yet. damn. */ + /* FIXME: should buffer the message and send to syslog later */ + homegrown_syslog_lostmsgcount++; + } + else + { if (homegrown_syslog_lostmsgcount) + { syslog(level, "ALERT: %d log messages lost\n", homegrown_syslog_lostmsgcount); + homegrown_syslog_lostmsgcount=0; + } + syslog (level, "%s", buf); + } + homegrown_syslog_mutex--; va_end (args); } @@ -76,7 +106,8 @@ return b; } -inline void recycle_buf (struct buffer *b) +/* mf, 15.06.2004: de-inline function for easier debugging */ +/*inline*/ void recycle_buf (struct buffer *b) { b->start = b->rstart; b->len = b->maxlen; @@ -174,7 +205,8 @@ -inline void toss (struct buffer *buf) +/* mf, 15.06.2004: de-inline for easier debugging */ +/*inline*/ void toss (struct buffer *buf) { /* * Toss a frame and free up the buffer that contained it diff -aur l2tpd-0.69_old/misc.h l2tpd-0.69_new/misc.h --- l2tpd-0.69_old/misc.h 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/misc.h 2005-09-26 00:48:20.000000000 -0600 @@ -63,6 +63,10 @@ #define halt() printf("Halted.\n") ; for(;;) +/* mf, 04.05.2004: rename log() => l2tpd_log() to avoid compiler warnings */ +/* about conflict with built-in function log() */ +#define log l2tpd_log + extern char hostname[]; extern void log (int level, const char *fmt, ...); extern struct buffer *new_buf (int); diff -aur l2tpd-0.69_old/network.c l2tpd-0.69_new/network.c --- l2tpd-0.69_old/network.c 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/network.c 2005-09-26 00:48:20.000000000 -0600 @@ -25,7 +25,8 @@ #include "l2tp.h" char hostname[256]; -unsigned int listen_addy = INADDR_ANY; /* Address to listen on */ +/* mf, 27.03.2003: now in file.c, config parameter "listenaddr" */ +/* unsigned int listen_addy = INADDR_ANY; */ /* Address to listen on */ struct sockaddr_in server, from; /* Server and transmitter structs */ int server_socket; /* Server socket */ #ifdef USE_KERNEL @@ -35,7 +36,7 @@ /* * Debugging info */ -int debug_tunnel = 0; +int debug_tunnel = 1; int debug_network = 0; /* Debug networking? */ int packet_dump = 0; /* Dump packets? */ int debug_avp = 1; /* Debug AVP negotiations? */ @@ -47,7 +48,7 @@ int length = sizeof (server); gethostname (hostname, sizeof (hostname)); server.sin_family = AF_INET; - server.sin_addr.s_addr = htonl (listen_addy); + server.sin_addr.s_addr = /* htonl (listen_addy); */ listen_addy; server.sin_port = htons (gconfig.port); if ((server_socket = socket (PF_INET, SOCK_DGRAM, 0)) < 0) { @@ -60,8 +61,8 @@ if (bind (server_socket, (struct sockaddr *) &server, sizeof (server))) { close (server_socket); - log (LOG_CRIT, "%s: Unable to bind socket. Terminating.\n", - __FUNCTION__); + log (LOG_CRIT, "%s: Unable to bind socket (%s). Terminating.\n", + __FUNCTION__, inet_ntoa(server.sin_addr)); return -EINVAL; }; if (getsockname (server_socket, (struct sockaddr *) &server, &length)) @@ -198,17 +199,26 @@ { if (t->self->needclose) { - log (LOG_DEBUG, + /* mf, 03.04.2003: provide more peer info in log message */ + /*log (LOG_DEBUG, "%s: Unable to deliver closing message for tunnel %d. Destroying anyway.\n", - __FUNCTION__, t->ourtid); + __FUNCTION__, t->ourtid);*/ + log (LOG_DEBUG, + "%s: Unable to deliver closing message for peer %s\n", + __FUNCTION__, t->tunneltag); t->self->needclose = 0; t->self->closing = -1; } else { - log (LOG_DEBUG, + /* mf, 03.04.2003: provide more peer info in log message */ + /*log (LOG_DEBUG, "%s: Maximum retries exceeded for tunnel %d. Closing.\n", - __FUNCTION__, t->ourtid); + __FUNCTION__, t->ourtid);*/ + log (LOG_DEBUG, + "%s: Maximum retries exceeded for peer %s\n", + __FUNCTION__, t->tunneltag); + strcpy (t->self->errormsg, "Timeout"); t->self->needclose = -1; } @@ -364,7 +374,7 @@ extract (buf->start, &tunnel, &call); if (debug_network) { - log (LOG_DEBUG, "%s: recv packet from %s, size = %d, + log (LOG_DEBUG, "%s: recv packet from %s, size = %d,\ tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call); } if (packet_dump) @@ -389,15 +399,26 @@ * to ack receiving the packet. */ if (debug_tunnel) + /* mf, 08.06.2004: args call, tunnel were left out. add them */ + /*log (LOG_DEBUG, + "%s: no such call %d on tunnel %d. Sending special ZLB\n", + __FUNCTION__);*/ log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", - __FUNCTION__); + __FUNCTION__, call, tunnel); handle_special (buf, c, call); + /* mf, 15.06.2004: handle_special just toss()'ed buf,*/ + /* we need to reallocate it */ + buf = new_buf (MAX_RECV_SIZE); } else - log (LOG_DEBUG, + /* mf, 22.04.2003: also log packet source address */ + /*log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", - __FUNCTION__, call, tunnel); + __FUNCTION__, call, tunnel);*/ + log (LOG_DEBUG, + "%s: unable to find call or tunnel to handle packet from %s:%d. tunnel= %d, call = %d Dumping.\n", + __FUNCTION__, inet_ntoa(from.sin_addr), ntohs(from.sin_port), tunnel, call); } else @@ -432,8 +453,11 @@ int result; recycle_payload (buf, sc->container->peer); #ifdef DEBUG_FLOW_MORE - log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", - __FUNCTION__, sc->rws, sc->pSs, sc->pLr); + /* mf, 03.04.2003: log with tunneltag */ +/* log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", + __FUNCTION__, sc->rws, sc->pSs, sc->pLr);*/ + log (LOG_DEBUG, "%s: payload to %s: rws = %d, pSs = %d, pLr = %d\n", + __FUNCTION__, sc->container->tunneltag, sc->rws, sc->pSs, sc->pLr); #endif /* if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) { #ifdef DEBUG_FLOW @@ -473,9 +497,13 @@ } if (result != 0) { - log (LOG_WARN, + /* mf, 08.06.2004: add more information to log msg: pppd pid, call id, tunnel id, peer */ + /* log (LOG_WARN, "%s: tossing read packet, error = %s (%d). Closing call.\n", - __FUNCTION__, strerror (-result), -result); + __FUNCTION__, strerror (-result), -result);*/ + log (LOG_WARN, + "%s: tossing read packet from pppd(%d), error = %s (%d). Closing call %s/rc=%d/lc=%d\n", + __FUNCTION__, sc->pppd, strerror (-result), -result, get_tunneltag(sc->container), sc->cid, sc->ourcid); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } diff -aur l2tpd-0.69_old/pty.c l2tpd-0.69_new/pty.c --- l2tpd-0.69_old/pty.c 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/pty.c 2005-09-26 00:48:20.000000000 -0600 @@ -1,62 +1,95 @@ -/* - * Layer Two Tunnelling Protocol Daemon - * Copyright (C) 1998 Adtran, Inc. - * Copyright (C) 2002 Jeff McAdams - * - * Mark Spencer - * - * This software is distributed under the terms - * of the GPL, which you should have received - * along with this source. - * - * Pseudo-pty allocation routines... Concepts and code borrowed - * from pty-redir by Magosanyi Arpad. - * - */ +/*********************************************************************** +* +* pty.c +* +* Code for dealing with pseudo-tty's for running pppd. +* +* Copyright (C) 2002 Roaring Penguin Software Inc. +* +* This software may be distributed under the terms of the GNU General +* Public License, Version 2, or (at your option) any later version. +* +* LIC: GPL +* +***********************************************************************/ #include "l2tp.h" +#include "misc.h" +#include +#include #include - -#ifdef SOLARIS -#define PTY00 "/dev/ptyXX" -#define PTY10 "pqrstuvwxyz" -#define PTY01 "0123456789abcdef" -#endif - -#ifdef LINUX -#define PTY00 "/dev/ptyXX" -#define PTY10 "pqrstuvwxyzabcde" -#define PTY01 "0123456789abcdef" +#include +#ifndef N_HDLC +#include #endif -#ifdef FREEBSD -#define PTY00 "/dev/ptyXX" -#define PTY10 "p" -#define PTY01 "0123456789abcdefghijklmnopqrstuv" -#endif +/********************************************************************** +* %FUNCTION: pty_get +* %ARGUMENTS: +* mfp -- pointer to master file descriptor +* sfp -- pointer to slave file descriptor +* %RETURNS: +* 0 on success, -1 on failure +* %DESCRIPTION: +* Opens a PTY and sets line discipline to N_HDLC for ppp. +* Taken almost verbatim from Linux pppd code. +***********************************************************************/ -int getPtyMaster (char *tty10, char *tty01) +int +pty_get(int *mfp, int *sfp) { - char *p10; - char *p01; - static char dev[] = PTY00; - int fd; - - for (p10 = PTY10; *p10; p10++) - { - dev[8] = *p10; - for (p01 = PTY01; *p01; p01++) - { - dev[9] = *p01; - fd = open (dev, O_RDWR | O_NONBLOCK); - if (fd >= 0) - { - *tty10 = *p10; - *tty01 = *p01; - return fd; + char pty_name[24]; + struct termios tios; + int mfd, sfd; + int disc = N_HDLC; + + mfd = -1; + sfd = -1; + + mfd = open("/dev/ptmx", O_RDWR); + if (mfd >= 0) { + int ptn; + if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { + snprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn); + ptn = 0; + if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) { + /* warn("Couldn't unlock pty slave %s: %m", pty_name); */ + } + if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) { + /* warn("Couldn't open pty slave %s: %m", pty_name); */ } } } - log (LOG_CRIT, "%s: No more free pseudo-tty's\n", __FUNCTION__); - return -1; + + if (sfd < 0 || mfd < 0) { + if (sfd >= 0) close(sfd); + if (mfd >= 0) close(mfd); + return -1; + } + + *mfp = mfd; + *sfp = sfd; + if (tcgetattr(sfd, &tios) == 0) { + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); + tios.c_cflag |= CS8 | CREAD | CLOCAL; + tios.c_iflag = IGNPAR; + tios.c_oflag = 0; + tios.c_lflag = 0; + tcsetattr(sfd, TCSAFLUSH, &tios); + } + if (ioctl(sfd, TIOCSETD, &disc) < 0) { + log(LOG_DEBUG,"Unable to set line discipline to N_HDLC"); + close(mfd); + close(sfd); + return -1; + } + disc = N_HDLC; + if (ioctl(mfd, TIOCSETD, &disc) < 0) { + log(LOG_DEBUG,"Unable to set line discipline to N_HDLC"); + close(mfd); + close(sfd); + return -1; + } + return 0; } + diff -aur l2tpd-0.69_old/scheduler.c l2tpd-0.69_new/scheduler.c --- l2tpd-0.69_old/scheduler.c 2002-04-10 14:09:33.000000000 -0600 +++ l2tpd-0.69_new/scheduler.c 2005-09-26 00:48:20.000000000 -0600 @@ -57,6 +57,8 @@ { /* Whoa, we got called from within ourselves! */ log (LOG_DEBUG, "%s : Whoa... cnt = %d\n", __FUNCTION__, cnt); + /* mf, 14.06.2004: decrement counter on exit */ + cnt--; return; } while (events)