📄 l2tpd.c
字号:
sc = st->call_head; while (sc) { close (sc->fd); sc = sc->next; } st = st->next; } /* close the UDP socket fd */ close (server_socket); /* close the control pipe fd */ close (control_fd); execv (PPPD, stropt); log (LOG_WARN, "%s: Exec of %s failed!\n", __FUNCTION__, PPPD); exit (1); }; close (fd2); pos = 0; while (stropt[pos]) { free (stropt[pos]); pos++; }; return 0;}void destroy_tunnel (struct tunnel *t){ /* * Immediately destroy a tunnel (and all its calls) * and free its resources. This may be called * by the tunnel itself,so it needs to be * "suicide safe" */ struct call *c, *me; struct tunnel *p; struct timeval tv; if (!t) return; /* * Save ourselves until the very * end, since we might be calling this ourselves. * We must divorce ourself from the tunnel * structure, however, to avoid recursion * because of the logic of the destroy_call */ me = t->self; /* * Destroy all the member calls */ c = t->call_head; while (c) { destroy_call (c); c = c->next; }; /* * Remove ourselves from the list of tunnels */ if (tunnels.head == t) { tunnels.head = t->next; tunnels.count--; } else { p = tunnels.head; if (p) { while (p->next && (p->next != t)) p = p->next; if (p->next) { p->next = t->next; tunnels.count--; } else { log (LOG_WARN, "%s: unable to locate tunnel in tunnel list\n", __FUNCTION__); } } else { log (LOG_WARN, "%s: tunnel list is empty!\n", __FUNCTION__); } } if (t->lac) { t->lac->t = NULL; if (t->lac->redial && (t->lac->rtimeout > 0) && !t->lac->rsched && t->lac->active) { log (LOG_LOG, "%s: Will redial in %d seconds\n", __FUNCTION__, t->lac->rtimeout); tv.tv_sec = t->lac->rtimeout; tv.tv_usec = 0; t->lac->rsched = schedule (tv, magic_lac_dial, t->lac); } } /* XXX L2TP/IPSec: remove relevant SAs here? NTB 20011010 * XXX But what if another tunnel is using same SA? */ if (t->lns) t->lns->t = NULL; free (t); free (me);}struct tunnel *l2tp_call (char *host, int port, struct lac *lac, struct lns *lns){ /* * Establish a tunnel from us to host * on port port */ struct call *tmp = NULL; struct hostent *hp; unsigned int addr; port = htons (port); hp = gethostbyname (host); if (!hp) { log (LOG_WARN, "%s: gethostbyname() failed for %s.\n", __FUNCTION__, host); return NULL; } bcopy (hp->h_addr, &addr, hp->h_length); /* Force creation of a new tunnel and set it's tid to 0 to cause negotiation to occur */ /* XXX L2TP/IPSec: Set up SA to addr:port here? NTB 20011010 */ tmp = get_call (0, 0, addr, port); if (!tmp) { log (LOG_WARN, "%s: Unable to create tunnel to %s.\n", __FUNCTION__, host); return NULL; } tmp->container->tid = 0; tmp->container->lac = lac; tmp->container->lns = lns; tmp->lac = lac; tmp->lns = lns; if (lac) lac->t = tmp->container; if (lns) lns->t = tmp->container; /* * Since our state is 0, we will establish a tunnel now */ log (LOG_LOG, "%s:Connecting to host %s, port %d\n", __FUNCTION__, host, ntohs (port)); control_finish (tmp->container, tmp); return tmp->container;}void magic_lac_tunnel (void *data){ struct lac *lac; lac = (struct lac *) data; if (!lac) { log (LOG_WARN, "%s: magic_lac_tunnel: called on NULL lac!\n", __FUNCTION__); return; } if (lac->lns) { /* FIXME: I should try different LNS's if I get failures */ l2tp_call (lac->lns->hostname, lac->lns->port, lac, NULL); return; } else if (deflac && deflac->lns) { l2tp_call (deflac->lns->hostname, deflac->lns->port, lac, NULL); return; } else { log (LOG_WARN, "%s: Unable to find hostname to dial for '%s'\n", __FUNCTION__, lac->entname); return; }}struct call *lac_call (int tid, struct lac *lac, struct lns *lns){ struct tunnel *t = tunnels.head; struct call *tmp; while (t) { if (t->ourtid == tid) { tmp = new_call (t); if (!tmp) { log (LOG_WARN, "%s: unable to create new call\n", __FUNCTION__); return NULL; } tmp->next = t->call_head; t->call_head = tmp; t->count++; tmp->cid = 0; tmp->lac = lac; tmp->lns = lns; if (lac) lac->c = tmp; log (LOG_LOG, "%s: Calling on tunnel %d\n", __FUNCTION__, tid); strcpy (tmp->dial_no, dial_no_tmp); /* jz: copy dialnumber to tmp->dial_no */ control_finish (t, tmp); return tmp; } t = t->next; }; log (LOG_DEBUG, "%s: No such tunnel %d to generate call.\n", __FUNCTION__, tid); return NULL;}void magic_lac_dial (void *data){ struct lac *lac; lac = (struct lac *) data; if (!lac->active) { log (LOG_DEBUG, "%s: LAC %s not active", __FUNCTION__, lac->entname); return; } lac->rsched = NULL; lac->rtries++; if (lac->rmax && (lac->rtries > lac->rmax)) { log (LOG_LOG, "%s: maximum retries exceeded.\n", __FUNCTION__); return; } if (!lac) { log (LOG_WARN, "%s : called on NULL lac!\n", __FUNCTION__); return; } if (!lac->t) {#ifdef DEGUG_MAGIC log (LOG_DEBUG, "%s : tunnel not up! Connecting!\n", __FUNCTION__);#endif magic_lac_tunnel (lac); return; } lac_call (lac->t->ourtid, lac, NULL);}void lac_hangup (int cid){ struct tunnel *t = tunnels.head; struct call *tmp; while (t) { tmp = t->call_head; while (tmp) { if (tmp->ourcid == cid) { log (LOG_LOG, "%s :Hanging up call %d, Local: %d, Remote: %d\n", __FUNCTION__, tmp->serno, tmp->ourcid, tmp->cid); strcpy (tmp->errormsg, "Goodbye!");/* tmp->needclose = -1; */ kill (tmp->pppd, SIGTERM); return; } tmp = tmp->next; } t = t->next; }; log (LOG_DEBUG, "%s : No such call %d to hang up.\n", __FUNCTION__, cid); return;}void lac_disconnect (int tid){ struct tunnel *t = tunnels.head; while (t) { if (t->ourtid == tid) { log (LOG_LOG, "%s: Disconnecting from %s, Local: %d, Remote: %d\n", __FUNCTION__, IPADDY (t->peer.sin_addr), t->ourtid, t->tid); t->self->needclose = -1; strcpy (t->self->errormsg, "Goodbye!"); call_close (t->self); return; } t = t->next; }; log (LOG_DEBUG, "%s: No such tunnel %d to hang up.\n", __FUNCTION__, tid); return;}struct tunnel *new_tunnel (){ struct tunnel *tmp = malloc (sizeof (struct tunnel)); char entropy_buf[2] = "\0"; if (!tmp) return NULL; tmp->control_seq_num = 0; tmp->control_rec_seq_num = 0; tmp->cLr = 0; tmp->call_head = NULL; tmp->next = NULL; tmp->debug = -1; tmp->tid = -1; tmp->hello = NULL;#ifndef TESTING/* while(get_call((tmp->ourtid = rand() & 0xFFFF),0,0,0)); */#ifdef USE_KERNEL if (kernel_support) tmp->ourtid = ioctl (server_socket, L2TPIOCADDTUNNEL, 0); else#endif/* tmp->ourtid = rand () & 0xFFFF; */ /* get_entropy((char *)&tmp->ourtid, 2); */ get_entropy(entropy_buf, 2); { int *temp; temp = (int *)entropy_buf; tmp->ourtid = *temp & 0xFFFF;#ifdef DEBUG_ENTROPY log(LOG_DEBUG, "ourtid = %u, entropy_buf = %hx\n", tmp->ourtid, *temp);#endif }#else tmp->ourtid = 0x6227;#endif tmp->nego = 0; tmp->count = 0; tmp->state = 0; /* Nothing */ tmp->peer.sin_family = AF_INET; tmp->peer.sin_port = 0; bzero (&(tmp->peer.sin_addr), sizeof (tmp->peer.sin_addr)); tmp->sanity = -1; tmp->qtid = -1; tmp->ourfc = ASYNC_FRAMING | SYNC_FRAMING; tmp->ourbc = 0; tmp->ourtb = (((_u64) rand ()) << 32) | ((_u64) rand ()); tmp->fc = -1; /* These really need to be specified by the peer */ tmp->bc = -1; /* And we want to know if they forgot */ tmp->hostname[0] = 0; tmp->vendor[0] = 0; tmp->secret[0] = 0; if (!(tmp->self = new_call (tmp))) { free (tmp); return NULL; }; tmp->ourrws = DEFAULT_RWS_SIZE; tmp->self->ourfbit = FBIT; tmp->lac = NULL; tmp->lns = NULL; tmp->chal_us.state = 0; tmp->chal_us.secret[0] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -