Ejemplo n.º 1
0
static int pre_init_modemu(void)
{
    switch (cmdarg.ttymode) {
#ifdef HAVE_GRANTPT
    char * ptyslave;
    case CA_SHOWDEV:
	tty.rfd = tty.wfd = getPtyMaster(&ptyslave);
	printf("%s\n", ptyslave);
	return 0;
    case CA_COMMX:
	tty.rfd = tty.wfd = getPtyMaster(&ptyslave);
	commxForkExec(cmdarg.commx, ptyslave);
	break;
#else
	char c10, c01;
    case CA_SHOWDEV:
	tty.rfd = tty.wfd = getPtyMaster(&c10, &c01);
	printf("%c%c\n", c10, c01);
	return 0;
    case CA_COMMX:
	tty.rfd = tty.wfd = getPtyMaster(&c10, &c01);
	commxForkExec(cmdarg.commx, c10, c01);
	break;
#endif
    case CA_STDINOUT:
	tty.rfd = 0;
	tty.wfd = 1;
	setTty();
	break;
    case CA_DEVGIVEN:
	tty.rfd = tty.wfd = openPtyMaster(cmdarg.dev);
	break;
    }

    return 1;
}
Ejemplo n.º 2
0
int start_pppd (struct call *c, struct ppp_opts *opts)
{
    char a, b;
    char tty[80];
    char *stropt[80];
    struct ppp_opts *p;
#ifdef USE_KERNEL
    struct l2tp_call_opts co;
#endif
    int pos = 1;
    int fd2;
#ifdef DEBUG_PPPD
    int x;
#endif
    struct termios ptyconf;
    struct call *sc;
    struct tunnel *st;

    p = opts;
    stropt[0] = strdup (PPPD);
    while (p)
    {
        stropt[pos] = (char *) malloc (strlen (p->option) + 1);
        strncpy (stropt[pos], p->option, strlen (p->option) + 1);
        pos++;
        p = p->next;
    }
    stropt[pos] = NULL;
    if (c->pppd > 0)
    {
        log (LOG_WARN, "%s: PPP already started on call!\n", __FUNCTION__);
        return -EINVAL;
    }
    if (c->fd > -1)
    {
        log (LOG_WARN, "%s: file descriptor already assigned!\n",
             __FUNCTION__);
        return -EINVAL;
    }
#ifdef USE_KERNEL
    if (kernel_support)
    {
        co.ourtid = c->container->ourtid;
        co.ourcid = c->ourcid;
        ioctl (server_socket, L2TPIOCGETCALLOPTS, &co);
        stropt[pos++] = strdup ("channel");
        stropt[pos] = (char *) malloc (10);
        snprintf (stropt[pos], 10, "%d", co.id);
        pos++;
        stropt[pos] = NULL;
    }
    else
    {
#endif
        if ((c->fd = getPtyMaster (&a, &b)) < 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);
        ptyconf.c_lflag &= ~ECHO;
        tcsetattr (c->fd, TCSANOW, &ptyconf);

        snprintf (tty, sizeof (tty), "/dev/tty%c%c", a, b);
        fd2 = open (tty, O_RDWR);
        if (fd2 < 0) {
            log (LOG_WARN, "unable to open tty %s, cannot start pppd", tty);
            return -EINVAL;
        }
	stropt[pos++] = strdup(tty);	
	stropt[pos] = NULL;
#ifdef USE_KERNEL
    }
#endif

#ifdef DEBUG_PPPD
    log (LOG_DEBUG, "%s: I'm running:  ", __FUNCTION__);
    for (x = 0; stropt[x]; x++)
    {
        log (LOG_DEBUG, "\"%s\" ", stropt[x]);
    };
    log (LOG_DEBUG, "\n");
#endif
#ifdef __uClinux__
    c->pppd = vfork ();
#else 
    c->pppd = fork ();
#endif
    if (c->pppd < 0)
    {
        log (LOG_WARN, "%s: unable to fork(), abandoning!\n", __FUNCTION__);
        return -EINVAL;
    }
    else if (!c->pppd)
    {
        /* child */

        close (0); /* redundant; the dup2() below would do that, too */
        close (1); /* ditto */
        /* close (2); No, we want to keep the connection to /dev/null. */ 

        /* connect the pty to stdin and stdout */
        dup2 (fd2, 0);
        dup2 (fd2, 1);

        /* close all the calls pty fds */
        st = tunnels.head;
        while (st)
        {
            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);

        if( c->dialing[0] )
        {
            setenv( "CALLER_ID", c->dialing, 1 );
        }
        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;
}
Ejemplo n.º 3
0
int start_pppd6 (struct call6 *c, struct ppp_opts *opts)
{
    /* char a, b; */
    char tty[512];
    char *stropt[80];
    struct ppp_opts *p;
#ifdef USE_KERNEL
    struct sockaddr_pppol2tp sax;
    int flags;
#endif
    int pos = 1;
    int fd2;
#ifdef DEBUG_PPPD
    int x;
#endif
    struct termios ptyconf;
    struct call6 *sc;
    struct tunnel6 *st;

    p = opts;
    stropt[0] = strdup (PPPD);
    while (p)
    {
        stropt[pos] = (char *) malloc (strlen (p->option) + 1);
        strncpy (stropt[pos], p->option, strlen (p->option) + 1);
        pos++;
        p = p->next;
    }
    stropt[pos] = NULL;
    if (c->pppd > 0)
    {
        l2tp_log(LOG_WARNING, "%s: PPP already started on call!\n", __FUNCTION__);
        return -EINVAL;
    }
    if (c->fd > -1)
    {
        l2tp_log (LOG_WARNING, "%s: file descriptor already assigned!\n",
             __FUNCTION__);
        return -EINVAL;
    }

#ifdef USE_KERNEL
    if (kernel_support)
    {
       fd2 = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
       if (fd2 < 0) {
           l2tp_log (LOG_WARNING, "%s: Unable to allocate PPPoL2TP socket.\n",
                __FUNCTION__);
           return -EINVAL;
       }
       flags = fcntl(fd2, F_GETFL);
       if (flags == -1 || fcntl(fd2, F_SETFL, flags | O_NONBLOCK) == -1) {
           l2tp_log (LOG_WARNING, "%s: Unable to set PPPoL2TP socket nonblock.\n",
                __FUNCTION__);
           return -EINVAL;
       }
       sax.sa_family = AF_PPPOX;
       sax.sa_protocol = PX_PROTO_OL2TP;
       sax.pppol2tp.pid = 0;
       sax.pppol2tp.fd = server_socket6;
       sax.pppol2tp.addr.sin6_addr.s6_addr = c->container->peer.sin6_addr.s6_addr;
       sax.pppol2tp.addr.sin6_port = c->container->peer.sin6_port;
       sax.pppol2tp.addr.sin6_family = AF_INET6;
       sax.pppol2tp.s_tunnel  = c->container->ourtid;
       sax.pppol2tp.s_session = c->ourcid;
       sax.pppol2tp.d_tunnel  = c->container->tid;
       sax.pppol2tp.d_session = c->cid;
       if (connect(fd2, (struct sockaddr *)&sax, sizeof(sax)) < 0) {
           l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket.\n",
                __FUNCTION__);
           return -EINVAL;
       }
       stropt[pos++] = strdup ("plugin");
       stropt[pos++] = strdup ("pppol2tp.so");
       stropt[pos++] = strdup ("pppol2tp");
       stropt[pos] = (char *) malloc (10);
       snprintf (stropt[pos], 10, "%d", fd2);
        pos++;
        stropt[pos] = NULL;
    }
    else
#endif
    {
        if ((c->fd = getPtyMaster (tty, sizeof(tty))) < 0)
        {
            l2tp_log (LOG_WARNING, "%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);
        ptyconf.c_lflag &= ~ECHO;
        tcsetattr (c->fd, TCSANOW, &ptyconf);
        if(fcntl(c->fd, F_SETFL, O_NONBLOCK)!=0) {
           l2tp_log(LOG_WARNING, "failed to set nonblock: %s\n", strerror(errno));
            return -EINVAL;
        }

        fd2 = open (tty, O_RDWR);
        if (fd2 < 0) {
            l2tp_log (LOG_WARNING, "unable to open tty %s, cannot start pppd", tty);
            return -EINVAL;
        }
        stropt[pos++] = strdup(tty);
        stropt[pos] = NULL;
    }

#ifdef DEBUG_PPPD
    l2tp_log (LOG_DEBUG, "%s: I'm running: \n", __FUNCTION__);
    for (x = 0; stropt[x]; x++)
    {
        l2tp_log (LOG_DEBUG, "\"%s\" \n", stropt[x]);
    };
#endif
#ifdef __uClinux__
    c->pppd = vfork ();
#else
    c->pppd = fork ();
#endif

    if (c->pppd < 0)
    {
        /* parent */
        l2tp_log(LOG_WARNING,"%s: unable to fork(), abandoning!\n", __FUNCTION__);
        return -EINVAL;
    }
    else if (!c->pppd)
    {
        /* child */

        close (0); /* redundant; the dup2() below would do that, too */
        close (1); /* ditto */
        /* close (2); No, we want to keep the connection to /dev/null. */
#ifdef USE_KERNEL
       if (!kernel_support)
#endif
       {

        /* connect the pty to stdin and stdout */
        dup2 (fd2, 0);
        dup2 (fd2, 1);

        /* close all the calls pty fds */
        st = tunnels6.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                close (sc->fd);
                sc = sc->next;
            }
            st = st->next;
        }
       }
//RY: start here

       	// close the UDP socket fd
       	close (server_socket6);
        /* close the control pipe fd */
        close (control_fd);
        if( c->dialing[0] )
        {
            setenv( "CALLER_ID", c->dialing, 1 );
        }
        execv (PPPD, stropt);
        l2tp_log (LOG_WARNING, "%s: Exec of %s failed!\n", __FUNCTION__, PPPD);
        _exit (1);
    }
    close (fd2);
    pos = 0;
    while (stropt[pos])
    {
        free (stropt[pos]);
        pos++;
    };
    return 0;
}
Ejemplo n.º 4
0
void death_handler (int signal)
{
    /*
       * If we get here, somebody terminated us with a kill or a control-c.
       * we call call_close on each tunnel twice to get a StopCCN out
       * for each one (we can't pause to make sure it's received.
       * Then we close the connections
     */
    struct tunnel *st, *st2;
    int sec;
    l2tp_log (LOG_INFO, "%s: Fatal signal %d received\n", __FUNCTION__, signal);
#ifdef USE_KERNEL
        if (kernel_support || signal != SIGTERM) {
#else
        if (signal != SIGTERM) {
#endif
                st = tunnels.head;
                while (st)
                {
                        st2 = st->next;
                        strcpy (st->self->errormsg, "Server closing");
                        sec = st->self->closing;
                        if (st->lac)
                                st->lac->redial = 0;
                        call_close (st->self);
                        if (!sec)
                        {
                                st->self->closing = -1;
                                call_close (st->self);
                        }
                        st = st2;
                }
        }

    /* erase pid and control files */
    unlink (gconfig.pidfile);
    unlink (gconfig.controlfile);

    free(dial_no_tmp);
    close(server_socket);
    close(control_fd);
    closelog();

    exit (1);
}

void sigterm_handler(int sig)
{
    sigterm_received = 1;
}

void sigint_handler(int sig)
{
    sigint_received = 1;
}

void sigchld_handler(int sig)
{
    sigchld_received = 1;
}

void sigusr1_handler(int sig)
{
    sigusr1_received = 1;
}

void sighup_handler(int sig)
{
    sighup_received = 1;
}

void process_signal(void)
{
    if (sigterm_received) { sigterm_received = 0; death_handler(SIGTERM); }
    if (sigint_received) { sigint_received = 0; death_handler(SIGINT); }
    if (sigchld_received) { sigchld_received = 0; child_handler(SIGCHLD); }
    if (sigusr1_received) { sigusr1_received = 0; status_handler(SIGUSR1); }
    if (sighup_received) { sighup_received = 0; null_handler(SIGHUP); }
}

int start_pppd (struct call *c, struct ppp_opts *opts)
{
    /* char a, b; */
    char tty[512];
    char *stropt[80];
    struct ppp_opts *p;
#ifdef USE_KERNEL
    struct sockaddr_pppol2tp sax;
    int flags;
#endif
    int pos = 1;
    int fd2 = -1;
#ifdef DEBUG_PPPD
    int x;
#endif
    struct termios ptyconf;
    struct call *sc;
    struct tunnel *st;

    p = opts;
    stropt[0] = strdup (PPPD);
    while (p)
    {
        stropt[pos] = (char *) malloc (strlen (p->option) + 1);
        strncpy (stropt[pos], p->option, strlen (p->option) + 1);
        pos++;
        p = p->next;
    }
    stropt[pos] = NULL;
    if (c->pppd > 0)
    {
        l2tp_log(LOG_WARNING, "%s: PPP already started on call!\n", __FUNCTION__);
        return -EINVAL;
    }
    if (c->fd > -1)
    {
        l2tp_log (LOG_WARNING, "%s: file descriptor already assigned!\n",
             __FUNCTION__);
        return -EINVAL;
    }

#ifdef USE_KERNEL
    if (kernel_support)
    {
       fd2 = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
       if (fd2 < 0) {
           l2tp_log (LOG_WARNING, "%s: Unable to allocate PPPoL2TP socket.\n",
                __FUNCTION__);
           return -EINVAL;
       }
       flags = fcntl(fd2, F_GETFL);
       if (flags == -1 || fcntl(fd2, F_SETFL, flags | O_NONBLOCK) == -1) {
           l2tp_log (LOG_WARNING, "%s: Unable to set PPPoL2TP socket nonblock.\n",
                __FUNCTION__);
           close(fd2);
           return -EINVAL;
       }
       memset(&sax, 0, sizeof(sax));
       sax.sa_family = AF_PPPOX;
       sax.sa_protocol = PX_PROTO_OL2TP;
       sax.pppol2tp.fd = c->container->udp_fd;
       sax.pppol2tp.addr.sin_addr.s_addr = c->container->peer.sin_addr.s_addr;
       sax.pppol2tp.addr.sin_port = c->container->peer.sin_port;
       sax.pppol2tp.addr.sin_family = AF_INET;
       sax.pppol2tp.s_tunnel  = c->container->ourtid;
       sax.pppol2tp.s_session = c->ourcid;
       sax.pppol2tp.d_tunnel  = c->container->tid;
       sax.pppol2tp.d_session = c->cid;
       if (connect(fd2, (struct sockaddr *)&sax, sizeof(sax)) < 0) {
           l2tp_log (LOG_WARNING, "%s: Unable to connect PPPoL2TP socket.\n",
                __FUNCTION__);
           close(fd2);
           return -EINVAL;
       }
       stropt[pos++] = strdup ("plugin");
       stropt[pos++] = strdup ("pppol2tp.so");
       stropt[pos++] = strdup ("pppol2tp");
       stropt[pos] = (char *) malloc (10);
       snprintf (stropt[pos], 10, "%d", fd2);
        pos++;
       if (c->container->lns) {
        stropt[pos++] = strdup ("pppol2tp_lns_mode");
        stropt[pos++] = strdup ("pppol2tp_tunnel_id");
        stropt[pos] = (char *) malloc (10);
        snprintf (stropt[pos], 10, "%d", c->container->ourtid);
            pos++;
        stropt[pos++] = strdup ("pppol2tp_session_id");
        stropt[pos] = (char *) malloc (10);
        snprintf (stropt[pos], 10, "%d", c->ourcid);
            pos++;
       }
        stropt[pos] = NULL;
    }
    else
#endif
    {
        if ((c->fd = getPtyMaster (tty, sizeof(tty))) < 0)
        {
            l2tp_log (LOG_WARNING, "%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);
        ptyconf.c_cflag &= ~(ICANON | ECHO);
        ptyconf.c_lflag &= ~ECHO;
        tcsetattr (c->fd, TCSANOW, &ptyconf);
        if(fcntl(c->fd, F_SETFL, O_NONBLOCK)!=0) {
           l2tp_log(LOG_WARNING, "failed to set nonblock: %s\n", strerror(errno));
            return -EINVAL;
        }

        fd2 = open (tty, O_RDWR);
        if (fd2 < 0) {
            l2tp_log (LOG_WARNING, "unable to open tty %s, cannot start pppd", tty);
            return -EINVAL;
        }
        stropt[pos++] = strdup(tty);
        stropt[pos] = NULL;
    }

#ifdef DEBUG_PPPD
    l2tp_log (LOG_DEBUG, "%s: I'm running: \n", __FUNCTION__);
    for (x = 0; stropt[x]; x++)
    {
        l2tp_log (LOG_DEBUG, "\"%s\" \n", stropt[x]);
    };
#endif
#ifdef __uClinux__
    c->pppd = vfork ();
#else 
    c->pppd = fork ();
#endif

    if (c->pppd < 0)
    {
        /* parent */
        l2tp_log(LOG_WARNING,"%s: unable to fork(), abandoning!\n", __FUNCTION__);
        close(fd2);
        return -EINVAL;
    }
    else if (!c->pppd)
    {
        /* child */

        close (0); /* redundant; the dup2() below would do that, too */
        close (1); /* ditto */
        /* close (2); No, we want to keep the connection to /dev/null. */ 
#ifdef USE_KERNEL
       if (!kernel_support)
#endif
       {

        /* connect the pty to stdin and stdout */
        dup2 (fd2, 0);
        dup2 (fd2, 1);
	close(fd2);
       }
        /* close all the calls pty fds */
        st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
#ifdef USE_KERNEL
                if (kernel_support) {
                    close(st->udp_fd); /* tunnel UDP fd */
                    close(st->pppox_fd); /* tunnel PPPoX fd */
                } else
#endif
                    close (sc->fd); /* call pty fd */
                sc = sc->next;
            }
            st = st->next;
        }

        /* close the UDP socket fd */
        if (server_socket > 0) {
            close (server_socket);
            server_socket = -1;
        }

        /* close the control pipe fd */
        if (control_fd > 0) {
            close (control_fd);
            control_fd = -1;
        }

        if( c->dialing[0] )
        {
            setenv( "CALLER_ID", c->dialing, 1 );
        }
        execv (PPPD, stropt);
        l2tp_log (LOG_WARNING, "%s: Exec of %s failed!\n", __FUNCTION__, PPPD);
        _exit (1);
    }
    close (fd2);
    pos = 0;
    while (stropt[pos])
    {
        free (stropt[pos]);
        pos++;
    };
    return 0;
}