| roamctl |
|---|
| startup/shutdown script for GRIC's aims_roam_svd (note the LD_PRELOAD value). |
#!/bin/sh
cd /etc/gricrad/executables
case "$1" in
start)
# DL: Override IP address
LD_PRELOAD=/etc/gricrad/executables/bind_override.so
export LD_PRELOAD
#
#Start roaming with no debug
#/etc/gricrad/executables/aims_roam_svd -d /etc/gricrad/config_files/ -a /var/adm/gricacct -R 1645 -A 1646 -U -e -c -l -t 10 &
#
#Start roaming with terminal debug
/etc/gricrad/executables/aims_roam_svd -d /etc/gricrad/config_files/ -a /var/adm/gricacct -R 1645 -A 1646 -U -x -e -c -l -t 10 &
#
#Start roaming with debug.log debug
#/etc/gricrad/executables/aims_roam_svd -d /etc/gricrad/config_files/ -a /var/adm/gricacct -R 1645 -A 1646 -U -x -e -c -l -t 10 > /etc/gricrad/debug.log &
;;
stop)
# DL: Kill GRIC processes
/usr/bin/ps -u root | egrep 'aims_roa|Relog' | awk '{print $1}' | xargs kill -9
;;
*)
echo 'This script only supports "start" or "stop"'
;;
esac
|
| bind_override.c |
| Note: This code isn't pretty - it doesn't even check sin_family to make sure the bind is a TCP/IP bind. But it works for the GRIC aims_roam_svd.
Compile the following (bind_override.c) with gcc -c -shared bind_override.c -o bind_override.so after changing the IP in it (note: tested on Solaris, should also work on Linux). |
#ifdef __linux__
#include <asm/unistd.h>
#include <linux/net.h>
static int errno;
static __inline__ _syscall2(int,socketcall,int,a1,unsigned long *,args)
#endif
struct in_addr {
unsigned int s_addr;
};
struct sockaddr_in {
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
int bind(int fd, struct sockaddr_in *s, int len) {
#ifdef __linux__
unsigned long sargs[3] = { fd, (long)s, len };
#endif
if (len >= 8 && s->sin_addr.s_addr == 0) {
printf("DL: Re-writing bind() syscall\n");
s->sin_addr.s_addr = inet_addr("192.168.0.2");
#ifdef __linux__
return socketcall(SYS_BIND, &sargs[0]);
#else
return _bind(fd, s, len);
#endif
} else {
printf("DL: bind() syscall already has explicit addr (%s)\n", inet_ntoa(s->sin_addr));
#ifdef __linux__
return socketcall(SYS_BIND, &sargs[0]);
#else
return _bind(fd, s, len);
#endif
}
}
|
| make-so |
|---|
| This script compiles and links as required. |
#!/bin/sh # Verbose gcc -c -shared -o virtual.so virtual.c ld -r -dy -G virtual.so /usr/lib/libnsl.so /usr/lib/libsocket.so -o virtual_linked.so # Quiet gcc -c -shared -o virtual_quiet.so virtual_quiet.c ld -r -dy -G virtual_quiet.so /usr/lib/libnsl.so /usr/lib/libsocket.so -o virtual_quiet_linked.so |
| virtual.c |
| The preload, similar to bind_override but with more test cases. |
#include <sys/select.h>
#define VIP "192.168.0.3"
#define AF_INET 2
#define SIN(x) ((struct sockaddr_in *)(x))
struct in_addr {
unsigned int s_addr;
};
struct sockaddr_in {
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
fd_set __v_bound;
int __v_init = 0;
struct sockaddr_in __v_addr;
int __v_len = sizeof(__v_addr);
static void __v_maybe_init(void) {
if (!__v_init) {
__v_init = 1;
FD_ZERO(&__v_bound);
}
bzero(__v_addr, __v_len);
__v_addr.sin_family = AF_INET;
__v_addr.sin_addr.s_addr = inet_addr(VIP);
}
int bind(int fd, void *s, size_t len) {
__v_maybe_init();
FD_SET(fd, &__v_bound);
if (len >= 8 && SIN(s)->sin_family == AF_INET && SIN(s)->sin_addr.s_addr == 0) {
printf("FD %d: Re-writing bind() syscall\n", fd);
SIN(s)->sin_addr.s_addr = __v_addr.sin_addr.s_addr;
return _bind(fd, s, len);
} else {
printf("FD %d: bind() syscall already has explicit addr (%s)\n", fd, inet_ntoa(SIN(s)->sin_addr));
return _bind(fd, s, len);
}
}
int close(int fd) {
__v_maybe_init();
if (fd > 0) {
FD_CLR(fd, &__v_bound);
}
return _close(fd);
}
int connect(int fd, void *s, int len) {
__v_maybe_init();
if (!FD_ISSET(fd, &__v_bound) && (len >= 8) && SIN(s)->sin_family == AF_INET) {
printf("FD %d: connect() without bind, binding\n", fd);
__v_addr.sin_port = 0;
_bind(fd, &__v_addr, __v_len);
}
FD_SET(fd, &__v_bound);
return _connect(fd, s, len);
}
|
| virtual_quiet.c |
| A quiet version of the virtual preload, since vnas runs from inetd so we can't output anything. |
#include <sys/select.h>
#define VIP "192.168.0.3"
#define AF_INET 2
#define SIN(x) ((struct sockaddr_in *)(x))
struct in_addr {
unsigned int s_addr;
};
struct sockaddr_in {
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
fd_set __v_bound;
int __v_init = 0;
struct sockaddr_in __v_addr;
int __v_len = sizeof(__v_addr);
static void __v_maybe_init(void) {
if (!__v_init) {
__v_init = 1;
FD_ZERO(&__v_bound);
}
bzero(__v_addr, __v_len);
__v_addr.sin_family = AF_INET;
__v_addr.sin_addr.s_addr = inet_addr(VIP);
}
int bind(int fd, void *s, size_t len) {
__v_maybe_init();
FD_SET(fd, &__v_bound);
if (len >= 8 && SIN(s)->sin_family == AF_INET && SIN(s)->sin_addr.s_addr == 0) {
SIN(s)->sin_addr.s_addr = __v_addr.sin_addr.s_addr;
return _bind(fd, s, len);
} else {
return _bind(fd, s, len);
}
}
int close(int fd) {
__v_maybe_init();
if (fd > 0) {
FD_CLR(fd, &__v_bound);
}
return _close(fd);
}
int connect(int fd, void *s, int len) {
__v_maybe_init();
if (!FD_ISSET(fd, &__v_bound) && (len >= 8) && SIN(s)->sin_family == AF_INET) {
__v_addr.sin_port = 0;
_bind(fd, &__v_addr, __v_len);
}
FD_SET(fd, &__v_bound);
return _connect(fd, s, len);
}
|
| vnas |
| vnas is moved to vnas.real, and this script put in it's place. |
#!/bin/sh LD_PRELOAD=/usr/ipass/bin/virtual_quiet_linked.so export LD_PRELOAD exec /usr/ipass/bin/vnas.real $* |
| rc.netserverd |
| The rc.netserverd needs these lines added just above the line starting netserver. |
LD_PRELOAD=/usr/ipass/bin/virtual_linked.so export LD_PRELOAD |
--