Make IPKDB working again.

Add support for i386 debugging and pci-based ne2000 boards.
This commit is contained in:
ws 2000-03-22 20:58:25 +00:00
parent 5be5f12199
commit 7da71e5f9e
22 changed files with 1070 additions and 812 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files.i386,v 1.151 2000/03/16 14:53:29 ad Exp $
# $NetBSD: files.i386,v 1.152 2000/03/22 20:58:25 ws Exp $
#
# new style config file for i386 architecture
#
@ -54,6 +54,7 @@ file arch/i386/i386/disksubr.c disk
file arch/i386/i386/gdt.c
file arch/i386/i386/in_cksum.s inet
file netinet/in4_cksum.c inet
file arch/i386/i386/ipkdb_glue.c ipkdb
file arch/i386/i386/kgdb_machdep.c kgdb
file arch/i386/i386/machdep.c
file arch/i386/i386/math_emulate.c math_emulate

View File

@ -0,0 +1,144 @@
/* $NetBSD: ipkdb_glue.c,v 1.1 2000/03/22 20:58:27 ws Exp $ */
/*
* Copyright (C) 2000 Wolfgang Solfrank.
* Copyright (C) 2000 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by TooLs GmbH.
* 4. The name of TooLs GmbH may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NO TLIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRUCT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "opt_ipkdb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <ipkdb/ipkdb.h>
#include <machine/ipkdb.h>
#include <machine/psl.h>
int ipkdbregs[NREG];
int ipkdb_trap_glue __P((struct trapframe));
#ifdef IPKDB_NE_PCI
#include <dev/pci/pcivar.h>
int ne_pci_ipkdb_attach __P((struct ipkdb_if *, bus_space_tag_t, /* XXX */
pci_chipset_tag_t, int, int));
#endif
static char ipkdb_mode = IPKDB_CMD_EXIT;
void
ipkdbinit()
{
}
int
ipkdb_poll()
{
/* For now */
return 0;
}
void
ipkdb_trap()
{
ipkdb_mode = IPKDB_CMD_STEP;
__asm __volatile ("pushf; pop %%eax; orl %0,%%eax; push %%eax; popf"
:: "i"(PSL_T));
}
int
ipkdb_trap_glue(frame)
struct trapframe frame;
{
if (ISPL(frame.tf_cs) != SEL_KPL)
return 0;
if (ipkdb_mode == IPKDB_CMD_EXIT
|| (ipkdb_mode != IPKDB_CMD_STEP && frame.tf_trapno == T_TRCTRAP))
return 0;
__asm __volatile ("cli"); /* Interrupts need to be disabled while in IPKDB */
ipkdbregs[EAX] = frame.tf_eax;
ipkdbregs[ECX] = frame.tf_ecx;
ipkdbregs[EDX] = frame.tf_edx;
ipkdbregs[EBX] = frame.tf_ebx;
ipkdbregs[ESP] = (int)&frame.tf_esp;
ipkdbregs[EBP] = frame.tf_ebp;
ipkdbregs[ESI] = frame.tf_esi;
ipkdbregs[EDI] = frame.tf_edi;
ipkdbregs[EIP] = frame.tf_eip;
ipkdbregs[EFLAGS] = frame.tf_eflags;
ipkdbregs[CS] = frame.tf_cs;
ipkdbregs[SS] = 0x10;
ipkdbregs[DS] = frame.tf_ds;
ipkdbregs[ES] = frame.tf_es;
__asm ("movl %%fs,%0; movl %%gs,%1"
: "=r"(ipkdbregs[FS]), "=r"(ipkdbregs[GS]));
switch ((ipkdb_mode = ipkdbcmds())) {
case IPKDB_CMD_EXIT:
case IPKDB_CMD_RUN:
ipkdbregs[EFLAGS] &= ~PSL_T;
break;
case IPKDB_CMD_STEP:
ipkdbregs[EFLAGS] |= PSL_T;
break;
}
frame.tf_eax = ipkdbregs[EAX];
frame.tf_ecx = ipkdbregs[ECX];
frame.tf_edx = ipkdbregs[EDX];
frame.tf_ebx = ipkdbregs[EBX];
frame.tf_ebp = ipkdbregs[EBP];
frame.tf_esi = ipkdbregs[ESI];
frame.tf_edi = ipkdbregs[EDI];
frame.tf_eip = ipkdbregs[EIP];
frame.tf_eflags = ipkdbregs[EFLAGS];
frame.tf_cs = ipkdbregs[CS];
frame.tf_ds = ipkdbregs[DS];
frame.tf_es = ipkdbregs[ES];
__asm __volatile ("movl %0,%%fs; movl %1,%%gs"
:: "r"(ipkdbregs[FS]), "r"(ipkdbregs[GS]));
return 1;
}
int
ipkdbif_init(kip)
struct ipkdb_if *kip;
{
#ifdef IPKDB_NE_PCI
pci_mode_detect(); /* XXX */
if (ne_pci_ipkdb_attach(kip, I386_BUS_SPACE_IO, NULL, 0, IPKDB_NE_PCISLOT) == 0) {
printf("IPKDB on %s\n", kip->name);
return 0;
}
#endif
return -1;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.216 2000/02/21 20:06:08 dbj Exp $ */
/* $NetBSD: locore.s,v 1.217 2000/03/22 20:58:27 ws Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -76,6 +76,7 @@
#include "opt_cputype.h"
#include "opt_ddb.h"
#include "opt_ipkdb.h"
#include "opt_vm86.h"
#include "opt_user_ldt.h"
#include "opt_dummy_nops.h"
@ -2156,15 +2157,21 @@ ENTRY(savectx)
#define TRAP(a) pushl $(a) ; jmp _C_LABEL(alltraps)
#define ZTRAP(a) pushl $0 ; TRAP(a)
#ifdef IPKDB
#define BPTTRAP(a) pushl $0; pushl $(a); jmp _C_LABEL(bpttraps)
#else
#define BPTTRAP(a) ZTRAP(a)
#endif
.text
IDTVEC(trap00)
ZTRAP(T_DIVIDE)
IDTVEC(trap01)
ZTRAP(T_TRCTRAP)
BPTTRAP(T_TRCTRAP)
IDTVEC(trap02)
ZTRAP(T_NMI)
IDTVEC(trap03)
ZTRAP(T_BPTFLT)
BPTTRAP(T_BPTFLT)
IDTVEC(trap04)
ZTRAP(T_OFLOW)
IDTVEC(trap05)
@ -2329,6 +2336,86 @@ calltrap:
4: .asciz "WARNING: SPL NOT LOWERED ON TRAP EXIT\n"
#endif /* DIAGNOSTIC */
#ifdef IPKDB
NENTRY(bpttraps)
INTRENTRY
call _C_LABEL(ipkdb_trap_glue)
testl %eax,%eax
jz calltrap
INTRFASTEXIT
ipkdbsetup:
popl %ecx
/* Disable write protection: */
movl %cr0,%eax
pushl %eax
andl $~CR0_WP,%eax
movl %eax,%cr0
/* Substitute Protection & Page Fault handlers: */
movl _C_LABEL(idt),%edx
pushl 13*8(%edx)
pushl 13*8+4(%edx)
pushl 14*8(%edx)
pushl 14*8+4(%edx)
movl $fault,%eax
movw %ax,13*8(%edx)
movw %ax,14*8(%edx)
shrl $16,%eax
movw %ax,13*8+6(%edx)
movw %ax,14*8+6(%edx)
pushl %ecx
ret
ipkdbrestore:
popl %ecx
/* Restore Protection & Page Fault handlers: */
movl _C_LABEL(idt),%edx
popl 14*8+4(%edx)
popl 14*8(%edx)
popl 13*8+4(%edx)
popl 13*8(%edx)
/* Restore write protection: */
popl %edx
movl %edx,%cr0
pushl %ecx
ret
NENTRY(ipkdbfbyte)
pushl %ebp
movl %esp,%ebp
call ipkdbsetup
movl 8(%ebp),%edx
movzbl (%edx),%eax
faultexit:
call ipkdbrestore
popl %ebp
ret
NENTRY(ipkdbsbyte)
pushl %ebp
movl %esp,%ebp
call ipkdbsetup
movl 8(%ebp),%edx
movl 12(%ebp),%eax
movb %al,(%edx)
call ipkdbrestore
popl %ebp
ret
fault:
popl %eax /* error code */
movl $faultexit,%eax
movl %eax,(%esp)
movl $-1,%eax
iret
#endif /* IPKDB */
/*
* Old call gate entry for syscall
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.376 2000/02/04 14:21:33 minoura Exp $ */
/* $NetBSD: machdep.c,v 1.377 2000/03/22 20:58:27 ws Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@ -77,6 +77,7 @@
#include "opt_cputype.h"
#include "opt_ddb.h"
#include "opt_ipkdb.h"
#include "opt_vm86.h"
#include "opt_user_ldt.h"
#include "opt_compat_netbsd.h"
@ -106,6 +107,10 @@
#include <sys/kcore.h>
#include <machine/kcore.h>
#ifdef IPKDB
#include <ipkdb/ipkdb.h>
#endif
#ifdef KGDB
#include <sys/kgdb.h>
#endif
@ -1652,6 +1657,11 @@ init386(first_avail)
if (boothowto & RB_KDB)
Debugger();
#endif
#ifdef IPKDB
ipkdb_init();
if (boothowto & RB_KDB)
ipkdb_connect(0);
#endif
#ifdef KGDB
kgdb_port_init();
if (boothowto & RB_KDB) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: mainbus.c,v 1.29 1999/11/12 18:39:39 drochner Exp $ */
/* $NetBSD: mainbus.c,v 1.30 2000/03/22 20:58:27 ws Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -144,6 +144,7 @@ mainbus_attach(parent, self, aux)
mba.mba_pba.pba_iot = I386_BUS_SPACE_IO;
mba.mba_pba.pba_memt = I386_BUS_SPACE_MEM;
mba.mba_pba.pba_dmat = &pci_bus_dma_tag;
mba.mba_pba.pba_pc = NULL;
mba.mba_pba.pba_flags = pci_bus_flags();
mba.mba_pba.pba_bus = 0;
config_found(self, &mba.mba_pba, mainbus_print);

View File

@ -0,0 +1,53 @@
/* $NetBSD: ipkdb.h,v 1.1 2000/03/22 20:58:28 ws Exp $ */
/*
* Copyright (C) 2000 Wolfgang Solfrank.
* Copyright (C) 2000 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by TooLs GmbH.
* 4. The name of TooLs GmbH may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NO TLIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRUCT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* register array */
#define EAX 0
#define ECX 1
#define EDX 2
#define EBX 3
#define ESP 4
#define EBP 5
#define ESI 6
#define EDI 7
#define EIP 8
#define EFLAGS 9
#define CS 10
#define SS 11
#define DS 12
#define ES 13
#define FS 14
#define GS 15
#define NREG 16
extern int ipkdbregs[NREG];

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.357 2000/03/22 20:28:29 soren Exp $
# $NetBSD: files,v 1.358 2000/03/22 20:58:28 ws Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@ -163,22 +163,14 @@ define crypto
define arp
# Device description for machine-independent IPKDB code.
define ipkdb
device ipkdbif: ipkdb
device ipkdbslip: ipkdb
device ipkdbppp: ipkdb
defopt opt_ipkdb.h IPKDB : IPKDBKEY
defopt opt_ipkdb.h IPKDBSECURE : IPKDB
defparam opt_ipkdb.h IPKDBKEY : IPKDB
# Common files for any ipkdb support
file ipkdb/ipkdb_ipkdb.c ipkdb needs-flag
file ipkdb/ipkdb_ipkdb.c ipkdb
file ipkdb/ipkdb_if.c ipkdb
# Support for slip
file ipkdb/ipkdb_slip.c ipkdbslip needs-flag
# Support for ppp (for now only fake)
file ipkdb/ipkdb_ppp.c ipkdbppp needs-flag
# Attribute for devices that read/write an IEEE 802.3u MII bus
# using the bit-bang method.
# XXX Can't be in dev/mii/files.mii because that file hasn't
@ -277,8 +269,9 @@ device hme: arp, ether, ifnet, mii
file dev/ic/hme.c hme
# 8390-family Ethernet controllers
defopt opt_ipkdb.h IPKDB_DP8390 : IPKDB
define dp8390nic
file dev/ic/dp8390.c dp8390nic
file dev/ic/dp8390.c dp8390nic | IPKDB_DP8390
# TROPIC Token-Ring controller
device tr: arp, token, ifnet
@ -350,8 +343,9 @@ file dev/ic/tms320av110.c tms320av110
# Novell NE2000-compatible Ethernet cards, based on the
# National Semiconductor DS8390.
defopt opt_ipkdb.h IPKDB_NE : IPKDB_DP8390
device ne: ether, ifnet, arp, dp8390nic
file dev/ic/ne2000.c ne
file dev/ic/ne2000.c ne | IPKDB_NE
# 8250/16[45]50-based "com" ports
# XXX In a perfect world, this would be done with attributes

View File

@ -1,4 +1,4 @@
/* $NetBSD: dp8390.c,v 1.34 2000/03/22 18:02:59 ws Exp $ */
/* $NetBSD: dp8390.c,v 1.35 2000/03/22 20:58:28 ws Exp $ */
/*
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
@ -13,6 +13,7 @@
* the author assume any responsibility for damages incurred with its use.
*/
#include "opt_ipkdb.h"
#include "opt_inet.h"
#include "opt_ns.h"
#include "bpfilter.h"
@ -57,6 +58,10 @@
#include <machine/bus.h>
#ifdef IPKDB_DP8390
#include <ipkdb/ipkdb.h>
#endif
#include <dev/ic/dp8390reg.h>
#include <dev/ic/dp8390var.h>
@ -1355,3 +1360,273 @@ dp8390_detach(sc, flags)
return (0);
}
#ifdef IPKDB_DP8390
static void dp8390_ipkdb_hwinit __P((struct ipkdb_if *));
static void dp8390_ipkdb_init __P((struct ipkdb_if *));
static void dp8390_ipkdb_leave __P((struct ipkdb_if *));
static int dp8390_ipkdb_rcv __P((struct ipkdb_if *, u_char *, int));
static void dp8390_ipkdb_send __P((struct ipkdb_if *, u_char *, int));
/*
* This is essentially similar to dp8390_config above.
*/
int
dp8390_ipkdb_attach(kip)
struct ipkdb_if *kip;
{
struct dp8390_softc *sc = kip->port;
if (sc->mem_size < 8192 * 2)
sc->txb_cnt = 1;
else if (sc->mem_size < 8192 * 3)
sc->txb_cnt = 2;
else
sc->txb_cnt = 3;
sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT;
sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT);
sc->mem_ring = sc->mem_start + (sc->rec_page_start << ED_PAGE_SHIFT);
sc->mem_end = sc->mem_start + sc->mem_size;
dp8390_stop(sc);
kip->start = dp8390_ipkdb_init;
kip->leave = dp8390_ipkdb_leave;
kip->receive = dp8390_ipkdb_rcv;
kip->send = dp8390_ipkdb_send;
return 0;
}
/*
* Similar to dp8390_init above.
*/
static void
dp8390_ipkdb_hwinit(kip)
struct ipkdb_if *kip;
{
struct dp8390_softc *sc = kip->port;
struct ifnet *ifp = &sc->sc_ec.ec_if;
bus_space_tag_t regt = sc->sc_regt;
bus_space_handle_t regh = sc->sc_regh;
int i;
sc->txb_inuse = 0;
sc->txb_new = 0;
sc->txb_next_tx = 0;
dp8390_stop(sc);
if (sc->dcr_reg & ED_DCR_LS)
NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg);
else
NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
NIC_PUT(regt, regh, ED_P0_RBCR0, 0);
NIC_PUT(regt, regh, ED_P0_RBCR1, 0);
NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto);
NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0);
if (sc->is790)
NIC_PUT(regt, regh, 0x09, 0);
NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start);
NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start);
NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop);
NIC_PUT(regt, regh, ED_P0_IMR, 0);
NIC_BARRIER(regt, regh);
NIC_PUT(regt, regh, ED_P0_ISR, 0xff);
NIC_BARRIER(regt, regh);
NIC_PUT(regt, regh, ED_P0_CR,
sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
NIC_BARRIER(regt, regh);
for (i = 0; i < sizeof kip->myenetaddr; i++)
NIC_PUT(regt, regh, ED_P1_PAR0 + i, kip->myenetaddr[i]);
/* multicast filter? */
sc->next_packet = sc->rec_page_start + 1;
NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet);
NIC_BARRIER(regt, regh);
NIC_PUT(regt, regh, ED_P1_CR,
sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
NIC_BARRIER(regt, regh);
/* promiscuous mode? */
NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_AB | ED_RCR_AM | sc->rcr_proto);
NIC_PUT(regt, regh, ED_P0_TCR, 0);
/* card-specific initialization? */
NIC_BARRIER(regt, regh);
NIC_PUT(regt, regh, ED_P0_CR,
sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
ifp->if_flags &= ~IFF_OACTIVE;
}
static void
dp8390_ipkdb_init(kip)
struct ipkdb_if *kip;
{
struct dp8390_softc *sc = kip->port;
bus_space_tag_t regt = sc->sc_regt;
bus_space_handle_t regh = sc->sc_regh;
u_char cmd;
cmd = NIC_GET(regt, regh, ED_P0_CR) & ~(ED_CR_PAGE_3 | ED_CR_STA);
/* Select page 0 */
NIC_BARRIER(regt, regh);
NIC_PUT(regt, regh, ED_P0_CR, cmd | ED_CR_PAGE_0 | ED_CR_STP);
NIC_BARRIER(regt, regh);
/* If not started, init chip */
if (cmd & ED_CR_STP)
dp8390_ipkdb_hwinit(kip);
/* If output active, wait for packets to drain */
while (sc->txb_inuse) {
while (!(cmd = (NIC_GET(regt, regh, ED_P0_ISR)
& (ED_ISR_PTX | ED_ISR_TXE))))
DELAY(1);
NIC_PUT(regt, regh, ED_P0_ISR, cmd);
if (--sc->txb_inuse)
dp8390_xmit(sc);
}
}
static void
dp8390_ipkdb_leave(kip)
struct ipkdb_if *kip;
{
struct dp8390_softc *sc = kip->port;
struct ifnet *ifp = &sc->sc_ec.ec_if;
ifp->if_timer = 0;
}
/*
* Similar to dp8390_intr above.
*/
static int
dp8390_ipkdb_rcv(kip, buf, poll)
struct ipkdb_if *kip;
u_char *buf;
int poll;
{
struct dp8390_softc *sc = kip->port;
bus_space_tag_t regt = sc->sc_regt;
bus_space_handle_t regh = sc->sc_regh;
u_char bnry, current, isr;
int len, nlen, packet_ptr;
struct dp8390_ring packet_hdr;
/* Switch to page 0. */
NIC_BARRIER(regt, regh);
NIC_PUT(regt, regh, ED_P0_CR,
sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
NIC_BARRIER(regt, regh);
while (1) {
isr = NIC_GET(regt, regh, ED_P0_ISR);
NIC_PUT(regt, regh, ED_P0_ISR, isr);
if (isr & (ED_ISR_PRX | ED_ISR_TXE)) {
NIC_GET(regt, regh, ED_P0_NCR);
NIC_GET(regt, regh, ED_P0_TSR);
}
if (isr & ED_ISR_OVW) {
dp8390_ipkdb_hwinit(kip);
continue;
}
if (isr & ED_ISR_CNT) {
NIC_GET(regt, regh, ED_P0_CNTR0);
NIC_GET(regt, regh, ED_P0_CNTR1);
NIC_GET(regt, regh, ED_P0_CNTR2);
}
/* Similar to dp8390_rint above. */
NIC_BARRIER(regt, regh);
NIC_PUT(regt, regh, ED_P0_CR,
sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
NIC_BARRIER(regt, regh);
current = NIC_GET(regt, regh, ED_P1_CURR);
NIC_BARRIER(regt, regh);
NIC_PUT(regt, regh, ED_P1_CR,
sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
NIC_BARRIER(regt, regh);
if (sc->next_packet == current) {
if (poll)
return 0;
continue;
}
packet_ptr = sc->mem_ring
+ ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT);
sc->read_hdr(sc, packet_ptr, &packet_hdr);
len = packet_hdr.count;
nlen = packet_hdr.next_packet - sc->next_packet;
if (nlen < 0)
nlen += sc->rec_page_stop - sc->rec_page_start;
nlen--;
if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
nlen--;
len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
len -= sizeof(packet_hdr);
if (len <= ETHERMTU
&& packet_hdr.next_packet >= sc->rec_page_start
&& packet_hdr.next_packet < sc->rec_page_stop) {
sc->ring_copy(sc, packet_ptr + sizeof(packet_hdr),
buf, len);
sc->next_packet = packet_hdr.next_packet;
bnry = sc->next_packet - 1;
if (bnry < sc->rec_page_start)
bnry = sc->rec_page_stop - 1;
NIC_PUT(regt, regh, ED_P0_BNRY, bnry);
return len;
}
dp8390_ipkdb_hwinit(kip);
}
}
static void
dp8390_ipkdb_send(kip, buf, l)
struct ipkdb_if *kip;
u_char *buf;
int l;
{
struct dp8390_softc *sc = kip->port;
bus_space_tag_t regt = sc->sc_regt;
bus_space_handle_t regh = sc->sc_regh;
struct mbuf mb;
mb.m_next = NULL;
mb.m_pkthdr.len = mb.m_len = l;
mtod(&mb, u_char *) = buf;
mb.m_flags = M_EXT | M_PKTHDR | M_EOR;
mb.m_type = MT_DATA;
l = sc->write_mbuf(sc, &mb,
sc->mem_start + ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT));
sc->txb_len[sc->txb_new] = max(l, ETHER_MIN_LEN - ETHER_CRC_LEN);
if (++sc->txb_new == sc->txb_cnt)
sc->txb_new = 0;
sc->txb_inuse++;
dp8390_xmit(sc);
while (!(NIC_GET(regt, regh, ED_P0_ISR) & (ED_ISR_PTX | ED_ISR_TXE)))
DELAY(1);
sc->txb_inuse--;
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: dp8390var.h,v 1.17 2000/03/22 18:02:59 ws Exp $ */
/* $NetBSD: dp8390var.h,v 1.18 2000/03/22 20:58:28 ws Exp $ */
/*
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
@ -163,3 +163,7 @@ void dp8390_disable __P((struct dp8390_softc *));
int dp8390_activate __P((struct device *, enum devact));
int dp8390_detach __P((struct dp8390_softc *, int));
#ifdef IPKDB_DP8390
int dp8390_ipkdb_attach __P((struct ipkdb_if *));
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: ne2000.c,v 1.28 2000/03/22 18:02:59 ws Exp $ */
/* $NetBSD: ne2000.c,v 1.29 2000/03/22 20:58:28 ws Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@ -54,6 +54,8 @@
* Common code shared by all NE2000-compatible Ethernet interfaces.
*/
#include "opt_ipkdb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
@ -77,6 +79,10 @@
#define bus_space_read_multi_stream_2 bus_space_read_multi_2
#endif /* __BUS_SPACE_HAS_STREAM_METHODS */
#ifdef IPKDB_NE
#include <ipkdb/ipkdb.h>
#endif
#include <dev/ic/dp8390reg.h>
#include <dev/ic/dp8390var.h>
@ -93,7 +99,7 @@ void ne2000_read_hdr __P((struct dp8390_softc *, int, struct dp8390_ring *));
int ne2000_test_mem __P((struct dp8390_softc *));
void ne2000_writemem __P((bus_space_tag_t, bus_space_handle_t,
bus_space_tag_t, bus_space_handle_t, u_int8_t *, int, size_t,
bus_space_tag_t, bus_space_handle_t, u_int8_t *, int, size_t,
int, int));
void ne2000_readmem __P((bus_space_tag_t, bus_space_handle_t,
bus_space_tag_t, bus_space_handle_t, int, u_int8_t *, size_t, int));
@ -798,3 +804,100 @@ ne2000_detach(sc, flags)
return (dp8390_detach(&sc->sc_dp8390, flags));
}
#ifdef IPKDB_NE
/*
* This code is essentially the same as ne2000_attach above.
*/
int
ne2000_ipkdb_attach(kip)
struct ipkdb_if *kip;
{
struct ne2000_softc *np = kip->port;
struct dp8390_softc *dp = &np->sc_dp8390;
bus_space_tag_t nict = dp->sc_regt;
bus_space_handle_t nich = dp->sc_regh;
int i, useword;
#ifdef GWETHER
/* Not supported (yet?) */
return -1;
#endif
if (np->sc_type == 0)
np->sc_type = ne2000_detect(nict, nich,
np->sc_asict, np->sc_asich);
if (np->sc_type == 0)
return -1;
useword = NE2000_USE_WORD(np);
dp->cr_proto = ED_CR_RD2;
dp->dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (useword ? ED_DCR_WTS : 0);
dp->rcr_proto = 0;
dp->test_mem = ne2000_test_mem;
dp->ring_copy = ne2000_ring_copy;
dp->write_mbuf = ne2000_write_mbuf;
dp->read_hdr = ne2000_read_hdr;
for (i = 0; i < 16; i++)
dp->sc_reg_map[i] = i;
switch (np->sc_type) {
case NE2000_TYPE_NE1000:
dp->mem_start = dp->mem_size = 8192;
kip->name = "ne1000";
break;
case NE2000_TYPE_NE2000:
dp->mem_start = dp->mem_size = 8192 * 2;
kip->name = "ne2000";
break;
case NE2000_TYPE_DL10019:
dp->mem_start = dp->mem_size = 8192 * 3;
kip->name = "dl10019";
break;
case NE2000_TYPE_AX88190:
dp->rcr_proto = ED_RCR_INTT;
dp->sc_flags |= DP8390_DO_AX88190_WORKAROUND;
dp->mem_start = dp->mem_size = 8192 * 2;
kip->name = "ax88190";
break;
}
if (dp8390_ipkdb_attach(kip))
return -1;
dp->mem_ring = dp->mem_start
+ ((dp->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
if (!(kip->flags & IPKDB_MYHW)) {
char romdata[16];
/* Read the station address. */
if (np->sc_type == NE2000_TYPE_AX88190) {
/* Select page 0 registers. */
NIC_BARRIER(nict, nich);
bus_space_write_1(nict, nich, ED_P0_CR,
ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
NIC_BARRIER(nict, nich);
/* Select word transfer */
bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_WTS);
ne2000_readmem(nict, nich, np->sc_asict, np->sc_asich,
NE2000_AX88190_NODEID_OFFSET, kip->myenetaddr,
ETHER_ADDR_LEN, useword);
} else {
ne2000_readmem(nict, nich, np->sc_asict, np->sc_asich,
0, romdata, sizeof romdata, useword);
useword = useword ? 2 : 1;
for (i = 0; i < ETHER_ADDR_LEN; i++)
kip->myenetaddr[i] = romdata[i * useword];
}
kip->flags |= IPKDB_MYHW;
}
dp8390_stop(dp);
return 0;
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: ne2000var.h,v 1.10 2000/02/09 15:40:24 enami Exp $ */
/* $NetBSD: ne2000var.h,v 1.11 2000/03/22 20:58:28 ws Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@ -66,4 +66,8 @@ int ne2000_detect __P((bus_space_tag_t, bus_space_handle_t,
bus_space_tag_t, bus_space_handle_t));
int ne2000_detach __P((struct ne2000_softc *, int));
#ifdef IPKDB_NE
int ne2000_ipkdb_attach __P((struct ipkdb_if *));
#endif
#endif /* _DEV_IC_NE2000VAR_H_ */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.pci,v 1.80 2000/03/22 00:43:47 cgd Exp $
# $NetBSD: files.pci,v 1.81 2000/03/22 20:58:29 ws Exp $
#
# Config file and device description for machine-independent PCI code.
# Included by ports that need it. Requires that the SCSI files be
@ -109,8 +109,10 @@ attach fxp at pci with fxp_pci
file dev/pci/if_fxp_pci.c fxp_pci
# NE2000-compatible PCI Ethernet cards
defparam opt_ipkdb.h IPKDB_NE_PCISLOT : IPKDB_NE_PCI
defopt opt_ipkdb.h IPKDB_NE_PCI : IPKDB_NE IPKDB_NE_PCISLOT
attach ne at pci with ne_pci: rtl80x9
file dev/pci/if_ne_pci.c ne_pci
file dev/pci/if_ne_pci.c ne_pci | IPKDB_NE_PCI
# Texas Instruments ThunderLAN Chip.
device tl: ether, ifnet, arp, i2c, i2c_eeprom, mii, mii_bitbang

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ne_pci.c,v 1.15 2000/03/06 03:07:08 mark Exp $ */
/* $NetBSD: if_ne_pci.c,v 1.16 2000/03/22 20:58:29 ws Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@ -37,6 +37,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "opt_ipkdb.h"
#include "opt_inet.h"
#include "bpfilter.h"
@ -59,6 +60,10 @@
#include <machine/bus.h>
#include <machine/intr.h>
#ifdef IPKDB_NE_PCI
#include <ipkdb/ipkdb.h>
#endif
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
@ -86,6 +91,18 @@ struct cfattach ne_pci_ca = {
sizeof(struct ne_pci_softc), ne_pci_match, ne_pci_attach
};
#ifdef IPKDB_NE_PCI
static struct ne_pci_softc ipkdb_softc;
static pci_chipset_tag_t ipkdb_pc;
static pcitag_t ipkdb_tag;
static struct ipkdb_if *ne_kip;
int ne_pci_ipkdb_attach __P((struct ipkdb_if *, bus_space_tag_t, /* XXX */
pci_chipset_tag_t, int, int));
static int ne_pci_isipkdb __P((pci_chipset_tag_t, pcitag_t));
#endif
const struct ne_pci_product {
pci_vendor_id_t npp_vendor;
pci_product_id_t npp_product;
@ -214,6 +231,13 @@ ne_pci_attach(parent, self, aux)
printf(": %s Ethernet\n", npp->npp_name);
#ifdef IPKDB_NE_PCI
if (ne_pci_isipkdb(pc, pa->pa_tag)) {
nict = ipkdb_softc.sc_ne2000.sc_dp8390.sc_regt;
nich = ipkdb_softc.sc_ne2000.sc_dp8390.sc_regh;
ne_kip->port = nsc;
} else
#endif
if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
&nict, &nich, NULL, NULL)) {
printf("%s: can't map i/o space\n", dsc->sc_dev.dv_xname);
@ -279,3 +303,71 @@ ne_pci_attach(parent, self, aux)
}
printf("%s: interrupting at %s\n", dsc->sc_dev.dv_xname, intrstr);
}
#ifdef IPKDB_NE_PCI
static int
ne_pci_isipkdb(pc, tag)
pci_chipset_tag_t pc;
pcitag_t tag;
{
return !memcmp(&pc, &ipkdb_pc, sizeof pc)
&& !memcmp(&tag, &ipkdb_tag, sizeof tag);
}
int
ne_pci_ipkdb_attach(kip, iot, pc, bus, dev)
struct ipkdb_if *kip;
bus_space_tag_t iot;
pci_chipset_tag_t pc;
int bus, dev;
{
struct pci_attach_args pa;
bus_space_tag_t nict, asict;
bus_space_handle_t nich, asich;
u_int32_t csr;
pa.pa_iot = iot;
pa.pa_pc = pc;
pa.pa_device = dev;
pa.pa_function = 0;
pa.pa_flags = PCI_FLAGS_IO_ENABLED;
pa.pa_tag = pci_make_tag(pc, bus, dev, /*func*/0);
pa.pa_id = pci_conf_read(pc, pa.pa_tag, PCI_ID_REG);
pa.pa_class = pci_conf_read(pc, pa.pa_tag, PCI_CLASS_REG);
if (ne_pci_lookup(&pa) == NULL)
return -1;
if (pci_mapreg_map(&pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
&nict, &nich, NULL, NULL))
return -1;
asict = nict;
if (bus_space_subregion(nict, nich, NE2000_ASIC_OFFSET,
NE2000_ASIC_NPORTS, &asich)) {
bus_space_unmap(nict, nich, NE2000_NPORTS);
return -1;
}
/* Enable card */
csr = pci_conf_read(pc, pa.pa_tag, PCI_COMMAND_STATUS_REG);
pci_conf_write(pc, pa.pa_tag, PCI_COMMAND_STATUS_REG,
csr | PCI_COMMAND_MASTER_ENABLE);
ipkdb_softc.sc_ne2000.sc_dp8390.sc_regt = nict;
ipkdb_softc.sc_ne2000.sc_dp8390.sc_regh = nich;
ipkdb_softc.sc_ne2000.sc_asict = asict;
ipkdb_softc.sc_ne2000.sc_asich = asich;
kip->port = &ipkdb_softc;
ipkdb_pc = pc;
ipkdb_tag = pa.pa_tag;
ne_kip = kip;
if (ne2000_ipkdb_attach(kip) < 0) {
bus_space_unmap(nict, nich, NE2000_NPORTS);
return -1;
}
return 0;
}
#endif

