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
#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)
{
int socket_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
CHECK(socket_fd != -1, "%s", strerror(errno));
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;
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));
CHECK(ioctl(socket_fd, SIOCGIFINDEX, &if_options) != -1, "%s", strerror(errno));
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));
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) 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.