Tag Archives: route

How to specify the source address for all outbound connections

If you have multiple IPs assigned on your Linux pc then there is a chance that you want to use different IPs for some applications than default one. Updating IP routes every time isn’t a good idea and you may mess up.

get bindhack.c

“`

wget ‘https://gist.githubusercontent.com/akhilin/f6660a2f93f64545ff8fcc0d6b23e42a/raw/7bf3f066b74a4b9e3d3768a8affee26da6a3ada6/bindhack.c’ -P /tmp/

“`

compile it

“`

gcc -fPIC -static -shared -o /tmp/bindhack.so /tmp/bindhack.c -lc -ldl

“`

Copy it to library folder

“`

cp /tmp/bindhack.so /usr/lib/ && chmod +x /usr/lib/bindhack.so

“`

Optional (ignore if you have it already )

“`

echo ‘nameserver 8.8.8.8’ >> /etc/resolv.conf

“`

using bindhack

“`

BIND_ADDR=<source ip> LD_PRELOAD=/usr/lib/bindhack.so <command here>

“`

Example

 

you can add below function in your .bashrc to spin it at any time

 

bindhack() {
# Author: Akhil Jalagam
[ $# -lt 2 ] && echo "missing arguments: $0 [bind ip] [command with quotes]"
wget 'https://gist.githubusercontent.com/akhilin/f6660a2f93f64545ff8fcc0d6b23e42a/raw/7bf3f066b74a4b9e3d3768a8affee26da6a3ada6/bindhack.c' -P /tmp/
gcc -fPIC -static -shared -o /tmp/bindhack.so /tmp/bindhack.c -lc -ldl
[ -f /usr/lib/bindhack.so ] || `type -P cp` /tmp/bindhack.so /usr/lib/ && chmod +x /usr/lib/bindhack.so
[ -f /etc/resolv.conf ] && `type -P cp` /etc/resolv.conf /etc/resolv.conf.bak && echo 'nameserver 8.8.8.8' >> /etc/resolv.conf
[ $# -eq 2 ] && BIND_ADDR=$1 LD_PRELOAD=/usr/lib/bindhack.so $2
echo ''
`type -P cp` /etc/resolv.conf.bak /etc/resolv.conf
}

 

take a look at bindhack.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <dlfcn.h>

#include <arpa/inet.h>

/* 
   This is the address you want to force everything to use. It can be
   overriden at runtime by specifying the BIND_SRC environment 
   variable.
*/
#define SRC_ADDR	"192.168.0.1"

/* 
   LIBC_NAME should be the name of the library that contains the real
   bind() and connect() library calls. On Linux this is libc, but on
   other OS's such as Solaris this would be the socket library
*/
#define LIBC_NAME	"libc.so.6" 

#define YES	1
#define NO	0

int
bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
{

	struct sockaddr_in src_addr;
	void	*libc;
	int	(*bind_ptr)(int, void *, int);
	int	ret;
	int	passthru;
	char 	*bind_src;

#ifdef DEBUG
	fprintf(stderr, "bind() override called for addr: %s\n", SRC_ADDR);
#endif

	libc = dlopen(LIBC_NAME, RTLD_LAZY);

	if (!libc)
	{
		fprintf(stderr, "Unable to open libc!\n");
		exit(-1);
	}

	*(void **) (&bind_ptr) = dlsym(libc, "bind");

	if (!bind_ptr)
	{
		fprintf(stderr, "Unable to locate bind function in lib\n");
		exit(-1);
	}
	
	passthru = YES;	/* By default, we just call regular bind() */

	if (my_addr==NULL)
	{
		/* If we get a NULL it's because we're being called
		   from the connect() hack */

		passthru = NO;

#ifdef DEBUG
		fprintf(stderr, "bind() Received NULL address.\n");
#endif

	}
	else
	{

		if (my_addr->sa_family == AF_INET)
		{
			struct sockaddr_in	myaddr_in;

			/* If this is an INET socket, then we spring to
			   action! */
			passthru = NO;

			memcpy(&myaddr_in, my_addr, addrlen);

			src_addr.sin_port = myaddr_in.sin_port;


		}
		else
		{
			passthru = YES;
		}

	}

	if (!passthru)
	{

#ifdef DEBUG
		fprintf(stderr, "Proceeding with bind hack\n");
#endif

		src_addr.sin_family = AF_INET;

		bind_src=getenv("BIND_SRC");

		/* If the environment variable BIND_SRC is set, then use
		   that as the source IP to bind instead of the hard-coded
		   SRC_ADDR one.
		*/
		if (bind_src)
		{
			ret = inet_pton(AF_INET, bind_src, &src_addr.sin_addr);
			if (ret<=0)
			{
				/* If the above failed, then try the
				   built in address. */

				inet_pton(AF_INET, SRC_ADDR, 
						&src_addr.sin_addr);
			}
		}
		else
		{
			inet_pton(AF_INET, SRC_ADDR, &src_addr.sin_addr);
		}


	/* Call real bind function */
		ret = (int)(*bind_ptr)(sockfd, 
					(void *)&src_addr, 
					sizeof(src_addr));
	}
	else
	{

#ifdef DEBUG
		fprintf(stderr, "Calling real bind unmolested\n");
#endif

	/* Call real bind function */
		ret = (int)(*bind_ptr)(sockfd, 
					(void *)my_addr, 
					addrlen);

	}
#ifdef DEBUG
	fprintf(stderr, "The real bind function returned: %d\n", ret);
#endif

	/* Clean up */
	dlclose(libc);

	return ret;

}

/* 
	Sometimes (alot of times) programs don't bother to call bind() 
	if they're just making an outgoing connection. To take care of
	these cases, we need to call bind when they call connect 
	instead. And of course, then call connect as well...
*/

int
connect(int  sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
{
	int	(*connect_ptr)(int, void *, int);
	void	*libc;
	int	ret;

#ifdef DEBUG
	fprintf(stderr, "connect() override called for addr: %s\n", SRC_ADDR);
#endif

	/* Before we call connect, let's call bind() and make sure we're
	   using our preferred source address.
	*/

	ret = bind(sockfd, NULL, 0); /* Our fake bind doesn't really need
					those params */

	libc = dlopen(LIBC_NAME, RTLD_LAZY);

	if (!libc)
	{
		fprintf(stderr, "Unable to open libc!\n");
		exit(-1);
	}

	*(void **) (&connect_ptr) = dlsym(libc, "connect");

	if (!connect_ptr)
	{
		fprintf(stderr, "Unable to locate connect function in lib\n");
		exit(-1);
	}


	/* Call real connect function */
	ret = (int)(*connect_ptr)(sockfd, (void *)serv_addr, addrlen);

	/* Clean up */
	dlclose(libc);

	return ret;	

}

 

 

How to check, add and delete routes in linux

There are two commands which are useful either to add or delete route, those are  route and ip. We will see how to change route using command route.

Route Synopsis

route
[-v] [-A family] add [-net|-host] target [netmask Nm] [gw Gw] [metric N] [mss M] [window W] [irtt I] [reject] [mod] [dyn] [reinstate] [[dev] If]
route
[-v] [-A family] del [-net|-host] target [gw Gw] [netmask Nm] [metric N] [[dev] If]
route
[-V] [--version] [-h] [--help]

To check the routing table

Command: nestat -rn

$ netstat -rn
Kernel IP routing table
Destination  Gateway      Genmask        Flags MSS Window irtt Iface
0.0.0.0      192.168.0.1  0.0.0.0        UG    0   0      0    wlan0
192.168.0.0  0.0.0.0      255.255.255.0  U     0   0      0    wlan0

Adding route

sudo route add -net 192.168.3.0 gw 192.168.1.1 netmask 255.255.255.0 dev eth0

Deleting route

sudo route del -net 192.168.3.0 gw 192.168.1.1 netmask 255.255.255.0 dev eth0

A quick way to add default route

route add default gw 192.168.1.1

A  quick way to delete defualt route

route del default gw 192.168.1.1

How to check routes (routing table) in linux

The route is nothing but a path or way to the specific or range of destination IP addresses. Linux kernel maintains these routes called as kernel routing table and will route the traffic accordingly.

You can use any one of them to display the routing table

route
netstat
ip

Command route

The command route is used to modify and check the existing routes. To check the routing table using route command,

$ route

This will display the list of routes currently configured

Command: route -n 

$ route -n
Kernel IP routing table
Destination    Gateway       Genmask        Flags  Metric Ref Use Iface
0.0.0.0        192.168.0.1   0.0.0.0        UG     0      0   0   wlan0
192.168.0.0    0.0.0.0       255.255.255.0  U      9      0   0   wlan0

This will give the output with out resolving the names

Command netstat

This command gives the statistics about the network. With this command you can do more than just printing routing table,

Print network connections,
routing tables,
interface statistics,
masquerade connections,  and
multicast memberships

To check the routing table,

Command: nestat -rn

$ netstat -rn
Kernel IP routing table
Destination  Gateway      Genmask        Flags MSS Window irtt Iface
0.0.0.0      192.168.0.1  0.0.0.0        UG    0   0      0    wlan0
192.168.0.0  0.0.0.0      255.255.255.0  U     0   0      0    wlan0

Where

Option -r  is to display the routing table

Option -n is not to resolve the names. Print the IP addresses only

Command IP

To check routing table using command ip 

Command: ip route list

$ ip route list
default via 192.168.0.1 dev wlan0 proto static 
192.168.0.0/24 dev wlan0 proto kernel scope link src 192.168.0.5 metric 9

To find hops, route of the destination and how your machine is reaching the destination you use tracepath

tracepath howto.lintel.in

Where you can replace howto.lintel.in with specific domain or IP address.

We added an updated article with more options on this topic.

Check out at https://howto.lintel.in/add-delete-routes-linux/