Click here to Skip to main content
15,074,987 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
See more:
I tried my best in the following program. But it doesn't establish the bridge between two network cards. Would you please review it and say what's wrong?
Thanks
OS: Ubuntu 20.04
C++
// This is a program which is going to make the bridge between two interfaces. brctl is going to be replaced by this program.

#define Uses_CHECK
#define Uses_close
#define Uses_errno
#define Uses_ETH_P_ALL
#define Uses_FD_SET
#define Uses_htons
#define Uses_ifreq
#define Uses_ioctl
#define Uses_printf
#define Uses_signal
#define Uses_sockaddr_ll
#define Uses_socket
#define Uses_strerror
#include <general.dep>

int _sock[2];

int _CtrlCHandler()
{
	printf(" terminating...\n");
	CHECK(close(_sock[0]) != -1, "");
	CHECK(close(_sock[1]) != -1, "");
	printf("all sockets closed successfully.\n");
}

void CtrlCHandler(int dummy)
{
	_CtrlCHandler();
}

int OpenSocket(const char *ifname)
{
	// getting socket
	int socket_fd = socket(PF_PACKET, SOCK_RAW/*|SOCK_NONBLOCK*/, htons(ETH_P_ALL));
	CHECK(socket_fd != -1, "%s", strerror(errno));

	// init interface options struct with the interface name
	struct ifreq if_options;
	memset(&if_options, 0, sizeof(struct ifreq));
	strncpy(if_options.ifr_name, ifname, sizeof(if_options.ifr_name) - 1);
	if_options.ifr_name[sizeof(if_options.ifr_name) - 1] = 0;

	// enable promiscuous mode
	CHECK(ioctl(socket_fd, SIOCGIFFLAGS, &if_options) != -1, "%s", strerror(errno));
	if_options.ifr_flags |= IFF_PROMISC;
	CHECK(ioctl(socket_fd, SIOCSIFFLAGS, &if_options) != -1, "%s", strerror(errno));

	// get interface index
	CHECK(ioctl(socket_fd, SIOCGIFINDEX, &if_options) != -1, "%s", strerror(errno));

	// bind socket to the interface
	struct sockaddr_ll my_addr;
	memset(&my_addr, 0, sizeof(my_addr));
	my_addr.sll_family = AF_PACKET;
	my_addr.sll_ifindex = if_options.ifr_ifindex;
	CHECK(bind(socket_fd, (struct sockaddr *)&my_addr, sizeof(my_addr)) != -1, "%s", strerror(errno));

	// socket is ready
	return socket_fd;
}

int MakeBridge(const char *if1, const char *if2)
{
	_sock[0] = OpenSocket(if1);
	CHECK_NO_MSG(_sock[0]);
	_sock[1] = OpenSocket(if2);
	CHECK_NO_MSG(_sock[1]);
	printf("sockets %d and %d opened successfully\n", _sock[0], _sock[1]);

	fd_set readfds, orig;
	int activity;
	char buf[1<<16];
	signal(SIGINT, CtrlCHandler);
	int packetNumber = 0;
	const int numSocks = _countof(_sock);
	int nfds = _sock[0];
	for (int i = 1; i < numSocks; i++)
		if (_sock[i] > nfds)
			nfds = _sock[i];
	nfds++;
	FD_ZERO(&orig);
	for (int i = 0; i < numSocks; i++)
		FD_SET(_sock[i], &orig);
	while (true)
	{
		readfds = orig;
		activity = select(nfds, &readfds, NULL, NULL, NULL);
		if (activity == -1)  // sockets closed
			break;
		CHECK(activity > 0, "");
		for (int i = 0; i < numSocks; i++)
			if (FD_ISSET(_sock[i], &readfds))
			{
				int len = recvfrom(_sock[i], buf, sizeof(buf), MSG_TRUNC, NULL, NULL);
				CHECK(len > 0, "");
				CHECK(len <= sizeof(buf), "small size buffer");
				printf("%10d %d %d\n", ++packetNumber, i, len);
				CHECK(sendto(_sock[!i], buf, len, 0, NULL, 0) == len, "");
			}
	}

	return 0;
}

int Usage(int argc, const char *argv[])
{
	printf("Usage: %s <if1> <if2>\n", argv[0]);
	printf("Bridges two interfaces with the names specified.\n");
	return 0;
}

int main(int argc, const char *argv[])
{
	if (argc != 3)
		return Usage(argc, argv);
	CHECK_NO_MSG(MakeBridge(argv[1], argv[2]));
	return 0;
}


What I have tried:

I think the code may say everything. I need to forward everything I get from one interface to another, so that the bridge may shape.
Posted
Updated 10-Mar-21 7:04am
v2
Comments
NotTodayYo 9-Mar-21 14:20pm
   
How could we possibly know what's wrong with the code? Just debug it.
Gerry Schmitz 9-Mar-21 14:27pm
   
And what is this "bridge" supposed to do?

1 solution

looks like you need some Debugger tutorial.

A "bridge" may be not the best word, but establish a connection between two hosts which sounds more than Networking and Socket Programming Tutorial in C. ;-)
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900