Last active
November 2, 2018 11:59
-
-
Save tuxillo/7cb37c0b281524e6286e4cf24f2377ac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <err.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <net/ethernet.h> | |
#include <net/if.h> | |
#if defined(__DragonFly__) | |
#include <net/bridge/if_bridgevar.h> | |
#elif defined(__FreeBSD__) | |
#include <net/if_bridgevar.h> | |
#endif | |
#include <sys/ioctl.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
int | |
create_socket(int domain) | |
{ | |
int s; | |
if ((s = socket(domain, SOCK_DGRAM, 0)) == -1) | |
err(1, "socket"); | |
return s; | |
} | |
char * | |
create_if(int s, const char *type) | |
{ | |
struct ifreq ifr; | |
/* For the bridge creation request */ | |
memset(&ifr, 0, sizeof(ifr)); | |
snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", type); | |
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) { | |
perror("SIOCIFCREATE2"); | |
return NULL; | |
} | |
printf("if=%s created\n", ifr.ifr_name); | |
return strndup(ifr.ifr_name, IF_NAMESIZE); | |
} | |
int | |
destroy_if(int s, const char *ifname) | |
{ | |
struct ifreq ifr; | |
memset(&ifr, 0, sizeof(ifr)); | |
snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", ifname); | |
if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) { | |
perror("SIOCIFDESTROY"); | |
return -1; | |
} | |
printf("if=%s destroyed\n", ifr.ifr_name); | |
return 0; | |
} | |
int | |
add2bridge(int s, const char *bifname, const char *ifname) | |
{ | |
struct ifreq ifr; | |
struct ifbreq ifbr; | |
struct ifdrv ifd; | |
int flags; | |
memset(&ifbr, 0, sizeof(ifbr)); | |
memset(&ifr, 0, sizeof(ifr)); | |
memset(&ifd, 0, sizeof(ifd)); | |
snprintf(ifbr.ifbr_ifsname, IF_NAMESIZE, "%s", ifname); | |
snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", ifname); | |
/* Set the interface UP */ | |
flags = IFF_UP; | |
ifr.ifr_flags |= flags & 0xFFFF; | |
ifr.ifr_flagshigh |= flags >> 16; | |
if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) { | |
perror("SIOCSIFFLAGS"); | |
return -1; | |
} | |
#if 0 | |
/* Get bridge priority */ | |
snprintf(ifd.ifd_name, IF_NAMESIZE, "%s", bifname); | |
ifd.ifd_cmd = BRDGGPRI; | |
ifd.ifd_len = sizeof(ifbr); | |
ifd.ifd_data = &ifbr; | |
if (ioctl(s, SIOCGDRVSPEC, &ifd) < 0) { | |
if (errno != EEXIST) { | |
perror("SIOCGDRVSPEC"); | |
return -1; | |
} | |
} | |
#endif | |
/* Add the tap to the bridge */ | |
memset(&ifd, 0, sizeof(ifd)); | |
snprintf(ifd.ifd_name, IF_NAMESIZE, "%s", bifname); | |
ifd.ifd_cmd = BRDGADD; | |
ifd.ifd_len = sizeof(ifbr); | |
ifd.ifd_data = &ifbr; | |
if (ioctl(s, SIOCSDRVSPEC, &ifd) < 0) { | |
if (errno != EEXIST) { | |
perror("SIOCSDRVSPEC"); | |
return -1; | |
} | |
} | |
printf("Added %s to %s\n", ifname, bifname); | |
return 0; | |
} | |
void | |
test(int domain) | |
{ | |
char *bif_name, *tif_name; | |
char *dom_name; | |
int s; | |
bif_name = tif_name = NULL; | |
switch(domain) { | |
case PF_LOCAL: | |
dom_name = strndup("PF_LOCAL", 12); | |
break; | |
case PF_INET: | |
dom_name = strndup("PF_INET", 12); | |
break; | |
default: | |
return; | |
} | |
printf("------ Trying with domain=%s\n", dom_name); | |
s = create_socket(domain); | |
free(dom_name); | |
if ((bif_name = create_if(s, "bridge")) == NULL) | |
errx(1, "Failed to create bridge interface"); | |
if ((tif_name = create_if(s, "tap")) == NULL) { | |
destroy_if(s, tif_name); | |
errx(1, "Failed to create tap interface"); | |
} | |
/* Add to the bridge */ | |
if (add2bridge(s, bif_name, tif_name) == -1) | |
goto cleanup; | |
cleanup: | |
/* Cleanup the interfaces created */ | |
destroy_if(s, bif_name); | |
destroy_if(s, tif_name); | |
if (bif_name) | |
free(bif_name); | |
if (tif_name) | |
free(tif_name); | |
close(s); | |
} | |
int | |
main(int argc, char *argv[]) | |
{ | |
test(PF_LOCAL); | |
test(PF_INET); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment