📄 slsnif.c
字号:
/* slsnif.c * Copyright (C) 2001 Yan "Warrior" Gurtovoy (ymg@dakotacom.net) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "ascii.h"#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "slsnif.h"void copyright() { printf("\n\nSerial Line Sniffer. Version %s\n", VERSION); printf("\tCopyright (C) 2001 Yan \"Warrior\" Gurtovoy (ymg@azstarnet.com)\n\n");}void usage() { copyright(); printf("Usage: slsnif [options] <port>\n\n"); printf("REQUIRED PARAMETERS:\n"); printf(" <port> - serial port to use (i.e /dev/ttyS0, /dev/ttyS1, etc.)\n\n"); printf("OPTIONS:\n"); printf(" -h (--help) - displays this help.\n"); printf(" -b (--bytes) - print number of bytes transmitted on every read.\n"); printf(" -n (--nolock) - don't try to lock the port.\n"); printf(" -t (--timestamp) - print timestamp for every transmission.\n"); printf(" -l (--log) <logfile> - file to store output in, defaults to stdout.\n"); printf(" -i (--in-tee) <file> - write raw data from device to this file(s).\n"); printf(" -o (--out-tee) <file> - write raw data from host to this file(s).\n"); printf(" -s (--speed) <speed> - baudrate to use, defaults to 9600 baud.\n"); printf(" -p (--port2) <port2> - serial port to use instead of pty.\n"); printf(" --color <color> - color to use for normal output.\n"); printf(" --timecolor <color> - color to use for timestamp.\n"); printf(" --bytescolor <color> - color to use for number of bytes transmitted.\n\n"); printf("Following names are valid colors:\n"); printf("燶tblack, red, green, yellow, blue, magenta, cyan, white,\n"); printf("\tbrightblack,brightred, brightgreen, brightyellow,\n"); printf("\tbrightblue, brightmagenta, brightcyan, brightwhite\n\n"); printf("Example: slsnif -l log.txt -s 2400 /dev/ttyS1\n\n");}void fatalError(char *msg) { perror(msg); _exit(-1);}int setRaw(int fd, struct termios *ttystate_orig) {/* set tty into raw mode */ struct termios tty_state; if (tcgetattr(fd, &tty_state) < 0) return 0; /* save off original settings */ *ttystate_orig = tty_state; /* set raw mode */ tty_state.c_lflag &= ~(ICANON | IEXTEN | ISIG | ECHO); tty_state.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON | BRKINT); tty_state.c_oflag &= ~OPOST; tty_state.c_cflag |= CS8; tty_state.c_cc[VMIN] = 1; tty_state.c_cc[VTIME] = 0; cfsetispeed(&tty_state, tty_data.baudrate); cfsetospeed(&tty_state, tty_data.baudrate); if (tcsetattr(fd, TCSAFLUSH, &tty_state) < 0) return 0; return 1;}void fmtData(unsigned char *in, char *out, int in_size) {/* format data */ char charbuf[15]; int i; /* flush output buffer */ out[0] = 0; for (i = 0; i < in_size; i++) { if (in[i] == 127) { /* it's a DEL character */ sprintf(charbuf, "%s (%03i) ", DEL, 127); } else { if (in[i] < 33) /* it's a control character or space */ sprintf(charbuf, "%s (%03i) ", ascii_chars[(int) in[i]], in[i]); else /* it's a printable character */ sprintf(charbuf, "%c (%03i) ", in[i], in[i]); } /* put formatted data into output buffer */ strcat(out, charbuf); }}void setColor(int out, char *color) {/* changes color on the terminal */ if (color[0]) { write(out, color, 7); } else { write(out, colors[WHITE].color, 7); }}void writeData(int in, int out, int aux, int mode) {/* reads data from `in`, formats it, writes it to `out` and `aux`. * mode 0 - read from pipe * mode 1 - read from port * mode 2 - read from pty */ unsigned char buffer[BUFFSIZE]; char outbuf[BUFFSIZE * 16 + 1]; int n;#ifdef HAVE_SYS_TIMEB_H struct timeb tstamp; char tbuf[29]; char tmp[25]; char tmp1[4];#else#ifdef HAVE_TIME_H time_t tstamp;#endif#endif if ((n = read(in, buffer, BUFFSIZE)) < 0) { if (mode) if (errno == EIO) sleep(1); else perror(mode == 1 ? RPORTFAIL : RPTYFAIL); else perror(RPIPEFAIL); } else { if (n > 0) { if (mode) { write(out, buffer, n); write(aux, buffer, n); } else { /* print timestamp if necessary */ if (tty_data.tstamp) { if (out == STDOUT_FILENO) setColor(out, tty_data.tclr); write(out, "\n\n", 2);#ifdef HAVE_SYS_TIMEB_H ftime(&tstamp); tmp[0] = tmp1[0] = tbuf[0] = 0; strncat(tmp, ctime(&(tstamp.time)), 24); strncat(tbuf, tmp, 19); sprintf(tmp1, ".%2ui", tstamp.millitm); strncat(tbuf, tmp1, 3); strcat(tbuf, tmp + 19); write(out, tbuf, 28);#else#ifdef HAVE_TIME_H time(&tstamp); write(out, ctime(&tstamp), 24);#endif#endif } else { write(out, "\n", 1); } if (out == STDOUT_FILENO) setColor(out, tty_data.clr); /* print prefix */ write(out, aux ? PORT_IN : PORT_OUT, PRFXSIZE); /* format data */ fmtData(buffer, outbuf, n); if (aux && reseek) { /* rotate log file */ lseek(tty_data.logfd, 0, SEEK_SET); for (entry= tee_files[0]; entry; entry = entry->next) lseek(entry->fd, 0, SEEK_SET); /* clear the flag */ reseek = FALSE; } /* print data */ write(out, outbuf, strlen(outbuf)); /* print total number of bytes if necessary */ if (tty_data.dspbytes) { buffer[0] = 0; sprintf(buffer, "\n%s %i", TOTALBYTES, n); if (out == STDOUT_FILENO) setColor(out, tty_data.bclr); write (out, buffer, strlen(buffer)); } for (entry = (aux ? tee_files[0] : tee_files[1]); entry; entry = entry->next) { if (n != write(entry->fd, buffer, n)) fatalError(TEEWRTFAIL); } } } }}void pipeReader() {/* get data drom pipes */ int maxfd; fd_set read_set; maxfd = max(tty_data.ptypipefd[0], tty_data.portpipefd[0]); while (TRUE) { FD_ZERO(&read_set); FD_SET(tty_data.ptypipefd[0], &read_set); FD_SET(tty_data.portpipefd[0], &read_set); if (select(maxfd + 1, &read_set, NULL, NULL, NULL) < 0) { /* don't bail out if error was caused by interrupt */ if (errno != EINTR) { perror(SELFAIL); return; } else { continue; } } if (FD_ISSET(tty_data.ptypipefd[0], &read_set)) writeData(tty_data.ptypipefd[0], tty_data.logfd, 0, 0); else if (FD_ISSET(tty_data.portpipefd[0], &read_set)) writeData(tty_data.portpipefd[0], tty_data.logfd, 1, 0); }}void closeAll() { int i;/* close all opened file descriptors */ /* unlock the port(s) if necessary */ if (!tty_data.nolock) { if (tty_data.portName && tty_data.portName[0]) dev_unlock(tty_data.portName); /* this pointer should be NULL if pty is used */ if (tty_data.ptyName) dev_unlock(tty_data.ptyName); } /* restore color */ if (tty_data.logfd == STDOUT_FILENO) setColor(tty_data.logfd, colors[WHITE].color); /* restore settings on pty */ if (tty_data.ptyraw) tcsetattr(tty_data.ptyfd, TCSAFLUSH, &tty_data.ptystate_orig); /* close pty */ if (tty_data.ptyfd >= 0) close(tty_data.ptyfd); /* restore settings on port */ if (tty_data.portraw) tcsetattr(tty_data.portfd, TCSAFLUSH, &tty_data.portstate_orig); /* close port */ if (tty_data.portfd >= 0) close(tty_data.portfd); /* close log file */ write(tty_data.logfd, "\n", 1); if (tty_data.logfd != STDOUT_FILENO && tty_data.logfd >= 0) if ((close(tty_data.logfd)) < 0) perror(CLOSEFAIL); /* close write pipes */ if (tty_data.ptypipefd[1] >= 0) close(tty_data.ptypipefd[1]); if (tty_data.portpipefd[1] >= 0) close(tty_data.portpipefd[1]); /* close tee files and free allocated memory for in/out tees */ for (i = 0; i < 2; i++) { entry = tee_files[i]; while (entry) { close(entry->fd); free(entry->name); tmp_entry = entry; entry = entry->next; free(tmp_entry); } } /* free allocated memory for portName */ if (tty_data.portName) free(tty_data.portName); if (pid >= 0) kill(pid, SIGINT);}RETSIGTYPE sighupP(int sig) {/* parent signal handler for SIGHUP */ if (pid >= 0) kill(pid, SIGHUP); return;}RETSIGTYPE sighupC(int sig) {/* child signal handler for SIGHUP */ reseek = 1; return;}RETSIGTYPE sigintP(int sig) {/*parent signal handler for SIGINT */ closeAll(); _exit(1);}RETSIGTYPE sigintC(int sig) {/* child signal handler for SIGINT */ /* close read pipes */ if (tty_data.ptypipefd[0] >= 0) close(tty_data.ptypipefd[0]); if (tty_data.portpipefd[0] >= 0) close(tty_data.portpipefd[0]); _exit(1);}RETSIGTYPE sigchldP(int sig) {/* signal handler for SIGCHLD */ int status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -