/********************************************************************** * %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_dump_sessions * %ARGUMENTS: * es -- event selector * fd -- command file descriptor * buf -- rest of command from user * %RETURNS: * Nothing * %DESCRIPTION: * Dumps info about all currently-active tunnels and sessions ***********************************************************************/ static void cmd_dump_sessions(EventSelector *es, int fd, char *buf) { dynstring str; char tmp[256]; void *cursor; char const *ans; l2tp_tunnel *tunnel; dynstring_init(&str); dynstring_append(&str, "OK\n"); /* Print info about each tunnel */ sprintf(tmp, "NumL2TPTunnels %d\n", l2tp_num_tunnels()); dynstring_append(&str, tmp); for (tunnel = l2tp_first_tunnel(&cursor); tunnel; tunnel = l2tp_next_tunnel(&cursor)) { describe_tunnel(tunnel, &str); } /* If something went wrong, say so... */ ans = dynstring_data(&str); if (!ans) { cmd_reply(es, fd, "ERR Out of memory"); return; } cmd_reply(es, fd, ans); dynstring_free(&str); }
/********************************************************************** * %FUNCTION: cmd_exit * %ARGUMENTS: * es -- Event selector * fd -- command file descriptor * %RETURNS: * Nothing * %DESCRIPTION: * Tears down tunnels and quits ***********************************************************************/ static void cmd_exit(EventSelector *es, int fd) { cmd_reply(es, fd, "OK Shutting down"); l2tp_tunnel_stop_all("Stopped by system administrator"); l2tp_cleanup(); exit(0); }
/********************************************************************** * %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"); }
static u08 cmd_flags(const u08 *cmd, u08 len) { console_t *c = console_get_current(); if(len>3) { return CMD_SYNTAX_ERR; } // read flags value if(len == 1) { cmd_reply('s', c->flags); return CMD_NO_REPLY; } else { // try to parse value u08 flags = c->flags; if(len == 2) { switch(cmd[1]) { case 'x': flags = (flags & ~FLAGS_FONT_2Y) | FLAGS_FONT_2X; break; case 'y': flags = (flags & ~FLAGS_FONT_2X) | FLAGS_FONT_2Y; break; case 'b': flags |= FLAGS_FONT_2XY; break; case 'n': flags &= ~FLAGS_FONT_2XY; break; case 'A': flags = (flags & ~FLAGS_FONT_CHARSET_MASK) | 0 << (FLAGS_FONT_CHARSET_SHIFT); break; case 'B': flags = (flags & ~FLAGS_FONT_CHARSET_MASK) | 1 << (FLAGS_FONT_CHARSET_SHIFT); break; } } else { if(!parse_byte(cmd+1,&flags)) { return CMD_NO_BYTE; } } c->flags = flags; } return CMD_OK; }
/********************************************************************** * %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"); } }
static u08 cmd_color(const u08 *cmd, u08 len) { if(len>3) { return CMD_SYNTAX_ERR; } console_t *c = console_get_current(); // read color value if(len == 1) { cmd_reply('c', c->color); return CMD_NO_REPLY; } else { u08 color; if(len == 2) { /* set foreground color */ if(!parse_nybble(cmd[1], &color)) { return CMD_NO_NYBBLE; } c->color = (color << 4) | (c->color & 0xf); } else { /* set both colors */ if(cmd[1] != '-') { if(!parse_byte(cmd+1, &color)) { return CMD_NO_BYTE; } c->color = color; } else { /* set background color */ if(!parse_nybble(cmd[2], &color)) { return CMD_NO_NYBBLE; } c->color = (c->color & 0xf0) | color; } } } return CMD_OK; }