View File

@ -1,4 +1,4 @@
$NetBSD: README.port,v 1.2 1997/06/26 07:21:44 thorpej Exp $
$NetBSD: README.port,v 1.3 2000/03/22 20:58:29 ws Exp $
What to Look for when Porting the IPKDB Interface
===============================================
@ -17,62 +17,53 @@ General Considerations
There is a problem when the debugger uses the same ethernet board as
does the rest of the kernel. For one thing there might arrive packets
destined for the kernel during debugging sessions. Since the debugger
receives all available packets for the time being it has to deliver
back to the driver those packets it has no use for. This implies that
the debugging driver must leave the interrupt pending conditions alone
so that the kernel driver gets the interrupt at the next time its
interrupt is enabled (whether this is when the debugger is left or
later with an spl*()). The same holds for the transmit interrupt
pending, at least when ipkdbinit determines that there is some packet
on its way out.
destined for the kernel during debugging sessions. These packets
are currently lost. For packets on their way out the driver has
to leave the interrupt pending condition alone, so the interrupt
handler gets a chance to send more packets via the interface.
Configuration Files
The interface that is used for debugging has to have a unique
attribute with the option "disable", and must allow the attachment
of a ipkdbif. The relevant part of the "files" file for interface
"xx" would look like this:
For any interface that may be used for debugging there should be
an option, put into opt_ipkdb.h, that is enabled if the kernel
shall actually use this interface. The relevant part of the
"files" file for interface "xx" would look like this:
define ipkdbxx { [ disable = 0 ] }
device xx: ether, ifnet, ipkdbxx
attach xx at yy
file dev/zz/if_xx.c xx | ipkdb_xx needs-flag
attach ipkdbif at ipkdbxx with ipkdb_xx
defopt opt_ipkdb.h IPKDB_XX : IPKDB
device xx: ether, ifnet, arp
file dev/zz/if_xx.c xx | ipkdb_xx
with proper values for yy and zz. The file dev/zz/if_xx.c contains
both the code of the kernel driver and the IPKDB driver for this
interface. You might want to #include "xx.h" in there and
conditionalize the compilation of the IPKDB driver with
#if NIPKDB_XX > 0.
The file dev/zz/if_xx.c contains both the code of the kernel
driver and the IPKDB driver for this interface. You should
#include "opt_ipkdb.h" in there and conditionalize the
compilation of the IPKDB driver with
#ifdef IPKDB_XX
The appropriate part of the machine configuration would read like
this:
xx* at yy
ipkdbif0 at xx?
options IPKDBKEY="\"IPKDB key for remote debugging\""
options IPKDB_XX
Note that the unit for ipkdbif in the configuration file must be
given explicitly! It's used to distinguish the interface used
for debugging from the one you want to debug a new interface
driver for (see below).
Driver Code
The interface is "probed" by calling the parent probe routine with
a first argument of NULL. The last argument to the probe routine
is a struct ipkdb_if pointer that needs to be (partly) initialized by
the probe code. Fields to be set by the probe routine are:
In order to be able to find the debugging interface, the driver
has to provide an attach routine that the machine dependent code
can call at an appropriate time (see below). The attach routine
should take as its first argument a pointer to a struct ipkdb_if
plus some additional parameters that allow it to access the
devices registers, hopefully using bus_space_* methods.
In the ipkdb_if structure, the attach routine must initialize
the following fields:
myenetaddr fill this with the own ethernet address of
the device/machine.
flags mark at least IPKDB_MYHW here.
name Name of the device, only used for a message.
port Port number, only used for a message by
machine/device independent code.
start routine called everytime IPKDB is entered.
leave routine called everytime IPKDB is left.
receive routine called to receive a packet.
@ -82,14 +73,13 @@ Additional fields that may be set are:
myinetaddr fill this with the own internet address,
and mark IPKDB_MYIP in flags.
unit These remaining fields are solely for
speed use by the driver.
fill
drvflags
port may be used as a pointer to some device
dependent data. Unused by other code.
The routine should check for existance of the ethernet board.
This routine should also try to find the system driver for the
same board and note its unit and device structure for later use.
This routine should also note enough information so it is able
to later find the system driver instance for the same board in
order to coordinate its action with the system driver.
The routine should return 0 on success and -1 on failure.
@ -104,9 +94,9 @@ kip is a pointer to the ipkdb_if structure used for debugging.
It should initialize the hardware and software interface.
This routine should also note the current state of the ethernet board
(as far as it can) so a later call to leave can reinstantiate this
state.
This routine should also note the current state of the board
(as far as it can) so a later call to leave can reinstantiate
this state.
void leave(struct ipkdb_if *kip)
@ -124,7 +114,7 @@ contain the ethernet checksum.
If poll is set, it should return immediately, if no packet is available.
Otherwise it should wait for the next packet.
This routine should return the number of bytes transferred to buf.
This routine shall return the number of bytes transferred to buf.
void send(struct ipkdb_if *kip, u_char *buf, int l)
@ -133,37 +123,10 @@ interface. The packet is already complete with the ethernet header,
but does not contain the ethernet checksum.
Debugging
If you have a working IPKDB, you can test new interface code for a
different interface by supplying "option IPKDBTEST" and attaching
a ipkdbif1 to the new interface in your configuration file. When
you boot the resulting kernel with the "-d" option, this will
initialize the new interface right after starting IPKDB on the
working one. Thereafter, the code will continue to send and
receive packets on the new interface until you set the variable
"ipkdb_test" to 0.
Note that during debugging interface code this way you are using
most of the code that comprises the debugger code itself. So you
have to be extremely careful with setting breakpoints and the like.
Interface between IPKDB and Machine (sys/arch/xxx/xxx/ipkdb_glue.c)
-----------------------------------------------------------------
void ipkdbcopy(s,d,n) void *s, *d; int n;
void ipkdbzero(d,n) void *d; int n;
void ipkdbcmp(s,d,n) char *s, *d; int n;
These routines are the same as bcopy, bzero and bcmp resp. They are
here with other names to allow setting breakpoints into the normal
routines during debugging. This implies that you shouldn't use
things like structure assignement in the code that gets used by
the debugger.
void ipkdbinit(void)
This routine gets called when the debugger should be entered for the

