diff -r -U3 rp-l2tp-0.4/handlers/cmd.c rp-l2tp-0.4+client/handlers/cmd.c --- rp-l2tp-0.4/handlers/cmd.c 2004-07-01 15:58:56.000000000 +0100 +++ rp-l2tp-0.4+client/handlers/cmd.c 2009-12-02 12:48:08.000000000 +0000 @@ -160,6 +160,8 @@ return l2tp_option_set(es, name, value, my_opts); } + if (Settings.client) return 0; + /* We have hit the end of our options. Open command socket */ if (!sockname) { sockname = "/var/run/l2tpctrl"; diff -r -U3 rp-l2tp-0.4/l2tp.h rp-l2tp-0.4+client/l2tp.h --- rp-l2tp-0.4/l2tp.h 2004-07-01 15:58:55.000000000 +0100 +++ rp-l2tp-0.4+client/l2tp.h 2009-12-02 12:46:29.000000000 +0000 @@ -192,6 +192,7 @@ typedef struct l2tp_settings_t { int listen_port; /* Port we listen on */ struct in_addr listen_addr; /* IP to bind to */ + int client; /* client mode */ } l2tp_settings; extern l2tp_settings Settings; @@ -472,7 +473,7 @@ /* options.c */ int l2tp_parse_config_file(EventSelector *es, - char const *fname); + char const *fname, int client); int l2tp_option_set(EventSelector *es, char const *name, char const *value, diff -r -U3 rp-l2tp-0.4/main.c rp-l2tp-0.4+client/main.c --- rp-l2tp-0.4/main.c 2002-09-30 20:45:00.000000000 +0100 +++ rp-l2tp-0.4+client/main.c 2009-12-02 12:57:11.000000000 +0000 @@ -23,6 +23,9 @@ #include #include #include +#include + +static void cmd_start_session(EventSelector *es, char *buf); static void usage(int argc, char *argv[], int exitcode) @@ -31,6 +34,7 @@ fprintf(stderr, "http://www.roaringpenguin.com/\n\n"); fprintf(stderr, "Usage: %s [options]\n", argv[0]); fprintf(stderr, "Options:\n"); + fprintf(stderr, "-c peer -- Start a client session with 'peer'\n"); fprintf(stderr, "-d level -- Set debugging to 'level'\n"); fprintf(stderr, "-f -- Do not fork\n"); fprintf(stderr, "-h -- Print usage\n"); @@ -46,8 +50,9 @@ int opt; int do_fork = 1; int debugmask = 0; + char *client = NULL; - while((opt = getopt(argc, argv, "d:fh")) != -1) { + while((opt = getopt(argc, argv, "c:d:fh")) != -1) { switch(opt) { case 'h': usage(argc, argv, EXIT_SUCCESS); @@ -58,6 +63,9 @@ case 'd': sscanf(optarg, "%d", &debugmask); break; + case 'c': + client = optarg; + break; default: usage(argc, argv, EXIT_FAILURE); } @@ -68,7 +76,7 @@ l2tp_peer_init(); l2tp_debug_set_bitmask(debugmask); - if (l2tp_parse_config_file(es, "/etc/l2tp/l2tp.conf") < 0) { + if (l2tp_parse_config_file(es, "/etc/l2tp/l2tp.conf", client != NULL) < 0) { l2tp_die(); } @@ -76,6 +84,9 @@ l2tp_die(); } + if (client != NULL) + cmd_start_session(es, client); + /* Daemonize */ if (do_fork) { i = fork(); @@ -119,6 +130,51 @@ l2tp_cleanup(); exit(EXIT_FAILURE); } + if (client != NULL && l2tp_num_tunnels() <= 0) { + l2tp_db(0, "%s", "auto-shutdown"); + l2tp_cleanup(); + exit(EXIT_SUCCESS); + } } return 0; } + +static void +cmd_start_session(EventSelector *es, char *buf) +{ + char peer[512]; + struct hostent *he; + struct sockaddr_in haddr; + l2tp_peer *p; + l2tp_session *sess; + + l2tp_db(0, "auto-starting session to %s", buf); + + buf = (char *) l2tp_chomp_word(buf, peer); + he = gethostbyname(peer); + if (!he) { + printf("%s\n", "ERR Unknown peer - gethostbyname failed"); + l2tp_db(0, "%s", "ERR Unknown peer - gethostbyname failed"); + return; + } + memcpy(&haddr.sin_addr, he->h_addr, sizeof(haddr.sin_addr)); + p = l2tp_peer_find(&haddr, NULL); + if (!p) { + printf("%s\n", "ERR Unknown peer"); + l2tp_db(0, "%s", "ERR Unknown peer"); + return; + } + sess = l2tp_session_call_lns(p, "foobar", es, NULL); + if (!sess) { + printf("%s\n", l2tp_get_errmsg()); + l2tp_db(0, "%s", l2tp_get_errmsg()); + return; + } + + /* Form reply */ + sprintf(peer, "OK %d %d", + (int) sess->tunnel->my_id, + (int) sess->my_id); + printf("%s\n", peer); + l2tp_db(0, "%s", peer); +} diff -r -U3 rp-l2tp-0.4/network.c rp-l2tp-0.4+client/network.c --- rp-l2tp-0.4/network.c 2003-06-11 03:17:17.000000000 +0100 +++ rp-l2tp-0.4+client/network.c 2009-12-02 12:37:56.000000000 +0000 @@ -86,8 +86,13 @@ } me.sin_family = AF_INET; - me.sin_addr = Settings.listen_addr; - me.sin_port = htons((uint16_t) Settings.listen_port); + if (Settings.client) { + me.sin_addr.s_addr = htonl(INADDR_ANY); + me.sin_port = htons(0); + } else { + me.sin_addr = Settings.listen_addr; + me.sin_port = htons((uint16_t) Settings.listen_port); + } if (bind(Sock, (struct sockaddr *) &me, sizeof(me)) < 0) { l2tp_set_errmsg("network_init: bind: %s", strerror(errno)); close(Sock); diff -r -U3 rp-l2tp-0.4/options.c rp-l2tp-0.4+client/options.c --- rp-l2tp-0.4/options.c 2003-06-11 03:16:34.000000000 +0100 +++ rp-l2tp-0.4+client/options.c 2009-12-02 12:45:37.000000000 +0000 @@ -340,7 +340,7 @@ ***********************************************************************/ int l2tp_parse_config_file(EventSelector *es, - char const *fname) + char const *fname, int client) { char buf[512]; char name[512]; @@ -353,6 +353,7 @@ /* Defaults */ Settings.listen_port = 1701; Settings.listen_addr.s_addr = htonl(INADDR_ANY); + Settings.client = client; fp = fopen(fname, "r"); if (!fp) {