working out the protocol between a Nokia 9000i and NServer.
Written by Jonathan McDowell for Project Purple, 1999
Extra stuff by Cornelius Cook (cook@cpoint.net), 1999
+ OSX support and EOF support by Pete Baker (peteb4ker@gmail.com), 2011
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
07/09/1999 - Started writing.
21Nov1999 - Cook: added command line support and extra error checking
27Nov1999 - Cook: added select, timer & changed output look
+ 24Jun2011 - Baker: Added OSX support. Added EOF character support
*/
-#define VERSION "0.0.3"
+#define VERSION "0.0.5"
#include <stdio.h>
#include <string.h>
speed_t speed_num[] = { B300, B1200, B2400, B4800, B9600, B19200, B38400,
B57600, B115200, B230400, B0 };
-int openport(const char *device, speed_t baud)
+int openport(const char *device, speed_t baud, int setup)
{
int filedes;
struct termios serparams;
exit(1);
}
- bzero(&serparams, sizeof(serparams));
-
- serparams.c_cflag=baud | CLOCAL | CS8 | CREAD;
+ if (setup) {
+ bzero(&serparams, sizeof(serparams));
- if (tcflush(filedes, TCIFLUSH)) {
- fprintf(stderr,"%s: ",device);
- perror("tcflush");
- exit(1);
- }
- if (tcsetattr(filedes, TCSANOW, &serparams)) {
- fprintf(stderr,"%s: ",device);
- perror("tcsetattr");
- exit(1);
+ cfsetspeed(&serparams, baud);
+ serparams.c_cflag |= CLOCAL | CS8 | CREAD;
+
+ if (tcflush(filedes, TCIFLUSH)) {
+ fprintf(stderr,"%s: ",device);
+ perror("tcflush");
+ exit(1);
+ }
+ if (tcsetattr(filedes, TCSANOW, &serparams)) {
+ fprintf(stderr,"%s: ",device);
+ perror("tcsetattr");
+ exit(1);
+ }
}
return filedes;
this returns the string for the character passed to it
It could be expanded in the future to maybe to string recognitions?
*/
-char *chardecide(unsigned char c, int alpha) {
+char *chardecide(unsigned char c, int alpha, char *format) {
static char result[256];
/* everyone should take up 5 characters */
snprintf(result,256,"%c",c);
}
} else {
- snprintf(result,256,"0x%02hX ",c);
+ snprintf(result,256,format,c);
}
return result;
}
void outputchar(unsigned char c, int port, int alpha,
- long usec_threshold, long usec_waited)
+ long usec_threshold, long usec_waited, char *name1, char *name2, char *format)
{
char *todisplay;
- todisplay=chardecide(c,alpha);
- disp_outputstr(port, todisplay, usec_threshold, usec_waited);
+ todisplay=chardecide(c,alpha,format);
+ disp_outputstr(port, todisplay, usec_threshold, usec_waited, name1, name2);
}
-void mainloop(int port1, int port2, int silent, int alpha, long usec_threshold)
+void mainloop(int port1, int port2, int silent, int alpha, int quit_on_eof, long usec_threshold, char *name1, char *name2, char *format)
{
unsigned char c1, c2;
- int last;
int rc;
fd_set rfds;
fd_set efds;
/* need the largest fd for the select call */
biggestfd=port1 > port2 ? port1 : port2;
biggestfd++;
- last=0;
while (!quit) {
/* reset the select set */
if (FD_ISSET(port1, &rfds)) {
for (rc=read(port1, &c1, 1);
rc>0; rc=read(port1, &c1, 1) ) {
- outputchar(c1,1,alpha,usec_threshold,timediff);
+ outputchar(c1,1,alpha,usec_threshold,timediff,name1,name2,format);
timediff=0;
if (!silent) write(port2,&c1,1);
}
- if (rc==0) {
+ if (rc==0 && quit_on_eof==1) {
/* EOF? */
quit=1;
}
if (FD_ISSET(port2, &rfds)) {
for (rc=read(port2, &c2, 1);
rc>0; rc=read(port2, &c2, 1) ) {
- outputchar(c2,2,alpha,usec_threshold,timediff);
+ outputchar(c2,2,alpha,usec_threshold,timediff,name1,name2,format);
timediff=0;
if (!silent) write(port1,&c2,1);
}
- if (rc==0) {
+ if (rc==0 && quit_on_eof==1) {
/* EOF? */
quit=1;
}
void usage()
{
- fprintf(stderr,"sersniff v%s
-
-Usage:
-sersniff [-h] [-i DEV | -l PORT] [-o DEV | -c HOST:PORT] [-b BAUD] [-w USEC]
--h This help
--x Show hex characters instead of alpha
--i DEVICE Port 1 device (defaults to /dev/ttyS0)
--l PORT Port 1 port for TCP
--o DEVICE Port 2 device (defaults to /dev/ttyS1)
--c HOST:PORT Port 2 host & port to connect to
--b BAUD Baud rate (Defaults to 19200)
--w USECS How many microsecs to wait before reporting a delay
- (default is %d)
--s Silent - don't pass data from port1 <=> port2,
- just display what we see from them.
-",VERSION,USEC);
+ fprintf(stderr,"sersniff v%s\n"
+
+"Usage:\n"
+"sersniff [-h] [-i DEV | -l PORT] [-o DEV | -c HOST:PORT] [-b BAUD] [-w USEC]\n"
+"-h This help\n"
+"-x Show hex characters instead of alpha\n"
+"-f PRINTF_OPTS printf style options for printing hex characters\n"
+" when '-x' switch is given (default \"<%%02hX>\")\n"
+"-i DEVICE Port 1 device (defaults to /dev/ttyS0). Use host:port for\n"
+" TCP.\n"
+"-1 PORT1_NAME Port 1 name to be printed (defaults to 'Port1')\n"
+"-o DEVICE Port 2 device (defaults to /dev/ttyS1). Use :port for TCP.\n"
+"-2 PORT2_NAME Port 2 name to be printed (defaults to 'Port2')\n"
+"-b BAUD Baud rate (Defaults to 19200)\n"
+"-n No port configuration (do not set BAUD or change settings)\n"
+"-w USECS How many microsecs to wait before reporting a delay\n"
+" (default is %d)\n"
+"-s Silent - don't pass data from port1 <=> port2,\n"
+" just display what we see from them.\n"
+"-z Don't quit when an EOF character is received.\n"
+,VERSION,USEC);
exit(1);
}
int port1, port2;
char *dev1=NULL;
char *dev2=NULL;
+ char *name1=NULL;
+ char *name2=NULL;
int listenport=0;
int connectport;
char *connecthost=NULL, *tmpchr=NULL;
speed_t baud=B0;
int silent=0;
long usec_threshold=USEC;
+ int setup_port=1;
+ int quit_on_eof=1;
+ char *format=NULL;
- while ((optret=getopt(argc,argv,"hxsi:l:o:c:b:w:"))!=EOF) {
+ while ((optret=getopt(argc,argv,"hxsnzi:l:o:c:b:w:1:2:f:"))!=EOF) {
switch (optret) {
case '?': case 'h': case ':':
usage();
usec_threshold=atoi(optarg);
break;
case 'i':
- dev1=strdup(optarg);
+ if ((tmpchr=strchr(optarg, ':'))!=NULL &&
+ (strchr(optarg, '/')==NULL)) {
+ *tmpchr='\0';
+ listenport=atoi(++tmpchr);
+ } else {
+ dev1=strdup(optarg);
+ }
break;
case 'o':
- dev2=strdup(optarg);
- break;
- case 'l':
- listenport=atoi(optarg);
- break;
- case 'c':
- if ((tmpchr=strchr(optarg, ':'))==NULL) {
- printf("Must specify -c option with host:port\n");
- exit(1);
+ if ((tmpchr=strchr(optarg, ':'))!=NULL &&
+ (strchr(optarg, '/')==NULL)) {
+ *tmpchr='\0';
+ connectport=atoi(++tmpchr);
+ connecthost=strdup(optarg);
+ } else {
+ dev2=strdup(optarg);
}
- *tmpchr='\0';
- connectport=atoi(++tmpchr);
- connecthost=strdup(optarg);
break;
case 'x':
show_alpha=0;
exit(1);
}
break;
+ case 'n':
+ setup_port=0;
+ break;
+ case '1':
+ name1=strdup(optarg);
+ break;
+ case '2':
+ name2=strdup(optarg);
+ break;
+ case 'f':
+ format=strdup(optarg);
+ break;
+ case 'z':
+ quit_on_eof=0;
+ break;
}
}
/* Default settings */
if (!dev1 && !listenport) dev1=strdup("/dev/ttyS0");
+ if (!name1 && !listenport) name1=strdup("Port1");
if (!dev2 && !connecthost) dev2=strdup("/dev/ttyS1");
+ if (!name2 && !connecthost) name2=strdup("Port2");
if (baud==B0) baud=B19200;
+ if (!format) format=strdup("0x%02hX");
disp_init();
if (dev1) {
- port1=openport(dev1, baud);
+ port1=openport(dev1, baud, setup_port);
} else {
disp_outputstatus("Waiting for connection to TCP port.");
port1=listensock(listenport);
}
if (dev2) {
- port2=openport(dev2, baud);
+ port2=openport(dev2, baud, setup_port);
} else {
disp_outputstatus("Connecting to TCP port.");
port2=opensock(connecthost, connectport);
exit(1);
}
- mainloop(port1, port2, silent, show_alpha, usec_threshold);
+ mainloop(port1, port2, silent, show_alpha, quit_on_eof, usec_threshold, name1, name2, format);
/* Clean up */
if (dev1) free(dev1);