Esempio n. 1
0
void do_control6 ()
{
    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 lac6 *lac;
    int call;
    int tunl;
    int cnt = -1;
    int done = 0;

    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_call6 (host, UDP_LISTEN_PORT, NULL, NULL);
            break;
        case 'c':
            switch_io = 1;  /* jz: Switch for Incoming - Outgoing Calls */

            tunstr = strtok (&buf[1], delims);
            authname = strtok (NULL, delims);
            password = strtok (NULL, delims);

            lac = laclist6;
            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_dial6 (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_call6 (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 = laclist6;
            while (lac && strcasecmp (lac->entname, tunstr)!=0)
            {
                lac = lac->next;
            }

            if(lac) {
                lac->active = -1;
                lac->rtries = 0;
                if (!lac->c)
                    magic_lac_dial6 (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_call6 (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_hangup6 (call);
            break;

        case 'd':
            tunstr = strchr (buf, ' ') + 1;
            lac = laclist6;
            while (lac)
            {
                if (!strcasecmp (lac->entname, tunstr))
                {
                    lac->active = 0;
                    lac->rtries = 0;
                    if (lac->t)
                        lac_disconnect6 (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_disconnect6 (tunl);
            break;
        case 's':
            show_status6();
            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();
}
Esempio n. 2
0
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();
}
Esempio n. 3
0
void init6(int argc, char *argv[])
{
	struct lac6 *lac;
//    struct in6_addr listenaddr;
    struct utsname uts;
//    char ipaddr[16];
//    char ipaddrStr[INET6_ADDRSTRLEN];
    init_args (argc,argv);
    srand( time(NULL) );
    rand_source = 0;
    //RY: required only when IP_ALLOCATION is defined
	//init_addr ();

	if (init_config6 ())
	{
		l2tp_log (LOG_CRIT, "%s: Unable to load config file\n", __FUNCTION__);
		exit (1);
	}

	//inet_pton(AF_INET6, "1002:0:0:0:0:0:12", gconfig.ipaddr.listenaddr6);
//	inet_pton(AF_INET6, "2001::12", gconfig.ipaddr.listenaddr6);
//	inet_ntop(AF_INET6, gconfig.ipaddr.listenaddr6, ipaddrStr, sizeof(ipaddrStr));
	if (uname (&uts)<0)
	{
		l2tp_log (LOG_CRIT, "%s : Unable to determine host system\n",
			__FUNCTION__);
		exit (1);
	}
    init_tunnel_list6 (&tunnels6);
    if (init_network ())
        exit (1);

    if (gconfig.daemon)
//        daemonize (); //RY: commented for debugging

    consider_pidfile();

    signal (SIGTERM, &death_handler6);
    signal (SIGINT, &death_handler6);
    signal (SIGCHLD, &child_handler6);
    signal (SIGUSR1, &status_handler6);
    signal (SIGHUP, &null_handler);
    init_scheduler ();

    unlink(gconfig.controlfile);
    mkfifo (gconfig.controlfile, 0600);

    open_controlfd();
    /*l2tp_log (LOG_INFO, "xl2tpd version " SERVER_VERSION " started on %s PID:%d\n",
         hostname, getpid ());*/
    printf( "xl2tpd version " SERVER_VERSION " started on %s PID:%d\n",
         hostname, getpid ());
    printf(
         "Written by Mark Spencer, Copyright (C) 1998, Adtran, Inc.\n");
    printf( "Forked by Scott Balmos and David Stipp, (C) 2001\n");
    printf( "Inherited by Jeff McAdams, (C) 2002\n");
    printf( "Forked again by Xelerance (www.xelerance.com) (C) 2006\n");

    printf( "Listening on IP address %s, port %d\n", IPADDY6(gconfig.ipaddr.listenaddr6)
              , gconfig.port);	//printing IP addr on screen
    lac = laclist6;
    while (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_dial6 (lac);
        }
        lac = lac->next;
    }
}
Esempio n. 4
0
void init (int argc,char *argv[])
{
    struct lac *lac;
    struct in_addr listenaddr;
    struct utsname uts;

    init_args (argc,argv);
    srand( time(NULL) );
    rand_source = 0;
    init_addr ();
    if (init_config ())
    {
        l2tp_log (LOG_CRIT, "%s: Unable to load config file\n", __FUNCTION__);
        exit (1);
    }
    if (uname (&uts)<0)
    {
        l2tp_log (LOG_CRIT, "%s : Unable to determine host system\n",
             __FUNCTION__);
        exit (1);
    }
    init_tunnel_list (&tunnels);
    if (init_network ())
        exit (1);

    if (gconfig.daemon)
        daemonize ();

    consider_pidfile();

    signal (SIGTERM, &sigterm_handler);
    signal (SIGINT, &sigint_handler);
    signal (SIGCHLD, &sigchld_handler);
    signal (SIGUSR1, &sigusr1_handler);
    signal (SIGHUP, &sighup_handler);
    init_scheduler ();

    unlink(gconfig.controlfile);
    mkfifo (gconfig.controlfile, 0600);

    open_controlfd();

    l2tp_log (LOG_INFO, "xl2tpd version " SERVER_VERSION " started on %s PID:%d\n",
         hostname, getpid ());
    l2tp_log (LOG_INFO,
         "Written by Mark Spencer, Copyright (C) 1998, Adtran, Inc.\n");
    l2tp_log (LOG_INFO, "Forked by Scott Balmos and David Stipp, (C) 2001\n");
    l2tp_log (LOG_INFO, "Inherited by Jeff McAdams, (C) 2002\n");
    l2tp_log (LOG_INFO, "Forked again by Xelerance (www.xelerance.com) (C) 2006\n");
    listenaddr.s_addr = gconfig.listenaddr;
    l2tp_log (LOG_INFO, "Listening on IP address %s, port %d\n",
              inet_ntoa(listenaddr), gconfig.port);
    lac = laclist;
    while (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);
        }
        lac = lac->next;
    }
}