⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interceptty.c

📁 intercept tty is using for listening a UART conversation
💻 C
📖 第 1 页 / 共 2 页
字号:
/*     interceptty.c * * This file is an adaptation of ttysnoops.c, from the ttysnoop-0.12d * package It was originally written by Carl Declerck, Ulrich * Callmeir, Carl Declerck, and Josh Bailey.  They deserve all of the * credit for the clever parts.  I, on the other hand, deserve all of * the blame for whatever I broke.  Please do not email the original * authors of ttysnoop about any problems with interceptty. * *//* $Id: interceptty.c,v 7.12 2004/09/05 23:01:35 gifford Exp $ */#include "config.h"#include <sys/types.h>#include <stdlib.h>#include <sys/wait.h>#include <sys/stat.h>#include <stdio.h>#include <ctype.h>#include <unistd.h>#include <signal.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <grp.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/un.h>#include <netdb.h>#include <pwd.h>#include <grp.h>#include "bsd-openpty.h"#include "common.h"#ifndef O_NOCTTY#define O_NOCTTY 0#endif#define DEFAULT_FRONTEND "/tmp/interceptty"struct sockaddr_in inet_resolve(const char *sockname);#define BUFF_SIZE	256char buff[BUFF_SIZE];char ttynam[TTYLEN+1] = "";int ptyfd = -1;int fdmax = 0;char    *backend = NULL,  *frontend = DEFAULT_FRONTEND,  *settings = NULL,  *outfilename = NULL,  *opt_ptyname = NULL,  *opt_ttyname = NULL;int     verbose = 0,  linebuff = 0,  quiet = 0;int     created_link = 0;char    last_pty[TTYLEN] = "",  last_tty[TTYLEN] = "";pid_t child_pid = 0;int please_die_now = 0;int listenfd = 0;mode_t frontend_mode = -1;uid_t frontend_owner = -1;gid_t frontend_group = -1;uid_t switch_uid = -1;gid_t switch_gid = -1;char *switch_root = NULL;int no_closedown = 0;FILE *outfile;/* find & open a pty to be used by the pty-master */int find_ptyxx (char *ptyname){  int fd, ttyfd;    if (my_openpty(&fd,&ttyfd,ptyname) < 0)    errorf("Couldn't openpty: %s\n",strerror(errno));  if (stty_raw(ttyfd) != 0)    errorf("Couldn't put pty into raw mode: %s\n",strerror(errno));  /* Throw away the ttyfd.  We'll keep it open because it prevents   * errors when the client disconnects, but we don't ever plan to   * read or write any data, so we needn't remember it.   */  return fd;}/* Create the pty */int create_pty (int *ptyfd, char *ttynam){  char name[TTYLEN+1];  if (opt_ptyname)  {     if (strlen(opt_ptyname) > TTYLEN)      errorf("Specified pty name is too long!");                    strcpy(name, opt_ptyname);    if (opt_ttyname)    {      if (strlen(opt_ttyname) > TTYLEN)        errorf("Specified tty name is too long!");      strcpy(ttynam, opt_ttyname);    }    else if (strncmp(name,"/dev/pty",8) == 0)    {      /* Hacky, or heuristic? */      strcpy(ttynam, name);      ttynam[5] = 't';    }    else if (frontend)    {      errorf("A pty was specified with -p, but I couldn't figure out a tty to go with it.\nEither give me a tty with the -t switch, \nor else tell me not to create a front-end device by passing '-' as the front-device.");    }    else    {      ttynam[0]='\0';    }    *ptyfd = open(opt_ptyname,O_RDWR|O_NOCTTY);  }  else  {    *ptyfd = find_ptyxx(name);    strcpy(ttynam, name);  }  if (*ptyfd < 0)    errorf("can't open pty '%s'\n",name);  return 1;}		/* do a graceful closedown */void closedown (void){	  if (no_closedown)    return;  stty_orig ();  if (created_link)    unlink(frontend);  if (child_pid)   {    if (verbose)      fprintf(stderr,"Sending signal %d to child pid %ld\n",SIGTERM,(long)child_pid);    kill(child_pid,SIGTERM);  }  if (verbose)    fprintf(stderr,"closing down everything\n");}/* signal handlers */void sighup (int sig){  sig = sig;  closedown ();}void sigpipe (int sig){  sig = sig;	  signal (SIGPIPE, sigpipe);}void sigint(int sig){  sig = sig;  closedown();  _exit(1);}void sigdeath(int sig){  please_die_now=1;}void sigchld(int sig){  child_pid = 0;  sigdeath(sig);}int alldigits(const char *s){  while(isdigit(*s))    s++;  return *s == '\0';}uid_t find_uid(const char *u){  struct passwd *pw;  if (alldigits(u))    return atoi(u);    if (!(pw = getpwnam(u)))    errorf("Error finding user '%s': %s\n",u,strerror(errno));  return pw->pw_uid;}gid_t find_gid(const char *g){  struct group *gr;  if (alldigits(g))    return atoi(g);  if (!(gr = getgrnam(g)))    errorf("Error finding group '%s': %s\n",g,strerror(errno));  return gr->gr_gid;}/* main program */void dumpbuff(int dir, char *buf, int buflen){  int i;  int ic;    for (i=0;i<buflen;i++)  {    if (dir)    {      fprintf(outfile, "> \t");    }    else    {      fprintf(outfile, "< ");    }    ic=(unsigned char)buf[i];    fprintf(outfile, "0x%02x",ic);    if ( (buf[i] >= 33) && (buf[i] <= 126) )    {      fprintf(outfile, " (%c)",buf[i]);    }    fprintf(outfile, "\n");  }  fflush(outfile);}/* Run stty on the given file descriptor with the given arguments */int fstty(int fd, char *stty_args){  int child_status;  int pid;  char *stty_cmd;          stty_cmd = malloc(strlen(stty_args)+1+strlen("stty "));  if (!stty_cmd)    errorf("Couldn't malloc for stty_cmd: %s\n",strerror(errno));  strcpy(stty_cmd,"stty ");  strcat(stty_cmd,stty_args);                  if ((pid=fork()) == 0)  {    /* Child */    if (dup2(fd,STDIN_FILENO) < 0)      errorf("Couldn't dup2(%d,STDIN_FILENO=%d): %s\n",fd,STDIN_FILENO,strerror(errno));    if (execlp("sh","sh","-c",stty_cmd,NULL) < 0)      errorf("Couldn't exec stty command: %s\n",strerror(errno));    /* Should never reach here. */    exit(-1);  }  else if (pid == -1)  {    errorf("Couldn't fork: %s\n",strerror(errno));  }                  free(stty_cmd);  /* Parent */  if (wait(&child_status) <= 0)    errorf("Error waiting for forked stty process: '%s'\n",strerror(errno));  if (!(WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0) )    errorf("stty %s failed\n",stty_args);  return 0;}                /************************************* * Set up backend device ************************************/int setup_back_inet_socket(char *backend, int f[2]){  struct sockaddr_in sa;  int fd;  sa = inet_resolve(backend);  if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 3)    errorf("Couldn't open socket: %s\n",strerror(errno));  if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) != 0)    errorf("Couldn't connect socket: %s\n", strerror(errno));  return f[0]=f[1]=fd;}int setup_back_unix_socket(char *sockname, int f[2]){  int fd;  struct sockaddr_un sa;    if ((strlen(sockname)+1) > sizeof(sa.sun_path))    errorf("Path name is too long for a Unix socket.\n");  sa.sun_family = AF_UNIX;  strcpy(sa.sun_path,sockname);    if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 3)    errorf("Couldn't open socket: %s\n",strerror(errno));  if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) != 0)    errorf("Couldn't connect socket: %s\n", strerror(errno));  return f[0]=f[1]=fd;}struct sockaddr_in inet_resolve(const char *sockname){  struct sockaddr_in sa;  char *hostname, *netport;  struct hostent *he;    if (strchr(sockname,':') == NULL)    errorf("Internet hostname must be @host:port\n");  if (!(hostname = strdup(sockname)))    errorf("Couldn't dup string: %s\n",strerror(errno));  netport = strchr(hostname,':');  *netport='\0';  netport++;    sa.sin_family=AF_INET;    if (!(he = gethostbyname(hostname)))    errorf("Couldn't resolve name '%s': %s.\n",hostname,	   (h_errno == HOST_NOT_FOUND) ? "Host not found" :	   ((h_errno == NO_ADDRESS)||(h_errno == NO_DATA)) ? "No data available" :	   (h_errno == NO_RECOVERY) ? "A non-recoverable name server error occured" :	   (h_errno == TRY_AGAIN) ? "A temporary error occured." :	   "An unknown error occured");  memcpy(&(sa.sin_addr),he->h_addr,he->h_length);      #if 0  if (!(se = getservbyname(netport)))    errorf("Couldn't resolve port.\n");  host_port=htons(se->s_port);#endif        if (!(sa.sin_port = htons(atoi(netport))))    errorf("Couldn't figure out port number.\n");  free(hostname);    return sa;}int setup_back_tty(char *backend, int f[2]){  int serialfd;    /* Open the serial port */  serialfd = open(backend, O_RDWR | O_NOCTTY | O_SYNC | O_NOCTTY);  if (serialfd < 0)    errorf("error opening backend device '%s': %s\n",backend,strerror(errno));  if (stty_raw(serialfd) != 0)    errorf("Error putting serial device '%s' in raw mode: %s\n",backend,strerror(errno));    /* Process settings from the -s switch */  if (settings) {    fstty(serialfd,settings);  }  return f[0]=f[1]=serialfd;}int setup_back_program(char *backend, int f[2]){  int sock[2];  if (socketpair(PF_UNIX,SOCK_STREAM,0,sock) != 0)    errorf("Couldn't create socket: %s\n",strerror(errno));  /* Now run the program */  switch (child_pid=fork()) {    case -1:      /* Error */      errorf("Error in fork(): %s\n",strerror(errno));    case 0:      /* Child */      if (close(sock[0]) != 0) {	errorf("Error in close(sock[0]): %s\n",strerror(errno));      }      if (close(STDIN_FILENO) != 0) {	errorf("Error in close(STDIN_FILENO): %s\n",strerror(errno));      }      if (dup2(sock[1],STDIN_FILENO) != STDIN_FILENO) {	errorf("Error in dup2(sock[1],STDIN_FILENO): %s\n",strerror(errno));      }      if (close(STDOUT_FILENO) != 0) {	errorf("Error in close(STDOUT_FILENO): %s\n",strerror(errno));      }      if (dup2(sock[1],STDOUT_FILENO) != STDOUT_FILENO) {	errorf("Error in dup2(sock[1],STDOUT_FILENO): %s\n",strerror(errno));      }            if (close(sock[1]) != 0) {	errorf("Error in close(sock[1]): %s\n",strerror(errno));      }      execl("/bin/sh","sh","-c",backend,NULL);      /* Only returns if there is an error. */      errorf("exec error: %s\n",strerror(errno));  }  /* Parent */  return f[0]=f[1]=sock[0];}/* This can also do front fds */int setup_back_fds(char *backend, int f[2]){  char *fd1_s,*fd2_s;  if (!(fd1_s = strdup(backend)))    errorf("Couldn't dup string: %s\n",strerror(errno));  if ((fd2_s = strchr(fd1_s,',')) != 0) {    *fd2_s='\0';    fd2_s++;  }  else {    fd2_s = fd1_s;  }  f[1]=atoi(fd2_s);  return f[0]=atoi(fd1_s);}int setup_backend(int f[2]){  switch(backend[0]) {    case '@':      if (strchr(backend,'/')!=0)        return setup_back_unix_socket(backend+1,f);      else        return setup_back_inet_socket(backend+1,f);    case '!':      return setup_back_program(backend+1,f);    case '=':      return setup_back_fds(backend+1,f);    default:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -