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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
47
src/dpni20.c
47
src/dpni20.c
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
283
src/osdnet.c
283
src/osdnet.c
@@ -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 */
|
||||
|
||||
15
src/osdnet.h
15
src/osdnet.h
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user