1
0
mirror of https://github.com/PDP-10/klh10.git synced 2026-02-08 01:01:56 +00:00

Add tap/bridge support,

and some other small build support things for my environment.
This commit is contained in:
Olaf Seibert
2015-04-27 23:33:58 +02:00
parent f5ed23867f
commit 0a03946833
11 changed files with 374 additions and 36 deletions

View File

@@ -21,7 +21,7 @@
# Build definitions
SRC = ../../src
CFLAGS = -c -g3 -O3
CFLAGS = -c -g3 -O3 -ggdb
CFLAGS_LINT = -ansi -pedantic -Wall -Wshadow \
-Wstrict-prototypes -Wmissing-prototypes \
-Wmissing-declarations -Wredundant-decls

View File

@@ -228,6 +228,10 @@ default for every OS that implements /dev/tun.
#include <sys/resource.h> /* For setpriority() */
#include <sys/mman.h> /* For mlockall() */
#if CENV_SYS_NETBSD
#include <poll.h>
#endif
#include "dpimp.h" /* DPIMP specific defs, grabs DPSUP if needed */
#ifdef RCSID

View File

@@ -169,6 +169,7 @@ The following general situations are possible:
RCSID(dpni20_c,"$Id: dpni20.c,v 2.7 2003/02/23 18:07:50 klh Exp $")
#endif
/* Globals */
int chpid; /* PID of child, handles input (net-to-10). */
@@ -432,6 +433,8 @@ main(int argc, char **argv)
progname = progname_w; /* Reset progname to indicate identity */
tentoeth(dpni); /* Parent process handles output to net */
osn_pfdeinit();
return 1; /* Never returns, but placate compiler */
}
@@ -498,6 +501,7 @@ void net_init(register struct dpni20_s *dpni)
ea_set(&ihost_ea, &npf.osnpf_ea); /* Copy actual ea */
}
/* Now set any return info values in shared struct.
*/
memcpy(dpni->dpni_eth, (char *)&ihost_ea, 6); /* Copy ether addr */
@@ -996,7 +1000,7 @@ pfshow(struct OSN_PFSTRUCT *pf)
/* LNX packetfilter initialization */
#if KLH10_NET_LNX
#if KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
/*
The Linux PF_PACKET interface is described to some extent
@@ -1092,6 +1096,10 @@ int lnx_filter(register struct dpni20_s *dpni,
*/
void eth_adrset(register struct dpni20_s *dpni)
{
#if OSN_USE_IPONLY
dbprintln("\"%s\" multicast table ignored - IP-only interface",
dpni->dpni_ifnam);
#else
unsigned char rdea[ETHER_ADRSIZ];
char old[OSN_EASTRSIZ];
char new[OSN_EASTRSIZ];
@@ -1157,6 +1165,7 @@ void eth_adrset(register struct dpni20_s *dpni)
}
}
#endif
/* Assume succeeded since call succeeded, and clobber our address! */
memcpy(dpni->dpni_eth, dpni->dpni_rqeth, ETHER_ADRSIZ);
}
@@ -1175,6 +1184,10 @@ void eth_adrset(register struct dpni20_s *dpni)
void eth_mcatset(register struct dpni20_s *dpni)
{
#if OSN_USE_IPONLY
dbprintln("\"%s\" multicast table ignored - IP-only interface",
dpni->dpni_ifnam);
#else
ossock_t s;
int i, n, j;
char ethstr[OSN_EASTRSIZ];
@@ -1249,6 +1262,7 @@ void eth_mcatset(register struct dpni20_s *dpni)
nmcats = n;
memcpy(ethmcat[0], dpni->dpni_mcat[0], (n * 6));
#endif
}
/* ARP Hackery */
@@ -1361,7 +1375,9 @@ int arp_myreply(register unsigned char *buf, register int cnt)
/* Now send it! Ignore any errors. */
if (swstatus) {
char ipstr[OSN_IPSTRSIZ];
dbprintln("ARP MyReply %s", ip_adrsprint(ipstr, ife->ife_ipchr));
char ethstr[OSN_EASTRSIZ];
dbprintln("ARP MyReply %s %s", ip_adrsprint(ipstr, ife->ife_ipchr),
eth_adrsprint(ethstr, ife->ife_ea));
}
#if KLH10_NET_DLPI
@@ -1372,6 +1388,9 @@ int arp_myreply(register unsigned char *buf, register int cnt)
(void) putmsg(pffd, NULL, &data, 0);
}
#else
/* XXX
* Why is this sent to the packet filter (= host) and not to the -10?????
*/
(void)write(pffd, pktbuf, sizeof(pktbuf));
#endif
return TRUE;
@@ -1441,7 +1460,7 @@ void ethtoten(register struct dpni20_s *dpni)
cnt = data.len;
/* Else cnt must be -1 as call failed */
}
#elif KLH10_NET_NIT || KLH10_NET_PFLT || KLH10_NET_LNX
#elif KLH10_NET_NIT || KLH10_NET_PFLT || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
cnt = read(pffd, buff, max);
#elif KLH10_NET_BPF
cnt = read(pffd, tbuff, tmax);
@@ -1499,17 +1518,20 @@ void ethtoten(register struct dpni20_s *dpni)
else
dbprint("Read=%d", cnt);
}
#if KLH10_NET_LNX
#if KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
/* Linux has no packet filtering, thus must apply manual check to
each and every packet read, unless dedicated. Ugh!
*/
if (!dpni->dpni_dedic) {
if (KLH10_NET_TAP_BRIDGE || !dpni->dpni_dedic) {
/* Sharing interface. Check for IP, DECNET, 802.3 */
if (!lnx_filter(dpni, buff, cnt))
if (!lnx_filter(dpni, buff, cnt)) {
if (DBGFLG)
dbprint("Dropped");
continue; /* Drop packet, continue reading */
}
}
#endif /* KLH10_NET_LNX */
#if KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_PFLT || KLH10_NET_LNX
#if KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_PFLT || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
#if 0
if (DBGFLG)
if (((struct ether_header *)buff)->ether_type == htons(ETHERTYPE_ARP))
@@ -1521,7 +1543,7 @@ void ethtoten(register struct dpni20_s *dpni)
if (DBGFLG)
dbprint("sent RPKT");
#endif /* KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_PFLT || KLH10_NET_LNX */
#endif /* KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_PFLT || KLH10_NET_LNX || NET_TAP_BRIDGE */
#if KLH10_NET_BPF
/* Screwy BPF algorithm requires more overhead because there's
@@ -1594,7 +1616,11 @@ void tentoeth(register struct dpni20_s *dpni)
/* Must check for outbound ARP requests if asked to and have
** at least one entry in our table of host's IP interfaces.
*/
#if KLH10_NET_TAP_BRIDGE
doarpchk = 0;
#else
doarpchk = (dpni->dpni_doarp & DPNI_ARPF_OCHK) && (osn_nifents() > 0);
#endif
dpx = dp_dpxto(&dp); /* Get ptr to "To-DP" xfer stuff */
buff = dp_xrbuff(dpx, &max);
@@ -1640,7 +1666,7 @@ void tentoeth(register struct dpni20_s *dpni)
}
#else
cnt = write(pffd, buff, rcnt);
#endif
#endif /* else KLH10_NET_DLPI */
if (cnt != rcnt) {
if ((cnt < 0) && (errno == EINTR)) {
continue; /* Start over, may have new cmd */
@@ -1701,6 +1727,9 @@ void dumppkt(unsigned char *ucp, int cnt)
fprintf(stderr, "\r\n");
}
}
/* Add OSDNET shared code here */

