From: Darby Weaver (ccie.weaver@gmail.com)
Date: Fri Jan 23 2009 - 05:07:02 ARST
If you really need something that's quick and clean and does the job - is
free less your own blood sweat and tears...
Why not try: CNCT
It's been around since the day of the dog, but hey - simple, fast, and
efficient is a good thing in scripting and it is well documented:
/*
* Program to connect to the telnet port of a Cisco router or terminal
* server, log in, run a series of commands contained in a command file,
* and log out. The session is displayed to stdout.
*
* Usage: cnct [-l] [-p <pw1>] [-e [<epw>]] [-c <cmd-file>] [--] <host>
*
* The command-line arguments are:
*
* host - the host name of the router or terminal server (required).
* -l - if -l is specified then pw1 and epw are interpreted
* as username and password respectively.
*
* pw1 - the first-level password for the router. If this argument
* is not specified, the connection to the Cisco will fail
* if a "Password:" prompt is received.
*
* epw - the "enable" password for the router. If the "-e" option
* is specified, the "enable" command will be issued after
* successful login (using the password specified with the "-p"
* option if appropriate). If a "Password:" prompt is received
* in response to the "enable" command and the "<epw>" argument
* is not specified, the connection will fail.
*
* cmd-file - the file containing the list of Cisco commands that
* will be executed after successful login (possibly at the
* "enable" level). The command "terminal length 0" is
* automatically entered if either or both of the "-p" and
* "-e" options are specified, and need not be included in the
* command file. This argument is optional. If not specified,
* commands will be read from stdin. The "exit" command is
* automatically issued to close the connection if EOF is
* encountered when reading the command file or stdin.
*
* -- - Two consecutive hyphens indicates the end of the options
* list. This allows the "-e" option to be specified without
* a corresponding password so that enable mode can be entered
* even if there is no enable password.
*
* For simplicity, the above arguments are used to build an initial login
* command sequence that is sent to the Cisco without any attempt to parse
* or otherwise interpret the response text from the Cisco. Thus, assuming
* both the "-p" and "-e" options are specified, this is the command sequence
* that will be sent to the Cisco:
*
* pw1
* enable
* epw
* terminal length 0
*
* Assuming the above commands are successful, the contents of the command
* file are sent to the Cisco, followed by an "exit" command. The program
* then copies output from the Cisco to stdout until the Cisco closes the
* connection, and then terminates. The exit status is two ("2") if the
* connection times out, one ("1") if there are other problems, and zero
* ("0") otherwise.
*
*
* Written by: Dana J. Dawson
* Sr. Network Analyst
* Corporate Computing & Networks
* Cray Research, Inc.
* (612) 683-3056
* dana@cray.com
* March, 1993
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
void usage(name)
char *name;
{
fprintf(stderr,
"USAGE: %s [-l] [-p <pw1>] [-e [<epw>]] [-c <cmd-file>] [--] <host>\n",
name);
exit(1);
}
main(argc, argv)
int argc;
char **argv;
{
int c; /* temporary work variable */
int n; /* temporary work variable */
int enable = 0; /* flag for 'enable' mode */
char *me = *argv; /* name of this executable */
int user = 0; /* non-zero if user/passwd scenario */
char *pw1 = NULL; /* first-level password string */
char *epw = NULL; /* enable password string */
char *cmdfile = NULL; /* name of command file */
char *host = NULL; /* host name or IP address string */
int nc; /* number of characters in "cmds" */
char cmds[BUFSIZ]; /* buffer for initial login commands */
char buf[BUFSIZ]; /* buffer for copying data and error messages */
int s; /* file descriptor for socket */
int cf = 0; /* file descriptor for input command file */
int ceof = 0; /* EOF indicator for input command file */
fd_set readset; /* read mask for "select()" */
int dport = 23; /* destination port - "telnet" */
unsigned long ipaddr; /* 32-bit numeric IP address of 'host' */
struct hostent *hp; /* host information structure for 'host' */
struct sockaddr_in dsa; /* socket address structure */
struct timeval timeout; /* connection timeout structure */
/* First, figure out the command line arguments... */
/* It's not pretty, but it works (besides, I'm new at this) */
while (--argc > 0) {
switch (c = **++argv) {
case '-':
if (host != NULL) usage(me);
switch (c = *++*argv) {
case '-':
if (host != NULL || !--argc || *++*argv) usage(me);
host = *++argv;
break;
case 'l':
if (user) usage(me);
user = 1;
break;
case 'p':
if (pw1 != NULL || !--argc || *++*argv) usage(me);
pw1 = *++argv;
break;
case 'e':
if (enable || !--argc || *++*argv) usage(me);
enable = 1;
epw = *++argv;
if (!strcmp(epw, "--") ||
!strcmp(epw, "-c") ||
!strcmp(epw, "-p") ) {
epw = NULL;
argc++;
argv--;
}
break;
case 'c':
if (cmdfile != NULL || !--argc || *++*argv) usage(me);
cmdfile = *++argv;
break;
default:
usage(me);
break;
}
break;
default:
if (host != NULL || --argc ) usage(me);
host = *argv;
break;
}
}
if (host == NULL) usage(me);
if (user && (!pw1 || !epw)) usage(me);
/* Now, open the input command file if it's not 'stdin'... */
if ((cmdfile != NULL) && ((cf = open(cmdfile, O_RDONLY, 0)) == -1)) {
sprintf(buf, "%s: Error opening command file for '%s'", me, host);
perror(buf);
exit(1);
}
/* Figure out the IP address for 'host' and open the socket... */
bzero((char *)&dsa, sizeof(dsa));
if ((ipaddr = inet_addr(host)) == -1) { /* 'host' is not an IP address */
if ((hp = gethostbyname(host)) == NULL) {
sprintf(buf, "%s: Unknown host for '%s'", me, host);
perror(buf);
exit(1);
}
bcopy((char *)*hp->h_addr_list, (char *)&dsa.sin_addr.s_addr, hp->h_length);
} else { /* 'host' was an IP address */
dsa.sin_addr.s_addr = ipaddr;
}
dsa.sin_family = AF_INET;
dsa.sin_port = htons(dport);
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
sprintf(buf, "%s: Error opening socket for '%s'", me, host);
perror(buf);
exit(1);
}
if (connect(s, &dsa, sizeof(dsa)) == -1) {
sprintf(buf, "%s: Error connecting to socket for '%s'", me, host);
perror(buf);
exit(1);
}
/* Build the login command sequence... */
nc = 0;
if (user) {
nc += strlen(sprintf(&cmds[nc], "%s\n", pw1));
nc += strlen(sprintf(&cmds[nc], "%s\n", epw));
nc += strlen(sprintf(&cmds[nc], "login\n"));
nc += strlen(sprintf(&cmds[nc], "%s\n", pw1));
nc += strlen(sprintf(&cmds[nc], "%s\n", epw));
} else {
if (pw1 != NULL) {
nc += strlen(sprintf(&cmds[nc], "%s\n", pw1));
}
if (enable) {
nc += strlen(sprintf(&cmds[nc], "enable\n"));
}
if (epw != NULL) {
nc += strlen(sprintf(&cmds[nc], "%s\n", epw));
}
}
if (nc) {
nc += strlen(sprintf(&cmds[nc], "terminal length 0\n\0"));
}
/* Now start reading and writing as necessary... */
for (;;) {
timeout.tv_sec = 60; /* timeout the connection after 1 minute */
timeout.tv_usec = 0;
FD_ZERO(&readset);
FD_SET(s, &readset);
if (!ceof) FD_SET(cf, &readset);
switch (select(FD_SETSIZE, &readset, (fd_set *)NULL,
(fd_set *)NULL, &timeout)) {
case -1:
sprintf(buf, "%s: Error selecting input for '%s'", me, host);
perror(buf);
exit(1);
break;
case 0:
sprintf(buf, "%s: Connection timed out for '%s'", me, host);
perror(buf);
exit(2);
break;
default:
break;
}
if (FD_ISSET(s, &readset)) {
switch (n = read(s, buf, BUFSIZ)) {
case -1:
sprintf(buf, "%s: Error reading socket for '%s'", me, host);
perror(buf);
exit(1);
case 0:
exit(0);
default:
write(1, buf, n);
break;
}
}
if (nc) {
if (write(s, cmds, nc) == -1) {
sprintf(buf, "%s: Error writing to socket for '%s'", me, host);
perror(buf);
exit(1);
}
nc = 0;
} else if (FD_ISSET(cf, &readset)) {
switch (n = read(cf, buf, 1)) {
case -1:
sprintf(buf, "%s: Error reading command file for
'%s'", me, host);
perror(buf);
exit(1);
case 0:
ceof = 1;
if (write(s, "exit\n", 5) == -1) {
sprintf(buf, "%s: Error writing to socket for
'%s'", me, host);
perror(buf);
exit(1);
}
break;
default:
if (write(s, buf, 1) == -1) {
sprintf(buf, "%s: Error writing to socket for
'%s'", me, host);
perror(buf);
exit(1);
}
break;
}
}
}
}
Blogs and organic groups at http://www.ccie.net
This archive was generated by hypermail 2.1.4 : Sun Mar 01 2009 - 09:43:39 ARST