Click here to Skip to main content
15,867,568 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 15-Aug-22 0:01am
v2
Comments
NotTodayYo 9-Mar-21 14:20pm    
How could we possibly know what's wrong with the code? Just debug it.
[no name] 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. ;-)
 
Share this answer
 

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