rad(8): Implement RFC 8781 PREF64 router advertisement option.

2022-10-15 Thread Florian Obser
With this clients can learn the presence and used prefix for Network
Address and Protocol Translation between IPv6 and IPv4 (NAT64).

Apparently there is support in mobile devices as well as in macOS.

This option, together with the the dhcp "IPv6-only preferred"
option (108) enables the Customer-side transLATor (CLAT) on macOS so
IPv4 literals can be used in IPv6-only networks.

OK?

diff --git engine.c engine.c
index dddff2d4579..543abffe388 100644
--- engine.c
+++ engine.c
@@ -269,6 +269,7 @@ engine_dispatch_main(int fd, short event, void *bula)
struct ra_prefix_conf   *ra_prefix_conf;
struct ra_rdnss_conf*ra_rdnss_conf;
struct ra_dnssl_conf*ra_dnssl_conf;
+   struct ra_pref64_conf   *pref64;
ssize_t  n;
int  shut = 0;
 
@@ -333,6 +334,7 @@ engine_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INIT(>ra_iface_list);
SIMPLEQ_INIT(>ra_options.ra_rdnss_list);
SIMPLEQ_INIT(>ra_options.ra_dnssl_list);
+   SIMPLEQ_INIT(>ra_options.ra_pref64_list);
ra_options = >ra_options;
break;
case IMSG_RECONF_RA_IFACE:
@@ -349,6 +351,7 @@ engine_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INIT(_iface_conf->ra_prefix_list);
SIMPLEQ_INIT(_iface_conf->ra_options.ra_rdnss_list);
SIMPLEQ_INIT(_iface_conf->ra_options.ra_dnssl_list);
+   SIMPLEQ_INIT(_iface_conf->ra_options.ra_pref64_list);
SIMPLEQ_INSERT_TAIL(>ra_iface_list,
ra_iface_conf, entry);
ra_options = _iface_conf->ra_options;
@@ -405,6 +408,18 @@ engine_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INSERT_TAIL(_options->ra_dnssl_list,
ra_dnssl_conf, entry);
break;
+   case IMSG_RECONF_RA_PREF64:
+   if(IMSG_DATA_SIZE(imsg) != sizeof(struct
+   ra_pref64_conf))
+   fatalx("%s: IMSG_RECONF_RA_PREF64 wrong length: 
"
+   "%lu", __func__, IMSG_DATA_SIZE(imsg));
+   if ((pref64 = malloc(sizeof(struct ra_pref64_conf))) ==
+   NULL)
+   fatal(NULL);
+   memcpy(pref64, imsg.data, sizeof(struct 
ra_pref64_conf));
+   SIMPLEQ_INSERT_TAIL(_options->ra_pref64_list, pref64,
+   entry);
+   break;
case IMSG_RECONF_END:
if (nconf == NULL)
fatalx("%s: IMSG_RECONF_END without "
diff --git frontend.c frontend.c
index 30bcde218c4..435d6aed8a8 100644
--- frontend.c
+++ frontend.c
@@ -113,6 +113,14 @@ struct ra_iface {
uint8_t  data[RA_MAX_SIZE];
 };
 
+#define ND_OPT_PREF64  38
+struct nd_opt_pref64 {
+   u_int8_tnd_opt_pref64_type;
+   u_int8_tnd_opt_pref64_len;
+   u_int16_t   nd_opt_pref64_sltime_plc;
+   u_int8_tnd_opt_pref64[12];
+};
+
 TAILQ_HEAD(, ra_iface) ra_interfaces;
 
 __dead void frontend_shutdown(void);
@@ -300,6 +308,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
struct ra_prefix_conf   *ra_prefix_conf;
struct ra_rdnss_conf*ra_rdnss_conf;
struct ra_dnssl_conf*ra_dnssl_conf;
+   struct ra_pref64_conf   *pref64;
int  n, shut = 0, icmp6sock, rdomain;
 
if (event & EV_READ) {
@@ -361,6 +370,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INIT(>ra_iface_list);
SIMPLEQ_INIT(>ra_options.ra_rdnss_list);
SIMPLEQ_INIT(>ra_options.ra_dnssl_list);
+   SIMPLEQ_INIT(>ra_options.ra_pref64_list);
ra_options = >ra_options;
break;
case IMSG_RECONF_RA_IFACE:
@@ -377,6 +387,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INIT(_iface_conf->ra_prefix_list);
SIMPLEQ_INIT(_iface_conf->ra_options.ra_rdnss_list);
SIMPLEQ_INIT(_iface_conf->ra_options.ra_dnssl_list);
+   SIMPLEQ_INIT(_iface_conf->ra_options.ra_pref64_list);
SIMPLEQ_INSERT_TAIL(>ra_iface_list,
ra_iface_conf, entry);
ra_options = _iface_conf->ra_options;
@@ -433,6 +444,18 @@ frontend_dispatch_main(int fd, short event, void *bula)

Re: cwm: do not overlap menu entries

2022-10-15 Thread Omar Polo
On 2022/10/14 14:11:19 -0400, Okan Demirmen  wrote:
> the below seems to work: Walter (thanks!) found the spot i missed on
> replacing height with ascent+descent.
> 
> please let me know.

diff reads fine works for me too, thanks!



octeon: installer: use installboot -p

2022-10-15 Thread Klemens Nanni
The installboot regress tests use -p on octeon which works fine.

I don't have serial console access to octen machines at the moment, but
this should just fly as installboot already has -p support on octeon.

It's also easy to test with snapshot media as one can easily apply this
patch in the installer's (S)hell prompt to /install.md with, e.g. ed(1).

visa kindly tested a fresh installation with this which works fine.

This leaves only loongson behind doing manual newfs rather than use -p,
but I don't have access to any hardware and regress doesn't cover it.

Feedback? OK?

Index: octeon/ramdisk/install.md
===
RCS file: /cvs/src/distrib/octeon/ramdisk/install.md,v
retrieving revision 1.23
diff -u -p -r1.23 install.md
--- octeon/ramdisk/install.md   6 Feb 2022 15:52:23 -   1.23
+++ octeon/ramdisk/install.md   11 Sep 2022 15:14:01 -
@@ -62,8 +62,7 @@ md_prep_fdisk() {
echo -n "Creating a FAT partition and an OpenBSD 
partition for rest of $_disk..."
fdisk -iy -b "65536@64:C" ${_disk} >/dev/null
echo "done."
-   disklabel $_disk 2>/dev/null | grep -q "^  i:" || 
disklabel -w -d $_disk
-   newfs -t msdos ${_disk}i
+   installboot -p $_disk
return ;;
[eE]*)
# Manually configure the MBR.



Re: rad(8): Implement RFC 8781 PREF64 router advertisement option.

2022-10-15 Thread Florian Obser
On 2022-10-15 13:00 +02, Florian Obser  wrote:
> With this clients can learn the presence and used prefix for Network
> Address and Protocol Translation between IPv6 and IPv4 (NAT64).
>
> Apparently there is support in mobile devices as well as in macOS.
>
> This option, together with the the dhcp "IPv6-only preferred"
> option (108) enables the Customer-side transLATor (CLAT) on macOS so
> IPv4 literals can be used in IPv6-only networks.
>

Better diff, I messed up the default and maximum lifetime seconds.

OK?

diff --git engine.c engine.c
index dddff2d4579..543abffe388 100644
--- engine.c
+++ engine.c
@@ -269,6 +269,7 @@ engine_dispatch_main(int fd, short event, void *bula)
struct ra_prefix_conf   *ra_prefix_conf;
struct ra_rdnss_conf*ra_rdnss_conf;
struct ra_dnssl_conf*ra_dnssl_conf;
+   struct ra_pref64_conf   *pref64;
ssize_t  n;
int  shut = 0;
 
@@ -333,6 +334,7 @@ engine_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INIT(>ra_iface_list);
SIMPLEQ_INIT(>ra_options.ra_rdnss_list);
SIMPLEQ_INIT(>ra_options.ra_dnssl_list);
+   SIMPLEQ_INIT(>ra_options.ra_pref64_list);
ra_options = >ra_options;
break;
case IMSG_RECONF_RA_IFACE:
@@ -349,6 +351,7 @@ engine_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INIT(_iface_conf->ra_prefix_list);
SIMPLEQ_INIT(_iface_conf->ra_options.ra_rdnss_list);
SIMPLEQ_INIT(_iface_conf->ra_options.ra_dnssl_list);
+   SIMPLEQ_INIT(_iface_conf->ra_options.ra_pref64_list);
SIMPLEQ_INSERT_TAIL(>ra_iface_list,
ra_iface_conf, entry);
ra_options = _iface_conf->ra_options;
@@ -405,6 +408,18 @@ engine_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INSERT_TAIL(_options->ra_dnssl_list,
ra_dnssl_conf, entry);
break;
+   case IMSG_RECONF_RA_PREF64:
+   if(IMSG_DATA_SIZE(imsg) != sizeof(struct
+   ra_pref64_conf))
+   fatalx("%s: IMSG_RECONF_RA_PREF64 wrong length: 
"
+   "%lu", __func__, IMSG_DATA_SIZE(imsg));
+   if ((pref64 = malloc(sizeof(struct ra_pref64_conf))) ==
+   NULL)
+   fatal(NULL);
+   memcpy(pref64, imsg.data, sizeof(struct 
ra_pref64_conf));
+   SIMPLEQ_INSERT_TAIL(_options->ra_pref64_list, pref64,
+   entry);
+   break;
case IMSG_RECONF_END:
if (nconf == NULL)
fatalx("%s: IMSG_RECONF_END without "
diff --git frontend.c frontend.c
index 30bcde218c4..435d6aed8a8 100644
--- frontend.c
+++ frontend.c
@@ -113,6 +113,14 @@ struct ra_iface {
uint8_t  data[RA_MAX_SIZE];
 };
 
+#define ND_OPT_PREF64  38
+struct nd_opt_pref64 {
+   u_int8_tnd_opt_pref64_type;
+   u_int8_tnd_opt_pref64_len;
+   u_int16_t   nd_opt_pref64_sltime_plc;
+   u_int8_tnd_opt_pref64[12];
+};
+
 TAILQ_HEAD(, ra_iface) ra_interfaces;
 
 __dead void frontend_shutdown(void);
@@ -300,6 +308,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
struct ra_prefix_conf   *ra_prefix_conf;
struct ra_rdnss_conf*ra_rdnss_conf;
struct ra_dnssl_conf*ra_dnssl_conf;
+   struct ra_pref64_conf   *pref64;
int  n, shut = 0, icmp6sock, rdomain;
 
if (event & EV_READ) {
@@ -361,6 +370,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INIT(>ra_iface_list);
SIMPLEQ_INIT(>ra_options.ra_rdnss_list);
SIMPLEQ_INIT(>ra_options.ra_dnssl_list);
+   SIMPLEQ_INIT(>ra_options.ra_pref64_list);
ra_options = >ra_options;
break;
case IMSG_RECONF_RA_IFACE:
@@ -377,6 +387,7 @@ frontend_dispatch_main(int fd, short event, void *bula)
SIMPLEQ_INIT(_iface_conf->ra_prefix_list);
SIMPLEQ_INIT(_iface_conf->ra_options.ra_rdnss_list);
SIMPLEQ_INIT(_iface_conf->ra_options.ra_dnssl_list);
+   SIMPLEQ_INIT(_iface_conf->ra_options.ra_pref64_list);
SIMPLEQ_INSERT_TAIL(>ra_iface_list,
ra_iface_conf, entry);
ra_options = 

mg: ewprintf("") -> eerase()

2022-10-15 Thread Omar Polo
as per subject; the effect is almost the same, they both clear the
echo area, but ewprintf("") sets `epresf' to require an additional
eerase() on the next-next input cycle.  avoid extra work! :)

ok?

diff /home/op/w/mg.master
commit - 4912f94d4a7e2b653e74201ac73923335fd298aa
path + /home/op/w/mg.master
blob - 810ea3ae3346112842126acfe47e1a934bd9acc0
file + dired.c
--- dired.c
+++ dired.c
@@ -1185,7 +1185,7 @@ gotofile(char *fpth)
ewprintf("File not found %s", fname);
return (FALSE);
} else {
-   ewprintf("");
+   eerase();
return (TRUE);
}
 }
blob - ced1a2dc4a9541a34a99f9ae96acf9f4e1237f33
file + echo.c
--- echo.c
+++ echo.c
@@ -67,15 +67,15 @@ eyorn(const char *sp)
for (;;) {
s = getkey(FALSE);
if (s == 'y' || s == 'Y' || s == ' ') {
-   ewprintf("");
+   eerase();
return (TRUE);
}
if (s == 'n' || s == 'N' || s == CCHR('M')) {
-   ewprintf("");
+   eerase();
return (FALSE);
}
if (s == CCHR('G')) {
-   ewprintf("");
+   eerase();
return (ctrlg(FFRAND, 1));
}
ewprintf("Please answer y or n.  %s? (y or n) ", sp);
@@ -101,19 +101,19 @@ eynorr(const char *sp)
for (;;) {
s = getkey(FALSE);
if (s == 'y' || s == 'Y' || s == ' ') {
-   ewprintf("");
+   eerase();
return (TRUE);
}
if (s == 'n' || s == 'N' || s == CCHR('M')) {
-   ewprintf("");
+   eerase();
return (FALSE);
}
if (s == 'r' || s == 'R') {
-   ewprintf("");
+   eerase();
return (REVERT);
}
if (s == CCHR('G')) {
-   ewprintf("");
+   eerase();
return (ctrlg(FFRAND, 1));
}
ewprintf("Please answer y, n or r.");
@@ -137,7 +137,7 @@ eyesno(const char *sp)
EFNUL | EFNEW | EFCR, sp);
for (;;) {
if (rep == NULL) {
-   ewprintf("");
+   eerase();
return (ABORT);
}
if (rep[0] != '\0') {
@@ -149,11 +149,11 @@ eyesno(const char *sp)
free(lp);
}
if (strcasecmp(rep, "yes") == 0) {
-   ewprintf("");
+   eerase();
return (TRUE);
}
if (strcasecmp(rep, "no") == 0) {
-   ewprintf("");
+   eerase();
return (FALSE);
}
}



Re: reorder_kernel: set up syslog traps before logfile

2022-10-15 Thread Klemens Nanni
On Sat, Oct 08, 2022 at 07:25:26PM +, Klemens Nanni wrote:
> If /usr is mounted read-only, kernel relinking fails silently without
> any log trace.
> 
>   # ksh /usr/libexec/reorder_kernel
>   /usr/libexec/reorder_kernel[35]: cannot create 
> /usr/share/relink/kernel/GENERIC.MP/relink.log: Read-only file system
> 
> This stderr line does not show up during boot because init(8) redirects
> stdout/err to /dev/null, executes rc(8) which inherits this and executes
> reorder_kernel with both streams thus discarded.
> 
> Eventually, I'd like reorder_kernel to temporarily remount $KERNEL_DIR
> read-write, just like rc's reorder_libs() does.  I have a diff for that
> but would like to approach things in smaller steps.
> 
> So first, defer the logfile setup after the syslog/console setup such
> that mkdir's failure triggers the ERR trap and users get notified:
> 
>   # ksh ./reorder_kernel.sh
>   ./reorder_kernel.sh[40]: cannot create 
> /usr/share/relink/kernel/GENERIC.MP/relink.log: Read-only file system
>   # tail -n1 /var/log/daemon
>   Oct 13 17:04:06 pbp reorder_kernel.sh: kernel relinking done
> 
> As of now, this logs success despite actual failure because of ksh's
> redirection/trap bug (see mail on tech@):  mkdir does not fail because
> the directory already exists, so `exec 1>$LOGFILE' tries to truncate but
> fails to trigger the ERR trap, thus hitting the non-default EXIT trap.
> 
> With ksh fixed this would log
>   Oct 13 17:04:06 pbp reorder_kernel.sh: failed -- see 
> /usr/share/relink/kernel/GENERIC.MP/relink.log
> which admittedly misleading, given that creating/truncating that vary
> logfile is the failure reason, but it seems better than silent nothing.

ksh's exec got fixed, so failure is now logged with this diff:

# tail -n0 -f /var/log/messages
[1] 95776
# /usr/libexec/reorder_kernel
/usr/libexec/reorder_kernel[35]: cannot create 
/usr/share/relink/kernel/GENERIC.MP/relink.log: Read-only file system
no log except stderr

# ksh ./reorder_kernel.sh
./reorder_kernel.sh[40]: cannot create 
/usr/share/relink/kernel/GENERIC.MP/relink.log: Read-only file system
Oct 16 09:16:37 eru reorder_kernel.sh: failed -- see 
/usr/share/relink/kernel/GENERIC.MP/relink.log
same "failed" message in xconsole(1)

> It could set up an intermediate trap or truly silently bail out on
> read-only FFS just like it does for NFS now, but it seems best to handle
> ro /usr as mentioned as a follow-up step.

Anyone?

This diff now works as expected;  not perfect but an improvement, imho.
Feedback? Objection? OK?


Index: reorder_kernel.sh
===
RCS file: /cvs/src/libexec/reorder_kernel/reorder_kernel.sh,v
retrieving revision 1.11
diff -u -p -r1.11 reorder_kernel.sh
--- reorder_kernel.sh   13 May 2022 13:20:16 -  1.11
+++ reorder_kernel.sh   10 Oct 2022 00:15:58 -
@@ -30,15 +30,15 @@ LOGFILE=$KERNEL_DIR/$KERNEL/relink.log
 PROGNAME=${0##*/}
 SHA256=/var/db/kernel.SHA256
 
-# Create kernel compile dir and redirect stdout/stderr to a logfile.
-mkdir -m 700 -p $KERNEL_DIR/$KERNEL
-exec 1>$LOGFILE
-exec 2>&1
-
 # Install trap handlers to inform about success or failure via syslog.
 trap 'trap - EXIT; logger -st $PROGNAME \
"failed -- see $LOGFILE" >>/dev/console 2>&1' ERR
 trap 'logger -t $PROGNAME "kernel relinking done"' EXIT
+
+# Create kernel compile dir and redirect stdout/stderr to a logfile.
+mkdir -m 700 -p $KERNEL_DIR/$KERNEL
+exec 1>$LOGFILE
+exec 2>&1
 
 if [[ -f $KERNEL_DIR.tgz ]]; then
rm -rf $KERNEL_DIR/$KERNEL/*



Re: em(4) IPv4, TCP, UDP checksum offloading

2022-10-15 Thread Moritz Buhl
With the previous diffs I am seeing sporadic connection problems in tcpbench
via IPv6 on Intel 82546GB.
The diff was too big anyways. Here is a smaller diff that introduces
checksum offloading for the controllers that use the advanced descriptors.

I tested this diff on i350 and 82571EB, receive, send, forwarding,
icmp4, icmp6, tcp4, tcp6, udp4, udp6, also over vlan and veb.

I am still looking for testing. Any feedback?

mbuhl

Index: dev/pci/if_em.c
===
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.362
diff -u -p -r1.362 if_em.c
--- dev/pci/if_em.c 23 Jun 2022 09:38:28 -  1.362
+++ dev/pci/if_em.c 15 Oct 2022 19:49:12 -
@@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
 #include 
 #include 
 
+#include 
+
 /*
  *  Driver version
  */
@@ -278,6 +280,8 @@ void em_receive_checksum(struct em_softc
 struct mbuf *);
 u_int  em_transmit_checksum_setup(struct em_queue *, struct mbuf *, u_int,
u_int32_t *, u_int32_t *);
+u_int  em_tx_ctx_setup(struct em_queue *, struct mbuf *, u_int, u_int32_t *,
+   u_int32_t *);
 void em_iff(struct em_softc *);
 void em_update_link_status(struct em_softc *);
 int  em_get_buf(struct em_queue *, int);
@@ -1220,10 +1224,9 @@ em_encap(struct em_queue *que, struct mb
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
}
 
-   if (sc->hw.mac_type >= em_82543 && sc->hw.mac_type != em_82575 &&
-   sc->hw.mac_type != em_82576 &&
-   sc->hw.mac_type != em_82580 && sc->hw.mac_type != em_i210 &&
-   sc->hw.mac_type != em_i350) {
+   if (sc->hw.mac_type >= em_82575 && sc->hw.mac_type <= em_i210) {
+   used += em_tx_ctx_setup(que, m, head, _upper, _lower);
+   } else if (sc->hw.mac_type >= em_82543) {
used += em_transmit_checksum_setup(que, m, head,
_upper, _lower);
} else {
@@ -1278,7 +1281,8 @@ em_encap(struct em_queue *que, struct mb
 
 #if NVLAN > 0
/* Find out if we are in VLAN mode */
-   if (m->m_flags & M_VLANTAG) {
+   if (m->m_flags & M_VLANTAG && (sc->hw.mac_type < em_82575 ||
+   sc->hw.mac_type > em_i210)) {
/* Set the VLAN id */
desc->upper.fields.special = htole16(m->m_pkthdr.ether_vtag);
 
@@ -1964,17 +1968,16 @@ em_setup_interface(struct em_softc *sc)
ifp->if_capabilities = IFCAP_VLAN_MTU;
 
 #if NVLAN > 0
-   if (sc->hw.mac_type != em_82575 && sc->hw.mac_type != em_82580 &&
-   sc->hw.mac_type != em_82576 &&
-   sc->hw.mac_type != em_i210 && sc->hw.mac_type != em_i350)
-   ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
+   ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
 #endif
 
-   if (sc->hw.mac_type >= em_82543 && sc->hw.mac_type != em_82575 &&
-   sc->hw.mac_type != em_82576 &&
-   sc->hw.mac_type != em_82580 && sc->hw.mac_type != em_i210 &&
-   sc->hw.mac_type != em_i350)
+   if (sc->hw.mac_type >= em_82543) {
ifp->if_capabilities |= IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
+   }
+   if (sc->hw.mac_type >= em_82575 && sc->hw.mac_type <= em_i210) {
+   ifp->if_capabilities |= IFCAP_CSUM_IPv4;
+   ifp->if_capabilities |= IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6;
+   }
 
/* 
 * Specify the media types supported by this adapter and register
@@ -2389,6 +2392,108 @@ em_free_transmit_structures(struct em_so
0, que->tx.sc_tx_dma.dma_map->dm_mapsize,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
}
+}
+
+u_int
+em_tx_ctx_setup(struct em_queue *que, struct mbuf *mp, u_int head,
+u_int32_t *olinfo_status, u_int32_t *cmd_type_len)
+{
+   struct e1000_adv_tx_context_desc *TD;
+   struct ether_header *eh = mtod(mp, struct ether_header *);
+   struct mbuf *m;
+   uint32_t vlan_macip_lens = 0, type_tucmd_mlhl = 0, mss_l4len_idx = 0;
+   int off = 0, hoff;
+   uint8_t ipproto, iphlen;
+
+   *olinfo_status = 0;
+   *cmd_type_len = 0;
+   TD = (struct e1000_adv_tx_context_desc *)>tx.sc_tx_desc_ring[head];
+   
+#if NVLAN > 0
+   if (ISSET(mp->m_flags, M_VLANTAG)) {
+   uint16_t vtag = htole16(mp->m_pkthdr.ether_vtag);
+   vlan_macip_lens |= vtag << E1000_ADVTXD_VLAN_SHIFT;
+   *cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
+   off = 1;
+   }
+#endif
+
+   vlan_macip_lens |= (sizeof(*eh) << E1000_ADVTXD_MACLEN_SHIFT);
+   
+   switch (ntohs(eh->ether_type)) {
+   case ETHERTYPE_IP: {
+   struct ip *ip;
+
+   m = m_getptr(mp, sizeof(*eh), );
+   ip = (struct ip *)(mtod(m, caddr_t) + hoff);
+
+   iphlen = ip->ip_hl <<