Beispiel #1
0
/*
 * startCall
 *
 * Launches PPPD for the call.
 *
 * args:        pppaddrs - local/remote IPs or "" for either/both if none
 * retn:        pty file descriptor
 *
 */
static int startCall(char **pppaddrs, struct in_addr *inetaddrs)
{
	/* PTY/TTY pair for talking to PPPd */
	int pty_fd, tty_fd;
	/* register pids of children */
#if BSDUSER_PPP || SLIRP
	int sockfd[2];

#ifndef AF_LOCAL
#ifdef AF_UNIX
#define AF_LOCAL AF_UNIX /* Old BSD */
#else
#define AF_LOCAL AF_FILE /* POSIX */
#endif
#endif

	/* userspace ppp doesn't need to waste a real pty/tty pair */
	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd)) {
		syslog(LOG_ERR, "CTRL: socketpair() error");
		syslog_perror("socketpair");
		exit(1);
	}
	tty_fd = sockfd[0];
	pty_fd = sockfd[1];
#else
	/* Finds an open pty/tty pair */
	if (openpty(&pty_fd, &tty_fd, NULL, NULL, NULL) != 0) {
		syslog(LOG_ERR, "CTRL: openpty() error");
		syslog_perror("openpty");
		exit(1);
	} else {
		struct termios tios;

		/* Turn off echo in the slave - to prevent loopback.
		   pppd will do this, but might not do it before we
		   try to send data. */
		if (tcgetattr(tty_fd, &tios) < 0) {
			syslog(LOG_ERR, "CTRL: tcgetattr() error");
			syslog_perror("tcgetattr");
			exit(1);
		}
		tios.c_lflag &= ~(ECHO | ECHONL);
		if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0) {
			syslog(LOG_ERR, "CTRL: tcsetattr() error");
			syslog_perror("tcsetattr");
			exit(1);
		}
	}
#endif
	if (pptpctrl_debug) {
		syslog(LOG_DEBUG, "CTRL: pty_fd = %d", pty_fd);
		syslog(LOG_DEBUG, "CTRL: tty_fd = %d", tty_fd);
	}
	/* Launch the PPPD  */
#ifndef HAVE_FORK
        switch(pppfork=vfork()){
#else
        switch(pppfork=fork()){
#endif
	case -1:	/* fork() error */
		syslog(LOG_ERR, "CTRL: Error forking to exec pppd");
		_exit(1);

	case 0:		/* child */
		if (dup2(tty_fd, 0) == -1) {
		  syslog(LOG_ERR, "CTRL: child tty_fd dup2 to stdin, %s",
			 strerror(errno));
		  exit(1);
		}
		if (dup2(tty_fd, 1) == -1) {
		  syslog(LOG_ERR, "CTRL: child tty_fd dup2 to stdout, %s",
			 strerror(errno));
		  exit(1);
		}
#if 0
		/* This must never be used if !HAVE_SYSLOG since that logs to stderr.
		 * Trying just never using it to see if it causes anyone else problems.
		 * It may let people see the pppd errors, which would be good.
		 */
		dup2(tty_fd, 2);
#endif
		if (tty_fd > 1)
			close(tty_fd);
		if (pty_fd > 1)
			close(pty_fd);
/* In case we move clientSocket back off stdin */
#ifndef clientSocket
		if (clientSocket > 1)
			close(clientSocket);
#elif clientSocket > 1
		close(clientSocket);
#endif
		launch_pppd(pppaddrs, inetaddrs);
		syslog(LOG_ERR, "CTRL: PPPD launch failed! (launch_pppd did not fork)");
		_exit(1);
	}
	
	close(tty_fd);
	return pty_fd;
}

/*
 * launch_pppd
 *
 * Launches the PPP daemon. The PPP daemon is responsible for assigning the
 * PPTP client its IP address.. These values are assigned via the command
 * line.
 *
 * Add return of connected ppp interface
 *
 * retn: 0 on success, -1 on failure.
 *
 */
