Gerade wenn man auch ein bisschen C kann, und mit den ueblichen Bibliotheksfunktionen halbwegs vertraut ist kann das sehr nuetzlich sein.
Vor etwa 15 Jahren wollten wir mit ein paar Freunden StarCraft spielen - das damals ziemlich gut via Wine lief. Problem: Wir waren alle in unterschiedlichen Laendern. Ein VPN fuer alle war schnell zusammengeworfen - aber dummerweise ist Starcraft nur fuer lokales Spielen ausgelegt, und bindet sich einfach nur an das erste Interface.
Dank LD_PRELOAD war das Problem 5 Minuten spaeter geloest:
// Use with SC_BIND_ADDR=addr LD_PRELOAD="/path/to/so" wine starcraft.exe
#define _GNU_SOURCE
#include <stdlib.h>
#include <netdb.h>
#include <dlfcn.h>
#include <string.h>
#include <unistd.h>
static inline int __write1(const char *s){
write(1, s, strlen(s));
return 0;
}
int (*libc_bind)(int fd, const struct sockaddr* add, socklen_t len);
void _init(void){
libc_bind = dlsym(RTLD_NEXT, "bind");
}
int bind(int fd, const struct sockaddr* addr, socklen_t len) {
struct addrinfo *bindres;
struct addrinfo hints;
char *sc_addr;
int i;
for (i=1; i==1; i++){
if (addr->sa_family!=AF_INET)
break;
if ((sc_addr=getenv("SC_BIND_ADDR"))!=NULL){
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
__write1("SC_BIND_ADDR is set.\nTrying to use ");
__write1(sc_addr); __write1("\n");
getaddrinfo(sc_addr, 0, &hints, &bindres);
if (bindres->ai_family==AF_INET) {
__write1("Overwriting bind\n");
return libc_bind(fd, bindres->ai_addr, bindres->ai_addrlen);
} else
break;
}
}
__write1("Using default bind address\n");
return libc_bind(fd, addr, len);
}