View File

@ -1,4 +1,4 @@
$NetBSD: TODO,v 1.2 1997/06/26 07:21:45 thorpej Exp $
$NetBSD: TODO,v 1.3 2000/03/22 20:58:29 ws Exp $
These are not necessarily in order of importance:
@ -21,6 +21,3 @@ and the rest of the kernel, I think).
Support prespecification of debugging host in the config file
to better control access to the debuggee.
Allow different source debugging ports for debugging multiple
machines from one debugger machine.

View File

@ -1,23 +0,0 @@
/* $NetBSD: debuggers.h,v 1.3 1997/06/26 07:21:45 thorpej Exp $ */
/*
* debuggers.h
* Generated by config program
*/
#include <ipkdb/ipkdb.h>
struct ipkdb_allow ipkdballow[] = {
#ifdef DEBUG_BY_TOOLS
{ { 255, 255, 255, 0 }, { 192, 76, 135, 0 } },
#endif
/*
* This entry doesn't ever match,
* but is needed if there is no other entry in this table.
*/
{ { 0, 0, 0, 0 }, { 1, 1, 1, 1 } }
};
int ipkdbcount = sizeof(ipkdballow)/sizeof(ipkdballow[0]);
#ifdef IPKDBKEY
char *ipkdbkey = IPKDBKEY;
#endif