static void launch_pppd(char **pppaddrs, struct in_addr *inetaddrs)
{
	char *pppd_argv[14];
	int an = 0;
	sigset_t sigs;

	pppd_argv[an++] = ppp_binary;

	if (pptpctrl_debug) {
		syslog(LOG_DEBUG, 
		       "CTRL (PPPD Launcher): program binary = %s", 
		       pppd_argv[an - 1]);
	}

#if BSDUSER_PPP

	/* The way that Brian Somers' user-land ppp works is to use the
	 * system name as a reference for most of the useful options. Hence
	 * most things can't be defined on the command line. On OpenBSD at
	 * least the file used for the systems is /etc/ppp/ppp.conf, where
	 * the pptp stanza should look something like:

	 pptp:
	 set speed sync
	 enable pap
	 enable chap
	 set dns a.a.a.a b.b.b.b
	 set ndbs x.x.x.x y.y.y.y
	 accept dns
	 add 10.0.0/24

	 * To be honest, at the time of writing, I haven't had the thing
	 * working enough to understand :) I will update this comment and
	 * make a sample config available when I get there.
	 */

	/* options for BSDUSER_PPP
	 *
	 * ignores IP addresses, config file option, speed
	 * fix usage info in pptpd.c and configure script if this changes
	 *
	 * IP addresses can be specified in /etc/ppp/ppp.secret per user
	 */
	pppd_argv[an++] = "-direct";
	pppd_argv[an++] = "pptp";	/* XXX this is the system name */
	/* should be dynamic - PMG */

#elif SLIRP

	/* options for SLIRP
	 *
	 * ignores IP addresses from config - SLIRP handles this
	 */
	pppd_argv[an++] = "-P";
	pppd_argv[an++] = "+chap";
	pppd_argv[an++] = "-b";

	/* If a speed has been specified, use it
	 * if not, use "smart" default (defaults.h)
	 */
	if (*speed) {
		pppd_argv[an++] = speed;
	} else {
		pppd_argv[an++] = PPP_SPEED_DEFAULT;
	}

	if (*pppdxfig) {
		pppd_argv[an++] = "-f";
		pppd_argv[an++] = pppdxfig;
	}

	if (pptpctrl_debug) {
		syslog(LOG_DEBUG, "CTRL (PPPD Launcher): Connection speed = %s", pppd_argv[an - 1]);
	}
#else

	/* options for 'normal' pppd */

	pppd_argv[an++] = "local";

	/* If a pppd option file is specified, use it
	 * if not, pppd will default to /etc/ppp/options
	 */
	if (*pppdxfig) {
		pppd_argv[an++] = "file";
		pppd_argv[an++] = pppdxfig;
	}
	
	/* If a speed has been specified, use it
	 * if not, use "smart" default (defaults.h)
	 */
	if (*speed) {
		pppd_argv[an++] = speed;
	} else {
		pppd_argv[an++] = PPP_SPEED_DEFAULT;
	}

	if (pptpctrl_debug) {
		if (*pppaddrs[0])
			syslog(LOG_DEBUG, "CTRL (PPPD Launcher): local address = %s", pppaddrs[0]);
		if (*pppaddrs[1])
			syslog(LOG_DEBUG, "CTRL (PPPD Launcher): remote address = %s", pppaddrs[1]);
	}
	
	if (*pppaddrs[0] || *pppaddrs[1]) {
		char pppInterfaceIPs[33];
		sprintf(pppInterfaceIPs, "%s:%s", pppaddrs[0], pppaddrs[1]);
		pppd_argv[an++] = pppInterfaceIPs;
	}
#endif

        if (!noipparam) {
                 pppd_argv[an++] = "ipparam";
                 pppd_argv[an++] = inet_ntoa(inetaddrs[1]);
        }

        if (pptp_logwtmp) {
                 pppd_argv[an++] = "plugin";
                 pppd_argv[an++] = "/usr/lib/pptpd/pptpd-logwtmp.so";
                 pppd_argv[an++] = "pptpd-original-ip";
                 pppd_argv[an++] = inet_ntoa(inetaddrs[1]);
        }

	/* argv arrays must always be NULL terminated */
	pppd_argv[an++] = NULL;
	/* make sure SIGCHLD is unblocked, pppd does not expect it */
	sigfillset(&sigs);
	sigprocmask(SIG_UNBLOCK, &sigs, NULL);
	/* run pppd now */
	execvp(pppd_argv[0], pppd_argv);
	/* execvp() failed */
	syslog(LOG_ERR, 
	       "CTRL (PPPD Launcher): Failed to launch PPP daemon. %s",
	       strerror(errno));
}
Beispiel #2
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;
    char ttydev[PATH_MAX];
    int pty_fd, tty_fd, gre_fd, rc;
    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;
    volatile int launchpppd = 1, debug = 0, nodaemon = 0;

    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},
	    {"version", 0, 0, 0},
            {"nodaemon", 0, 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");
                } else if (option_index == 12) { /* --version */
		    fprintf(stdout, "%s\n", version);
		    exit(0);
                } else if (option_index == 13) {/* --nodaemon */
                    nodaemon = 1;
                }
                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]);

    /* Get IP address for the hostname in argv[1] */
    inetaddr = get_ip_address(argv[optind]);
    optind++;

    /* Find the ppp options, extract phone number */
    pppdargc = argc - optind;
    pppdargv = argv + optind;
    log("The synchronous pptp option is %sactivated\n", syncppp ? "" : "NOT ");

    /* 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){
        rc = openpty (&pty_fd, &tty_fd, ttydev, NULL, NULL);
        if (rc < 0) { 
            close(callmgr_sock); 
            fatal("Could not find free pty.");
        }

#if defined(__linux__)
		/*
		 * if we do not turn off echo now,  then if pppd sleeps for any
		 * length of time (DNS timeouts or whatever) the other end of the
		 * connect may detect the link as looped.  Other OSen may want this
		 * as well,  but for now linux gets it.
		 */
		{
			struct termios tios;
			tcgetattr(tty_fd, &tios);
			cfmakeraw(&tios);
			tcsetattr(tty_fd, TCSAFLUSH, &tios);
		}
