int main (int argc, char *argv[]) { /* Foxconn added start pling 03/20/2012 */ /* Add the default first */ struct in_addr l2tp_serv_ip; fxc_add_gw(1, l2tp_serv_ip); /* Foxconn added end pling 03/20/2012 */ init(argc,argv); dial_no_tmp = calloc (128, sizeof (char)); /* Foxconn, add by MJ. A global variable to mark the first execution */ #ifdef AUTO_CONNECT is_first_run = 1; #endif network_thread (); return 0; }
/* TODO: redesign to avoid longjmp/setjmp. Several variables here have a volatile qualifier to silence warnings from gcc < 3.0. Remove the volatile qualifiers if longjmp/setjmp are removed. */ int main(int argc, char **argv, char **envp) { struct in_addr inetaddr; volatile int callmgr_sock = -1; #ifdef CODE_IN_USE //Winster Chan added 05/16/2006 char ttydev[PATH_MAX]; int rc; #endif //CODE_IN_USE Winster Chan added 05/16/2006 int pty_fd, tty_fd, gre_fd; volatile pid_t parent_pid, child_pid; u_int16_t call_id, peer_call_id; char buf[128]; int pppdargc; char **pppdargv; char phonenrbuf[65]; /* maximum length of field plus one for the trailing * '\0' */ char * volatile phonenr = NULL; #ifdef CODE_IN_USE //Winster Chan added 05/16/2006 volatile int launchpppd = 1; #else volatile int launchpppd = 0; #endif //CODE_IN_USE Winster Chan added 05/16/2006 volatile int debug = 0; /* Foxconn added start, Winster Chan, 06/26/2006 */ FILE *fp; /* Foxconn added end, Winster Chan, 06/26/2006 */ while(1){ /* structure with all recognised options for pptp */ static struct option long_options[] = { {"phone", 1, 0, 0}, {"nolaunchpppd", 0, 0, 0}, {"quirks", 1, 0, 0}, {"debug", 0, 0, 0}, {"sync", 0, 0, 0}, {"timeout", 1, 0, 0}, {"logstring", 1, 0, 0}, {"localbind", 1, 0, 0}, {"loglevel", 1, 0, 0}, {"nobuffer", 0, 0, 0}, {"idle-wait", 1, 0, 0}, {"max-echo-wait", 1, 0, 0}, {0, 0, 0, 0} }; int option_index = 0; int c; c = getopt_long (argc, argv, "", long_options, &option_index); if (c == -1) break; /* no more options */ switch (c) { case 0: if (option_index == 0) { /* --phone specified */ /* copy it to a buffer, as the argv's will be overwritten * by inststr() */ strncpy(phonenrbuf,optarg,sizeof(phonenrbuf)); phonenrbuf[sizeof(phonenrbuf) - 1] = '\0'; phonenr = phonenrbuf; } else if (option_index == 1) {/* --nolaunchpppd specified */ launchpppd = 0; } else if (option_index == 2) {/* --quirks specified */ if (set_quirk_index(find_quirk(optarg))) usage(argv[0]); } else if (option_index == 3) {/* --debug */ debug = 1; } else if (option_index == 4) {/* --sync specified */ syncppp = 1; } else if (option_index == 5) {/* --timeout */ float new_packet_timeout = atof(optarg); if (new_packet_timeout < 0.0099 || new_packet_timeout > 10) { fprintf(stderr, "Packet timeout %s (%f) out of range: " "should be between 0.01 and 10 seconds\n", optarg, new_packet_timeout); log("Packet timeout %s (%f) out of range: should be" "between 0.01 and 10 seconds", optarg, new_packet_timeout); exit(2); } else { packet_timeout_usecs = new_packet_timeout * 1000000; } } else if (option_index == 6) {/* --logstring */ log_string = strdup(optarg); } else if (option_index == 7) {/* --localbind */ if (inet_pton(AF_INET, optarg, (void *) &localbind) < 1) { fprintf(stderr, "Local bind address %s invalid\n", optarg); log("Local bind address %s invalid\n", optarg); exit(2); } } else if (option_index == 8) { /* --loglevel */ log_level = atoi(optarg); if (log_level < 0 || log_level > 2) usage(argv[0]); } else if (option_index == 9) { /* --nobuffer */ disable_buffer = 1; } else if (option_index == 10) { /* --idle-wait */ int x = atoi(optarg); if (x < 0) { fprintf(stderr, "--idle-wait must not be negative\n"); log("--idle-wait must not be negative\n"); exit(2); } else { idle_wait = x; } } else if (option_index == 11) { /* --max-echo-wait */ int x = atoi(optarg); if (x < 0) { fprintf(stderr, "--max-echo-wait must not be negative\n"); log("--max-echo-wait must not be negative\n"); exit(2); } else { max_echo_wait = x; } fprintf(stderr, "--max-echo-wait ignored, not yet implemented\n"); } break; case '?': /* unrecognised option */ /* fall through */ default: usage(argv[0]); } if (c == -1) break; /* no more options for pptp */ } /* at least one argument is required */ if (argc <= optind) usage(argv[0]); fxc_add_gw(1, inetaddr); /* foxocnn added by EricHuang, 04/03/2007 */ /* Get IP address for the hostname in argv[1] */ inetaddr = get_ip_address(argv[optind]); optind++; fxc_add_gw(2, inetaddr); /* foxocnn added by EricHuang, 04/04/2007 */ /* Find the ppp options, extract phone number */ pppdargc = argc - optind; pppdargv = argv + optind; log("The synchronous pptp option is %sactivated\n", syncppp ? "" : "NOT "); /* Foxconn added start, Winster Chan, 06/26/2006 */ pptp_pppox_open(&poxfd, &pppfd); /* Foxconn added end, Winster Chan, 06/26/2006 */ /* Now we have the peer address, bind the GRE socket early, before starting pppd. This prevents the ICMP Unreachable bug documented in <1026868263.2855.67.camel@jander> */ gre_fd = pptp_gre_bind(inetaddr); if (gre_fd < 0) { close(callmgr_sock); fatal("Cannot bind GRE socket, aborting."); } /* Find an open pty/tty pair. */ if(launchpppd){ #ifdef CODE_IN_USE //Winster Chan added 05/16/2006 rc = openpty (&pty_fd, &tty_fd, ttydev, NULL, NULL); if (rc < 0) { close(callmgr_sock); fatal("Could not find free pty."); } /* fork and wait. */ signal(SIGUSR1, do_nothing); /* don't die */ signal(SIGCHLD, do_nothing); /* don't ignore SIGCHLD */ parent_pid = getpid(); switch (child_pid = fork()) { case -1: fatal("Could not fork pppd process"); case 0: /* I'm the child! */ close (tty_fd); signal(SIGUSR1, SIG_DFL); child_pid = getpid(); break; default: /* parent */ close (pty_fd); /* * There is still a very small race condition here. If a signal * occurs after signaled is checked but before pause is called, * things will hang. */ if (!signaled) { pause(); /* wait for the signal */ } if (signaled == SIGCHLD) fatal("Child process died"); launch_pppd(ttydev, pppdargc, pppdargv); /* launch pppd */ perror("Error"); fatal("Could not launch pppd"); } #endif //CODE_IN_USE Winster Chan added 05/16/2006 } else { /* ! launchpppd */ pty_fd = tty_fd = STDIN_FILENO; /* close unused file descriptor, that is redirected to the pty */ close(STDOUT_FILENO); child_pid = getpid(); parent_pid = 0; /* don't kill pppd */ } do { /* * Open connection to call manager (Launch call manager if necessary.) */ callmgr_sock = open_callmgr(inetaddr, phonenr, argc, argv, envp, pty_fd, gre_fd); /* Exchange PIDs, get call ID */ } while (get_call_id(callmgr_sock, parent_pid, child_pid, &call_id, &peer_call_id) < 0); /* Foxconn added start, Winster Chan, 06/26/2006 */ /* Store pptp call_id & peer_call_id to file */ fp = fopen("/tmp/ppp/callIds", "w"); fprintf(fp, "%d %d\n", call_id, peer_call_id); fclose(fp); /* Foxconn added start by EricHuang, 03/20/2007 */ if ( fp = fopen("/tmp/ppp/pptpSrvIp", "w") ) { fprintf(fp, "%s", inet_ntoa(inetaddr)); fclose(fp); } /* Foxconn added end by EricHuang, 03/20/2007 */ /* Connect pptp kernel module */ pptp_pppox_connect(&poxfd, &pppfd, call_id, peer_call_id); /* Foxconn added end, Winster Chan, 06/26/2006 */ /* Send signal to wake up pppd task */ if (launchpppd) { #ifdef CODE_IN_USE //Winster Chan added 05/16/2006 kill(parent_pid, SIGUSR1); sleep(2); /* become a daemon */ if (!debug && daemon(0, 0) != 0) { perror("daemon"); } #endif //CODE_IN_USE Winster Chan added 05/16/2006 } else { /* re-open stderr as /dev/null to release it */ file2fd("/dev/null", "wb", STDERR_FILENO); } snprintf(buf, sizeof(buf), "pptp: GRE-to-PPP gateway on %s", ttyname(tty_fd)); inststr(argc, argv, envp, buf); if (sigsetjmp(env, 1)!= 0) goto shutdown; signal(SIGINT, sighandler); signal(SIGTERM, sighandler); signal(SIGKILL, sighandler); signal(SIGCHLD, sighandler); signal(SIGUSR1, sigstats); /* Do GRE copy until close. */ pptp_gre_copy(call_id, peer_call_id, pty_fd, gre_fd); shutdown: /* on close, kill all. */ #ifdef CODE_IN_USE //Winster Chan added 05/16/2006 if(launchpppd) kill(parent_pid, SIGTERM); #endif //CODE_IN_USE Winster Chan added 05/16/2006 close(pty_fd); close(callmgr_sock); /* Foxconn added start, Winster Chan, 06/26/2006 */ close(pppfd); close(poxfd); /* Foxconn added end, Winster Chan, 06/26/2006 */ exit(0); }
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; FILE *fp; port = htons (port); /* Foxconn, added by MJ. 01/29/2010 */ struct in_addr l2tp_serv_ip; /* add routing for DNS server 01/29/2010*/ fxc_add_gw(1, l2tp_serv_ip); /* Foxconn, added end.*/ 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); /* Foxconn, add start by MJ., for l2tp. 01/28/2010 */ if (hp->h_addrtype == AF_INET){ memcpy(&l2tp_serv_ip.s_addr, hp->h_addr, sizeof(l2tp_serv_ip.s_addr)); if ( fp = fopen("/tmp/ppp/l2tpSrvIp", "w") ) { fprintf(fp, "%s", inet_ntoa(l2tp_serv_ip)); fclose(fp); } } /* Add routing for L2TP server */ fxc_add_gw(2, l2tp_serv_ip); /* Foxconn, add end, by MJ., for l2tp. 01/28/2010 */ /* 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; }