/********************************************************************** * %FUNCTION: cmd_start_session * %ARGUMENTS: * es -- event selector * fd -- command file descriptor * buf -- rest of command from user * %RETURNS: * Nothing * %DESCRIPTION: * Starts an L2TP session, if possible ***********************************************************************/ static void cmd_start_session(EventSelector *es, int fd, char *buf) { char peer[512]; struct hostent *he; struct sockaddr_in haddr; l2tp_peer *p; l2tp_session *sess; buf = (char *) l2tp_chomp_word(buf, peer); he = gethostbyname(peer); if (!he) { cmd_reply(es, fd, "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) { cmd_reply(es, fd, "ERR Unknown peer"); return; } sess = l2tp_session_call_lns(p, "foobar", es, NULL); if (!sess) { cmd_reply(es, fd, l2tp_get_errmsg()); return; } /* Form reply */ sprintf(peer, "OK %d %d", (int) sess->tunnel->my_id, (int) sess->my_id); cmd_reply(es, fd, peer); }
/********************************************************************** * %FUNCTION: cmd_stop_session * %ARGUMENTS: * es -- event selector * fd -- command file descriptor * buf -- rest of command from user * %RETURNS: * Nothing * %DESCRIPTION: * Stops an L2TP session, identified by (Tunnel, Session) pair. ***********************************************************************/ static void cmd_stop_session(EventSelector *es, int fd, char *buf) { char junk[512]; l2tp_tunnel *tunnel; l2tp_session *sess; unsigned int x; buf = (char *) l2tp_chomp_word(buf, junk); if (sscanf(junk, "%u", &x) != 1) { cmd_reply(es, fd, "ERR Syntax error: stop-session tid sid"); return; } tunnel = l2tp_tunnel_find_by_my_id((uint16_t) x); if (!tunnel) { cmd_reply(es, fd, "ERR No such tunnel"); return; } buf = (char *) l2tp_chomp_word(buf, junk); if (sscanf(junk, "%u", &x) != 1) { cmd_reply(es, fd, "ERR Syntax error: stop-session tid sid"); return; } sess = l2tp_tunnel_find_session(tunnel, (uint16_t) x); if (!sess) { cmd_reply(es, fd, "ERR No such session"); return; } /* Stop the session */ l2tp_session_send_CDN(sess, RESULT_GENERAL_REQUEST, ERROR_OK, "Call terminated by operator"); cmd_reply(es, fd, "OK Session stopped"); }
/********************************************************************** * %FUNCTION: handle_lns_option * %ARGUMENTS: * es -- event selector * desc -- descriptor * value -- the hostname * %RETURNS: * 0 * %DESCRIPTION: * Copies LNS options to prototype ***********************************************************************/ static int handle_lns_option(EventSelector *es, l2tp_opt_descriptor *desc, char const *value) { char word[512]; while (value && *value) { value = l2tp_chomp_word(value, word); if (!word[0]) break; if (prototype.num_lns_options < MAX_OPTS) { char *x = strdup(word); if (x) prototype.lns_options[prototype.num_lns_options++] = x; prototype.lns_options[prototype.num_lns_options] = NULL; } else { break; } } return 0; }
/********************************************************************** * %FUNCTION: cmd_handler * %ARGUMENTS: * es -- event selector * fd -- file descriptor * buf -- buffer which was read * len -- length of data * flag -- flags * data -- not used * %RETURNS: * Nothing * %DESCRIPTION: * Processes a command from the user ***********************************************************************/ static void cmd_handler(EventSelector *es, int fd, char *buf, int len, int flag, void *data) { char word[512]; if (flag == EVENT_TCP_FLAG_IOERROR || flag == EVENT_TCP_FLAG_TIMEOUT) { close(fd); return; } if (len < 511) { buf[len+1] = 0; } else { buf[len] = 0; } /* Chop off newline */ if (len && (buf[len-1] == '\n')) { buf[len-1] = 0; } /* Get first word */ buf = (char *) l2tp_chomp_word(buf, word); if (!strcmp(word, "exit")) { cmd_exit(es, fd); } else if (!strcmp(word, "start-session")) { cmd_start_session(es, fd, buf); } else if (!strcmp(word, "stop-session")) { cmd_stop_session(es, fd, buf); } else if (!strcmp(word, "dump-sessions")) { cmd_dump_sessions(es, fd, buf); } else { cmd_reply(es, fd, "ERR Unknown command"); } }
/********************************************************************** * %FUNCTION: split_line_into_words * %ARGUMENTS: * line -- the input line * name, value -- buffers which are large enough to contain all chars in line * %RETURNS: * Nothing * %DESCRIPTION: * Splits line into two words. A word is: * - Non-whitespace chars: foobarbazblech_3 * - Quoted text: "Here is text \"with embedded quotes\"" ***********************************************************************/ static void split_line_into_words(char const *line, char *name, char *value) { line = l2tp_chomp_word(line, name); line = l2tp_chomp_word(line, value); }