#endif

        /* 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);
                close (gre_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");
        }
    } 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);

    /* Send signal to wake up pppd task */
    if (launchpppd) {
        kill(parent_pid, SIGUSR1);
        sleep(2);
        /* become a daemon */
        if (!(debug || nodaemon) && daemon(0, 0) != 0) {
            perror("daemon");
        }
    } 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));
#ifdef PR_SET_NAME
    rc = prctl(PR_SET_NAME, "pptpgw", 0, 0, 0);
    if (rc != 0) perror("prctl");
#endif
    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. */
    if(launchpppd)
        kill(parent_pid, SIGTERM);
    close(pty_fd);
    close(callmgr_sock);
    exit(0);
}
Beispiel #3
0
int main(int argc, char **argv, char **envp) {
  struct in_addr inetaddr;
  int callmgr_sock = -1;
  char ptydev[PTYMAX], ttydev[TTYMAX];
  int pty_fd = -1;
  int gre_fd = -1;
  static volatile pid_t child_pid;
  u_int16_t call_id, peer_call_id;
  
#ifdef EMBED
  openlog(argv[0],LOG_PID,LOG_USER);
#endif

  if (argc < 2)
    usage(argv[0]);

  /* Step 1: Get IP address for the hostname in argv[1] */
  for (;;) {
    inetaddr = get_ip_address(argv[1]);
    if(inetaddr.s_addr != 0)
      break;
    sleep(RESPAWN_DELAY);
  }

  /*
   * open the GRE socket early so that we do not get
   * ENOPROTOOPT errors if the other end responds too
   * quickly to our initial connection
   */
  gre_fd = socket(AF_INET, SOCK_RAW, PPTP_PROTO);
  if (gre_fd < 0) {
	pptp_error("socket: %s\n", strerror(errno));
    sleep(RESPAWN_DELAY);
	exit(1);
  }

  for (;;) {
    /* Step 2: Open connection to call manager
	 *         (Launch call manager if necessary.)
	 */
	callmgr_sock = open_callmgr(inetaddr, argc,argv,envp);
	if(callmgr_sock < 0){
      close(gre_fd);
	  pptp_error("Could not open connection to call manager - terminating");
	  sleep(RESPAWN_DELAY);
	  exit(1);
	}
	pptp_debug("callmgr opened - fd = %x", callmgr_sock);

	/* Step 5: Exchange PIDs, get call ID */
	if (get_call_id(callmgr_sock, getpid(), &call_id, &peer_call_id) >= 0)
		break;

	close(callmgr_sock);
  }

  /* Step 3: Find an open pty/tty pair. */
  pty_fd = getpseudotty(ttydev, ptydev);
  if (pty_fd < 0) {
    close(gre_fd);
    close(callmgr_sock);
	pptp_error("Could not find free pty.");
	sleep(RESPAWN_DELAY);
	exit(1);
  }
  pptp_debug("got a free ttydev");
  
  /* Step 4: fork and wait. */
  signal(SIGUSR1, do_nothing); /* don't die */
  switch (child_pid = vfork()) {
  case -1:
    signal(SIGUSR1, SIG_DFL);
    pptp_debug("vfork failed %s", strerror(errno));
	sleep(RESPAWN_DELAY);
	goto shutdown;
  case 0: /* I'm the child! */
//    signal(SIGUSR1, SIG_DFL);
	pptp_debug("entered child");
    pptp_debug("callids established..");
	close(callmgr_sock);
	close(gre_fd);
	close(pty_fd);
    launch_pppd(ttydev, argc-2, argv+2); /* launch pppd */
	sleep(RESPAWN_DELAY);
	exit(1); /* in case launch_pppd returns */
    break;
  default: /* parent */
    /*
     * 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 0
	if (!signaled) {
	  pause(); /* wait for the signal */
    }
    pptp_error("Error %s", strerror(errno));
#endif /*0*/
    break;
  }

