/*
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 <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>
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);
};
syntax highlighted by Code2HTML, v. 0.9.1