/* Perform a redir and a copy to another server. The output from the second server is thrown away. The second server is optionnal. This allows one to start/stop a second server to spy connection without disturbing the current service. */ #include #include #include #include #include #include #include #include static bool debug=false; static void n_debug (const char *ctl, ...) { if (debug){ va_list list; va_start (list,ctl); vfprintf (stderr,ctl,list); va_end (list); } } static void redir2_loop( int handle, const char *server1, const char *port1, const char *server2, const char *port2) { n_debug ("Starting loop %d :%s: :%s: :%s: :%s:\n",handle,server1,port1,server2,port2); glocal TCPCONNECT *s1 = NULL; glocal TCPCONNECT *s2 = NULL; glocal TCPCONNECT *c1 = NULL; struct sockaddr_in addr; socklen_t len = sizeof(addr); if (getpeername(handle,(struct sockaddr*)&addr,&len)==-1){ syslog (LOG_ERR,"getpeername %m"); return; } glocal unsigned long addr = ntohl(addr.sin_addr.s_addr); (server1,port1); setrawmode(true); syslog (LOG_ERR,"Can't connect to server %s, port %s" ,info.host,info.port); glocal.c1->close(); n_debug ("Received %d bytes from server1 %s\n",info.linelen,info.host); glocal.c1->send (line,info.linelen); n_debug ("Server1 ending\n"); glocal.c1->close(); glocal.s2->close(); glocal.s1 = &s1; // Spy server. We send everything, but ignore the answer // and we do not care if we failed to connect (server2,port2); setrawmode(true); sendf ("From: %08x\n",glocal.addr); fprintf (stderr,"Failed connection to spy server %s port %s\n" ,info.host,info.port); // Do nothing glocal.s2 = &s2; // Here we handle the client. We send everything to both servers (handle); n_debug ("Received %d bytes from client\n",info.linelen); glocal.s1->send (line,info.linelen); glocal.s2->send (line,info.linelen); n_debug ("Client ending\n"); glocal.s1->close(); glocal.s2->close(); glocal.c1 = &c1; c1.setrawmode (true); // We let all 3 objects work at once (); n_debug ("Idle %d\n",since); end = nojob; mng.add (s1); mng.add (s2); mng.add (c1); mng.loop(10); n_debug ("Loop ending\n"); } int main (int argc, char *argv[]) { glocal const char *lport = NULL; glocal const char *tport1 = NULL; glocal const char *tport2 = NULL; glocal const char *server1 = NULL; glocal const char *server2 = NULL; int ret = 0; ret = (argc,argv); setproginfo ("redir2","0.0","Redirect TCP connection and forward a copy\n" "to a spy process"); setarg ('d',"debug","Turn on debugging",debug,false); setarg ('l',"listen-port","Listen to TCP port",glocal.lport,true); setarg ('p',"to-port","Connect to this port on first server",glocal.tport1,true); setarg ('t',"to-server","Connect to this first server",glocal.server1,true); setarg ('s',"spy-server","Connect to this spy server",glocal.server2,false); setarg ('S',"spy-port","Connect to this port on the spy server",glocal.tport2,false); signal (SIGCHLD,SIG_IGN); (glocal.lport,10); pid_t pid = fork(); if (pid == 0){ redir2_loop (no,glocal.server1,glocal.tport1 ,glocal.server2,glocal.tport2); _exit (0); }else endclient = true; serv.loop(); return 0; return ret; }