View File

@@ -337,6 +337,7 @@ CMDDEF(cd_lights, fc_lights, CMRF_TLIN, "<hexaddr>",
KEYSBEGIN(fectbkeys)
KEYDEF("?", cd_ques)
KEYDEF("help", cd_help)
KEYDEF("exit", cd_quit)
KEYDEF("quit", cd_quit)
KEYDEF("load", cd_load)
KEYDEF("dump", cd_dump)
@@ -2765,6 +2766,7 @@ fc_dump(struct cmd_s *cm)
static void
fc_lights(struct cmd_s *cm)
{
#if KLH10_DEV_LITES /* Moby conditional for entire file */
unsigned long port = 0;
int c;
char *sloc = cm->cmd_arglin;
@@ -2783,6 +2785,7 @@ fc_lights(struct cmd_s *cm)
}
}
printf("?Bad address\n");
#endif /* KLH10_DEV_LITES */
}
/* Instruction printing routines */

View File

@@ -759,7 +759,7 @@ dw10_t op10ashc(register dw10_t d,
** must be done to the argument prior to the call!
*/
static dw10_t
x_ashc(register dw10_t d,
x_ashc(/*register*/ dw10_t d,
register int i)
{
#endif /* IFFLAGS */
@@ -3238,7 +3238,7 @@ static int qdivstep(qw10_t *aq,
register dw10_t d,
register int nmagbits)
{
register qw10_t qw;
/*register*/ qw10_t qw;
dw10_t quot;
register int qbit;

View File

@@ -68,7 +68,7 @@ int
osn_ifsock(char *ifnam, ossock_t *as)
{
#if (KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
KLH10_NET_TUN || KLH10_NET_LNX)
KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
return ((*as = socket(AF_INET, SOCK_DGRAM, 0)) >= 0);
#else
# error OSD implementation needed for osn_ifsock
@@ -79,7 +79,7 @@ int
osn_ifclose(ossock_t s)
{
#if (KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
KLH10_NET_TUN || KLH10_NET_LNX)
KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
return (close(s) >= 0);
#else
# error OSD implementation needed for osn_ifclose
@@ -161,6 +161,12 @@ or alternatively:
? (sizeof(struct ifreq) - sizeof(struct sockaddr) + (ifr).ifr_addr.sa_len) \
: sizeof(struct ifreq))
This has been made trickier by NetBSD 5.0, which doesn't put a sockaddr
but a (union with as largest member a) sockaddr_storage in the ifreq.
Now the size is always the same again, but not sizeof(struct sockaddr).
This can (probably) be recognised by the existence of
#define ifr_space ifr_ifru.ifru_space / * sockaddr_storage * /
*/
/*
Note that searching for AF_INET or IP addresses only finds interfaces that
@@ -288,7 +294,7 @@ osn_iftab_pass(int opts, int npass, int s, struct ifconf *ifc)
uses a variable-size "ifreq" entry! Choke...
*/
ifnext = ifp + 1; /* Assume normal entry at first */
#if NETIF_HAS_SALEN
#if NETIF_HAS_SALEN && !defined(ifr_space)
if (ifp->ifr_addr.sa_len > sizeof(struct sockaddr)) {
offset = ifp->ifr_addr.sa_len - sizeof(struct sockaddr);
ifnext = (struct ifreq *)((char *)ifnext + offset);
@@ -382,6 +388,8 @@ osn_iftab_pass(int opts, int npass, int s, struct ifconf *ifc)
}
}
#include <stddef.h>
void
osn_ifctab_show(FILE *f, struct ifconf *ifc)
{
@@ -393,7 +401,14 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
int nents = 0;
int nvary = 0;
fprintf(f, "Interface table: %ld bytes (%d entries if std addr len %d)\n",
fprintf(f, "sizeof struct ifreq = %d\r\n", (int) sizeof(struct ifreq));
fprintf(f, "IFNAMSIZ = %d\r\n", (int) IFNAMSIZ);
fprintf(f, "offset of struct sockaddr_storage = %d\r\n", (int) offsetof(struct ifreq, ifr_space));
fprintf(f, "sizeof struct sockaddr = %d\r\n", (int) sizeof(struct sockaddr));
fprintf(f, "sizeof struct sockaddr_storage = %d\r\n", (int) sizeof(struct sockaddr_storage));
fprintf(f, "sizeof union ifr_ifru = %d\r\n", (int) sizeof(ifr->ifr_ifru));
fprintf(f, "Interface table: %ld bytes (%d entries if std addr len %d)\r\n",
(long)ifc->ifc_len, ifc->ifc_len/sizeof(struct ifreq),
(int)sizeof(struct sockaddr));
@@ -408,18 +423,19 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
len = sizeof(struct sockaddr);
#endif
fprintf(f, "offset: %d\r\n", (int)((char *)ifr - (char *)ifc->ifc_req));
/* Output entry data */
fprintf(f, "%2d: \"%.*s\" fam %d, len %d",
fprintf(f, "%2d: \"%.*s\" sockaddr.sa_family %d, .sa_len %d",
i, (int)sizeof(ifr->ifr_name), ifr->ifr_name,
ifr->ifr_addr.sa_family, len);
if (len) {
cp = (unsigned char *) ifr->ifr_addr.sa_data;
fprintf(f, " = %x", *cp);
fprintf(f, " = (sockaddr.sa_data) %x", *cp);
for (--len; len > 0; --len) {
fprintf(f, ":%x", *++cp);
}
}
fprintf(f, "\n");
fprintf(f, "\r\n");
cp = (unsigned char *) ifr->ifr_addr.sa_data;
switch (ifr->ifr_addr.sa_family) {
@@ -429,7 +445,7 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
struct in_addr *in = &skin->sin_addr;
unsigned char *ucp = (unsigned char *) &in->s_addr;
fprintf(f, " AF_INET = port %d, IP %d.%d.%d.%d\n",
fprintf(f, " AF_INET = port %d, IP %d.%d.%d.%d\r\n",
(int)skin->sin_port,
ucp[0], ucp[1], ucp[2], ucp[3]);
}
@@ -439,7 +455,7 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
case AF_LINK:
{
struct sockaddr_dl *dla = (struct sockaddr_dl *) &ifr->ifr_addr;
fprintf(f, " AF_LINK = type %d, alen %d",
fprintf(f, " AF_LINK = type %d, sdl_alen %d",
dla->sdl_type, dla->sdl_alen);
if (len = dla->sdl_alen) {
cp = (unsigned char *) LLADDR(dla);
@@ -448,18 +464,23 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
fprintf(f, ":%x", *++cp);
}
}
fprintf(f, "\n");
fprintf(f, "\r\n");
}
break;
#endif
#if defined(AF_INET6)
case AF_INET6:
fprintf(f, " AF_INET6 (No handler for this)\r\n");
break;
#endif
default:
fprintf(f, " No handler for this family\n");
fprintf(f, " No handler for this family\r\n");
}
/* Move onto next entry */
#if NETIF_HAS_SALEN
#if NETIF_HAS_SALEN && !defined(ifr_space)
if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)) {
++nvary;
ifr = (struct ifreq *)((char *)(ifr + 1) +
@@ -469,10 +490,10 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
ifr++;
}
if (nvary)
fprintf(f, "Interface summary: %d entries of varying length\n",
fprintf(f, "Interface summary: %d entries of varying length\r\n",
nents);
else
fprintf(f, "Interface summary: %d entries of std length %d\n",
fprintf(f, "Interface summary: %d entries of std length %d\r\n",
nents, (int)sizeof(struct ifreq));
}
@@ -483,7 +504,7 @@ osn_iftab_show(FILE *f, struct ifent *ifents, int nents)
register struct ifent *ife;
int i;
fprintf(f, "Filtered IFE table: %d entries\n", nents);
fprintf(f, "Filtered IFE table: %d entries\r\n", nents);
for (i = 0, ife = ifents; i < nents; ++i, ++ife) {
fprintf(f, "%2d: \"%s\"", i, ife->ife_name);
@@ -502,7 +523,7 @@ osn_iftab_show(FILE *f, struct ifent *ifents, int nents)
fprintf(f, " (Other: fam %d)",
ife->ife_pother->ifr_addr.sa_family);
}
fprintf(f, "\n");
fprintf(f, "\r\n");
}
}
@@ -897,6 +918,9 @@ osn_ifeaget(int s, /* Socket for (AF_INET, SOCK_DGRAM, 0) */
return TRUE;
}
static struct eth_addr emhost_ea = /* Emulated host ether addr for tap */
{ 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };
/* OSN_PFEAGET - get physical ethernet address for an open packetfilter FD.
*
* Also not well documented, but generally easier to perform.
@@ -945,8 +969,20 @@ osn_pfeaget(int pfs, /* Packetfilter socket or FD */
}
ea_set(eap, endp.end_addr);
#elif KLH10_NET_BPF && !CENV_SYS_NETBSD && !CENV_SYS_FREEBSD
/* NetBSD no longer seems to support this */
#elif KLH10_NET_TAP_BRIDGE
/* If we do tap(4) + bridge(4), the ether address of the tap is wholly
* irrelevant, it is on the other side of the "wire".
* Our own address is something we can make up completely.
*/
if (emhost_ea.ea_octets[5] == 0xFF) {
time_t t = time(NULL);
emhost_ea.ea_octets[5] = t & 0xFE;
emhost_ea.ea_octets[4] = (t >> 8) & 0xFF;
emhost_ea.ea_octets[3] = (t >> 16) & 0xFF;
}
ea_set(eap, &emhost_ea); /* Return the ether address */
#elif (KLH10_NET_BPF && !CENV_SYS_NETBSD && !CENV_SYS_FREEBSD)
/* NetBSD no longer seems to support this (on bpf) */
struct ifreq ifr;
strncpy(ifr.ifr_name, ifnam, sizeof(ifr.ifr_name));
@@ -1131,7 +1167,7 @@ osn_ifeaset(int s, /* Socket for (AF_INET, SOCK_DGRAM, 0) */
char *ifnam, /* Interface name */
unsigned char *newpa) /* New ether address */
{
#if CENV_SYS_DECOSF || KLH10_NET_LNX \
#if CENV_SYS_DECOSF || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE \
|| (CENV_SYS_FREEBSD && defined(SIOCSIFLLADDR))
/* Common preamble code */
@@ -1190,6 +1226,8 @@ osn_ifeaset(int s, /* Socket for (AF_INET, SOCK_DGRAM, 0) */
if (ownsock) close(s);
return FALSE;
}
# elif KLH10_NET_TAP_BRIDGE
ea_set(&emhost_ea, newpa);
# else
# error "Unimplemented OS routine osn_ifeaset()"
# endif
@@ -1338,6 +1376,7 @@ pfopen(void)
}
#endif /* KLH10_NET_PFLT || KLH10_NET_BPF */
#if KLH10_NET_PFLT
@@ -1916,6 +1955,212 @@ osn_pfinit(struct osnpf *osnpf, void *arg)
}
#endif /* KLH10_NET_NIT */
/*
* Too bad that this is never called...
*/
osn_pfdeinit()
{
#if KLH10_NET_TAP_BRIDGE
void tap_bridge_close();
tap_bridge_close();
#endif
}
#if KLH10_NET_TAP_BRIDGE
osn_pfinit(register struct osnpf *osnpf, void *arg)
{
int fd;
char *ifnam = osnpf->osnpf_ifnam;
/* No "default interface" concept here */
if (!ifnam || !ifnam[0])
esfatal(1, "Packetfilter interface must be specified");
fd = tap_bridge_open(ifnam);
/* Now get our fresh new virtual interface's ethernet address.
*/
(void) osn_pfeaget(fd, ifnam, (unsigned char *)&(osnpf->osnpf_ea));
return fd;
}
#include <net/if_tap.h>
#include <net/if_bridgevar.h>
#include <stdint.h>
static struct ifreq br_ifr;
static struct ifreq tap_ifr;
static int my_tap;
/*
* A TAP is a virtual ethernet interface, much like TUN is a virtual IP
* interface. We can use it to inject packets into the Unix input stream,
* provided it is UP and the host side has a matching IP address and
* netmask (also much like TUN), or that it is bridged to another interface.
*
* Here we try to create the user-given interface and then bridge it to
* the "default" interface. This is probably the most common configuration.
* If something else is desired, the user can set up the tap herself,
* and we'll just use it as it is. This is useful for a routed approach,
* for instance.
*/
int
tap_bridge_open(char *ifnam)
{
int tapfd;
int res;
union ipaddr netmask;
char cmdbuff[128];
struct ifent *ife;
int s;
int i;
struct ifbreq br_req;
struct ifdrv br_ifd;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
esfatal(1, "tap_bridge_open: socket() failed");
}
/* try to create tapN as specified by the user */
memset(&tap_ifr, 0, sizeof(tap_ifr));
strcpy(tap_ifr.ifr_name, ifnam);
res = ioctl(s, SIOCIFCREATE, &tap_ifr);
if (res == 0) {
my_tap = 1;
dbprintln("Created host-side tap \"%s\"", ifnam);
} else {
if (errno != EEXIST)
esfatal(1, "tap_bridge_open: can't create tap \"%s\"?", ifnam);
my_tap = 0;
dbprintln("Host-side tap \"%s\" alread exists; use it as-is", ifnam);
}
sprintf(cmdbuff, "/dev/%s", ifnam);
tapfd = open(cmdbuff, O_RDWR, 0);
if (tapfd < 0) {
/* Note possible error meanings:
ENOENT - no such filename
ENXIO - not configured in kernel
*/
esfatal(1, "Couldn't find or open 10-side tap \"%s\"", cmdbuff);
}
dbprintln("Opened 10-side tap \"%s\"", cmdbuff);
/* Finally, turn on IFF_UP just in case the above didn't do it.
Note interface name is still there from the SIOCIFCREATE.
*/
if (ioctl(s, SIOCGIFFLAGS, &tap_ifr) < 0) {
esfatal(1, "tap_bridge_open tap SIOCGIFFLAGS failed");
}
if (!(tap_ifr.ifr_flags & IFF_UP)) {
tap_ifr.ifr_flags |= IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, &tap_ifr) < 0) {
esfatal(1, "tap_bridge_open tap SIOCSIFFLAGS failed");
}
if (DP_DBGFLG)
dbprint("tap_bridge_open tap did SIOCSIFFLAGS");
}
if (my_tap) {
for (i = 0; i < 1000; i++) {
/* try to create bridge%d */
memset(&br_ifr, 0, sizeof(br_ifr));
sprintf(br_ifr.ifr_name, "bridge%d", i);
res = ioctl(s, SIOCIFCREATE, &br_ifr);
if (res == 0)
break;
if (errno != EEXIST)
esfatal(1, "tap_bridge_open: can't create bridge \"%s\"?", br_ifr.ifr_name);
}
dbprintln("Created bridge \"%s\"", br_ifr.ifr_name);
/*
* Find default IP interface to bridge with.
* It might find the wrong one if there is more than one.
*/
ife = osn_ipdefault();
if (!ife)
esfatal(0, "Couldn't find default interface");
if (swstatus)
dbprintln("Bridging with default interface \"%s\"", ife->ife_name);
if (1) {
sprintf(cmdbuff, "/sbin/brconfig %s add %s add %s up",
br_ifr.ifr_name, ife->ife_name, ifnam);
res = system(cmdbuff);
dbprintln("%s => %d", cmdbuff, res);
} else {
/* do whatever brconfig bridge0 add intf0 does... */
memset(&br_ifd, 0, sizeof(br_ifd));
memset(&br_req, 0, sizeof(br_req));
/* set name of the bridge */
strcpy(br_ifd.ifd_name, br_ifr.ifr_name);
br_ifd.ifd_cmd = BRDGADD;
br_ifd.ifd_len = sizeof(br_req);
br_ifd.ifd_data = &br_req;
/* brconfig bridge0 add tap0 (the virtual interface) */
strcpy(br_req.ifbr_ifsname, ifnam);
res = ioctl(s, SIOCSDRVSPEC, &br_ifd);
if (res == -1)
esfatal(1, "tap_bridge_open: can't add virtual intf to bridge?");
/* brconfig bridge0 add vr0 (the hardware interface) */
strcpy(br_req.ifbr_ifsname, ife->ife_name);
res = ioctl(s, SIOCSDRVSPEC, &br_ifd);
if (res == -1)
esfatal(1, "tap_bridge_open: can't add real intf to bridge?");
/* Finally, turn on IFF_UP just in case the above didn't do it.
* Note interface name is still there.
*/
if (ioctl(s, SIOCGIFFLAGS, &br_ifr) < 0) {
esfatal(1, "tap_bridge_open bridge SIOCGIFFLAGS failed");
}
if (!(br_ifr.ifr_flags & IFF_UP)) {
br_ifr.ifr_flags |= IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, &br_ifr) < 0) {
esfatal(1, "tap_bridge_open bridge SIOCSIFFLAGS failed");
}
if (DP_DBGFLG)
dbprint("tap_bridge_open bridge did SIOCSIFFLAGS");
}
}
}
close(s);
return tapfd; /* Success! */
}
void
tap_bridge_close()
{
if (my_tap) {
int s, res;
struct ifreq tap_ifr;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
esfatal(1, "tap_bridge_close: socket() failed");
}
/* Destroy bridge */
res = ioctl(s, SIOCIFDESTROY, &br_ifr);
res = ioctl(s, SIOCIFDESTROY, &tap_ifr);
close(s);
}
}
#endif /* KLH10_NET_TAP_BRIDGE */
#if KLH10_NET_DLPI
/* DLPI packetfilter initialization */