View File

@ -1,8 +1,8 @@
/* $NetBSD: ipkdb.h,v 1.3 1997/04/19 01:52:16 thorpej Exp $ */
/* $NetBSD: ipkdb.h,v 1.4 2000/03/22 20:58:29 ws Exp $ */
/*
* Copyright (C) 1993-1996 Wolfgang Solfrank.
* Copyright (C) 1993-1996 TooLs GmbH.
* Copyright (C) 1993-2000 Wolfgang Solfrank.
* Copyright (C) 1993-2000 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,65 +33,33 @@
#ifndef _IPKDB_H
#define _IPKDB_H
struct device;
struct cfdata;
extern int ipkdb_probe __P((struct device *, struct cfdata *, void *));
extern void ipkdb_attach __P((struct device *, struct device *, void *));
struct ipkdb_allow {
u_char mask[4];
u_char match[4];
};
extern struct ipkdb_allow ipkdballow[]; /* allowed debuggers */
extern int ipkdbcount; /* count of above */
extern int ipkdbpanic;
#define IPKDBPORT 1138 /* debugging port */
extern void ipkdbcopy __P((void *, void *, int));
extern void ipkdbzero __P((void *, int));
extern int ipkdbcmp __P((void *, void *, int));
extern int ipkdbfbyte __P((unsigned char *));
extern int ipkdbsbyte __P((unsigned char *, int));
struct ipkdb_if {
/* These fields are used by IPKDB itself: */
u_char myenetaddr[6]; /* to be filled by the driver */
u_char myinetaddr[4];
u_char hisenetaddr[6];
u_char hisinetaddr[4];
u_char flags; /* driver marks IPKDB_MYHW here */
u_char connect;
u_char pkt[1500];
int pktlen;
u_int32_t seq;
u_int32_t id;
int mtu;
u_char ass[1500];
u_char assbit[1500/8/8 + 1];
short asslen;
char gotbuf[32*1024];
char *got;
int gotlen;
struct ethercom *arp;
struct cfdata *cfp;
char *name; /* to be filled by the driver */
int port; /* to be filled by the driver */
void (*start)(); /* to be filled by the driver */
void (*leave)(); /* to be filled by the driver */
int (*receive)(); /* to be filled by the driver */
void (*send)(); /* to be filled by the driver */
/* Additional routines used only if debugging via SLIP: */
int (*getc)(); /* to be filled by the driver */
void (*putc)(); /* to be filled by the driver */
/* The rest is solely used by the driver: */
int unit;
int speed;
int fill;
int drvflags;
u_int8_t myenetaddr[6]; /* to be filled by the driver */
u_int8_t myinetaddr[4];
u_int8_t hisenetaddr[6];
u_int8_t hisinetaddr[4];
u_int16_t hisport;
u_char pkt[1500];
int pktlen;
u_int32_t seq;
u_int32_t id;
int mtu;
u_char ass[1500];
u_int8_t assbit[1500/8/8 + 1];
u_int16_t asslen;
u_int8_t flags; /* driver marks IPKDB_MYHW here */
/* Data from here on is to be filled by the driver */
char *name;
void *port;
void (*start) __P((struct ipkdb_if *));
void (*leave) __P((struct ipkdb_if *));
int (*receive) __P((struct ipkdb_if *, u_char *, int));
void (*send) __P((struct ipkdb_if *, u_char *, int));
};
/* flags: */
@ -101,39 +69,46 @@ struct ipkdb_if {
#define IPKDB_HISIP 0x08
#define IPKDB_CONNECTED 0x10
/* connect: */
#define IPKDB_NOIF 0 /* no interface */
#define IPKDB_NO 1 /* no host may connect to ipkdb */
#define IPKDB_SAME 2 /* only the previous host may connect */
#define IPKDB_ALL 3 /* any host may connect */
#ifndef IPKDB_DEF
#define IPKDB_DEF IPKDB_ALL /* default to anyone may connect */
#endif
/*
* Interface routines, to be called by machine dependent code.
*/
extern void ipkdb_init __P((void));
extern void ipkdb_connect __P((int));
extern void ipkdb_panic __P((void));
extern int ipkdbcmds __P((void));
/* Return values from ipkdbcmds: */
#define IPKDB_CMD_RUN 0
#define IPKDB_CMD_STEP 1
#define IPKDB_CMD_EXIT 2
/* Forward declaration to not force <sys/net/if.h> inclusion */
struct ifnet;
/* To be called by udp_input on receipt of a possible debugging packet */
struct in_addr;
struct mbuf;
extern int checkipkdb __P((struct in_addr *, u_short, u_short,
struct mbuf *, int, int));
/*
* Interface routines, to be called by ipkdb itself
* Interface routines, to be called by ipkdb itself.
*/
extern void ipkdbinet __P((struct ipkdb_if *kip));
extern int ipkdbifinit __P((struct ipkdb_if *kip, int unit));
extern int ipkdbifinit __P((struct ipkdb_if *));
/*
* Network interface routines, to be called by network card drivers
* Utilities (used to avoid calling system routines during debugging).
*/
extern void ipkdbrint __P((struct ipkdb_if *kip, struct ifnet *ifp));
extern void ipkdbgotpkt __P((struct ipkdb_if *kip, char *pkt, int len));
extern __inline void ipkdbattach __P((struct ipkdb_if *kip, struct ethercom *arp));
extern __inline void ipkdbattach(kip, arp)
struct ipkdb_if *kip;
struct ethercom *arp;
{
if (!kip->arp)
kip->arp = arp;
}
extern void ipkdbcopy __P((void *, void *, int));
extern void ipkdbzero __P((void *, int));
extern int ipkdbcmp __P((void *, void *, int));
/* Routine for SLIP IPKDB initialization: (to be called by serial driver) */
extern void ipkdb_serial __P((struct ipkdb_if *));
/*
* Machine dependent routines for IPKDB.
*/
extern void ipkdbinit __P((void));
extern void ipkdb_trap __P((void));
extern int ipkdb_poll __P((void));
#endif
extern int ipkdbif_init __P((struct ipkdb_if *));
extern int ipkdbfbyte __P((u_char *));
extern int ipkdbsbyte __P((u_char *, int));
#endif /* _IPKDB_H */

View File

@ -1,8 +1,8 @@
/* $NetBSD: ipkdb_if.c,v 1.9 1999/05/18 23:52:59 thorpej Exp $ */
/* $NetBSD: ipkdb_if.c,v 1.10 2000/03/22 20:58:29 ws Exp $ */
/*
* Copyright (C) 1993-1996 Wolfgang Solfrank.
* Copyright (C) 1993-1996 TooLs GmbH.
* Copyright (C) 1993-2000 Wolfgang Solfrank.
* Copyright (C) 1993-2000 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -30,299 +30,32 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bpfilter.h"
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_ether.h>
#include <netinet/in.h>
#include <netinet/if_inarp.h>
#include <ipkdb/ipkdb.h>
#include <machine/ipkdb.h>
int ipkdb_probe __P((struct device *, struct cfdata *, void *));
void ipkdb_attach __P((struct device *, struct device *, void *));
static void ipkdbrcpy __P((struct ipkdb_if * , void *, void *, int));
static void ipkdbwcpy __P((struct ipkdb_if * , void *, void *, int));
static int ipkdbread __P((struct ipkdb_if *));
/* For the config system the device doesn't exist */
int
ipkdb_probe(parent, match, aux)
struct device *parent;
struct cfdata *match;
void *aux;
{
return 0;
}
void
ipkdb_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
panic("ipkdb_attach");
}
static void
ipkdbrcpy(kip, vsp, vdp, l)
struct ipkdb_if *kip;
void *vsp;
void *vdp;
int l;
{
int l1;
char *sp = vsp, *dp = vdp;
/* bounce source pointer */
while (sp >= kip->gotbuf + sizeof kip->gotbuf)
sp -= sizeof kip->gotbuf;
l1 = kip->gotbuf + sizeof kip->gotbuf - sp;
if (l >= l1) {
ipkdbcopy(sp, dp, l1);
l -= l1;
dp += l1;
sp = kip->gotbuf;
}
if (l)
ipkdbcopy(sp, dp, l);
}
static void
ipkdbwcpy(kip, vsp, vdp, l)
struct ipkdb_if *kip;
void *vsp;
void *vdp;
int l;
{
int l1;
char *sp = vsp, *dp = vdp;
/* bounce destination pointer */
while (dp >= kip->gotbuf + sizeof kip->gotbuf)
dp -= sizeof kip->gotbuf;
l1 = kip->gotbuf + sizeof kip->gotbuf - dp;
if (l >= l1) {
ipkdbcopy(sp, dp, l1);
l -= l1;
sp += l1;
dp = kip->gotbuf;
}
if (l)
ipkdbcopy(sp, dp, l);
}
static int
ipkdbread(kip)
struct ipkdb_if *kip;
{
struct ifnet *ifp = &kip->arp->ec_if;
struct ether_header *eh;
struct mbuf *m, **mp, *head = 0;
int l, len;
char *buf = kip->got;
ipkdbrcpy(kip, buf, &len, sizeof(int));
buf += sizeof(int);
kip->got += len + sizeof(int);
if (kip->got >= kip->gotbuf + sizeof kip->gotbuf)
kip->got -= sizeof kip->gotbuf;
if ((kip->gotlen -= len + sizeof(int)) < 0)
goto bad;
/* Allocate a header mbuf */
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == 0)
goto bad;
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = len;
l = MHLEN;
mp = &head;
/*
* Pull packet out of buf.
*/
while (len > 0) {
if (head) {
MGET(m, M_DONTWAIT, MT_DATA);
if (m == 0) {
m_freem(head);
goto bad;
}
l = MLEN;
}
if (len >= MINCLSIZE) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_free(m);
m_freem(head);
goto bad;
}
l = MCLBYTES;
}
m->m_len = l = min(len, l);
ipkdbrcpy(kip, buf, mtod(m, caddr_t), l);
buf += l;
len -= l;
*mp = m;
mp = &m->m_next;
}
ifp->if_ipackets++;
eh = mtod(head, struct ether_header *);
#if NBPFILTER > 0
/*
* Check if there's a bp filter listening on this interface.
* If so, hand off the raw packet to bpf.
*/
if (kip->arp->ec_if.if_bpf)
bpf_mtap(kip->arp->ec_if.if_bpf, head);
/*
* Note that the interface cannot be in promiscuous mode if
* there are no bpf listeners. And if we are in promiscuous
* mode, we have to check if this packet is really ours.
*/
if ((ifp->if_flags&IFF_PROMISC)
&& ipkdbcmp(eh->ether_dhost,
LLADDR(ifp->if_sadl),
sizeof eh->ether_dhost)
!= 0
&& !(eh->ether_dhost[0] & 1)) { /* !mcast && !bcast */
m_freem(head);
return 0;
}
#endif
(*ifp->if_input)(ifp, head);
return 1;
bad:
ifp->if_ierrors++;
/* flush buffer */
kip->got = kip->gotbuf;
kip->gotlen = 0;
return -1;
}
/*
* How to handle packets arriving during debugging:
* 0 - drop 'em immediately
* 1 - deliver 'em just as they would without debugging
*/
#ifdef __notyet__ /* results in mp_map overflows XXX */
char ipkdbget = 1;
#else
char ipkdbget = 0;
#endif
/*
* Interface driver interrupt handler calls here
* to get packets buffered by IPKDB.
*/
void
ipkdbrint(kip, ifp)
struct ipkdb_if *kip;
struct ifnet *ifp;
{
if (kip && kip->arp && ifp == &kip->arp->ec_if)
while (kip->gotlen > 0)
ipkdbread(kip);
}
/*
* IPKDB hands out a packet that it doesn't want
*/
void
ipkdbgotpkt(kip, cp, len)
struct ipkdb_if *kip;
char *cp;
int len;
{
char *buf;
if (!kip->arp || !ipkdbget)
return;
if (kip->gotlen + sizeof(int) + len > sizeof kip->gotbuf)
return;
buf = kip->got + kip->gotlen;
ipkdbwcpy(kip, &len, buf, sizeof(int));
buf += sizeof(int);
ipkdbwcpy(kip, cp, buf, len);
kip->gotlen += sizeof(int) + roundup(len, sizeof(int));
}
/*
* IPKDB wants to know the IP address of its interface
*/
void
ipkdbinet(kip)
struct ipkdb_if *kip;
{
struct ifaddr *ap;
if (kip->arp) {
for (ap = kip->arp->ec_if.if_addrlist.tqh_first; ap; ap = ap->ifa_list.tqe_next) {
if (ap->ifa_addr->sa_family == AF_INET) {
ipkdbcopy(&((struct sockaddr_in *)ap->ifa_addr)->sin_addr,
kip->myinetaddr, sizeof kip->myinetaddr);
kip->flags |= IPKDB_MYIP;
return;
}
}
}
}
/*
* Initialize IPKDB Interface handling
*/
int
ipkdbifinit(kip, unit)
ipkdbifinit(kip)
struct ipkdb_if *kip;
int unit;
{
struct cfdata *cfp, *pcfp;
extern struct cfdata cfdata[];
short *pp;
u_char *cp;
/* flush buffer */
kip->got = kip->gotbuf;
/* defaults: */
kip->mtu = ETHERMTU;
for (cp = kip->hisenetaddr; cp < kip->hisenetaddr + sizeof kip->hisenetaddr;)
*cp++ = -1;
for (cp = kip->hisinetaddr; cp < kip->hisinetaddr + sizeof kip->hisinetaddr;)
*cp++ = -1;
/* search for interface */
for (cfp = cfdata; cfp->cf_driver; cfp++) {
if (strcmp(cfp->cf_driver->cd_name, "ipkdb")
|| cfp->cf_unit != unit)
continue;
kip->cfp = cfp;
for (pp = cfp->cf_parents; *pp >= 0; pp++) {
pcfp = cfdata + *pp;
if (pcfp->cf_attach->ca_match((struct device *)0,
pcfp,
kip)
>= 0) {
printf("IPKDB on %s at address %x\n",
kip->name, kip->port);
if (cfp->cf_loc[0]) /* disable interface from system */
pcfp->cf_fstate = FSTATE_FOUND;
return 0;
}
}
}
return -1;
return ipkdbif_init(kip);
}

