/* Just library with connect(2) replacement... Configuration and running notes: a) make b) make install c) export CONN_ADDR=ip.ad.dre.ss d) export LD_PRELOAD=/usr/lib/libconnect.so.M.N e) enjoy... all programs, which calls connect(2) now will connect from address, which exported as CONN_ADDR.. dedicated to inty and irc.lucky.net. * $Id: connect.c,v 1.2 2000/05/22 17:29:23 snar Exp $ */ #include #include #include #include #include #include #include #include #include static int conn_initialised=0; static int (*real_connect)(int, struct sockaddr*, int)=NULL; static struct sockaddr_in tobi; int connect __P((int s, const struct sockaddr *re, socklen_t namelen)) { struct sockaddr_in nm,*remo=(struct sockaddr_in*)re; int nml; char* name; repete: switch(conn_initialised) { case -1: return ENOENT; case 0: name=getenv("CONN_ADDR"); bzero(&tobi,sizeof(struct sockaddr_in)); real_connect=dlsym(RTLD_NEXT,"_connect"); if(!real_connect) { printf("Can't locate symbol _connect in RTLD_NEXT: %s\n", dlerror()); conn_initialised=-1; return errno; }; if(name) { tobi.sin_addr.s_addr=inet_addr(name); tobi.sin_family=PF_INET; tobi.sin_port=0; conn_initialised=1; #ifdef CONN_DEBUG printf("oki, all connect(2)'s wil be from %s\n", inet_ntoa(tobi.sin_addr)); #endif } else { conn_initialised=2; #ifdef CONN_DEBUG printf("will connect(2)'s from INADDR_ANY..\n"); #endif }; goto repete; case 1: nml=sizeof(nm); if(getsockname(s,(struct sockaddr*)&nm,&nml)==-1) { return errno; }; if(bcmp(&nm.sin_addr.s_addr,&tobi.sin_addr.s_addr, sizeof(nm.sin_addr.s_addr))) { #ifdef CONN_DEBUG printf("attempt to connect %s:%u from wrong", inet_ntoa(remo->sin_addr), ntohs(remo->sin_port)); printf(" address (%s:%u)\n", inet_ntoa(nm.sin_addr), ntohs(nm.sin_port)); #endif if(bind(s,(struct sockaddr*)&tobi, sizeof(struct sockaddr_in))==-1) { #ifdef CONN_DEBUG printf("bind() failed: %s\n",strerror(errno)); #endif return errno; }; }; break; case 2: break; default: printf("conn_initialised: unknown state %i\n",conn_initialised); return 0; }; return real_connect(s,(struct sockaddr*)remo,namelen); };