View File

@@ -59,6 +59,9 @@
#ifndef KLH10_NET_DLPI /* Solaris Data Link Provider Interface */
# define KLH10_NET_DLPI 0
#endif
#ifndef KLH10_NET_TAP_BRIDGE /* BSD Ethernet Tunnel device + a bridge */
# define KLH10_NET_TAP_BRIDGE 0
#endif
#ifndef KLH10_NET_TUN /* BSD IP Tunnel device */
# define KLH10_NET_TUN 0
#endif
@@ -67,14 +70,18 @@
#endif
#if !(KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
KLH10_NET_TUN || KLH10_NET_LNX)
KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
/* None explicitly specified, pick a reasonable default */
# if (CENV_SYS_FREEBSD && OSN_USE_IPONLY)
# if ((CENV_SYS_NETBSD || CENV_SYS_FREEBSD) && OSN_USE_IPONLY)
# undef KLH10_NET_TUN
# define KLH10_NET_TUN 1
# elif (CENV_SYS_NETBSD || CENV_SYS_FREEBSD)
# undef KLH10_NET_BPF
# define KLH10_NET_BPF 1
/*
* # undef KLH10_NET_BPF
* # define KLH10_NET_BPF 1
*/
# undef KLH10_NET_TAP_BRIDGE
# define KLH10_NET_TAP_BRIDGE 1
# elif CENV_SYS_DECOSF
# undef KLH10_NET_PFLT
# define KLH10_NET_PFLT 1