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; } }
void do_control () { char buf[1024]; char *host; char *tunstr; char *callstr; char *sub_str; /* jz: use by the strtok function */ char *tmp_ptr; /* jz: use by the strtok function */ struct lac *lac; int call; int tunl; int cnt = -1; while (cnt) { cnt = read (control_fd, buf, sizeof (buf)); if (cnt > 0) { if (buf[cnt - 1] == '\n') buf[--cnt] = 0; #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Got message %s (%d bytes long)\n", __FUNCTION__, buf, cnt); #endif switch (buf[0]) { case 't': host = strchr (buf, ' ') + 1; #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to tunnel to %s\n", __FUNCTION__, host); #endif l2tp_call (host, UDP_LISTEN_PORT, NULL, NULL); break; case 'c': switch_io = 1; /* jz: Switch for Incoming - Outgoing Calls */ tunstr = strchr (buf, ' ') + 1; lac = laclist; while (lac) { if (!strcasecmp (lac->entname, tunstr)) { lac->active = -1; lac->rtries = 0; if (!lac->c) magic_lac_dial (lac); break; } lac = lac->next; } if (lac) break; tunl = atoi (tunstr); if (!tunl) { log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); break; } #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n", __FUNCTION__, tunl); #endif lac_call (tunl, NULL, NULL); break; case 'o': /* jz: option 'o' for doing a outgoing call */ switch_io = 0; /* jz: Switch for incoming - outgoing Calls */ sub_str = strchr (buf, ' ') + 1; tunstr = strtok (sub_str, " "); /* jz: using strtok function to get */ tmp_ptr = strtok (NULL, " "); /* params out of the pipe */ strcpy (dial_no_tmp, tmp_ptr); lac = laclist; while (lac) { if (!strcasecmp (lac->entname, tunstr)) { lac->active = -1; lac->rtries = 0; if (!lac->c) magic_lac_dial (lac); else log (LOG_DEBUG, "Session '%s' already active!\n", lac->entname); break; } lac = lac->next; } if (lac) break; tunl = atoi (tunstr); if (!tunl) { log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); break; } #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n", __FUNCTION__, tunl); #endif lac_call (tunl, NULL, NULL); break; case 'h': callstr = strchr (buf, ' ') + 1; call = atoi (callstr); #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to hangup call %d\n", __FUNCTION__, call); #endif lac_hangup (call); break; case 'd': tunstr = strchr (buf, ' ') + 1; lac = laclist; while (lac) { if (!strcasecmp (lac->entname, tunstr)) { lac->active = 0; lac->rtries = 0; if (lac->t) lac_disconnect (lac->t->ourtid); else log (LOG_DEBUG, "Session '%s' not up\n", lac->entname); break; } lac = lac->next; } if (lac) break; tunl = atoi (tunstr); if (!tunl) { log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); break; } #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to disconnect tunnel %d\n", __FUNCTION__, tunl); #endif lac_disconnect (tunl); break; case 's': show_status (); break; default: log (LOG_DEBUG, "Unknown command %c\n", buf[0]); } } } /* Otherwise select goes nuts */ close (control_fd); control_fd = open (gconfig.controlfile, O_RDONLY | O_NONBLOCK, 0600); if (control_fd < 0) { log (LOG_CRIT, "%s: Unable to open %s for reading.", __FUNCTION__, gconfig.controlfile); } }
void do_control () { char buf[1024]; char *host; char *tunstr; char *callstr; char *authname = NULL; char *password = NULL; char delims[] = " "; char *sub_str; /* jz: use by the strtok function */ char *tmp_ptr; /* jz: use by the strtok function */ struct lac *lac; int call; int tunl; int cnt = -1; int done = 0; bzero(buf, sizeof(buf)); buf[0]='\0'; while (!done) { cnt = read (control_fd, buf, sizeof (buf)); if (cnt <= 0) { if(cnt < 0 && errno != EINTR) { perror("controlfd"); } done=1; break; } if (buf[cnt - 1] == '\n') buf[--cnt] = 0; #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Got message %s (%d bytes long)\n", __FUNCTION__, buf, cnt); #endif switch (buf[0]) { case 't': host = strchr (buf, ' ') + 1; #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to tunnel to %s\n", __FUNCTION__, host); #endif l2tp_call (host, UDP_LISTEN_PORT, NULL, NULL); break; case 'c': switch_io = 1; /* jz: Switch for Incoming - Outgoing Calls */ tunstr = strtok (&buf[1], delims); /* Are these passed on the command line? */ authname = strtok (NULL, delims); password = strtok (NULL, delims); lac = laclist; while (lac && strcasecmp (lac->entname, tunstr)!=0) { lac = lac->next; } if(lac) { lac->active = -1; lac->rtries = 0; if (authname != NULL) strncpy (lac->authname, authname, STRLEN); if (password != NULL) strncpy (lac->password, password, STRLEN); if (!lac->c) magic_lac_dial (lac); else { l2tp_log (LOG_DEBUG, "Session '%s' already active!\n", lac->entname); } break; } /* did not find a tunnel by name, look by number */ tunl = atoi (tunstr); if (!tunl) { l2tp_log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); break; } #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n", __FUNCTION__, tunl); #endif lac_call (tunl, NULL, NULL); break; case 'o': /* jz: option 'o' for doing a outgoing call */ switch_io = 0; /* jz: Switch for incoming - outgoing Calls */ sub_str = strchr (buf, ' ') + 1; tunstr = strtok (sub_str, " "); /* jz: using strtok function to get */ tmp_ptr = strtok (NULL, " "); /* params out of the pipe */ strcpy (dial_no_tmp, tmp_ptr); lac = laclist; while (lac && strcasecmp (lac->entname, tunstr)!=0) { lac = lac->next; } if(lac) { lac->active = -1; lac->rtries = 0; if (!lac->c) magic_lac_dial (lac); else l2tp_log (LOG_DEBUG, "Session '%s' already active!\n", lac->entname); break; } /* did not find a tunnel by name, look by number */ tunl = atoi (tunstr); if (!tunl) { l2tp_log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); break; } #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n", __FUNCTION__, tunl); #endif lac_call (tunl, NULL, NULL); break; case 'h': callstr = strchr (buf, ' ') + 1; call = atoi (callstr); #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to hangup call %d\n", __FUNCTION__, call); #endif lac_hangup (call); break; case 'd': tunstr = strchr (buf, ' ') + 1; lac = laclist; while (lac) { if (!strcasecmp (lac->entname, tunstr)) { lac->active = 0; lac->rtries = 0; if (lac->t) lac_disconnect (lac->t->ourtid); else l2tp_log (LOG_DEBUG, "Session '%s' not up\n", lac->entname); break; } lac = lac->next; } if (lac) break; tunl = atoi (tunstr); if (!tunl) { l2tp_log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); break; } #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to disconnect tunnel %d\n", __FUNCTION__, tunl); #endif lac_disconnect (tunl); break; case 's': show_status (); break; default: l2tp_log (LOG_DEBUG, "Unknown command %c\n", buf[0]); } } /* Otherwise select goes nuts. Yeah, this just seems wrong */ close (control_fd); open_controlfd(); }
void do_control () { char buf[CONTROL_PIPE_MESSAGE_SIZE]; char *bufp; /* current buffer pointer */ char *host; char *tunstr; char *callstr; char *authname = NULL; char *password = NULL; char delims[] = " "; char *sub_str; /* jz: use by the strtok function */ char *tmp_ptr; /* jz: use by the strtok function */ struct lac *lac; struct lac *prev_lac; /* for lac removing */ int call; int tunl; int cnt = -1; int done = 0; bzero(buf, sizeof(buf)); buf[0]='\0'; char* res_filename; /* name of file to write result of command */ FILE* resf; /* stream for write result of command */ while (!done) { cnt = read (control_fd, buf, sizeof (buf)); if (cnt <= 0) { if(cnt < 0 && errno != EINTR) { perror("controlfd"); } done = 1; break; } if (buf[cnt - 1] == '\n') buf[--cnt] = 0; #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Got message %s (%d bytes long)\n", __FUNCTION__, buf, cnt); #endif bufp = buf; /* check if caller want to get result */ if (bufp[0] == '@') { /* parse filename (@/path/to/file *...), where * is command */ res_filename = &bufp[1]; int fnlength = strcspn(res_filename, " "); if ((fnlength == 0) || (res_filename[fnlength] == '\0')){ l2tp_log (LOG_DEBUG, "%s: Can't parse result filename or command\n", __FUNCTION__ ); continue; } res_filename[fnlength] = '\0'; bufp = &res_filename[fnlength + 1]; /* skip filename in bufp */ /*FIXME: check quotes to allow filenames with spaces? (do not forget quotes escaping to allow filenames with quotes)*/ /*FIXME: write to res_filename may cause SIGPIPE, need to catch it*/ resf = fopen (res_filename, "w"); if (!resf) { l2tp_log (LOG_DEBUG, "%s: Can't open result file %s\n", __FUNCTION__, res_filename); continue; } } else resf = NULL; switch (bufp[0]) { case 't': host = strchr (bufp, ' ') + 1; #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to tunnel to %s\n", __FUNCTION__, host); #endif if (l2tp_call (host, UDP_LISTEN_PORT, NULL, NULL)) write_res (resf, "%02i OK\n", 0); else write_res (resf, "%02i Error\n", 1); break; case 'c': switch_io = 1; /* jz: Switch for Incoming - Outgoing Calls */ tunstr = strtok (&bufp[1], delims); /* Are these passed on the command line? */ authname = strtok (NULL, delims); password = strtok (NULL, delims); lac = laclist; while (lac && strcasecmp (lac->entname, tunstr)!=0) { lac = lac->next; } if(lac) { lac->active = -1; lac->rtries = 0; if (authname != NULL) strncpy (lac->authname, authname, STRLEN); if (password != NULL) strncpy (lac->password, password, STRLEN); if (!lac->c) { magic_lac_dial (lac); write_res (resf, "%02i OK\n", 0); } else { l2tp_log (LOG_DEBUG, "Session '%s' already active!\n", lac->entname); write_res (resf, "%02i Session '%s' already active!\n", 1, lac->entname); } break; } /* did not find a tunnel by name, look by number */ tunl = atoi (tunstr); if (!tunl) { l2tp_log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); write_res (resf, "%02i No such tunnel '%s'\n", 1, tunstr); break; } #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n", __FUNCTION__, tunl); #endif if (lac_call (tunl, NULL, NULL)) write_res (resf, "%02i OK\n", 0); else write_res (resf, "%02i Error\n", 1); break; case 'o': /* jz: option 'o' for doing a outgoing call */ switch_io = 0; /* jz: Switch for incoming - outgoing Calls */ sub_str = strchr (bufp, ' ') + 1; tunstr = strtok (sub_str, " "); /* jz: using strtok function to get */ tmp_ptr = strtok (NULL, " "); /* params out of the pipe */ strcpy (dial_no_tmp, tmp_ptr); lac = laclist; while (lac && strcasecmp (lac->entname, tunstr)!=0) { lac = lac->next; } if(lac) { lac->active = -1; lac->rtries = 0; if (!lac->c) { magic_lac_dial (lac); write_res (resf, "%02i OK\n", 0); } else { l2tp_log (LOG_DEBUG, "Session '%s' already active!\n", lac->entname); write_res (resf, "%02i Session '%s' already active!\n", 1, lac->entname); } break; } /* did not find a tunnel by name, look by number */ tunl = atoi (tunstr); if (!tunl) { l2tp_log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); write_res (resf, "%02i No such tunnel '%s'\n", 1, tunstr); break; } #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n", __FUNCTION__, tunl); #endif if (lac_call (tunl, NULL, NULL)) write_res (resf, "%02i OK\n", 0); else write_res (resf, "%02i Error\n", 1); break; case 'h': callstr = strchr (bufp, ' ') + 1; call = atoi (callstr); #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to hangup call %d\n", __FUNCTION__, call); #endif lac_hangup (call); write_res (resf, "%02i OK\n", 0); break; case 'd': tunstr = strchr (bufp, ' ') + 1; lac = laclist; while (lac) { if (!strcasecmp (lac->entname, tunstr)) { lac->active = 0; lac->rtries = 0; if (lac->t) { lac_disconnect (lac->t->ourtid); write_res (resf, "%02i OK\n", 0); } else { l2tp_log (LOG_DEBUG, "Session '%s' not up\n", lac->entname); write_res (resf, "%02i Session '%s' not up\n", 1, lac->entname); } break; } lac = lac->next; } if (lac) break; tunl = atoi (tunstr); if (!tunl) { l2tp_log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); write_res (resf, "%02i No such tunnel '%s'\n", 1, tunstr); break; } #ifdef DEBUG_CONTROL l2tp_log (LOG_DEBUG, "%s: Attempting to disconnect tunnel %d\n", __FUNCTION__, tunl); #endif lac_disconnect (tunl); write_res (resf, "%02i OK\n", 0); break; case 's': show_status (); break; case 'a': /* add new or modify existing lac configuration */ { int create_new_lac = 0; tunstr = strtok (&bufp[1], delims); if ((!tunstr) || (!strlen (tunstr))) { write_res (resf, "%02i Configuration parse error: lac-name expected\n", 1); l2tp_log (LOG_CRIT, "%s: lac-name expected\n", __FUNCTION__); break; } /* go to the end of tunnel name*/ bufp = tunstr + strlen (tunstr) + 1; /* try to find lac with _tunstr_ name in laclist */ lac = laclist; while (lac) { if (!strcasecmp (tunstr, lac->entname)) break; lac = lac->next; } if (!lac) { /* nothing found, create new lac */ lac = new_lac (); if (!lac) { write_res (resf, "%02i Could't create new lac: no memory\n", 2); l2tp_log (LOG_CRIT, "%s: Couldn't create new lac\n", __FUNCTION__); break; } create_new_lac = 1; } strncpy (lac->entname, tunstr, sizeof (lac->entname)); if (parse_one_line_lac (bufp, lac)) { write_res (resf, "%02i Configuration parse error\n", 3); break; } if (create_new_lac) { lac->next = laclist; laclist = lac; } if (lac->autodial) { #ifdef DEBUG_MAGIC l2tp_log (LOG_DEBUG, "%s: Autodialing '%s'\n", __FUNCTION__, lac->entname[0] ? lac->entname : "(unnamed)"); #endif lac->active = -1; switch_io = 1; /* If we're a LAC, autodials will be ICRQ's */ magic_lac_dial (lac); /* FIXME: Should I check magic_lac_dial result somehow? */ } write_res (resf, "%02i OK\n", 0); } break; case 'r': // find lac in laclist tunstr = strchr (bufp, ' ') + 1; lac = laclist; prev_lac = NULL; while (lac && strcasecmp (lac->entname, tunstr) != 0) { prev_lac = lac; lac = lac->next; } if (!lac) { l2tp_log (LOG_DEBUG, "No such tunnel '%s'\n", tunstr); write_res (resf, "%02i No such tunnel '%s'\n", 1, tunstr); break; } // disconnect lac lac->active = 0; lac->rtries = 0; if (lac->t) { lac_disconnect (lac->t->ourtid); } // removes lac from laclist if (prev_lac == NULL) laclist = lac->next; else prev_lac->next = lac->next; free(lac); lac = NULL; write_res (resf, "%02i OK\n", 0); break; default: l2tp_log (LOG_DEBUG, "Unknown command %c\n", bufp[0]); write_res (resf, "%02i Unknown command %c\n", 1, bufp[0]); } if (resf) { fclose (resf); } } /* Otherwise select goes nuts. Yeah, this just seems wrong */ close (control_fd); open_controlfd(); }
void do_control (char *cmd) { char buf[1024]; char *host; char *tunstr; char *callstr; char *sub_str; /* jz: use by the strtok function */ char *tmp_ptr; /* jz: use by the strtok function */ struct lac *lac; int call; int tunl; int cnt = -1; int first_run = 0; while (cnt) { /* Foxconn, add by MJ. for building L2TP tunnel in the begining. */ if(cmd != NULL) { first_run = 1; strcpy(buf, cmd); cnt = strlen(buf); log (LOG_DEBUG, "%s -> L2TP connect immediately. \n", __FUNCTION__); } else cnt = read (control_fd, buf, sizeof (buf)); /*add end, by MJ.*/ if (cnt > 0) { if (buf[cnt - 1] == '\n') buf[--cnt] = 0; #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Got message %s (%d bytes long)\n", __FUNCTION__, buf, cnt); #endif switch (buf[0]) { case 't': host = strchr (buf, ' ') + 1; #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to tunnel to %s\n", __FUNCTION__, host); #endif l2tp_call (host, UDP_LISTEN_PORT, NULL, NULL); break; case 'c': switch_io = 1; /* jz: Switch for Incoming - Outgoing Calls */ tunstr = strchr (buf, ' ') + 1; lac = laclist; while (lac) { if (!strcasecmp (lac->entname, tunstr)) { lac->active = -1; lac->rtries = 0; if (!lac->c) magic_lac_dial (lac); else log (LOG_DEBUG, "%s: Session '%s' already active!\n", __FUNCTION__, lac->entname); break; } lac = lac->next; } if (lac){ if (first_run) cnt = 0; /*Foxconn, by MJ., for leaving while*/ break; } tunl = atoi (tunstr); if (!tunl) { log (LOG_DEBUG, "%s: No such tunnel '%s'\n", __FUNCTION__, tunstr); if (first_run) cnt = 0; /*Foxconn, by MJ., for leaving while*/ break; } #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n", __FUNCTION__, tunl); #endif lac_call (tunl, NULL, NULL); if (first_run) cnt = 0; /*Foxconn, by MJ., for leaving while*/ break; case 'o': /* jz: option 'o' for doing a outgoing call */ switch_io = 0; /* jz: Switch for incoming - outgoing Calls */ sub_str = strchr (buf, ' ') + 1; tunstr = strtok (sub_str, " "); /* jz: using strtok function to get */ tmp_ptr = strtok (NULL, " "); /* params out of the pipe */ strcpy (dial_no_tmp, tmp_ptr); lac = laclist; while (lac) { if (!strcasecmp (lac->entname, tunstr)) { lac->active = -1; lac->rtries = 0; if (!lac->c) magic_lac_dial (lac); else log (LOG_DEBUG, "%s: Session '%s' already active!\n", __FUNCTION__, lac->entname); break; } lac = lac->next; } if (lac) break; tunl = atoi (tunstr); if (!tunl) { log (LOG_DEBUG, "%s: No such tunnel '%s'\n", __FUNCTION__, tunstr); break; } #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to call on tunnel %d\n", __FUNCTION__, tunl); #endif lac_call (tunl, NULL, NULL); break; case 'h': callstr = strchr (buf, ' ') + 1; call = atoi (callstr); #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to call %d\n", __FUNCTION__, call); #endif lac_hangup (call); break; case 'd': tunstr = strchr (buf, ' ') + 1; lac = laclist; while (lac) { if (!strcasecmp (lac->entname, tunstr)) { lac->active = 0; lac->rtries = 0; if (lac->t) lac_disconnect (lac->t->ourtid); else log (LOG_DEBUG, "%s: Session '%s' not up\n", __FUNCTION__, lac->entname); break; } lac = lac->next; } if (lac) break; tunl = atoi (tunstr); if (!tunl) { log (LOG_DEBUG, "%s: No such tunnel '%s'\n", __FUNCTION__, tunstr); break; } #ifdef DEBUG_CONTROL log (LOG_DEBUG, "%s: Attempting to disconnect tunnel %d\n", __FUNCTION__, tunl); #endif lac_disconnect (tunl); break; case 's': show_status (1); break; default: log (LOG_DEBUG, "%s: Unknown command %c\n", __FUNCTION__, buf[0]); } } } /* Otherwise select goes nuts */ close (control_fd); control_fd = open (CONTROL_PIPE, O_RDONLY | O_NONBLOCK, 0600); }