#if 0
  /* Step 5b: Send signal to wake up pppd task */
  kill(parent_pid, SIGUSR1);
  sleep(2);
#endif /*0*/

  if (sigsetjmp(env, 1)!=0) goto shutdown;
  signal(SIGINT,  sighandler);
  signal(SIGTERM, sighandler);
  signal(SIGKILL, sighandler);

  {
    char buf[128];
    snprintf(buf, sizeof(buf), "pptp: GRE-to-PPP gateway on %s", ptydev);
    inststr(argc,argv,envp, buf);
  }

  /* Step 6: Do GRE copy until close. */
  pptp_gre_copy(peer_call_id, call_id, pty_fd, gre_fd, inetaddr);

shutdown:
  /* Make sure pppd exits as well */
  if (child_pid > 0)
    kill(child_pid, SIGTERM);
  if (gre_fd != -1)
    close(gre_fd);
  if (pty_fd != -1)
    close(pty_fd);
  if (callmgr_sock != -1)
    close(callmgr_sock);
  exit(0);
}
void hackSetupData(char **data, size_t datalen, RIL_Token t)
{
	const char *apn;
	char *user = NULL;
	char *pass = NULL;
	char *cmd;
	char *userpass;
	int err;
	ATResponse *p_response = NULL;
	int fd, pppstatus,i,fd2;
	FILE *pppconfig;
	size_t cur = 0;
	ssize_t written, rlen;
	char status[32] = {0};
	char *buffer;
	long buffSize, len;
	int retry = 10;
	char *response[3] = { "1", "ppp0", "255.255.255.255" };
	int mypppstatus;
	int ret;
	struct termios  ios;

	ALOGW("hackSetupData(%s)\n",((const char **)data)[2]);

	apn = ((const char **)data)[2];
	user = ((char **)data)[3];
	if(user != NULL)
	{
		if (strlen(user)<2)
			user = "******";
	} else
		user = "******";

	pass = ((char **)data)[4];
	if(pass != NULL)
	{
		if (strlen(pass)<2)
			pass = "******";
	} else
		pass = "******";


	if(*data[0]=='0')
		ALOGD("Android want us to connect as CDMA while we are a GSM phone !");

    strcpy(current_apn, apn);
	asprintf(&cmd, "AT+CGDCONT=1,\"IP\",\"%s\",,0,0", apn);
	//FIXME check for error here
	//err = at_send_command(cmd, NULL);
	send_modem(cmd);
	free(cmd);
	msleep(300);

	// Set required QoS params to default
	send_modem("AT+CGQREQ=1");
	msleep(300);
	// Set minimum QoS params to default
	send_modem("AT+CGQMIN=1");
	msleep(300);
	// packet-domain event reporting
	send_modem("AT+CGEREP=1,0");
	msleep(300);

	asprintf(&userpass, "%s * %s\n", user, pass);
	len = strlen(userpass);

	// if file does not exist we will create it
	system("touch /etc/ppp/pap-secrets");	
	fd = open("/etc/ppp/pap-secrets",O_WRONLY);
	if(fd < 0) {
		ALOGE("unable to open /etc/ppp/pap-secrets\n");
		goto error;
	}
	write(fd, userpass, len);
	close(fd);

	// if file does not exist we will create it
	system("touch /etc/ppp/chap-secrets");
	fd = open("/etc/ppp/chap-secrets",O_WRONLY);
	if(fd < 0) {
		ALOGE("unable to open /etc/ppp/chap-secrets\n");
		goto error;
	}
	write(fd, userpass, len);
	close(fd);
	free(userpass);

	// if file does not exist we will create it
	system("touch /etc/ppp/options.smd");
	pppconfig = fopen("/etc/ppp/options.smd","r");
	if(!pppconfig) {
		ALOGE("unable to open /etc/ppp/options.smd\n");
		goto error;
	}

	//filesize
	fseek(pppconfig, 0, SEEK_END);
	buffSize = ftell(pppconfig);
	rewind(pppconfig);

	//allocate memory
	buffer = (char *) malloc (sizeof(char)*buffSize);
	if (buffer == NULL) {
		ALOGE("hackSetupData: malloc buffer failed\n");
		goto error;
	}

	//read in the original file
	len = fread (buffer,1,buffSize,pppconfig);
	if (len != buffSize) {
		ALOGE("hackSetupData: fread failed\n");
		goto error;
	}
	fclose(pppconfig);

	// if file does not exist we will create it
	system("touch /etc/ppp/options.smd1");
	pppconfig = fopen("/etc/ppp/options.smd1","w");
	fwrite(buffer,1,buffSize,pppconfig);
	fprintf(pppconfig,"user %s\n",user);
	fclose(pppconfig);
	free(buffer);

	ALOGW("launching pppd\n");
    is_data_active = 1;
    launch_pppd();

    // Give some time to launch pppd
	sleep(7);

	ALOGD("setupData exit\n");
	
	RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
	return;
	error:
		ALOGE("PL:hackSetupData: ERROR ?");
		RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}
void interceptOnRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen)
{
    int i;
//    ALOGD("PL:InterceptRequestComplete(%d, %d)", (int)t, responselen);
    if(request_call_list_token == t) {
        // response from data call list
        request_call_list_token = 0;
        ALOGW("DataCallList");
        RIL_Data_Call_Response *data_calls = (RIL_Data_Call_Response *)response;
        for(i = 0 ; i < (int)(responselen / sizeof(RIL_Data_Call_Response)); i++) {
            ALOGD("call[%d]:cid=%d, active=%d, type=%s, apn=%s, add=%s\n",
                 i,
                 data_calls[i].cid,
                 data_calls[i].active,
                 data_calls[i].type,
                 data_calls[i].apn,
                 data_calls[i].address
                );
        }
    } else if(request_registration_state_token == t) {
        char **strings;
        request_registration_state_token = 0;
        strings = (char **)response;
        char dbg[128];
        int status;
        int strings_cnt = (int)(responselen / sizeof(char *));

        strcpy(dbg, "RegState:");
        dbg[127] = 0;
        for(i = 0 ; i < strings_cnt; i++) {
            strncat(dbg, strings[i] ? strings[i] : "null", 127);
            strncat(dbg, " ", 127);
        }
        ALOGW(dbg);
        // Workaround for htc_ril bug, it sometimes set null to string[0] that make rild crash
        if(strings[0] == NULL)
            strings[0] = "0";

        if((strings_cnt > 3) && (strings[0] != NULL) && (strings[3] != NULL)) {
            if((atoi(strings[0]) != 0) && (atoi(strings[3]) != 0)) {
                ALOGW("State: Net ready");
                is_network_ready = 1;
            }
            else {
                ALOGW("State: no Net");
                is_network_ready = 0;
            }
            // Notify monitoring thread
            if(monitor_pid) {
                ALOGW("Notif mon(%d) up", monitor_pid);
                if(kill(monitor_pid, is_network_ready ? SIGUSR1 : SIGUSR2) == -1) {
                    ALOGE("MONITOR DIED?, respawn it");
                    // wait to remove zombie
                    if(waitpid(monitor_pid, &status, WNOHANG|WUNTRACED) > 0) {
                        ALOGW("monitor was zombie");
                        // waitpid found a process
                        if(WIFSIGNALED(status)) {
                            ALOGW("monitor has received a signal (%d) ??", WTERMSIG(status));
                        } else if(WIFSTOPPED(status)) {
                            ALOGW("monitor has been stopped by signal (%d) ??", WSTOPSIG(status));
                        }
                    }
                    if(is_network_ready && is_data_active) {
                        ALOGW("data active, try to restart monitor after death");
                        launch_pppd();
                    }
                }
            }
        }
    }
    s_rilenv->OnRequestComplete(t, e, response, responselen);
}
Beispiel #6
0
/*
 * startCall
 *
 * Launches PPPD for the call.
 *
 * args:        pppaddrs - local/remote IPs or "" for either/both if none
 * retn:        pty file descriptor
 *
 */
