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

Intermediate state.

Tested with NetBSD host and TOPS-20 guest only: ifmeth=pcap and ifmeth=tap+bridge work.
Not tested wit ITS guest or Linux host.
Not cleaned up.
This commit is contained in:
Olaf Seibert
2016-01-03 17:07:58 +01:00
parent 3586d96356
commit d23813a1dd
7 changed files with 536 additions and 361 deletions

View File

@@ -27,7 +27,11 @@ CFLAGS_LINT = -ansi -pedantic -Wall -Wshadow \
-Wmissing-declarations -Wredundant-decls
# Source definitions
CENVFLAGS = -DCENV_CPU_ALPHA=1 -DCENV_SYS_NETBSD=1 -include netbsd-sucks.h
CENVFLAGS = -DCENV_CPU_ALPHA=1 -DCENV_SYS_NETBSD=1 -include netbsd-sucks.h \
-DKLH10_NET_PCAP=1 \
-DKLH10_NET_TUN=1 \
-DKLH10_NET_TAP=1 \
-DKLH10_NET_BRIDGE=1
# Any target with no customized rule here is simply passed on to the
# standard Makefile. If no target is specified, "usage" is passed on

View File

@@ -305,7 +305,6 @@ void hosttoimp(struct dpimp_s *);
void net_init(struct dpimp_s *);
#if !KLH10_NET_TUN
void arp_init(struct dpimp_s *);
struct arpent *arptab_look(struct in_addr);
struct arpent *arp_look(struct in_addr, struct ether_addr *);
@@ -319,7 +318,6 @@ void arp_reply(unsigned char *eap, unsigned char *iap);
int hi_iproute(struct in_addr *ipa, unsigned char *lp, int cnt);
void ip_write(struct in_addr *, unsigned char *, int);
void ether_write(struct eth_header *, unsigned char *, int);
#endif /* !KLH10_NET_TUN */
void ihl_frag(int, unsigned char *);
void ihl_hhsend(struct dpimp_s *, int, unsigned char *);
@@ -745,10 +743,6 @@ net_init(struct dpimp_s *dpimp)
{ 0x06, 0, 0, 0x00000000 }, /* (005) ret #0 */
#endif
#define OSN_PFSTRUCT bpf_program
#define PF_FLEN bf_len
#define PF_FILT bf_insns
#define BPF_PFMAX 50 /* Max instructions in BPF filter */
struct bpf_insn bpf_pftab[BPF_PFMAX];
struct bpf_program bpf_pfilter = { 0,
@@ -806,17 +800,17 @@ struct bpf_insn bpf_jump(unsigned short code, bpf_u_int32 k,
#define BPFI_RETWIN() BPFI_RET((u_int)-1) /* Success return */
static void pfshow(struct OSN_PFSTRUCT *);
static void pfshow(struct bpf_program *);
struct OSN_PFSTRUCT *
struct bpf_program *
pfbuild(void *arg, struct in_addr *ipa)
{
struct dpimp_s *dpimp = (struct dpimp_s *)arg;
unsigned char *ucp = (unsigned char *)ipa;
struct OSN_PFSTRUCT *pfp = &bpf_pfilter;
struct bpf_program *pfp = &bpf_pfilter;
struct bpf_insn *p;
p = pfp->PF_FILT; /* Point to 1st instruction in BPF program */
p = pfp->bf_insns; /* Point to 1st instruction in BPF program */
/* We're interested in IP (and thus ARP as well) packets.
This is assumed to be the LAST part of the filter, thus
@@ -854,7 +848,7 @@ pfbuild(void *arg, struct in_addr *ipa)
*p++ = BPFI_RETFAIL(); /* Fail */
}
pfp->PF_FLEN = p - pfp->PF_FILT; /* Set # of items on list */
pfp->bf_len = p - pfp->bf_insns; /* Set # of items on list */
if (DBGFLG) /* If debugging, print out resulting filter */
pfshow(pfp);
@@ -865,18 +859,18 @@ pfbuild(void *arg, struct in_addr *ipa)
/* Debug auxiliary to print out packetfilter we composed.
*/
static void
pfshow(struct OSN_PFSTRUCT *pf)
pfshow(struct bpf_program *pf)
{
int i;
fprintf(stderr, "[dpimp: kernel packetfilter pri <>, len %d:\r\n",
/* pf->PF_PRIO, */ pf->PF_FLEN);
for (i = 0; i < pf->PF_FLEN; ++i)
/* pf->PF_PRIO, */ pf->bf_len);
for (i = 0; i < pf->bf_len; ++i)
fprintf(stderr, "%04X %2d %2d %0X\r\n",
pf->PF_FILT[i].code,
pf->PF_FILT[i].jt,
pf->PF_FILT[i].jf,
pf->PF_FILT[i].k);
pf->bf_insns[i].code,
pf->bf_insns[i].jt,
pf->bf_insns[i].jf,
pf->bf_insns[i].k);
fprintf(stderr, "]\r\n");
}
#endif /* KLH10_NET_PCAP */
@@ -921,7 +915,6 @@ int lnx_filter(struct dpimp_s *dpimp,
}
#if !KLH10_NET_TUN
/* ARP hacking code. Originally modelled after old BSD ARP stuff. */
@@ -1373,7 +1366,6 @@ arp_reply(unsigned char *eap, /* Requestor ether addr */
ether_write(&eh, (unsigned char *)&arp.arp, sizeof(arp.arp));
}
#endif /* !KLH10_NET_TUN */
/* IMPTOHOST - Child-process main loop for pumping packets from IMP to HOST.
** Reads packets from net, fragments if necessary, and feeds
@@ -1392,6 +1384,7 @@ imptohost(struct dpimp_s *dpimp)
unsigned char *buffp;
size_t max;
int stoploop = 50;
int ether_hdr_offset;
inibuf = dp_xsbuff(dpx, &max); /* Get initial buffer ptr */
@@ -1402,11 +1395,11 @@ imptohost(struct dpimp_s *dpimp)
if (DBGFLG)
fprintf(stderr, "[dpimp-R: sent INIT]\r\n");
#if KLH10_NET_TUN
# define ETHER_HDR_OFFSET 0 /* No ether headers on TUN */
#else
# define ETHER_HDR_OFFSET ETHER_HDRSIZ
#endif
if (pfdata.pf_ip4_only) {
ether_hdr_offset = 0;
} else {
ether_hdr_offset = ETHER_HDRSIZ;
}
for (;;) {
/* Make sure that buffer is free before clobbering it */
@@ -1416,12 +1409,12 @@ imptohost(struct dpimp_s *dpimp)
fprintf(stderr, "[dpimp-R: InWait]\r\n");
/* Set up buffer and initialize offsets */
buffp = inibuf + DPIMP_DATAOFFSET - ETHER_HDR_OFFSET;
buffp = inibuf + DPIMP_DATAOFFSET - ether_hdr_offset;
/* OK, now do a blocking read on packetfilter input! */
cnt = osn_pfread(&pfdata, buffp, MAXETHERLEN);
if (cnt <= ETHER_HDR_OFFSET) {
if (cnt <= ether_hdr_offset) {
/* If call times out due to E/BIOCSRTIMEOUT, will return 0 */
if (cnt == 0 && dpimp->dpimp_rdtmo)
continue; /* Just try again */
@@ -1463,8 +1456,7 @@ imptohost(struct dpimp_s *dpimp)
continue; /* Drop packet, continue reading */
}
#if !KLH10_NET_TUN
/* if (!pfdata.pf_ip4_only) */ {
if (!pfdata.pf_ip4_only) {
/* Verify that pf filtering is doing its job */
switch (eh_tget((struct eth_header *)buffp)) {
case ETHERTYPE_IP:
@@ -1478,13 +1470,12 @@ imptohost(struct dpimp_s *dpimp)
continue;
}
}
#endif
/* OK, it claims to be an IP packet, see if so long that we
** need to fragment it. Yech!
*/
cnt -= ETHER_HDR_OFFSET;
buffp += ETHER_HDR_OFFSET;
cnt -= ether_hdr_offset;
buffp += ether_hdr_offset;
if (cnt > SI_MAXMSG) {
ihl_frag(cnt, buffp);
@@ -1546,11 +1537,11 @@ ihl_hhsend(struct dpimp_s *dpimp,
/* Hack to set host/imp value as properly as possible. */
memcpy((char *)&haddr.ia_octet[0], pp + IPBOFF_SRC, 4);
if ((haddr.ia_addr.s_addr & ihost_nm.s_addr) != ihost_net.s_addr) {
#if !KLH10_NET_TUN
haddr.ia_addr = gwdef_ip; /* Not local, use default GW */
#else
haddr.ia_addr = tun_ip; /* Not local, use tunnel end */
#endif
if (pfdata.pf_ip4_only) {
haddr.ia_addr = tun_ip; /* Not local, use tunnel end */
} else {
haddr.ia_addr = gwdef_ip; /* Not local, use default GW */
}
}
ihobuf[SIH_HSIZ+SIL_HST] = haddr.ia_octet[1];
@@ -1598,9 +1589,7 @@ hosttoimp(struct dpimp_s *dpimp)
size_t max;
int rcnt;
unsigned char *inibuf;
#if !KLH10_NET_TUN
struct in_addr ipdest;
#endif
inibuf = dp_xrbuff(dpx, &max); /* Get initial buffer ptr */
@@ -1724,8 +1713,6 @@ hosttoimp(struct dpimp_s *dpimp)
}
}
#if !KLH10_NET_TUN
/* HI_IPROUTE - Determine where to actually send Host-Host IP datagram.
** See discussion of routing in comments at start of file.
For now, let's build the IP address by slapping the 1st IP byte
@@ -1831,7 +1818,6 @@ ether_write(struct eth_header *hp,
#endif
}
#endif /* !KLH10_NET_TUN */
void
dumppkt(unsigned char *ucp, int cnt)

View File

@@ -95,6 +95,8 @@
#define DPIMP_VERSION ((1<<10) | (1<<5) | (3)) /* 1.1.3 */
#define IFNAM_LEN 16 /* at least IFNAMSIZ! */
/* DPIMP-specific stuff */
/* C = controlling parent sets, D = Device proc sets */
/* If both, 1st letter indicates inital setter */
@@ -102,7 +104,7 @@ struct dpimp_s {
struct dpc_s dpimp_dpc; /* CD Standard DPC portion */
int dpimp_ver; /* C Version of shared struct */
int dpimp_attrs; /* C Attribute flags */
char dpimp_ifnam[16]; /* CD Interface name if any */
char dpimp_ifnam[IFNAM_LEN];/* CD Interface name if any */
char dpimp_ifmeth[16]; /* C Interface access method */
unsigned char dpimp_eth[6]; /* CD Ethernet address of interface */
unsigned char dpimp_ip[4]; /* C 10's IP address to filter on, if shared */

View File

@@ -170,6 +170,7 @@ The following general situations are possible:
int chpid; /* PID of child, handles input (net-to-10). */
int swstatus = TRUE;
struct osnpf npf;
struct pfdata pfdata; /* Packet-Filter state */
struct dp_s dp; /* Device-Process struct for DP ops */
@@ -191,6 +192,7 @@ struct ether_addr ihost_ea; /* Native host ether addr for selected ifc */
int nmcats = 0;
unsigned char ethmcat[DPNI_MCAT_SIZ][6]; /* Table of known MCAT addresses */
/* Local predeclarations */
void ethtoten(struct dpni20_s *);
@@ -393,10 +395,10 @@ main(int argc, char **argv)
dbprintln(" addr %s",
ip_adrsprint(sbuf, (unsigned char *)&ihost_ip));
#endif
#if KLH10_NET_TUN
dbprintln(" tun %s",
ip_adrsprint(sbuf, (unsigned char *)&tun_ip));
#endif
if (pfdata.pf_ip4_only) {
dbprintln(" tun %s",
ip_adrsprint(sbuf, (unsigned char *)&tun_ip));
}
dbprintln(" VHOST %s",
ip_adrsprint(sbuf, (unsigned char *)&ehost_ip));
}
@@ -439,7 +441,7 @@ main(int argc, char **argv)
progname = progname_w; /* Reset progname to indicate identity */
tentoeth(dpni); /* Parent process handles output to net */
osn_pfdeinit();
osn_pfdeinit(&pfdata, &npf);
return 1; /* Never returns, but placate compiler */
}
@@ -456,7 +458,7 @@ void net_init(struct dpni20_s *dpni)
/* Get the IP address for the tunnel, if specified */
memcpy((char *)&tun_ip, (char *)&dpni->dpni_tun, 4);
#if !KLH10_NET_TUN
/* Ensure network device name, if specified, isn't too long */
if (dpni->dpni_ifnam[0] && (strlen(dpni->dpni_ifnam)
>= sizeof(ifr.ifr_name))) {
@@ -489,7 +491,6 @@ void net_init(struct dpni20_s *dpni)
dbprintln("Using default interface \"%s\"", dpni->dpni_ifnam);
}
}
#endif
/* Now set remaining stuff */
@@ -497,7 +498,6 @@ void net_init(struct dpni20_s *dpni)
the ethernet address for the selected interface.
*/
{
struct osnpf npf;
npf.osnpf_ifnam = dpni->dpni_ifnam;
npf.osnpf_ifmeth = dpni->dpni_ifmeth;
@@ -560,10 +560,6 @@ void net_init(struct dpni20_s *dpni)
*/
#define OSN_PFSTRUCT bpf_program
#define PF_FLEN bf_len
#define PF_FILT bf_insns
#define BPF_PFMAX 50 /* Max instructions in BPF filter */
struct bpf_insn bpf_pftab[BPF_PFMAX];
struct bpf_program bpf_pfilter = { 0,
@@ -620,16 +616,16 @@ struct bpf_insn bpf_jump(unsigned short code, bpf_u_int32 k,
#define BPFI_RETFAIL() BPFI_RET(0) /* Failure return */
#define BPFI_RETWIN() BPFI_RET((u_int)-1) /* Success return */
static void pfshow(struct OSN_PFSTRUCT *);
static void pfshow(struct bpf_program *);
struct OSN_PFSTRUCT *
struct bpf_program *
pfbuild(void *arg, struct in_addr *ipa)
{
struct dpni20_s *dpni = (struct dpni20_s *)arg;
struct OSN_PFSTRUCT *pfp = &bpf_pfilter;
struct bpf_program *pfp = &bpf_pfilter;
struct bpf_insn *p;
p = pfp->PF_FILT; /* Point to 1st instruction in BPF program */
p = pfp->bf_insns; /* Point to 1st instruction in BPF program */
/* First check for broadcast/multicast bit in dest address */
*p++ = BPFI_LDB(PKBOFF_EDEST); /* Get 1st byte of dest ether addr */
@@ -737,7 +733,7 @@ pfbuild(void *arg, struct in_addr *ipa)
*p++ = BPFI_RETFAIL(); /* Fail */
}
pfp->PF_FLEN = p - pfp->PF_FILT; /* Set # of items on list */
pfp->bf_len = p - pfp->bf_insns; /* Set # of items on list */
if (DBGFLG) /* If debugging, print out resulting filter */
pfshow(pfp);
@@ -748,19 +744,19 @@ pfbuild(void *arg, struct in_addr *ipa)
/* Debug auxiliary to print out packetfilter we composed.
*/
static void
pfshow(struct OSN_PFSTRUCT *pf)
pfshow(struct bpf_program *pf)
{
int i;
fprintf(stderr, "[%s: kernel packetfilter pri <>, len %d:\r\n",
progname,
/* pf->PF_PRIO, */ pf->PF_FLEN);
for (i = 0; i < pf->PF_FLEN; ++i)
/* pf->PF_PRIO, */ pf->bf_len);
for (i = 0; i < pf->bf_len; ++i)
fprintf(stderr, "%04X %2d %2d %0X\r\n",
pf->PF_FILT[i].code,
pf->PF_FILT[i].jt,
pf->PF_FILT[i].jf,
pf->PF_FILT[i].k);
pf->bf_insns[i].code,
pf->bf_insns[i].jt,
pf->bf_insns[i].jf,
pf->bf_insns[i].k);
fprintf(stderr, "]\r\n");
}
@@ -1103,6 +1099,7 @@ int arp_myreply(unsigned char *buf, int cnt)
#endif
ucp += ETHER_ADRSIZ;
ea_set(ucp, (char *)&ihost_ea); /* Set source addr to ours! */
ucp[5]++; /* but modified to pass the echo check */
ucp += ETHER_ADRSIZ;
*ucp++ = (ETHERTYPE_ARP>>8)&0377; /* Set high byte of type */
*ucp++ = (ETHERTYPE_ARP )&0377; /* Set low byte of type */
@@ -1157,11 +1154,10 @@ int arp_myreply(unsigned char *buf, int cnt)
dpx = dp_dpxfr(&dp); /* Get ptr to from-DP comm rgn */
buff = dp_xsbuff(dpx, &max); /* Set up buffer ptr & max count */
/* Tell KLH10 we're initialized and ready by sending initial packet */
if (sizeof(pktbuf) <= max &&
dp_xswait(dpx)) { /* Wait until buff free, in case */
memcpy(buff, pktbuf, sizeof(pktbuf));
dp_xsend(dpx, DPNI_RPKT, cnt);
memcpy(buff, pktbuf, ARP_PKTSIZ);
dp_xsend(dpx, DPNI_RPKT, ARP_PKTSIZ);
if (DP_DBGFLG)
dbprint("sent ARP reply to -10");
}
@@ -1284,11 +1280,7 @@ void tentoeth(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);

View File

@@ -421,16 +421,18 @@ static int pareth(char *cp, unsigned char *adr)
#define OSN_PFSTRUCT bpf_program
struct OSN_PFSTRUCT *
struct bpf_program *
pfbuild(void *arg, struct in_addr *ipa)
{
return NULL;
}
struct OSN_PFSTRUCT *
struct bpf_program *
pfeabuild(void *arg, unsigned char *ea)
{
return NULL;
}
#define IFNAM_LEN 16 /* at least IFNAMSIZ! */
#include "osdnet.c"

File diff suppressed because it is too large Load Diff

View File

@@ -59,43 +59,45 @@
#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 */
#ifndef KLH10_NET_TUN /* IP Tunnel device */
# define KLH10_NET_TUN 0
#endif
#ifndef KLH10_NET_LNX /* Linux PF_PACKET interface */
# define KLH10_NET_LNX 0
#ifndef KLH10_NET_TAP /* Ethernet Tunnel device */
# define KLH10_NET_TAP 0
#endif
#ifndef KLH10_NET_BRIDGE /* Bridge (used with an Ethernet tunnel) */
# define KLH10_NET_BRIDGE 0
#endif
#ifndef KLH10_NET_PCAP /* pretty generic libpcap interface */
# define KLH10_NET_PCAP 0
#endif
#if !(KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
KLH10_NET_LNX || KLH10_NET_PCAP || KLH10_NET_TUN || KLH10_NET_TAP_BRIDGE)
KLH10_NET_LNX || KLH10_NET_PCAP || KLH10_NET_TUN || KLH10_NET_BRIDGE)
/* None explicitly specified, pick a reasonable default */
# if ((CENV_SYS_NETBSD || CENV_SYS_FREEBSD || CENV_SYS_LINUX) && OSN_USE_IPONLY)
# undef KLH10_NET_PCAP
# define KLH10_NET_PCAP 1
# if (CENV_SYS_NETBSD || CENV_SYS_FREEBSD || CENV_SYS_LINUX)
# undef KLH10_NET_TUN
# define KLH10_NET_TUN 1
# elif 0
# undef KLH10_NET_PCAP
# define KLH10_NET_PCAP 1
# elif (CENV_SYS_NETBSD || CENV_SYS_FREEBSD)
# undef KLH10_NET_TAP_BRIDGE
# define KLH10_NET_TAP_BRIDGE 1
# undef KLH10_NET_TAP
# define KLH10_NET_TAP 1
# undef KLH10_NET_BRIDGE
# define KLH10_NET_BRIDGE 1
# elif CENV_SYS_DECOSF
# undef KLH10_NET_PFLT
# define KLH10_NET_PFLT 1
# elif CENV_SYS_SUN
# undef KLH10_NET_NIT
# define KLH10_NET_NIT 1
# elif CENV_SYS_SOLARIS
# undef KLH10_NET_DLPI
# define KLH10_NET_DLPI 1
# elif CENV_SYS_LINUX
# undef KLH10_NET_LNX
# define KLH10_NET_LNX 1
# else
# error "Must specify a KLH10_NET_ configuration"
# endif
@@ -384,16 +386,32 @@ union ipaddr {
struct in_addr ia_addr;
};
struct pfdata;
struct osnpf;
typedef ssize_t (*osn_pfread_f)(struct pfdata *pfdata, void *buf, size_t nbytes);
typedef int (*osn_pfwrite_f)(struct pfdata *pfdata, const void *buf, size_t nbytes);
typedef void (*osn_pfdeinit_f)(struct pfdata *, struct osnpf *);
/*
* A structure that aggregates information about the packet filter variant
* which is in use.
*/
struct pfdata {
int pf_fd; /* most but not all have a file descriptor */
int pf_meth; /* which packet "filter" is in use */
void *pf_handle; /* pcap has a handle */
int pf_can_filter; /* has a packet filter built-in and enabled */
int pf_ip4_only; /* set TRUE for IP i/f; FALSE for ethernet i/f */
osn_pfread_f pf_read; /* indirection to packet reading function */
osn_pfwrite_f pf_write; /* indirection to packet writing function */
osn_pfdeinit_f pf_deinit; /* indirection to closing function */
};
#define PF_METH_NONE 0
#define PF_METH_PCAP 1
#define PF_METH_TUN 2
#define PF_METH_TAP 3
int osn_iftab_init(void);
int osn_nifents(void); /* # of entries cached by osn_iftab_init */
@@ -437,9 +455,11 @@ struct osnpf { /* Arg struct for common initialization params */
union ipaddr osnpf_tun; /* INOUT: IP address host side of tunnel */
struct ether_addr osnpf_ea; /* OUT: ether address of ifc */
};
/* the void * is an argument to pass on to pfbuild() */
void osn_pfinit(struct pfdata *, struct osnpf *, void *);
void osn_pfdeinit(void);
void osn_pfdeinit(struct pfdata *, struct osnpf *);
ssize_t osn_pfread(struct pfdata *pfdata, void *buf, size_t nbytes);
int osn_pfwrite(struct pfdata *pfdata, const void *buf, size_t nbytes);