From 1e215bfd3e224199b5f746593bb15383ab0efa38 Mon Sep 17 00:00:00 2001 From: Matteo Nastasi Date: Sun, 12 Feb 2012 19:04:32 +0100 Subject: [PATCH 1/1] first commit --- makefile | 27 ++++++++ overhosts.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++ overhosts.h | 24 ++++++++ test.c | 65 ++++++++++++++++++++ 4 files changed, 289 insertions(+) create mode 100644 makefile create mode 100644 overhosts.c create mode 100644 overhosts.h create mode 100644 test.c diff --git a/makefile b/makefile new file mode 100644 index 0000000..d0ad137 --- /dev/null +++ b/makefile @@ -0,0 +1,27 @@ +# +# Project overhosts +# + +VER=0.0.1 +EXE=overhosts.so test +OBJ=overhosts.o +PKGNAME=overhosts +TARGET=$(EXE) + +CC=gcc + +ALL: $(TARGET) + +overhosts.so: overhosts.c overhosts.h + $(CC) -Wall -fPIC -shared -ldl -o $@ $< + +test: test.c + $(CC) -Wall -g -ggdb -o $@ $< + +clean: + rm -f $(EXE) $(OBJ) *~ $(TARGET) + +pkg: + tar -zcv --transform="s,^,$(PKGNAME)-$(VER)/," -f ../$(PKGNAME)_$(VER).tgz * + +.PHONY: clean pkg ALL diff --git a/overhosts.c b/overhosts.c new file mode 100644 index 0000000..a23a5cf --- /dev/null +++ b/overhosts.c @@ -0,0 +1,173 @@ +/* + * overhosts.c + * + * Copyright (C) 2012 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. You should have received a + * copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc, 59 Temple Place - + * Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* + compile like this: + + gcc -c -fPIC preload_open.c + ld -shared -o preload_open.so preload_open.o -ldl + + export LD_PRELOAD=/etc/magic/preload_open.so + myapp ARGS + +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "overhosts.h" + +void __attribute__ ((constructor)) overhosts_init(void); + +struct hostent *(* ohreal_gethostbyname)(const char *name) = NULL; +struct hostent *(* ohreal_gethostbyname2)(const char *name, int af) = NULL; +int (*ohreal_getaddrinfo)(const char *node, const char *service, + const struct addrinfo *hints, + struct addrinfo **res) = NULL; +// void (* ohreal_freeaddrinfo)(struct addrinfo *res) = NULL; +#if 0 +static struct hostent ohreal_he = { "bernoulli", + (char *[]){ NULL }, + AF_INET, + 4, + (char *[]){ "\x7f\x00\x00\x01", NULL } +}; +#endif + +/* +static struct addrinfo ohreal_ai = { + + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + struct sockaddr *ai_addr; + char *ai_canonname; + struct addrinfo *ai_next; + }; + +*/ + +void __attribute__ ((constructor)) overhosts_init(void) +{ + ohreal_gethostbyname = dlsym((void *)-1, "gethostbyname"); + // printf("PREINTT\n"); + ohreal_gethostbyname2 = dlsym((void *)-1, "gethostbyname2"); + ohreal_getaddrinfo = dlsym((void *)-1, "getaddrinfo"); + // printf("INITT\n"); +} + +static int is_an_alias(const char *name); + +static int is_an_alias(const char *name) +{ + char *alias, *p, *e; + char bf[4096]; + + if ((alias = getenv("OVERHOSTS_ALIASES")) == NULL) { + // printf("fuori1 [%s]\n", name); + return 0; + } + + strcpy(bf, "|"); + strcat(bf, name); + + // printf("in1 [%s][%s]\n", bf, name); + + if (((p = strstr(alias, bf)) != NULL) || ((p = strstr(alias, name)) && p == alias)) { + e = p+strlen(name); + if (p > alias) + e++; + // printf("in2 [%s][%c]\n", bf, *e); + if (*e == '\0' || *e == '|') { + // printf("fuori2 [%s]\n", name); + return 1; + } + } + + return 0; +} + + + +// struct hostent *gethostbyname(const char *name); +struct hostent *gethostbyname2(const char *name, int af); + +struct hostent *gethostbyname2(const char *name, int af) +{ + char *real; + if (is_an_alias(name) && (real = getenv("OVERHOSTS_REAL")) != NULL) { + return (gethostbyname2(real, af)); + } + else { + return (gethostbyname2(name, af)); + } +} + +// struct hostent *gethostbyname(const char *name); +struct hostent *gethostbyname(const char *name); + +struct hostent *gethostbyname(const char *name) +{ + char *real; + if (is_an_alias(name) && (real = getenv("OVERHOSTS_REAL")) != NULL) { + return (gethostbyname(real)); + } + else { + return (gethostbyname(name)); + } +} + +int getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, + struct addrinfo **res); + +int getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, + struct addrinfo **res) +{ + char *real; + + if (is_an_alias(node) && (real = getenv("OVERHOSTS_REAL")) != NULL) { + + if (hints->ai_flags | AI_CANONNAME) { + printf("WARNING: AI_CANONAME set\n"); + } + return ohreal_getaddrinfo(real, service, + hints, res); + } + else { + return ohreal_getaddrinfo(node, service, + hints, res); + } +} diff --git a/overhosts.h b/overhosts.h new file mode 100644 index 0000000..8bf509a --- /dev/null +++ b/overhosts.h @@ -0,0 +1,24 @@ +/* + * overhosts.h + * + * Copyright (C) 2012 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. You should have received a + * copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc, 59 Temple Place - + * Suite 330, Boston, MA 02111-1307, USA. + * + */ + + +#include +#include + diff --git a/test.c b/test.c new file mode 100644 index 0000000..90715bc --- /dev/null +++ b/test.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 500 + +int +main(int argc, char *argv[]) +{ + struct addrinfo hints; + struct addrinfo *result, *rp; + int s; + + if (argc < 3) { + fprintf(stderr, "Usage: %s host port msg...\n", argv[0]); + exit(EXIT_FAILURE); + } + + /* Obtain address(es) matching host/port */ + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = 0; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ + /* hints.ai_flags = 0; */ + hints.ai_flags = AI_CANONNAME; /* For wildcard IP address */ + hints.ai_protocol = 0; /* Any protocol */ + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + s = getaddrinfo(argv[1], argv[2], &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + exit(EXIT_FAILURE); + } + + /* getaddrinfo() returns a list of address structures. + Try each address until we successfully connect(2). + If socket(2) (or connect(2)) fails, we (close the socket + and) try the next address. */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + printf("ai_flags: %d\n", rp->ai_flags); + printf("ai_family: %d\n", rp->ai_family); + printf("ai_socktype: %d\n", rp->ai_socktype); + printf("ai_protocol: %d\n", rp->ai_protocol); + printf("ai_addrlen: %d\n", rp->ai_addrlen); + printf("ai_addr.type: %d\n", rp->ai_addr->sa_family); /* PF_INET */ + if (rp->ai_addr->sa_family == AF_INET) { + printf("sin_port: %d\n" , ntohs(((struct sockaddr_in *)rp->ai_addr)->sin_port)); + printf("sin_addr: %s\n", inet_ntoa(((struct sockaddr_in *)rp->ai_addr)->sin_addr)); + } + printf("ai_canonname:[%s]\n", rp->ai_canonname); + } + + freeaddrinfo(result); /* No longer needed */ + + exit(EXIT_SUCCESS); +} -- 2.17.1