static int startCall(char **pppaddrs, struct in_addr *inetaddrs)
{
	/* Launch the PPPD  */
#ifndef HAVE_FORK
        switch(pppfork=vfork()){
#else
        switch(pppfork=fork()){
#endif
	case -1:	/* fork() error */
		syslog(LOG_ERR, "CTRL: Error forking to exec pppd");
		_exit(1);

	case 0:		/* child */
/* In case we move clientSocket back off stdin */
#ifndef clientSocket
		if (clientSocket > 1)
			close(clientSocket);
#elif clientSocket > 1
		close(clientSocket);
#endif
		launch_pppd(pppaddrs, inetaddrs);
		syslog(LOG_ERR, "CTRL: PPPD launch failed! (launch_pppd did not fork)");
		_exit(1);
	}

	return -1;
}

/*
 * launch_pppd
 *
 * Launches the PPP daemon. The PPP daemon is responsible for assigning the
 * PPTP client its IP address.. These values are assigned via the command
 * line.
 *
 * Add return of connected ppp interface
 *
 * retn: 0 on success, -1 on failure.
 *
 */
static void launch_pppd(char **pppaddrs, struct in_addr *inetaddrs)
{
	char *pppd_argv[25];
	int an = 0;
	sigset_t sigs;
	char tmp[128];

	pppd_argv[an++] = ppp_binary;

	if (pptpctrl_debug) {
		syslog(LOG_DEBUG,
		       "CTRL (PPPD Launcher): program binary = %s",
		       pppd_argv[an - 1]);
	}

#if BSDUSER_PPP

	/* The way that Brian Somers' user-land ppp works is to use the
	 * system name as a reference for most of the useful options. Hence
	 * most things can't be defined on the command line. On OpenBSD at
	 * least the file used for the systems is /etc/ppp/ppp.conf, where
	 * the pptp stanza should look something like:

	 pptp:
	 set speed sync
	 enable pap
	 enable chap
	 set dns a.a.a.a b.b.b.b
	 set ndbs x.x.x.x y.y.y.y
	 accept dns
	 add 10.0.0/24

	 * To be honest, at the time of writing, I haven't had the thing
	 * working enough to understand :) I will update this comment and
	 * make a sample config available when I get there.
	 */

	/* options for BSDUSER_PPP
	 *
	 * ignores IP addresses, config file option, speed
	 * fix usage info in pptpd.c and configure script if this changes
	 *
	 * IP addresses can be specified in /etc/ppp/ppp.secret per user
	 */
	pppd_argv[an++] = "-direct";
	pppd_argv[an++] = "pptp";	/* XXX this is the system name */
	/* should be dynamic - PMG */

#elif SLIRP

	/* options for SLIRP
	 *
	 * ignores IP addresses from config - SLIRP handles this
	 */
	pppd_argv[an++] = "-P";
	pppd_argv[an++] = "+chap";
	pppd_argv[an++] = "-b";

	/* If a speed has been specified, use it
	 * if not, use "smart" default (defaults.h)
	 */
	if (*speed) {
		pppd_argv[an++] = speed;
	} else {
		pppd_argv[an++] = PPP_SPEED_DEFAULT;
	}

	if (*pppdxfig) {
		pppd_argv[an++] = "-f";
		pppd_argv[an++] = pppdxfig;
	}

	if (pptpctrl_debug) {
		syslog(LOG_DEBUG, "CTRL (PPPD Launcher): Connection speed = %s", pppd_argv[an - 1]);
	}
#else

	/* options for 'normal' pppd */

	pppd_argv[an++] = "local";

	/* If a pppd option file is specified, use it
	 * if not, pppd will default to /etc/ppp/options
	 */
	if (*pppdxfig) {
		pppd_argv[an++] = "file";
		pppd_argv[an++] = pppdxfig;
	}

	/* If a speed has been specified, use it
	 * if not, use "smart" default (defaults.h)
	 */
	if (*speed) {
		pppd_argv[an++] = speed;
	} else {
		pppd_argv[an++] = PPP_SPEED_DEFAULT;
	}

	if (pptpctrl_debug) {
		if (*pppaddrs[0])
			syslog(LOG_DEBUG, "CTRL (PPPD Launcher): local address = %s", pppaddrs[0]);
		if (*pppaddrs[1])
			syslog(LOG_DEBUG, "CTRL (PPPD Launcher): remote address = %s", pppaddrs[1]);
	}

	if (*pppaddrs[0] || *pppaddrs[1]) {
		char pppInterfaceIPs[33];
		sprintf(pppInterfaceIPs, "%s:%s", pppaddrs[0], pppaddrs[1]);
		pppd_argv[an++] = pppInterfaceIPs;
	}
#endif

        if (!noipparam) {
                 pppd_argv[an++] = "ipparam";
                 pppd_argv[an++] = inet_ntoa(inetaddrs[1]);
        }

        if (pptp_logwtmp) {
                 pppd_argv[an++] = "plugin";
                 pppd_argv[an++] = "/usr/lib/pptpd/pptpd-logwtmp.so";
                 pppd_argv[an++] = "pptpd-original-ip";
                 pppd_argv[an++] = inet_ntoa(inetaddrs[1]);
        }

	pppd_argv[an++] = "plugin";
	pppd_argv[an++] = "pptp.so";
	pppd_argv[an++] = "pptp_client";
	strcpy(tmp,inet_ntoa(inetaddrs[1]));
	pppd_argv[an++] = strdup(tmp);
	pppd_argv[an++] = "pptp_sock";
	sprintf(tmp,"%u",pptp_sock);
	pppd_argv[an++] = strdup(tmp);
	pppd_argv[an++] = "nodetach";

	/* argv arrays must always be NULL terminated */
	pppd_argv[an++] = NULL;
	/* make sure SIGCHLD is unblocked, pppd does not expect it */
	sigfillset(&sigs);
	sigprocmask(SIG_UNBLOCK, &sigs, NULL);
	/* run pppd now */
	execvp(pppd_argv[0], pppd_argv);
	/* execvp() failed */
	syslog(LOG_ERR,
	       "CTRL (PPPD Launcher): Failed to launch PPP daemon. %s",
	       strerror(errno));
}