View File

@ -1,8 +1,8 @@
/* $NetBSD: ipkdb_ipkdb.c,v 1.8 1999/05/04 23:30:21 thorpej Exp $ */
/* $NetBSD: ipkdb_ipkdb.c,v 1.9 2000/03/22 20:58:29 ws Exp $ */
/*
* Copyright (C) 1993-1996 Wolfgang Solfrank.
* Copyright (C) 1993-1996 TooLs GmbH.
* Copyright (C) 1993-2000 Wolfgang Solfrank.
* Copyright (C) 1993-2000 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -30,6 +30,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "opt_ipkdb.h"
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
@ -48,21 +50,17 @@
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <machine/stdarg.h>
#include <machine/cpu.h>
#include <machine/reg.h>
#include <ipkdb/ipkdb.h>
#include "debuggers.h"
#include <machine/ipkdb.h>
int ipkdbpanic = 0;
static char *ipkdbkey = IPKDBKEY;
static struct ipkdb_if ipkdb_if;
#ifdef IPKDBTEST
static struct ipkdb_if new_if;
static int ipkdb_test = 0;
#endif
static u_char *ipkdbaddr __P((u_char *, int *, void **));
static void peekmem __P((struct ipkdb_if *, u_char *, void *, long));
@ -79,30 +77,21 @@ static void init __P((struct ipkdb_if *));
static void *chksum __P((void *, int));
static void getpkt __P((struct ipkdb_if *, char *, int *));
static void putpkt __P((struct ipkdb_if *, char *, int));
static int maskcmp __P((void *, void *, void *));
static int check_ipkdb __P((struct ipkdb_if *, struct in_addr *, u_short, u_short, char *, int));
static int check_ipkdb __P((struct ipkdb_if *, struct in_addr *, char *, int));
static int connectipkdb __P((struct ipkdb_if *, char *, int));
#ifdef IPKDBKEY
static int hmac_init __P((void));
#endif
void
ipkdb_init()
{
ipkdb_if.connect = IPKDB_DEF;
ipkdbinit();
if ( ipkdbifinit(&ipkdb_if, 0) < 0
|| !(ipkdb_if.flags&IPKDB_MYHW)) {
if ( ipkdbifinit(&ipkdb_if) < 0
|| !(ipkdb_if.flags&IPKDB_MYHW)
|| !hmac_init()) {
/* Interface not found, drop IPKDB */
printf("IPKDB: No interface found!\n");
ipkdb_if.connect = IPKDB_NOIF;
boothowto &= ~RB_KDB;
}
#ifdef IPKDBKEY
if (!hmac_init())
ipkdb_if.connect = IPKDB_NO;
#endif
}
void
@ -113,36 +102,53 @@ ipkdb_connect(when)
if (when == 0)
printf("waiting for remote debugger\n");
ipkdb_trap();
#ifdef IPKDBTEST
new_if.connect = IPKDB_ALL;
if ( ipkdbifinit(&new_if, 1) < 0
|| !(new_if.flags&IPKDB_MYHW)) {
/* Interface not found, no test */
return;
}
init(&new_if);
putpkt(&new_if, "s", 1);
for (ipkdb_test = 1; ipkdb_test;) {
static char buf[512];
int plen;
getpkt(&new_if, buf, &plen);
if (!plen)
continue;
putpkt(&new_if, "eunknown command", 16);
}
#endif
}
void
ipkdb_panic()
{
if (ipkdb_if.connect == IPKDB_NOIF)
return;
ipkdbpanic = 1;
ipkdb_trap();
}
/*
* Doesn't handle overlapping regions!
*/
void
ipkdbcopy(s, d, n)
void *s, *d;
int n;
{
char *sp = s, *dp = d;
while (--n >= 0)
*dp++ = *sp++;
}
void
ipkdbzero(d, n)
void *d;
int n;
{
char *dp = d;
while (--n >= 0)
*dp++ = 0;
}
int
ipkdbcmp(s, d, n)
void *s, *d;
int n;
{
char *sp = s, *dp = d;
while (--n >= 0)
if (*sp++ != *dp++)
return *--dp - *--sp;
return 0;
}
int
ipkdbcmds()
{
@ -151,11 +157,11 @@ ipkdbcmds()
int plen;
if (!(ipkdb_if.flags&IPKDB_MYHW)) /* no interface */
return 2;
return IPKDB_CMD_EXIT;
init(&ipkdb_if);
if (ipkdbpanic > 1) {
ipkdb_if.leave(&ipkdb_if);
return 0;
return IPKDB_CMD_RUN;
}
putpkt(&ipkdb_if, "s", 1);
while (1) {
@ -163,7 +169,7 @@ ipkdbcmds()
if (!plen) {
if (ipkdbpanic && ipkdb_poll()) {
ipkdb_if.leave(&ipkdb_if);
return 0;
return IPKDB_CMD_RUN;
} else
continue;
} else
@ -215,15 +221,14 @@ ipkdbcmds()
}
case 'S':
ipkdb_if.leave(&ipkdb_if);
return 1;
return IPKDB_CMD_STEP;
case 'X':
putpkt(&ipkdb_if, "ok",2);
ipkdb_if.connect = IPKDB_DEF; /* ??? */
ipkdb_if.leave(&ipkdb_if);
return 2;
return IPKDB_CMD_EXIT;
case 'C':
ipkdb_if.leave(&ipkdb_if);
return 0;
return IPKDB_CMD_RUN;
}
}
}
@ -272,7 +277,6 @@ pokemem(ifp, cp, addr, len)
void *addr;
long len;
{
int c;
u_char *p = addr;
while (--len >= 0)
@ -364,9 +368,10 @@ assemble(ifp, buf)
* decide whether to keep the old
* or start a new one
*/
i = getns(&ip->ip_id)^getns(&((struct ip *)ifp->ass)->ip_id);
i ^= (i >> 2)^(i >> 4)^(i >> 8)^(i >> 12);
if (i&1)
i = (getns(&ip->ip_id)
^ getns(&((struct ip *)ifp->ass)->ip_id));
i ^= ((i >> 2) ^ (i >> 4) ^ (i >> 8) ^ (i >> 12));
if (i & 1)
/* keep the old */
return 0;
ifp->asslen = 0;
@ -377,7 +382,7 @@ assemble(ifp, buf)
ipkdbcopy(&iph, ifp->ass, sizeof iph);
}
off = getns(&ip->ip_off);
len = ((off&IP_OFFMASK) << 3) + getns(&ip->ip_len) - ip->ip_hl * 4;
len = ((off & IP_OFFMASK) << 3) + getns(&ip->ip_len) - ip->ip_hl * 4;
if (ifp->asslen < len)
ifp->asslen = len;
if (ifp->asslen + sizeof *ip > sizeof ifp->ass) {
@ -385,24 +390,25 @@ assemble(ifp, buf)
ifp->asslen = 0;
return 0;
}
if (!(off&IP_MF)) {
if (!(off & IP_MF)) {
off &= IP_OFFMASK;
cp = ifp->assbit + (off >> 3);
for (i = off & 7; i < 8; *cp |= 1 << i++);
for (i = (off & 7); i < 8; *cp |= 1 << i++);
for (; cp < ifp->assbit + sizeof ifp->assbit; *cp++ = -1);
} else {
off &= IP_OFFMASK;
cp = ifp->assbit + (off >> 3);
ecp = ifp->assbit + (len >> 6);
if (cp == ecp)
for (i = off & 7; i <= (len >> 3)&7; *cp |= 1 << i++);
for (i = (off & 7); i <= ((len >> 3) & 7);
*cp |= 1 << i++);
else {
for (i = off & 7; i < 8; *cp |= 1 << i++);
for (i = (off & 7); i < 8; *cp |= 1 << i++);
for (; ++cp < ecp; *cp = -1);
for (i = 0; i < ((len >> 3)&7); *cp |= 1 << i++);
for (i = 0; i < ((len >> 3) & 7); *cp |= 1 << i++);
}
}
ipkdbcopy((caddr_t)buf + ip->ip_hl * 4,
ipkdbcopy((char *)buf + ip->ip_hl * 4,
ifp->ass + sizeof *ip + (off << 3),
len - (off << 3));
for (cp = ifp->assbit; cp < ifp->assbit + sizeof ifp->assbit;)
@ -471,7 +477,7 @@ inpkt(ifp, ibuf, poll)
ar_sha(ah),
ah->ar_hln);
ipkdbcopy(ifp->myinetaddr,
ar_sha(ah),
ar_spa(ah),
ah->ar_pln);
ifp->send(ifp, ibuf, 74);
continue;
@ -482,11 +488,6 @@ inpkt(ifp, ibuf, poll)
}
break;
case ETHERTYPE_IP:
if (ipkdbcmp(eh->ether_dhost,
ifp->myenetaddr,
sizeof ifp->myenetaddr))
/* not only for us */
break;
ip = (struct ip *)(ibuf + 14);
if ( ip->ip_v != IPVERSION
|| ip->ip_hl < 5
@ -498,7 +499,7 @@ inpkt(ifp, ibuf, poll)
break;
if (ip->ip_p != IPPROTO_UDP)
break;
if (getns(&ip->ip_off)&~IP_DF) {
if (getns(&ip->ip_off) & ~IP_DF) {
if (!assemble(ifp, ip))
break;
ip = (struct ip *)ifp->ass;
@ -516,13 +517,14 @@ inpkt(ifp, ibuf, poll)
&& cksum(cksum(0, &ipo, sizeof ipo), udp, ul))
/* wrong checksum */
break;
if (!(ifp->flags&IPKDB_MYIP)) {
if (!(ifp->flags & IPKDB_MYIP)) {
if ( getns(&udp->uh_sport) == 67
&& getns(&udp->uh_dport) == 68
&& *(char *)(udp + 1) == 2) {
/* this is a BOOTP reply to our ethernet address */
/* should check a bit more? XXX */
ipkdbcopy(&ip->ip_dst,
char *bootp = (char *)(udp + 1);
ipkdbcopy(bootp + 16,
ifp->myinetaddr,
sizeof ifp->myinetaddr);
ifp->flags |= IPKDB_MYIP;
@ -531,7 +533,6 @@ inpkt(ifp, ibuf, poll)
return 0;
}
if ( ipkdbcmp(&ip->ip_dst, ifp->myinetaddr, sizeof ifp->myinetaddr)
|| getns(&udp->uh_sport) != IPKDBPORT
|| getns(&udp->uh_dport) != IPKDBPORT)
break;
/* so now it's a UDP packet for the debugger */
@ -543,14 +544,15 @@ inpkt(ifp, ibuf, poll)
if (!getnl(p) && p[6] == 'O') {
l = getns(p + 4);
if ( l <= ul - sizeof *udp - 6
&& check_ipkdb(ifp, &ip->ip_src, udp->uh_sport,
udp->uh_dport, p, l + 6)) {
&& check_ipkdb(ifp, &ip->ip_src,
p, l + 6)) {
ipkdbcopy(&ip->ip_src,
ifp->hisinetaddr,
sizeof ifp->hisinetaddr);
ipkdbcopy(eh->ether_shost,
ifp->hisenetaddr,
sizeof ifp->hisenetaddr);
ifp->hisport = getns(&udp->uh_sport);
ifp->flags |= IPKDB_HISHW|IPKDB_HISIP;
return p;
}
@ -576,8 +578,6 @@ inpkt(ifp, ibuf, poll)
/* unknown type */
break;
}
if (l)
ipkdbgotpkt(ifp, ibuf, l);
}
return 0;
}
@ -591,20 +591,26 @@ outpkt(ifp, in, l, srcport, dstport)
int l;
int srcport, dstport;
{
u_char *sp;
struct ether_header *eh;
struct ip *ip;
struct udphdr *udp;
u_char *cp;
char obuf[ETHERMTU+14];
char _obuf[ETHERMTU + 16];
#define obuf (_obuf + 2) /* align ip data in packet */
struct ipovly ipo;
int i, off;
ipkdbzero(obuf, sizeof obuf);
ipkdbzero(_obuf, sizeof _obuf);
eh = (struct ether_header *)obuf;
if (!(ifp->flags&IPKDB_HISHW))
for (cp = eh->ether_dhost; cp < eh->ether_dhost + sizeof eh->ether_dhost;)
*cp++ = -1;
/*
* If we don't have his ethernet address, or this is a bootp request,
* broadcast the packet.
*/
if (!(ifp->flags & IPKDB_HISHW)
|| dstport == 67)
for (cp = eh->ether_dhost;
cp < eh->ether_dhost + sizeof eh->ether_dhost;
*cp++ = -1);
else
ipkdbcopy(ifp->hisenetaddr, eh->ether_dhost, sizeof eh->ether_dhost);
ipkdbcopy(ifp->myenetaddr, eh->ether_shost, sizeof eh->ether_shost);
@ -616,7 +622,15 @@ outpkt(ifp, in, l, srcport, dstport)
ip->ip_ttl = 255;
ip->ip_p = IPPROTO_UDP;
ipkdbcopy(ifp->myinetaddr, &ip->ip_src, sizeof ip->ip_src);
ipkdbcopy(ifp->hisinetaddr, &ip->ip_dst, sizeof ip->ip_dst);
/*
* If this is a bootp request, broadcast it.
*/
if (dstport == 67)
for (cp = (u_char *)&ip->ip_dst;
cp < (u_char *)&ip->ip_dst + sizeof ip->ip_dst;
*cp++ = -1);
else
ipkdbcopy(ifp->hisinetaddr, &ip->ip_dst, sizeof ip->ip_dst);
udp = (struct udphdr *)(ip + 1);
setns(&udp->uh_sport, srcport);
setns(&udp->uh_dport, dstport);
@ -631,16 +645,17 @@ outpkt(ifp, in, l, srcport, dstport)
for (cp = (u_char *)(udp + 1), l += sizeof *udp, off = 0;
l > 0;
l -= i, in += i, off += i, cp = (u_char *)udp) {
i = l > ifp->mtu - sizeof *ip ? ((ifp->mtu - sizeof *ip)&~7) : l;
i = l > ifp->mtu - sizeof *ip ? ((ifp->mtu - sizeof *ip) & ~7) : l;
ipkdbcopy(in, cp, i);
setns(&ip->ip_len, i + sizeof *ip);
setns(&ip->ip_off, (l > i ? IP_MF : 0)|(off >> 3));
setns(&ip->ip_off, (l > i ? IP_MF : 0) | (off >> 3));
ip->ip_sum = 0;
setns(&ip->ip_sum, ~cksum(0, ip, sizeof *ip));
if (i + sizeof *ip < ETHERMIN)
i = ETHERMIN - sizeof *ip;
ifp->send(ifp, obuf, i + sizeof *ip + 14);
}
#undef obuf
}
static void
@ -648,32 +663,25 @@ init(ifp)
struct ipkdb_if *ifp;
{
u_char *cp;
struct ether_header *eh;
struct ip *ip;
struct udphdr *udp;
u_char buf[ETHERMTU+14];
struct ipovly ipo;
u_char _ibuf[ETHERMTU + 16];
#define ibuf (_ibuf + 2) /* align ip data in packet */
int secs = 0;
ifp->start(ifp);
#ifdef __notyet__
if (!(ifp->flags&IPKDB_MYIP))
ipkdbinet(ifp);
#endif
if (ifp->flags&IPKDB_MYIP)
if (ifp->flags & IPKDB_MYIP)
return;
while (!(ifp->flags&IPKDB_MYIP)) {
ipkdbzero(buf, sizeof buf);
cp = buf;
while (!(ifp->flags & IPKDB_MYIP)) {
ipkdbzero(_ibuf, sizeof _ibuf);
cp = _ibuf;
*cp++ = 1; /* BOOTP_REQUEST */
*cp++ = 1; /* Ethernet hardware */
*cp++ = 6; /* length of address */
setnl(++cp, 0x12345678); /* some random number? */
setns(cp + 4, secs++);
ipkdbcopy(ifp->myenetaddr, cp + 24, sizeof ifp->myenetaddr);
outpkt(ifp, buf, 300, 68, 67);
inpkt(ifp, buf, 2);
outpkt(ifp, _ibuf, 300, 68, 67);
inpkt(ifp, ibuf, 2);
if (ipkdbpanic && ipkdb_poll()) {
ipkdbpanic++;
return;
@ -682,9 +690,9 @@ init(ifp)
cp = ifp->myinetaddr;
printf("My IP address is %d.%d.%d.%d\n",
cp[0], cp[1], cp[2], cp[3]);
#undef ibuf
}
#ifdef IPKDBKEY
/* HMAC Checksumming routines, see draft-ietf-ipsec-hmac-md5-00.txt */
#define LENCHK 16 /* Length of checksum in bytes */
@ -713,13 +721,20 @@ static struct ipkdb_MD5Context {
u_char in[64];
} icontext, ocontext;
static u_int32_t getNl __P((void *));
static void setNl __P((void *, u_int32_t));
static void ipkdb_MD5Transform __P((struct ipkdb_MD5Context *));
static void ipkdb_MD5Init __P((struct ipkdb_MD5Context *));
static void ipkdb_MD5Update __P((struct ipkdb_MD5Context *, u_char *, u_int));
static u_char *ipkdb_MD5Final __P((struct ipkdb_MD5Context *));
__inline static u_int32_t
getNl(vs)
void *vs;
{
u_char *s = vs;
return *s|(s[1] << 8)|(s[2] << 16)|(s[3] << 24);
return *s | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
}
__inline static void
@ -736,22 +751,24 @@ setNl(vs, l)
}
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
/* #define F1(x, y, z) (((x) & (y)) | (~(x) & (z))) */
#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ z ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
#define F3(x, y, z) ((x) ^ (y) ^ (z))
#define F4(x, y, z) ((y) ^ ((x) | ~(z)))
/* This is the central step in the MD5 algorithm. */
#define ipkdb_MD5STEP(f, w, x, y, z, data, s) \
(w += f(x, y, z) + data, w = w << s | (w>>(32-2))&0xffffffff, w += x)
((w) += f(x, y, z) + (data), \
(w) = ((w) << (s)) | (((w) >> (32 - 2)) & 0xffffffff), \
(w) += (x))
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data for this routine.
*/
void
static void
ipkdb_MD5Transform(ctx)
struct ipkdb_MD5Context *ctx;
{
@ -1057,23 +1074,6 @@ chksum(buf, len)
ipkdb_MD5Update(&context, digest, 16);
return ipkdb_MD5Final(&context);
}
#else
#define LENCHK 1 /* Length of checksum in bytes */
static void *
chksum(buf, l)
void *buf;
int l;
{
static char csum[1];
int sum;
char *cp = buf;
for (sum = 0; --l >= 0; sum += *cp++);
csum[0] = sum;
return csum;
}
#endif
static void
getpkt(ifp, buf, lp)
@ -1083,7 +1083,8 @@ getpkt(ifp, buf, lp)
{
char *got;
int l;
char ibuf[ETHERMTU+14];
char _ibuf[ETHERMTU + 16];
#define ibuf (_ibuf + 2) /* align ip data in packet */
*lp = 0;
while (1) {
@ -1100,10 +1101,11 @@ getpkt(ifp, buf, lp)
return;
}
if ( ifp->pktlen
&& ((ifp->flags&(IPKDB_MYIP|IPKDB_HISIP|IPKDB_CONNECTED))
== (IPKDB_MYIP|IPKDB_HISIP|IPKDB_CONNECTED)))
outpkt(ifp, ifp->pkt, ifp->pktlen, IPKDBPORT, IPKDBPORT);
&& ((ifp->flags & (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED))
== (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED)))
outpkt(ifp, ifp->pkt, ifp->pktlen, IPKDBPORT, ifp->hisport);
}
#undef ibuf
}
static void
@ -1117,37 +1119,23 @@ putpkt(ifp, buf, l)
ipkdbcopy(buf, ifp->pkt + 6, l);
ipkdbcopy(chksum(ifp->pkt, l + 6), ifp->pkt + 6 + l, LENCHK);
ifp->pktlen = l + 6 + LENCHK;
if ( (ifp->flags&(IPKDB_MYIP|IPKDB_HISIP|IPKDB_CONNECTED))
!= (IPKDB_MYIP|IPKDB_HISIP|IPKDB_CONNECTED))
if ( (ifp->flags & (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED))
!= (IPKDB_MYIP | IPKDB_HISIP | IPKDB_CONNECTED))
return;
outpkt(ifp, ifp->pkt, ifp->pktlen, IPKDBPORT, IPKDBPORT);
}
static __inline int
maskcmp(vin, vmask, vmatch)
void *vin, *vmask, *vmatch;
{
int i;
u_char *in = vin, *mask = vmask, *match = vmatch;
for (i = 4; --i >= 0;)
if ((*in++&*mask++) != *match++)
return 0;
return 1;
outpkt(ifp, ifp->pkt, ifp->pktlen, IPKDBPORT, ifp->hisport);
}
static int
check_ipkdb(ifp, shost, sport, dport, p, l)
check_ipkdb(ifp, shost, p, l)
struct ipkdb_if *ifp;
struct in_addr *shost;
u_short sport, dport;
char *p;
int l;
{
u_char hisenet[6];
u_char hisinet[4];
u_int16_t hisport;
char save;
struct ipkdb_allow *kap;
#ifndef IPKDBSECURE
if (securelevel > 0)
@ -1155,64 +1143,49 @@ check_ipkdb(ifp, shost, sport, dport, p, l)
#endif
if (ipkdbcmp(chksum(p, l), p + l, LENCHK))
return 0;
switch (ifp->connect) {
default:
return 0;
case IPKDB_SAME:
if (ipkdbcmp(shost, ifp->hisinetaddr, sizeof ifp->hisinetaddr))
return 0;
if (getns(&sport) != IPKDBPORT || getns(&dport) != IPKDBPORT)
return 0;
bzero(&hisinet, sizeof hisinet);
break;
case IPKDB_ALL:
for (kap = ipkdballow; kap < ipkdballow + ipkdbcount; kap++) {
if (maskcmp(shost, kap->mask, kap->match))
break;
}
if (kap >= ipkdballow + ipkdbcount)
return 0;
if (getns(&sport) != IPKDBPORT || getns(&dport) != IPKDBPORT)
return 0;
ipkdbcopy(ifp->hisenetaddr, hisenet, sizeof hisenet);
ipkdbcopy(ifp->hisinetaddr, hisinet, sizeof hisinet);
save = ifp->flags;
ipkdbcopy(shost, ifp->hisinetaddr, sizeof ifp->hisinetaddr);
ifp->flags &= ~IPKDB_HISHW;
ifp->flags |= IPKDB_HISIP;
break;
}
ipkdbcopy(ifp->hisenetaddr, hisenet, sizeof hisenet);
ipkdbcopy(ifp->hisinetaddr, hisinet, sizeof hisinet);
hisport = ifp->hisport;
save = ifp->flags;
ipkdbcopy(shost, ifp->hisinetaddr, sizeof ifp->hisinetaddr);
ifp->flags &= ~IPKDB_HISHW;
ifp->flags |= IPKDB_HISIP;
if (connectipkdb(ifp, p + 6, l - 6) < 0) {
if (ifp->connect == IPKDB_ALL) {
ipkdbcopy(hisenet, ifp->hisenetaddr, sizeof ifp->hisenetaddr);
ipkdbcopy(hisinet, ifp->hisinetaddr, sizeof ifp->hisinetaddr);
ipkdb_if.flags = save;
}
ipkdbcopy(hisenet, ifp->hisenetaddr, sizeof ifp->hisenetaddr);
ipkdbcopy(hisinet, ifp->hisinetaddr, sizeof ifp->hisinetaddr);
ifp->hisport = hisport;
ifp->flags = save;
return 0;
}
return 1;
}
/*
* Should check whether packet came across the correct interface
* Should check whether packet came across the correct interface. XXX
*/
int
checkipkdb(shost, sport, dport, m, off, len)
struct in_addr *shost;
u_short sport, dport;
struct mbuf *m;
int off, len;
{
char *p;
int l;
char ibuf[ETHERMTU+50];
if (dport != IPKDBPORT)
return 0;
if (len > sizeof ibuf)
return 0;
m_copydata(m, off, len, ibuf);
p = ibuf;
if (getnl(p) || p[6] != 'O')
return 0;
l = getns(p + 4);
if (l > len - 6 || !check_ipkdb(&ipkdb_if, shost, sport, dport, p, l + 6))
if (l > len - 6 || !check_ipkdb(&ipkdb_if, shost, p, l + 6))
return 0;
ipkdb_if.hisport = sport;
ipkdb_connect(1);
return 1;
}
@ -1236,7 +1209,6 @@ connectipkdb(ifp, buf, l)
l -= 1 + sizeof(u_int32_t);
for (cp = buf + 1 + sizeof(u_int32_t); --l >= 0; printf("%c", *cp++));
printf(" (%d.%d.%d.%d)\n", ip[0], ip[1], ip[2], ip[3]);
ifp->connect = IPKDB_SAME; /* if someone once connected, he may do so again */
ifp->flags |= IPKDB_CONNECTED;
ifp->seq = 0;
ifp->pktlen = 0;

View File

@ -1,136 +0,0 @@
/* $NetBSD: ipkdb_slip.c,v 1.4 1998/01/13 02:26:07 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
* Copyright (C) 1995, 1996 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by TooLs GmbH.
* 4. The name of TooLs GmbH may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/device.h>
#include <net/if.h>
#include <net/if_ether.h>
#include <netinet/in.h>
#include <netinet/if_inarp.h>
#include <ipkdb/ipkdb.h>
#include <machine/ipkdb.h>
/* These should be in <net/if_sl.h> or some such! */
#define FRAME_END 0xc0 /* Frame End */
#define FRAME_ESCAPE 0xdb /* Frame Esc */
#define TRANS_FRAME_END 0xdc /* transposed frame end */
#define TRANS_FRAME_ESCAPE 0xdd /* transposed frame esc */
static int
ipkdbrcv(kip, buf, poll)
struct ipkdb_if *kip;
u_char *buf;
int poll;
{
int c, len = 0;
/* Fake an ether header: */
ipkdbcopy(kip->myenetaddr, buf, sizeof kip->myenetaddr);
buf += sizeof kip->myenetaddr;
ipkdbcopy(kip->hisenetaddr, buf, sizeof kip->hisenetaddr);
buf += sizeof kip->hisenetaddr;
*buf++ = ETHERTYPE_IP >> 8;
*buf++ = (u_char)ETHERTYPE_IP;
do {
switch ((c = kip->getc(kip, poll))) {
case -1:
break;
case TRANS_FRAME_ESCAPE:
case TRANS_FRAME_END:
if (kip->drvflags&0x100) {
kip->drvflags &= ~0x100;
c = c == TRANS_FRAME_ESCAPE ? FRAME_ESCAPE : FRAME_END;
}
default:
if (kip->fill >= 0 && kip->fill < ETHERMTU)
buf[kip->fill++] = c;
else
kip->fill = -1;
break;
case FRAME_END:
len = kip->fill;
kip->fill = 0;
break;
case FRAME_ESCAPE:
kip->drvflags |= 0x100;
break;
}
} while (!poll && len <= 0);
return len ? len + 14 : 0;
}
static void
ipkdbsend(kip, buf, l)
struct ipkdb_if *kip;
u_char *buf;
int l;
{
buf += 14;
l -= 14;
while (--l >= 0) {
switch (*buf) {
default:
kip->putc(kip, *buf++);
break;
case FRAME_ESCAPE:
case FRAME_END:
kip->putc(kip, FRAME_ESCAPE);
kip->putc(kip, *buf == FRAME_END ? TRANS_FRAME_END : TRANS_FRAME_ESCAPE);
buf++;
break;
}
}
kip->putc(kip, FRAME_END);
}
void
ipkdb_serial(kip)
struct ipkdb_if *kip;
{
struct cfdata *cf = kip->cfp;
kip->myenetaddr[0] = 1; /* make it a local address */
kip->myenetaddr[1] = 0;
kip->myenetaddr[2] = cf->cf_loc[1] >> 24;
kip->myenetaddr[3] = cf->cf_loc[1] >> 16;
kip->myenetaddr[4] = cf->cf_loc[1] >> 8;
kip->myenetaddr[5] = cf->cf_loc[1];
kip->flags |= IPKDB_MYHW;
kip->mtu = 296;
kip->receive = ipkdbrcv;
kip->send = ipkdbsend;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_prf.c,v 1.66 2000/01/26 07:50:33 thorpej Exp $ */
/* $NetBSD: subr_prf.c,v 1.67 2000/03/22 20:58:30 ws Exp $ */
/*-
* Copyright (c) 1986, 1988, 1991, 1993
@ -41,8 +41,8 @@
*/
#include "opt_ddb.h"
#include "opt_ipkdb.h"
#include "opt_multiprocessor.h"
#include "ipkdb.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -66,6 +66,10 @@
#include <ddb/ddbvar.h>
#endif
#ifdef IPKDB
#include <ipkdb/ipkdb.h>
#endif
#if defined(MULTIPROCESSOR)
struct simplelock kprintf_slock = SIMPLELOCK_INITIALIZER;
@ -199,7 +203,7 @@ panic(fmt, va_alist)
printf("\n");
va_end(ap);
#if NIPKDB > 0
#ifdef IPKDB
ipkdb_panic();
#endif
#ifdef KGDB

View File

@ -1,4 +1,4 @@
/* $NetBSD: udp_usrreq.c,v 1.63 2000/03/01 12:49:42 itojun Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.64 2000/03/22 20:58:30 ws Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -65,8 +65,7 @@
*/
#include "opt_ipsec.h"
#include "ipkdb.h"
#include "opt_ipkdb.h"
#include <sys/param.h>
#include <sys/malloc.h>
@ -119,6 +118,10 @@
#include <netkey/key_debug.h>
#endif /*IPSEC*/
#ifdef IPKDB
#include <ipkdb/ipkdb.h>
#endif
/*
* UDP protocol implementation.
* Per RFC 768, August, 1980.
@ -289,7 +292,7 @@ udp_input(m, va_alist)
goto bad;
}
udpstat.udps_noport++;
#if NIPKDB > 0
#ifdef IPKDB
if (checkipkdb(&ip->ip_src, uh->uh_sport, uh->uh_dport,
m, iphlen + sizeof(struct udphdr),
m->m_pkthdr.len - iphlen - sizeof(struct udphdr))) {
@ -638,7 +641,7 @@ udp4_realinput(src, dst, m, off)
goto bad;
}
udpstat.udps_noport++;
#if NIPKDB > 0
#ifdef IPKDB
if (checkipkdb(src4, *sport, *dport, m, off,
m->m_pkthdr.len - off)) {
/*
@ -1090,7 +1093,7 @@ udp_input(m, va_alist)
}
udpstat.udps_noport++;
*ip = save_ip;
#if NIPKDB > 0
#ifdef IPKDB
if (checkipkdb(&ip->ip_src,
uh->uh_sport,
uh->uh_dport,