summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-02-10 15:34:55 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-02-18 15:00:48 +0100
commit46b3858b27d78e14a220f8d251fd7ab28a5244f4 (patch)
tree95e29e1fdafe3d709895f30df44a6716652041c9
parentepoch01: Update due to API changes (diff)
downloadrtems-libbsd-46b3858b27d78e14a220f8d251fd7ab28a5244f4.tar.bz2
Update to FreeBSD stable/12 2020-02-10
Git mirror commit 0d1c391321b34b3025cf0e72f2231d836ff76da8.
m---------freebsd-org0
-rw-r--r--freebsd/contrib/expat/lib/ascii.h32
-rw-r--r--freebsd/contrib/expat/lib/asciitab.h94
-rw-r--r--freebsd/contrib/expat/lib/expat.h330
-rw-r--r--freebsd/contrib/expat/lib/expat_external.h115
-rw-r--r--freebsd/contrib/expat/lib/iasciitab.h94
-rw-r--r--freebsd/contrib/expat/lib/internal.h76
-rw-r--r--freebsd/contrib/expat/lib/latin1tab.h94
-rw-r--r--freebsd/contrib/expat/lib/nametab.h274
-rw-r--r--freebsd/contrib/expat/lib/utf8tab.h95
-rw-r--r--freebsd/contrib/expat/lib/xmlparse.c6205
-rw-r--r--freebsd/contrib/expat/lib/xmlrole.c819
-rw-r--r--freebsd/contrib/expat/lib/xmlrole.h45
-rw-r--r--freebsd/contrib/expat/lib/xmltok.c1471
-rw-r--r--freebsd/contrib/expat/lib/xmltok.h249
-rw-r--r--freebsd/contrib/expat/lib/xmltok_impl.c1115
-rw-r--r--freebsd/contrib/expat/lib/xmltok_impl.h103
-rw-r--r--freebsd/contrib/expat/lib/xmltok_ns.c117
-rw-r--r--freebsd/contrib/libpcap/diag-control.h8
-rw-r--r--freebsd/contrib/libpcap/fmtutils.c99
-rw-r--r--freebsd/contrib/libpcap/fmtutils.h5
-rw-r--r--freebsd/contrib/libpcap/ftmacros.h18
-rw-r--r--freebsd/contrib/libpcap/gencode.c1868
-rw-r--r--freebsd/contrib/libpcap/gencode.h55
-rw-r--r--freebsd/contrib/libpcap/grammar.c1282
-rw-r--r--freebsd/contrib/libpcap/grammar.h8
-rw-r--r--freebsd/contrib/libpcap/grammar.y312
-rw-r--r--freebsd/contrib/libpcap/nametoaddr.c32
-rw-r--r--freebsd/contrib/libpcap/optimize.c318
-rw-r--r--freebsd/contrib/libpcap/pcap-bpf.c104
-rw-r--r--freebsd/contrib/libpcap/pcap-common.c85
-rw-r--r--freebsd/contrib/libpcap/pcap-common.h8
-rw-r--r--freebsd/contrib/libpcap/pcap-int.h36
-rw-r--r--freebsd/contrib/libpcap/pcap.c407
-rw-r--r--freebsd/contrib/libpcap/pcap/compiler-tests.h2
-rw-r--r--freebsd/contrib/libpcap/pcap/funcattrs.h14
-rw-r--r--freebsd/contrib/libpcap/pcap/nflog.h18
-rw-r--r--freebsd/contrib/libpcap/pcap/pcap-inttypes.h11
-rw-r--r--freebsd/contrib/libpcap/pcap/pcap.h52
-rw-r--r--freebsd/contrib/libpcap/pcap/sll.h40
-rw-r--r--freebsd/contrib/libpcap/pcap/socket.h93
-rw-r--r--freebsd/contrib/libpcap/portability.h91
-rw-r--r--freebsd/contrib/libpcap/savefile.c49
-rw-r--r--freebsd/contrib/libpcap/scanner.c5069
-rw-r--r--freebsd/contrib/libpcap/scanner.h2
-rw-r--r--freebsd/contrib/libpcap/scanner.l37
-rw-r--r--freebsd/contrib/libpcap/sf-pcap.c169
-rw-r--r--freebsd/contrib/libpcap/sf-pcap.h2
-rw-r--r--freebsd/contrib/libpcap/sf-pcapng.c200
-rw-r--r--freebsd/contrib/libpcap/sf-pcapng.h2
-rw-r--r--freebsd/contrib/tcpdump/addrtoname.c7
-rw-r--r--freebsd/contrib/tcpdump/netdissect.h2
-rw-r--r--freebsd/contrib/tcpdump/print-802_11.c15
-rw-r--r--freebsd/contrib/tcpdump/print-aoe.c2
-rw-r--r--freebsd/contrib/tcpdump/print-babel.c4
-rw-r--r--freebsd/contrib/tcpdump/print-bfd.c215
-rw-r--r--freebsd/contrib/tcpdump/print-bgp.c49
-rw-r--r--freebsd/contrib/tcpdump/print-bootp.c7
-rw-r--r--freebsd/contrib/tcpdump/print-dccp.c53
-rw-r--r--freebsd/contrib/tcpdump/print-decnet.c33
-rw-r--r--freebsd/contrib/tcpdump/print-domain.c7
-rw-r--r--freebsd/contrib/tcpdump/print-dvmrp.c26
-rw-r--r--freebsd/contrib/tcpdump/print-eigrp.c2
-rw-r--r--freebsd/contrib/tcpdump/print-esp.c91
-rw-r--r--freebsd/contrib/tcpdump/print-fr.c9
-rw-r--r--freebsd/contrib/tcpdump/print-hncp.c14
-rw-r--r--freebsd/contrib/tcpdump/print-icmp.c14
-rw-r--r--freebsd/contrib/tcpdump/print-icmp6.c31
-rw-r--r--freebsd/contrib/tcpdump/print-ipnet.c44
-rw-r--r--freebsd/contrib/tcpdump/print-isakmp.c1
-rw-r--r--freebsd/contrib/tcpdump/print-juniper.c5
-rw-r--r--freebsd/contrib/tcpdump/print-l2tp.c214
-rw-r--r--freebsd/contrib/tcpdump/print-ldp.c28
-rw-r--r--freebsd/contrib/tcpdump/print-lmp.c59
-rw-r--r--freebsd/contrib/tcpdump/print-nfs.c4
-rw-r--r--freebsd/contrib/tcpdump/print-openflow.c8
-rw-r--r--freebsd/contrib/tcpdump/print-ospf.c4
-rw-r--r--freebsd/contrib/tcpdump/print-ospf6.c3
-rw-r--r--freebsd/contrib/tcpdump/print-pflog.c8
-rw-r--r--freebsd/contrib/tcpdump/print-ppi.c4
-rw-r--r--freebsd/contrib/tcpdump/print-rsvp.c2
-rw-r--r--freebsd/contrib/tcpdump/print-rx.c8
-rw-r--r--freebsd/contrib/tcpdump/print-sflow.c10
-rw-r--r--freebsd/contrib/tcpdump/print-sl.c34
-rw-r--r--freebsd/contrib/tcpdump/print-sll.c11
-rw-r--r--freebsd/contrib/tcpdump/print-smb.c13
-rw-r--r--freebsd/contrib/tcpdump/print-tcp.c14
-rw-r--r--freebsd/contrib/tcpdump/print-udp.c4
-rw-r--r--freebsd/contrib/tcpdump/print-vrrp.c8
-rw-r--r--freebsd/contrib/tcpdump/print-vtp.c2
-rw-r--r--freebsd/contrib/tcpdump/print-wb.c2
-rw-r--r--freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h2
-rw-r--r--freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-dvmrp-data.h1
-rw-r--r--freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-pim-data.h1
-rw-r--r--freebsd/contrib/tcpdump/signature.c4
-rw-r--r--freebsd/contrib/tcpdump/smbutil.c42
-rw-r--r--freebsd/contrib/tcpdump/tcpdump.c45
-rw-r--r--freebsd/contrib/tcpdump/util-print.c20
-rw-r--r--freebsd/lib/libc/net/nslexer.c47
-rw-r--r--freebsd/lib/libc/net/nsparser.c2
-rw-r--r--freebsd/lib/libc/resolv/res_findzonecut.c2
-rw-r--r--freebsd/sbin/dhclient/bpf.c8
-rw-r--r--freebsd/sbin/dhclient/dhclient.c24
-rw-r--r--freebsd/sbin/ifconfig/ifconfig.c10
-rw-r--r--freebsd/sbin/ifconfig/iflagg.c7
-rw-r--r--freebsd/sbin/ifconfig/ifmedia.c32
-rw-r--r--freebsd/sbin/ifconfig/sfp.c69
-rw-r--r--freebsd/sbin/nvmecontrol/comnd.c2
-rw-r--r--freebsd/sbin/nvmecontrol/identify.c33
-rw-r--r--freebsd/sbin/nvmecontrol/identify_ext.c25
-rw-r--r--freebsd/sbin/nvmecontrol/logpage.c2
-rw-r--r--freebsd/sbin/nvmecontrol/modules/wdc/wdc.c3
-rw-r--r--freebsd/sbin/nvmecontrol/nc_util.c3
-rw-r--r--freebsd/sbin/nvmecontrol/ns.c2
-rw-r--r--freebsd/sbin/nvmecontrol/nvmecontrol_ext.h2
-rw-r--r--freebsd/sbin/nvmecontrol/power.c3
-rw-r--r--freebsd/sbin/pfctl/parse.c31
-rw-r--r--freebsd/sbin/ping6/ping6.c12
-rw-r--r--freebsd/sys/arm/freescale/imx/imx_gpio.c12
-rw-r--r--freebsd/sys/arm/ti/ti_sdhci.c27
-rw-r--r--freebsd/sys/cam/cam_periph.h2
-rw-r--r--freebsd/sys/cam/scsi/scsi_all.c40
-rw-r--r--freebsd/sys/dev/dwc/if_dwc.c9
-rw-r--r--freebsd/sys/dev/e1000/e1000_api.c1
-rw-r--r--freebsd/sys/dev/e1000/e1000_hw.h1
-rw-r--r--freebsd/sys/dev/e1000/if_em.c55
-rw-r--r--freebsd/sys/dev/gpio/gpiobus.c144
-rw-r--r--freebsd/sys/dev/gpio/gpiobusvar.h19
-rw-r--r--freebsd/sys/dev/gpio/ofw_gpiobus.c82
-rw-r--r--freebsd/sys/dev/kbd/kbd.c21
-rw-r--r--freebsd/sys/dev/kbd/kbdreg.h15
-rw-r--r--freebsd/sys/dev/mii/mii.c14
-rw-r--r--freebsd/sys/dev/nvme/nvme.c19
-rw-r--r--freebsd/sys/dev/nvme/nvme.h12
-rw-r--r--freebsd/sys/dev/nvme/nvme_ctrlr.c324
-rw-r--r--freebsd/sys/dev/nvme/nvme_ctrlr_cmd.c20
-rw-r--r--freebsd/sys/dev/nvme/nvme_pci.c87
-rw-r--r--freebsd/sys/dev/nvme/nvme_private.h49
-rw-r--r--freebsd/sys/dev/nvme/nvme_qpair.c119
-rw-r--r--freebsd/sys/dev/nvme/nvme_sysctl.c6
-rw-r--r--freebsd/sys/dev/ofw/ofw_bus_subr.h3
-rw-r--r--freebsd/sys/dev/pci/pci.c17
-rw-r--r--freebsd/sys/dev/pci/pci_private.h2
-rw-r--r--freebsd/sys/dev/sdhci/sdhci.c9
-rw-r--r--freebsd/sys/dev/usb/controller/dwc_otg_fdt.c26
-rw-r--r--freebsd/sys/dev/usb/input/uep.c1
-rw-r--r--freebsd/sys/dev/usb/input/ukbd.c5
-rw-r--r--freebsd/sys/dev/usb/input/ums.c1
-rw-r--r--freebsd/sys/dev/usb/serial/uslcom.c7
-rw-r--r--freebsd/sys/dev/usb/usb_bus.h12
-rw-r--r--freebsd/sys/dev/usb/usb_device.h14
-rw-r--r--freebsd/sys/dev/usb/usb_generic.c5
-rw-r--r--freebsd/sys/dev/usb/usb_ioctl.h2
-rw-r--r--freebsd/sys/dev/usb/usb_transfer.c42
-rw-r--r--freebsd/sys/fs/devfs/devfs_vnops.c58
-rw-r--r--freebsd/sys/kern/kern_conf.c45
-rw-r--r--freebsd/sys/kern/kern_linker.c12
-rw-r--r--freebsd/sys/kern/kern_mib.c5
-rw-r--r--freebsd/sys/kern/kern_mtxpool.c2
-rw-r--r--freebsd/sys/kern/kern_sysctl.c53
-rw-r--r--freebsd/sys/kern/kern_timeout.c11
-rw-r--r--freebsd/sys/kern/subr_bus.c38
-rw-r--r--freebsd/sys/kern/subr_firmware.c6
-rw-r--r--freebsd/sys/kern/subr_gtaskqueue.c89
-rw-r--r--freebsd/sys/kern/subr_taskqueue.c140
-rwxr-xr-xfreebsd/sys/kern/sys_pipe.c21
-rw-r--r--freebsd/sys/kern/tty.c72
-rw-r--r--freebsd/sys/kern/uipc_mbuf2.c4
-rw-r--r--freebsd/sys/kern/uipc_usrreq.c3
-rw-r--r--freebsd/sys/net/dlt.h18
-rw-r--r--freebsd/sys/net/if.c128
-rw-r--r--freebsd/sys/net/if_bridge.c22
-rw-r--r--freebsd/sys/net/if_clone.c19
-rw-r--r--freebsd/sys/net/if_clone.h3
-rw-r--r--freebsd/sys/net/if_epair.c42
-rw-r--r--freebsd/sys/net/if_lagg.c84
-rw-r--r--freebsd/sys/net/if_lagg.h12
-rw-r--r--freebsd/sys/net/if_llatbl.c20
-rw-r--r--freebsd/sys/net/if_tap.c1153
-rw-r--r--freebsd/sys/net/if_tap.h24
-rw-r--r--freebsd/sys/net/if_tapvar.h71
-rw-r--r--freebsd/sys/net/if_tun.c1132
-rw-r--r--freebsd/sys/net/if_tuntap.c1923
-rw-r--r--freebsd/sys/net/if_vlan.c36
-rw-r--r--freebsd/sys/net/iflib.h5
-rw-r--r--freebsd/sys/net/route.c17
-rw-r--r--freebsd/sys/net/sff8472.h79
-rw-r--r--freebsd/sys/net/vnet.h4
-rw-r--r--freebsd/sys/net80211/ieee80211.c2
-rw-r--r--freebsd/sys/netinet/in_mcast.c22
-rw-r--r--freebsd/sys/netinet/ip_carp.c26
-rw-r--r--freebsd/sys/netinet/ip_carp.h4
-rw-r--r--freebsd/sys/netinet/ip_mroute.c26
-rw-r--r--freebsd/sys/netinet/ip_output.c2
-rw-r--r--freebsd/sys/netinet/ip_reass.c56
-rw-r--r--freebsd/sys/netinet/sctp_asconf.c111
-rw-r--r--freebsd/sys/netinet/sctp_dtrace_define.h177
-rw-r--r--freebsd/sys/netinet/sctp_indata.c52
-rw-r--r--freebsd/sys/netinet/sctp_input.c36
-rw-r--r--freebsd/sys/netinet/sctp_os_bsd.h7
-rw-r--r--freebsd/sys/netinet/sctp_output.c13
-rw-r--r--freebsd/sys/netinet/sctp_pcb.c9
-rw-r--r--freebsd/sys/netinet/sctp_pcb.h2
-rw-r--r--freebsd/sys/netinet/sctp_usrreq.c10
-rw-r--r--freebsd/sys/netinet/sctputil.c34
-rw-r--r--freebsd/sys/netinet/sctputil.h2
-rw-r--r--freebsd/sys/netinet/tcp_input.c43
-rw-r--r--freebsd/sys/netinet/tcp_output.c14
-rw-r--r--freebsd/sys/netinet/tcp_subr.c2
-rw-r--r--freebsd/sys/netinet/tcp_timer.c9
-rw-r--r--freebsd/sys/netinet/tcp_timer.h3
-rw-r--r--freebsd/sys/netinet/tcp_usrreq.c106
-rw-r--r--freebsd/sys/netinet/tcp_var.h3
-rw-r--r--freebsd/sys/netinet/udp_usrreq.c11
-rw-r--r--freebsd/sys/netinet/udp_var.h3
-rw-r--r--freebsd/sys/netinet6/dest6.c45
-rw-r--r--freebsd/sys/netinet6/frag6.c1107
-rw-r--r--freebsd/sys/netinet6/icmp6.c347
-rw-r--r--freebsd/sys/netinet6/in6.c3
-rw-r--r--freebsd/sys/netinet6/in6_mcast.c24
-rw-r--r--freebsd/sys/netinet6/in6_pcb.c16
-rw-r--r--freebsd/sys/netinet6/in6_pcb.h2
-rw-r--r--freebsd/sys/netinet6/in6_proto.c35
-rw-r--r--freebsd/sys/netinet6/in6_src.c12
-rw-r--r--freebsd/sys/netinet6/ip6_forward.c1
-rw-r--r--freebsd/sys/netinet6/ip6_input.c215
-rw-r--r--freebsd/sys/netinet6/ip6_mroute.c23
-rw-r--r--freebsd/sys/netinet6/ip6_output.c216
-rw-r--r--freebsd/sys/netinet6/ip6_var.h38
-rw-r--r--freebsd/sys/netinet6/mld6.c26
-rw-r--r--freebsd/sys/netinet6/mld6_var.h2
-rw-r--r--freebsd/sys/netinet6/nd6.c138
-rw-r--r--freebsd/sys/netinet6/nd6.h11
-rw-r--r--freebsd/sys/netinet6/nd6_nbr.c128
-rw-r--r--freebsd/sys/netinet6/nd6_rtr.c1032
-rw-r--r--freebsd/sys/netinet6/raw_ip6.c64
-rw-r--r--freebsd/sys/netinet6/route6.c26
-rw-r--r--freebsd/sys/netinet6/sctp6_usrreq.c73
-rw-r--r--freebsd/sys/netinet6/udp6_usrreq.c59
-rw-r--r--freebsd/sys/netipsec/xform_ah.c16
-rw-r--r--freebsd/sys/netipsec/xform_esp.c20
-rw-r--r--freebsd/sys/netpfil/pf/pf.c7
-rw-r--r--freebsd/sys/opencrypto/cryptodev.c124
-rw-r--r--freebsd/sys/sys/buf.h2
-rw-r--r--freebsd/sys/sys/bus.h1
-rw-r--r--freebsd/sys/sys/conf.h2
-rw-r--r--freebsd/sys/sys/kernel.h2
-rw-r--r--freebsd/sys/sys/linker.h5
-rw-r--r--freebsd/sys/sys/malloc.h8
-rw-r--r--freebsd/sys/sys/mbuf.h4
-rw-r--r--freebsd/sys/sys/mount.h1
-rw-r--r--freebsd/sys/sys/pcpu.h24
-rw-r--r--freebsd/sys/sys/proc.h3
-rw-r--r--freebsd/sys/sys/signalvar.h1
-rw-r--r--freebsd/sys/sys/smp.h2
-rw-r--r--freebsd/sys/sys/sysctl.h14
-rw-r--r--freebsd/sys/sys/systm.h7
-rw-r--r--freebsd/sys/sys/taskqueue.h5
-rw-r--r--freebsd/sys/sys/unpcb.h2
-rw-r--r--freebsd/sys/sys/vnode.h4
-rw-r--r--freebsd/sys/vm/uma_core.c42
-rw-r--r--freebsd/sys/vm/vm_extern.h9
-rw-r--r--freebsd/usr.bin/netstat/inet.c6
-rw-r--r--freebsd/usr.bin/netstat/inet6.c10
-rw-r--r--freebsd/usr.bin/netstat/main.c3
-rw-r--r--freebsd/usr.bin/netstat/mroute.c12
-rw-r--r--freebsd/usr.sbin/arp/arp.c3
-rw-r--r--libbsd.py8
-rw-r--r--rtemsbsd/include/machine/pcpu_aux.h0
-rw-r--r--rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h145
-rw-r--r--rtemsbsd/include/rtems/bsd/local/usbdevs.h2
-rw-r--r--rtemsbsd/include/rtems/bsd/local/usbdevs_data.h12
272 files changed, 18849 insertions, 15989 deletions
diff --git a/freebsd-org b/freebsd-org
-Subproject 7e8d1444023128d34fb9aa4e4515928a4f794d1
+Subproject 0d1c391321b34b3025cf0e72f2231d836ff76da
diff --git a/freebsd/contrib/expat/lib/ascii.h b/freebsd/contrib/expat/lib/ascii.h
index d10530b0..c3587e57 100644
--- a/freebsd/contrib/expat/lib/ascii.h
+++ b/freebsd/contrib/expat/lib/ascii.h
@@ -1,5 +1,33 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define ASCII_A 0x41
diff --git a/freebsd/contrib/expat/lib/asciitab.h b/freebsd/contrib/expat/lib/asciitab.h
index 79a15c28..63b1d1b4 100644
--- a/freebsd/contrib/expat/lib/asciitab.h
+++ b/freebsd/contrib/expat/lib/asciitab.h
@@ -1,36 +1,64 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+ /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+ /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+ /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+ /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+ /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+ /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+ /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+ /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+ /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+ /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+ /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+ /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+ /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+ /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+ /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+ /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+ /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/freebsd/contrib/expat/lib/expat.h b/freebsd/contrib/expat/lib/expat.h
index 086e24b3..48a6e2a3 100644
--- a/freebsd/contrib/expat/lib/expat.h
+++ b/freebsd/contrib/expat/lib/expat.h
@@ -1,19 +1,38 @@
-/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Expat_INCLUDED
#define Expat_INCLUDED 1
-#ifdef __VMS
-/* 0 1 2 3 0 1 2 3
- 1234567890123456789012345678901 1234567890123456789012345678901 */
-#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
-#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler
-#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler
-#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg
-#endif
-
#include <stdlib.h>
#include "expat_external.h"
@@ -24,10 +43,9 @@ extern "C" {
struct XML_ParserStruct;
typedef struct XML_ParserStruct *XML_Parser;
-/* Should this be defined using stdbool.h when C99 is available? */
typedef unsigned char XML_Bool;
-#define XML_TRUE ((XML_Bool) 1)
-#define XML_FALSE ((XML_Bool) 0)
+#define XML_TRUE ((XML_Bool)1)
+#define XML_FALSE ((XML_Bool)0)
/* The XML_Status enum gives the possible return values for several
API functions. The preprocessor #defines are included so this
@@ -95,7 +113,9 @@ enum XML_Error {
/* Added in 2.0. */
XML_ERROR_RESERVED_PREFIX_XML,
XML_ERROR_RESERVED_PREFIX_XMLNS,
- XML_ERROR_RESERVED_NAMESPACE_URI
+ XML_ERROR_RESERVED_NAMESPACE_URI,
+ /* Added in 2.2.1. */
+ XML_ERROR_INVALID_ARGUMENT
};
enum XML_Content_Type {
@@ -135,25 +155,23 @@ enum XML_Content_Quant {
typedef struct XML_cp XML_Content;
struct XML_cp {
- enum XML_Content_Type type;
- enum XML_Content_Quant quant;
- XML_Char * name;
- unsigned int numchildren;
- XML_Content * children;
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ XML_Char *name;
+ unsigned int numchildren;
+ XML_Content *children;
};
-
/* This is called for an element declaration. See above for
description of the model argument. It's the caller's responsibility
to free model when finished with it.
*/
-typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
- const XML_Char *name,
- XML_Content *model);
+typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData,
+ const XML_Char *name,
+ XML_Content *model);
XMLPARSEAPI(void)
-XML_SetElementDeclHandler(XML_Parser parser,
- XML_ElementDeclHandler eldecl);
+XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl);
/* The Attlist declaration handler is called for *each* attribute. So
a single Attlist declaration with multiple attributes declared will
@@ -163,17 +181,12 @@ XML_SetElementDeclHandler(XML_Parser parser,
value will be NULL in the case of "#REQUIRED". If "isrequired" is
true and default is non-NULL, then this is a "#FIXED" default.
*/
-typedef void (XMLCALL *XML_AttlistDeclHandler) (
- void *userData,
- const XML_Char *elname,
- const XML_Char *attname,
- const XML_Char *att_type,
- const XML_Char *dflt,
- int isrequired);
+typedef void(XMLCALL *XML_AttlistDeclHandler)(
+ void *userData, const XML_Char *elname, const XML_Char *attname,
+ const XML_Char *att_type, const XML_Char *dflt, int isrequired);
XMLPARSEAPI(void)
-XML_SetAttlistDeclHandler(XML_Parser parser,
- XML_AttlistDeclHandler attdecl);
+XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl);
/* The XML declaration handler is called for *both* XML declarations
and text declarations. The way to distinguish is that the version
@@ -183,15 +196,13 @@ XML_SetAttlistDeclHandler(XML_Parser parser,
was no standalone parameter in the declaration, that it was given
as no, or that it was given as yes.
*/
-typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData,
- const XML_Char *version,
- const XML_Char *encoding,
- int standalone);
+typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData,
+ const XML_Char *version,
+ const XML_Char *encoding,
+ int standalone);
XMLPARSEAPI(void)
-XML_SetXmlDeclHandler(XML_Parser parser,
- XML_XmlDeclHandler xmldecl);
-
+XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl);
typedef struct {
void *(*malloc_fcn)(size_t size);
@@ -219,7 +230,6 @@ XML_ParserCreate(const XML_Char *encoding);
XMLPARSEAPI(XML_Parser)
XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
-
/* Constructs a new parser using the memory management suite referred to
by memsuite. If memsuite is NULL, then use the standard library memory
suite. If namespaceSeparator is non-NULL it creates a parser with
@@ -235,7 +245,7 @@ XML_ParserCreate_MM(const XML_Char *encoding,
const XML_Char *namespaceSeparator);
/* Prepare a parser object to be re-used. This is particularly
- valuable when memory allocation overhead is disproportionatly high,
+ valuable when memory allocation overhead is disproportionately high,
such as when a large number of small documnents need to be parsed.
All handlers are cleared from the parser, except for the
unknownEncodingHandler. The parser's external state is re-initialized
@@ -249,31 +259,27 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
/* atts is array of name/value pairs, terminated by 0;
names and values are 0 terminated.
*/
-typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
- const XML_Char *name,
- const XML_Char **atts);
-
-typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
- const XML_Char *name);
+typedef void(XMLCALL *XML_StartElementHandler)(void *userData,
+ const XML_Char *name,
+ const XML_Char **atts);
+typedef void(XMLCALL *XML_EndElementHandler)(void *userData,
+ const XML_Char *name);
/* s is not 0 terminated. */
-typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
- const XML_Char *s,
- int len);
+typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData,
+ const XML_Char *s, int len);
/* target and data are 0 terminated */
-typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
- void *userData,
- const XML_Char *target,
- const XML_Char *data);
+typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData,
+ const XML_Char *target,
+ const XML_Char *data);
/* data is 0 terminated */
-typedef void (XMLCALL *XML_CommentHandler) (void *userData,
- const XML_Char *data);
+typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data);
-typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
-typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
+typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData);
+typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData);
/* This is called for any characters in the XML document for which
there is no applicable handler. This includes both characters that
@@ -288,25 +294,23 @@ typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
default handler: for example, a comment might be split between
multiple calls.
*/
-typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
- const XML_Char *s,
- int len);
+typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s,
+ int len);
/* This is called for the start of the DOCTYPE declaration, before
any DTD or internal subset is parsed.
*/
-typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
- void *userData,
- const XML_Char *doctypeName,
- const XML_Char *sysid,
- const XML_Char *pubid,
- int has_internal_subset);
+typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData,
+ const XML_Char *doctypeName,
+ const XML_Char *sysid,
+ const XML_Char *pubid,
+ int has_internal_subset);
/* This is called for the start of the DOCTYPE declaration when the
closing > is encountered, but after processing any external
subset.
*/
-typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
+typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
/* This is called for entity declarations. The is_parameter_entity
argument will be non-zero if the entity is a parameter entity, zero
@@ -326,20 +330,14 @@ typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
Note that is_parameter_entity can't be changed to XML_Bool, since
that would break binary compatibility.
*/
-typedef void (XMLCALL *XML_EntityDeclHandler) (
- void *userData,
- const XML_Char *entityName,
- int is_parameter_entity,
- const XML_Char *value,
- int value_length,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName);
+typedef void(XMLCALL *XML_EntityDeclHandler)(
+ void *userData, const XML_Char *entityName, int is_parameter_entity,
+ const XML_Char *value, int value_length, const XML_Char *base,
+ const XML_Char *systemId, const XML_Char *publicId,
+ const XML_Char *notationName);
XMLPARSEAPI(void)
-XML_SetEntityDeclHandler(XML_Parser parser,
- XML_EntityDeclHandler handler);
+XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler);
/* OBSOLETE -- OBSOLETE -- OBSOLETE
This handler has been superseded by the EntityDeclHandler above.
@@ -350,24 +348,20 @@ XML_SetEntityDeclHandler(XML_Parser parser,
entityName, systemId and notationName arguments will never be
NULL. The other arguments may be.
*/
-typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
- void *userData,
- const XML_Char *entityName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName);
+typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)(
+ void *userData, const XML_Char *entityName, const XML_Char *base,
+ const XML_Char *systemId, const XML_Char *publicId,
+ const XML_Char *notationName);
/* This is called for a declaration of notation. The base argument is
whatever was set by XML_SetBase. The notationName will never be
NULL. The other arguments can be.
*/
-typedef void (XMLCALL *XML_NotationDeclHandler) (
- void *userData,
- const XML_Char *notationName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId);
+typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData,
+ const XML_Char *notationName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
/* When namespace processing is enabled, these are called once for
each namespace declaration. The call to the start and end element
@@ -375,14 +369,12 @@ typedef void (XMLCALL *XML_NotationDeclHandler) (
declaration handlers. For an xmlns attribute, prefix will be
NULL. For an xmlns="" attribute, uri will be NULL.
*/
-typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
- void *userData,
- const XML_Char *prefix,
- const XML_Char *uri);
+typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData,
+ const XML_Char *prefix,
+ const XML_Char *uri);
-typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
- void *userData,
- const XML_Char *prefix);
+typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData,
+ const XML_Char *prefix);
/* This is called if the document is not standalone, that is, it has an
external subset or a reference to a parameter entity, but does not
@@ -393,7 +385,7 @@ typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
conditions above this handler will only be called if the referenced
entity was actually read.
*/
-typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
+typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData);
/* This is called for a reference to an external parsed general
entity. The referenced entity is not automatically parsed. The
@@ -429,12 +421,11 @@ typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
Note that unlike other handlers the first argument is the parser,
not userData.
*/
-typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
- XML_Parser parser,
- const XML_Char *context,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId);
+typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
/* This is called in two situations:
1) An entity reference is encountered for which no declaration
@@ -446,10 +437,9 @@ typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
the event would be out of sync with the reporting of the
declarations or attribute values
*/
-typedef void (XMLCALL *XML_SkippedEntityHandler) (
- void *userData,
- const XML_Char *entityName,
- int is_parameter_entity);
+typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity);
/* This structure is filled in by the XML_UnknownEncodingHandler to
provide information to the parser about encodings that are unknown
@@ -506,8 +496,8 @@ typedef void (XMLCALL *XML_SkippedEntityHandler) (
typedef struct {
int map[256];
void *data;
- int (XMLCALL *convert)(void *data, const char *s);
- void (XMLCALL *release)(void *data);
+ int(XMLCALL *convert)(void *data, const char *s);
+ void(XMLCALL *release)(void *data);
} XML_Encoding;
/* This is called for an encoding that is unknown to the parser.
@@ -525,23 +515,19 @@ typedef struct {
If info does not describe a suitable encoding, then the parser will
return an XML_UNKNOWN_ENCODING error.
*/
-typedef int (XMLCALL *XML_UnknownEncodingHandler) (
- void *encodingHandlerData,
- const XML_Char *name,
- XML_Encoding *info);
+typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData,
+ const XML_Char *name,
+ XML_Encoding *info);
XMLPARSEAPI(void)
-XML_SetElementHandler(XML_Parser parser,
- XML_StartElementHandler start,
+XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
XML_EndElementHandler end);
XMLPARSEAPI(void)
-XML_SetStartElementHandler(XML_Parser parser,
- XML_StartElementHandler handler);
+XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler);
XMLPARSEAPI(void)
-XML_SetEndElementHandler(XML_Parser parser,
- XML_EndElementHandler handler);
+XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler);
XMLPARSEAPI(void)
XML_SetCharacterDataHandler(XML_Parser parser,
@@ -551,8 +537,7 @@ XMLPARSEAPI(void)
XML_SetProcessingInstructionHandler(XML_Parser parser,
XML_ProcessingInstructionHandler handler);
XMLPARSEAPI(void)
-XML_SetCommentHandler(XML_Parser parser,
- XML_CommentHandler handler);
+XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler);
XMLPARSEAPI(void)
XML_SetCdataSectionHandler(XML_Parser parser,
@@ -572,20 +557,17 @@ XML_SetEndCdataSectionHandler(XML_Parser parser,
default handler, or to the skipped entity handler, if one is set.
*/
XMLPARSEAPI(void)
-XML_SetDefaultHandler(XML_Parser parser,
- XML_DefaultHandler handler);
+XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler);
/* This sets the default handler but does not inhibit expansion of
internal entities. The entity reference will not be passed to the
default handler.
*/
XMLPARSEAPI(void)
-XML_SetDefaultHandlerExpand(XML_Parser parser,
- XML_DefaultHandler handler);
+XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler);
XMLPARSEAPI(void)
-XML_SetDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start,
+XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
XML_EndDoctypeDeclHandler end);
XMLPARSEAPI(void)
@@ -593,16 +575,14 @@ XML_SetStartDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start);
XMLPARSEAPI(void)
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
- XML_EndDoctypeDeclHandler end);
+XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end);
XMLPARSEAPI(void)
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
XML_UnparsedEntityDeclHandler handler);
XMLPARSEAPI(void)
-XML_SetNotationDeclHandler(XML_Parser parser,
- XML_NotationDeclHandler handler);
+XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler);
XMLPARSEAPI(void)
XML_SetNamespaceDeclHandler(XML_Parser parser,
@@ -630,8 +610,7 @@ XML_SetExternalEntityRefHandler(XML_Parser parser,
instead of the parser object.
*/
XMLPARSEAPI(void)
-XML_SetExternalEntityRefHandlerArg(XML_Parser parser,
- void *arg);
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg);
XMLPARSEAPI(void)
XML_SetSkippedEntityHandler(XML_Parser parser,
@@ -706,11 +685,11 @@ XML_UseParserAsHandlerArg(XML_Parser parser);
be called, despite an external subset being parsed.
Note: If XML_DTD is not defined when Expat is compiled, returns
XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+ Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT.
*/
XMLPARSEAPI(enum XML_Error)
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
-
/* Sets the base to be used for resolving relative URIs in system
identifiers in declarations. Resolving relative identifiers is
left to the application: this value will be passed through as the
@@ -729,15 +708,16 @@ XML_GetBase(XML_Parser parser);
to the XML_StartElementHandler that were specified in the start-tag
rather than defaulted. Each attribute/value pair counts as 2; thus
this correspondds to an index into the atts array passed to the
- XML_StartElementHandler.
+ XML_StartElementHandler. Returns -1 if parser == NULL.
*/
XMLPARSEAPI(int)
XML_GetSpecifiedAttributeCount(XML_Parser parser);
/* Returns the index of the ID attribute passed in the last call to
- XML_StartElementHandler, or -1 if there is no ID attribute. Each
- attribute/value pair counts as 2; thus this correspondds to an
- index into the atts array passed to the XML_StartElementHandler.
+ XML_StartElementHandler, or -1 if there is no ID attribute or
+ parser == NULL. Each attribute/value pair counts as 2; thus this
+ correspondds to an index into the atts array passed to the
+ XML_StartElementHandler.
*/
XMLPARSEAPI(int)
XML_GetIdAttributeIndex(XML_Parser parser);
@@ -749,10 +729,10 @@ XML_GetIdAttributeIndex(XML_Parser parser);
info->valueEnd - info->valueStart = 4 bytes.
*/
typedef struct {
- XML_Index nameStart; /* Offset to beginning of the attribute name. */
- XML_Index nameEnd; /* Offset after the attribute name's last byte. */
- XML_Index valueStart; /* Offset to beginning of the attribute value. */
- XML_Index valueEnd; /* Offset after the attribute value's last byte. */
+ XML_Index nameStart; /* Offset to beginning of the attribute name. */
+ XML_Index nameEnd; /* Offset after the attribute name's last byte. */
+ XML_Index valueStart; /* Offset to beginning of the attribute value. */
+ XML_Index valueEnd; /* Offset after the attribute value's last byte. */
} XML_AttrInfo;
/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
@@ -788,20 +768,20 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
(resumable = 0) an already suspended parser. Some call-backs may
still follow because they would otherwise get lost. Examples:
- endElementHandler() for empty elements when stopped in
- startElementHandler(),
- - endNameSpaceDeclHandler() when stopped in endElementHandler(),
+ startElementHandler(),
+ - endNameSpaceDeclHandler() when stopped in endElementHandler(),
and possibly others.
Can be called from most handlers, including DTD related call-backs,
except when parsing an external parameter entity and resumable != 0.
Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
- Possible error codes:
+ Possible error codes:
- XML_ERROR_SUSPENDED: when suspending an already suspended parser.
- XML_ERROR_FINISHED: when the parser has already finished.
- XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
- When resumable != 0 (true) then parsing is suspended, that is,
- XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
+ When resumable != 0 (true) then parsing is suspended, that is,
+ XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
@@ -812,7 +792,7 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
the externalEntityRefHandler() to call XML_StopParser() on the parent
parser (recursively), if one wants to stop parsing altogether.
- When suspended, parsing can be resumed by calling XML_ResumeParser().
+ When suspended, parsing can be resumed by calling XML_ResumeParser().
*/
XMLPARSEAPI(enum XML_Status)
XML_StopParser(XML_Parser parser, XML_Bool resumable);
@@ -820,7 +800,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable);
/* Resumes parsing after it has been suspended with XML_StopParser().
Must not be called from within a handler call-back. Returns same
status codes as XML_Parse() or XML_ParseBuffer().
- Additional error code XML_ERROR_NOT_SUSPENDED possible.
+ Additional error code XML_ERROR_NOT_SUSPENDED possible.
*Note*:
This must be called on the most deeply nested child parser instance
@@ -832,12 +812,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable);
XMLPARSEAPI(enum XML_Status)
XML_ResumeParser(XML_Parser parser);
-enum XML_Parsing {
- XML_INITIALIZED,
- XML_PARSING,
- XML_FINISHED,
- XML_SUSPENDED
-};
+enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED };
typedef struct {
enum XML_Parsing parsing;
@@ -869,8 +844,7 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
Otherwise returns a new XML_Parser object.
*/
XMLPARSEAPI(XML_Parser)
-XML_ExternalEntityParserCreate(XML_Parser parser,
- const XML_Char *context,
+XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context,
const XML_Char *encoding);
enum XML_ParamEntityParsing {
@@ -901,6 +875,7 @@ enum XML_ParamEntityParsing {
entities is requested; otherwise it will return non-zero.
Note: If XML_SetParamEntityParsing is called after XML_Parse or
XML_ParseBuffer, then it has no effect and will always return 0.
+ Note: If parser == NULL, the function will do nothing and return 0.
*/
XMLPARSEAPI(int)
XML_SetParamEntityParsing(XML_Parser parser,
@@ -910,10 +885,10 @@ XML_SetParamEntityParsing(XML_Parser parser,
Helps in preventing DoS attacks based on predicting hash
function behavior. This must be called before parsing is started.
Returns 1 if successful, 0 when called after parsing has started.
+ Note: If parser == NULL, the function will do nothing and return 0.
*/
XMLPARSEAPI(int)
-XML_SetHashSalt(XML_Parser parser,
- unsigned long hash_salt);
+XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt);
/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
XML_GetErrorCode returns information about the error.
@@ -930,12 +905,16 @@ XML_GetErrorCode(XML_Parser parser);
be within the relevant markup. When called outside of the callback
functions, the position indicated will be just past the last parse
event (regardless of whether there was an associated callback).
-
+
They may also be called after returning from a call to XML_Parse
or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then
the location is the location of the character at which the error
was detected; otherwise the location is the location of the last
parse event, as described above.
+
+ Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber
+ return 0 to indicate an error.
+ Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
*/
XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
@@ -958,14 +937,12 @@ XML_GetCurrentByteCount(XML_Parser parser);
the handler that makes the call.
*/
XMLPARSEAPI(const char *)
-XML_GetInputContext(XML_Parser parser,
- int *offset,
- int *size);
+XML_GetInputContext(XML_Parser parser, int *offset, int *size);
/* For backwards compatibility with previous versions. */
-#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
-#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
/* Frees the content model passed to the element declaration handler */
XMLPARSEAPI(void)
@@ -1025,21 +1002,20 @@ enum XML_FeatureEnum {
};
typedef struct {
- enum XML_FeatureEnum feature;
- const XML_LChar *name;
- long int value;
+ enum XML_FeatureEnum feature;
+ const XML_LChar *name;
+ long int value;
} XML_Feature;
XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);
-
/* Expat follows the semantic versioning convention.
See http://semver.org.
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 2
-#define XML_MICRO_VERSION 0
+#define XML_MICRO_VERSION 9
#ifdef __cplusplus
}
diff --git a/freebsd/contrib/expat/lib/expat_external.h b/freebsd/contrib/expat/lib/expat_external.h
index aa08a2f8..b3b6e74d 100644
--- a/freebsd/contrib/expat/lib/expat_external.h
+++ b/freebsd/contrib/expat/lib/expat_external.h
@@ -1,5 +1,33 @@
-/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Expat_External_INCLUDED
@@ -7,10 +35,6 @@
/* External API definitions */
-#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
-#define XML_USE_MSC_EXTENSIONS 1
-#endif
-
/* Expat tries very hard to make the API boundary very specifically
defined. There are two macros defined to control this boundary;
each of these can be defined before including this header to
@@ -34,11 +58,11 @@
system headers may assume the cdecl convention.
*/
#ifndef XMLCALL
-#if defined(_MSC_VER)
-#define XMLCALL __cdecl
-#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
-#define XMLCALL __attribute__((cdecl))
-#else
+# if defined(_MSC_VER)
+# define XMLCALL __cdecl
+# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
+# define XMLCALL __attribute__((cdecl))
+# else
/* For any platform which uses this definition and supports more than
one calling convention, we need to extend this definition to
declare the convention used on that platform, if it's possible to
@@ -49,41 +73,46 @@
pre-processor and how to specify the same calling convention as the
platform's malloc() implementation.
*/
-#define XMLCALL
-#endif
-#endif /* not defined XMLCALL */
-
+# define XMLCALL
+# endif
+#endif /* not defined XMLCALL */
-#if !defined(XML_STATIC) && !defined(XMLIMPORT)
-#ifndef XML_BUILDING_EXPAT
+#if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
+# ifndef XML_BUILDING_EXPAT
/* using Expat from an application */
-#ifdef XML_USE_MSC_EXTENSIONS
-#define XMLIMPORT __declspec(dllimport)
-#endif
+# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
+# define XMLIMPORT __declspec(dllimport)
+# endif
+# endif
+#endif /* not defined XML_STATIC */
+
+#ifndef XML_ENABLE_VISIBILITY
+# define XML_ENABLE_VISIBILITY 0
#endif
-#endif /* not defined XML_STATIC */
-#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
-#define XMLIMPORT __attribute__ ((visibility ("default")))
+#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
+# define XMLIMPORT __attribute__((visibility("default")))
#endif
/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
-#define XMLIMPORT
+# define XMLIMPORT
#endif
-#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
-#define XML_ATTR_MALLOC __attribute__((__malloc__))
+#if defined(__GNUC__) \
+ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+# define XML_ATTR_MALLOC __attribute__((__malloc__))
#else
-#define XML_ATTR_MALLOC
+# define XML_ATTR_MALLOC
#endif
-#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
-#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#if defined(__GNUC__) \
+ && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
#else
-#define XML_ATTR_ALLOC_SIZE(x)
+# define XML_ATTR_ALLOC_SIZE(x)
#endif
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
@@ -93,30 +122,30 @@ extern "C" {
#endif
#ifdef XML_UNICODE_WCHAR_T
-#define XML_UNICODE
+# ifndef XML_UNICODE
+# define XML_UNICODE
+# endif
+# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
+# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
+# endif
#endif
-#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
-#ifdef XML_UNICODE_WCHAR_T
+#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
+# ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
-#else
+# else
typedef unsigned short XML_Char;
typedef char XML_LChar;
-#endif /* XML_UNICODE_WCHAR_T */
-#else /* Information is UTF-8 encoded. */
+# endif /* XML_UNICODE_WCHAR_T */
+#else /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
-#endif /* XML_UNICODE */
+#endif /* XML_UNICODE */
-#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
-#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
-typedef __int64 XML_Index;
-typedef unsigned __int64 XML_Size;
-#else
+#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
typedef long long XML_Index;
typedef unsigned long long XML_Size;
-#endif
#else
typedef long XML_Index;
typedef unsigned long XML_Size;
diff --git a/freebsd/contrib/expat/lib/iasciitab.h b/freebsd/contrib/expat/lib/iasciitab.h
index 24a1d5cc..ea97cfcf 100644
--- a/freebsd/contrib/expat/lib/iasciitab.h
+++ b/freebsd/contrib/expat/lib/iasciitab.h
@@ -1,37 +1,65 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+ /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+ /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+ /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+ /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+ /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+ /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+ /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+ /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+ /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+ /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+ /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+ /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+ /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+ /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+ /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+ /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+ /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/freebsd/contrib/expat/lib/internal.h b/freebsd/contrib/expat/lib/internal.h
index 94cb98e1..60913dab 100644
--- a/freebsd/contrib/expat/lib/internal.h
+++ b/freebsd/contrib/expat/lib/internal.h
@@ -18,9 +18,38 @@
Note: Use of these macros is based on judgement, not hard rules,
and therefore subject to change.
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
+#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__)
/* We'll use this version by default only where we know it helps.
regparm() generates warnings on Solaris boxes. See SF bug #692878.
@@ -30,8 +59,8 @@
#define FASTCALL __attribute__((stdcall, regparm(3)))
and let's try this:
*/
-#define FASTCALL __attribute__((regparm(3)))
-#define PTRFASTCALL __attribute__((regparm(3)))
+# define FASTCALL __attribute__((regparm(3)))
+# define PTRFASTCALL __attribute__((regparm(3)))
#endif
/* Using __fastcall seems to have an unexpected negative effect under
@@ -45,50 +74,49 @@
/* Make sure all of these are defined if they aren't already. */
#ifndef FASTCALL
-#define FASTCALL
+# define FASTCALL
#endif
#ifndef PTRCALL
-#define PTRCALL
+# define PTRCALL
#endif
#ifndef PTRFASTCALL
-#define PTRFASTCALL
+# define PTRFASTCALL
#endif
#ifndef XML_MIN_SIZE
-#if !defined(__cplusplus) && !defined(inline)
-#ifdef __GNUC__
-#define inline __inline
-#endif /* __GNUC__ */
-#endif
+# if ! defined(__cplusplus) && ! defined(inline)
+# ifdef __GNUC__
+# define inline __inline
+# endif /* __GNUC__ */
+# endif
#endif /* XML_MIN_SIZE */
#ifdef __cplusplus
-#define inline inline
+# define inline inline
#else
-#ifndef inline
-#define inline
-#endif
+# ifndef inline
+# define inline
+# endif
#endif
#ifndef UNUSED_P
-# ifdef __GNUC__
-# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
-# else
-# define UNUSED_P(p) UNUSED_ ## p
-# endif
+# define UNUSED_P(p) (void)p
#endif
-
#ifdef __cplusplus
extern "C" {
#endif
-
+#ifdef XML_ENABLE_VISIBILITY
+# if XML_ENABLE_VISIBILITY
+__attribute__((visibility("default")))
+# endif
+#endif
void
-align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);
-
+_INTERNAL_trim_to_complete_utf8_characters(const char *from,
+ const char **fromLimRef);
#ifdef __cplusplus
}
diff --git a/freebsd/contrib/expat/lib/latin1tab.h b/freebsd/contrib/expat/lib/latin1tab.h
index 53c25d76..6f916041 100644
--- a/freebsd/contrib/expat/lib/latin1tab.h
+++ b/freebsd/contrib/expat/lib/latin1tab.h
@@ -1,36 +1,64 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
-/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+ /* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+ /* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+ /* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+ /* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+ /* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+ /* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+ /* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/freebsd/contrib/expat/lib/nametab.h b/freebsd/contrib/expat/lib/nametab.h
index b05e62c7..3681df34 100644
--- a/freebsd/contrib/expat/lib/nametab.h
+++ b/freebsd/contrib/expat/lib/nametab.h
@@ -1,150 +1,136 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
static const unsigned namingBitmap[] = {
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
-0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
-0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
-0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
-0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
-0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
-0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
-0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
-0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
-0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
-0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
-0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
-0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
-0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
-0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
-0x40000000, 0xF580C900, 0x00000007, 0x02010800,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
-0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
-0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
-0x00000000, 0x00004C40, 0x00000000, 0x00000000,
-0x00000007, 0x00000000, 0x00000000, 0x00000000,
-0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
-0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
-0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
-0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
-0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
-0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
-0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
-0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
-0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
-0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
-0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
-0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
-0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
-0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
-0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
-0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000,
+ 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+ 0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+ 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF,
+ 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+ 0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE,
+ 0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+ 0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF,
+ 0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+ 0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF,
+ 0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+ 0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF,
+ 0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF,
+ 0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000,
+ 0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+ 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40,
+ 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F,
+ 0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+ 0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000,
+ 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB,
+ 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+ 0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000,
+ 0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+ 0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF,
+ 0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+ 0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF,
+ 0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+ 0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718,
+ 0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+ 0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF,
+ 0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE,
+ 0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+ 0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+ 0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0x77FFFFFF,
};
static const unsigned char nmstrtPages[] = {
-0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
-0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char namePages[] = {
-0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
-0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21,
+ 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
};
diff --git a/freebsd/contrib/expat/lib/utf8tab.h b/freebsd/contrib/expat/lib/utf8tab.h
index 7bb3e776..a22986ac 100644
--- a/freebsd/contrib/expat/lib/utf8tab.h
+++ b/freebsd/contrib/expat/lib/utf8tab.h
@@ -1,37 +1,64 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
-/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
+ /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+ /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+ /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+ /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+ /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+ /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+ /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+ /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+ /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+ /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+ /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+ /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+ /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+ /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+ /* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+ /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/freebsd/contrib/expat/lib/xmlparse.c b/freebsd/contrib/expat/lib/xmlparse.c
index 868a7b3f..0de1f0aa 100644
--- a/freebsd/contrib/expat/lib/xmlparse.c
+++ b/freebsd/contrib/expat/lib/xmlparse.c
@@ -1,97 +1,174 @@
#include <machine/rtems-bsd-user-space.h>
-/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/* f519f27c7c3b79fee55aeb8b1e53b7384b079d9118bf3a62eb3a60986a6742f2 (2.2.9+)
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#if ! defined(_GNU_SOURCE)
+# define _GNU_SOURCE 1 /* syscall prototype */
+#endif
+
+#ifdef _WIN32
+/* force stdlib to define rand_s() */
+# if ! defined(_CRT_RAND_S)
+# define _CRT_RAND_S
+# endif
+#endif
+
#include <stddef.h>
-#include <string.h> /* memset(), memcpy() */
+#include <string.h> /* memset(), memcpy() */
#include <assert.h>
-#include <limits.h> /* UINT_MAX */
+#include <limits.h> /* UINT_MAX */
+#include <stdio.h> /* fprintf */
+#include <stdlib.h> /* getenv, rand_s */
-#ifdef WIN32
-#define getpid GetCurrentProcessId
+#ifdef _WIN32
+# define getpid GetCurrentProcessId
#else
-#include <sys/time.h> /* gettimeofday() */
-#include <sys/types.h> /* getpid() */
-#include <unistd.h> /* getpid() */
+# include <sys/time.h> /* gettimeofday() */
+# include <sys/types.h> /* getpid() */
+# include <unistd.h> /* getpid() */
+# include <fcntl.h> /* O_RDONLY */
+# include <errno.h>
#endif
#define XML_BUILDING_EXPAT 1
-#ifdef WIN32
-#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
+#ifdef _WIN32
+# include "winconfig.h"
#elif defined(HAVE_EXPAT_CONFIG_H)
-#include <expat_config.h>
-#endif /* ndef WIN32 */
+# include <expat_config.h>
+#endif /* ndef _WIN32 */
#include "ascii.h"
#include "expat.h"
+#include "siphash.h"
+
+#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+# if defined(HAVE_GETRANDOM)
+# include <sys/random.h> /* getrandom */
+# else
+# include <unistd.h> /* syscall */
+# include <sys/syscall.h> /* SYS_getrandom */
+# endif
+# if ! defined(GRND_NONBLOCK)
+# define GRND_NONBLOCK 0x0001
+# endif /* defined(GRND_NONBLOCK) */
+#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
+
+#if defined(HAVE_LIBBSD) \
+ && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
+# include <bsd/stdlib.h>
+#endif
+
+#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
+# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
+#endif
+
+#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \
+ && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \
+ && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \
+ && ! defined(XML_POOR_ENTROPY)
+# error You do not have support for any sources of high quality entropy \
+ enabled. For end user security, that is probably not what you want. \
+ \
+ Your options include: \
+ * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
+ * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
+ * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
+ * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \
+ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
+ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
+ * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \
+ * Windows (rand_s): _WIN32. \
+ \
+ If insist on not using any of these, bypass this error by defining \
+ XML_POOR_ENTROPY; you have been warned. \
+ \
+ If you have reasons to patch this detection code away or need changes \
+ to the build system, please open a bug. Thank you!
+#endif
#ifdef XML_UNICODE
-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
-#define XmlConvert XmlUtf16Convert
-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
-#define XmlEncode XmlUtf16Encode
+# define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+# define XmlConvert XmlUtf16Convert
+# define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+# define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+# define XmlEncode XmlUtf16Encode
/* Using pointer subtraction to convert to integer type. */
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
+# define MUST_CONVERT(enc, s) \
+ (! (enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
typedef unsigned short ICHAR;
#else
-#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
-#define XmlConvert XmlUtf8Convert
-#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
-#define XmlEncode XmlUtf8Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+# define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+# define XmlConvert XmlUtf8Convert
+# define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+# define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+# define XmlEncode XmlUtf8Encode
+# define MUST_CONVERT(enc, s) (! (enc)->isUtf8)
typedef char ICHAR;
#endif
-
#ifndef XML_NS
-#define XmlInitEncodingNS XmlInitEncoding
-#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
-#undef XmlGetInternalEncodingNS
-#define XmlGetInternalEncodingNS XmlGetInternalEncoding
-#define XmlParseXmlDeclNS XmlParseXmlDecl
+# define XmlInitEncodingNS XmlInitEncoding
+# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+# undef XmlGetInternalEncodingNS
+# define XmlGetInternalEncodingNS XmlGetInternalEncoding
+# define XmlParseXmlDeclNS XmlParseXmlDecl
#endif
#ifdef XML_UNICODE
-#ifdef XML_UNICODE_WCHAR_T
-#define XML_T(x) (const wchar_t)x
-#define XML_L(x) L ## x
-#else
-#define XML_T(x) (const unsigned short)x
-#define XML_L(x) x
-#endif
+# ifdef XML_UNICODE_WCHAR_T
+# define XML_T(x) (const wchar_t) x
+# define XML_L(x) L##x
+# else
+# define XML_T(x) (const unsigned short)x
+# define XML_L(x) x
+# endif
#else
-#define XML_T(x) x
-#define XML_L(x) x
+# define XML_T(x) x
+# define XML_L(x) x
#endif
/* Round up n to be a multiple of sz, where sz is a power of 2. */
-#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
-/* Handle the case where memmove() doesn't exist. */
-#ifndef HAVE_MEMMOVE
-#ifdef HAVE_BCOPY
-#define memmove(d,s,l) bcopy((s),(d),(l))
-#else
-#error memmove does not exist on this platform, nor is a substitute available
-#endif /* HAVE_BCOPY */
-#endif /* HAVE_MEMMOVE */
+/* Do safe (NULL-aware) pointer arithmetic */
+#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
#include "internal.h"
#include "xmltok.h"
@@ -111,17 +188,9 @@ typedef struct {
const XML_Memory_Handling_Suite *mem;
} HASH_TABLE;
-/* Basic character hash algorithm, taken from Python's string hash:
- h = h * 1000003 ^ character, the constant being a prime number.
+static size_t keylen(KEY s);
-*/
-#ifdef XML_UNICODE
-#define CHAR_HASH(h, c) \
- (((h) * 0xF4243) ^ (unsigned short)(c))
-#else
-#define CHAR_HASH(h, c) \
- (((h) * 0xF4243) ^ (unsigned char)(c))
-#endif
+static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
/* For probing (after a collision) we need a step size relative prime
to the hash table size, which is a power of 2. We use double-hashing,
@@ -131,9 +200,9 @@ typedef struct {
We limit the maximum step size to table->size / 4 (mask >> 2) and make
it odd, since odd numbers are always relative prime to a power of 2.
*/
-#define SECOND_HASH(hash, mask, power) \
- ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
-#define PROBE_STEP(hash, mask, power) \
+#define SECOND_HASH(hash, mask, power) \
+ ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
+#define PROBE_STEP(hash, mask, power) \
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
typedef struct {
@@ -141,7 +210,7 @@ typedef struct {
NAMED **end;
} HASH_TABLE_ITER;
-#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
+#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
#define INIT_DATA_BUF_SIZE 1024
#define INIT_ATTS_SIZE 16
#define INIT_ATTS_VERSION 0xFFFFFFFF
@@ -188,20 +257,20 @@ typedef struct {
TAG objects in a free list.
*/
typedef struct tag {
- struct tag *parent; /* parent of this element */
- const char *rawName; /* tagName in the original encoding */
+ struct tag *parent; /* parent of this element */
+ const char *rawName; /* tagName in the original encoding */
int rawNameLength;
- TAG_NAME name; /* tagName in the API encoding */
- char *buf; /* buffer for name components */
- char *bufEnd; /* end of the buffer */
+ TAG_NAME name; /* tagName in the API encoding */
+ char *buf; /* buffer for name components */
+ char *bufEnd; /* end of the buffer */
BINDING *bindings;
} TAG;
typedef struct {
const XML_Char *name;
const XML_Char *textPtr;
- int textLen; /* length in XML_Chars */
- int processed; /* # of processed bytes - when suspended */
+ int textLen; /* length in XML_Chars */
+ int processed; /* # of processed bytes - when suspended */
const XML_Char *systemId;
const XML_Char *base;
const XML_Char *publicId;
@@ -212,13 +281,13 @@ typedef struct {
} ENTITY;
typedef struct {
- enum XML_Content_Type type;
- enum XML_Content_Quant quant;
- const XML_Char * name;
- int firstchild;
- int lastchild;
- int childcnt;
- int nextsib;
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ const XML_Char *name;
+ int firstchild;
+ int lastchild;
+ int childcnt;
+ int nextsib;
} CONTENT_SCAFFOLD;
#define INIT_SCAFFOLD_ELEMENTS 32
@@ -306,10 +375,8 @@ typedef struct open_internal_entity {
XML_Bool betweenDecl; /* WFC: PE Between Declarations */
} OPEN_INTERNAL_ENTITY;
-typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr);
+typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
+ const char *end, const char **endPtr);
static Processor prologProcessor;
static Processor prologInitProcessor;
@@ -330,128 +397,113 @@ static Processor externalEntityInitProcessor3;
static Processor externalEntityContentProcessor;
static Processor internalEntityProcessor;
-static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
-static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
- const char *s, const char *next);
-static enum XML_Error
-initializeEncoding(XML_Parser parser);
-static enum XML_Error
-doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
- const char *end, int tok, const char *next, const char **nextPtr,
- XML_Bool haveMore);
-static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl);
-static enum XML_Error
-doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
- const char *start, const char *end, const char **endPtr,
- XML_Bool haveMore);
-static enum XML_Error
-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
- const char *end, const char **nextPtr, XML_Bool haveMore);
+static enum XML_Error handleUnknownEncoding(XML_Parser parser,
+ const XML_Char *encodingName);
+static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+ const char *s, const char *next);
+static enum XML_Error initializeEncoding(XML_Parser parser);
+static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
+ const char *s, const char *end, int tok,
+ const char *next, const char **nextPtr,
+ XML_Bool haveMore, XML_Bool allowClosingDoctype);
+static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
+ XML_Bool betweenDecl);
+static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
+ const ENCODING *enc, const char *start,
+ const char *end, const char **endPtr,
+ XML_Bool haveMore);
+static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
+ const char **startPtr, const char *end,
+ const char **nextPtr, XML_Bool haveMore);
#ifdef XML_DTD
-static enum XML_Error
-doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
- const char *end, const char **nextPtr, XML_Bool haveMore);
+static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
+ const char **startPtr, const char *end,
+ const char **nextPtr, XML_Bool haveMore);
#endif /* XML_DTD */
-static enum XML_Error
-storeAtts(XML_Parser parser, const ENCODING *, const char *s,
- TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
-static enum XML_Error
-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- const XML_Char *uri, BINDING **bindingsPtr);
-static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
- XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
-static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
- const char *, const char *, STRING_POOL *);
-static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
- const char *, const char *, STRING_POOL *);
-static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static int
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
-static enum XML_Error
-storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end);
-static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-
-static const XML_Char * getContext(XML_Parser parser);
-static XML_Bool
-setContext(XML_Parser parser, const XML_Char *context);
+static void freeBindings(XML_Parser parser, BINDING *bindings);
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
+ const char *s, TAG_NAME *tagNamePtr,
+ BINDING **bindingsPtr);
+static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
+ const ATTRIBUTE_ID *attId, const XML_Char *uri,
+ BINDING **bindingsPtr);
+static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
+ XML_Bool isId, const XML_Char *dfltValue,
+ XML_Parser parser);
+static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
+ XML_Bool isCdata, const char *,
+ const char *, STRING_POOL *);
+static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
+ XML_Bool isCdata, const char *,
+ const char *, STRING_POOL *);
+static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end);
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end);
+static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end);
+static int reportComment(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end);
+static void reportDefault(XML_Parser parser, const ENCODING *enc,
+ const char *start, const char *end);
+
+static const XML_Char *getContext(XML_Parser parser);
+static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
static void FASTCALL normalizePublicId(XML_Char *s);
-static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
-/* do not call if parentParser != NULL */
+static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
+/* do not call if m_parentParser != NULL */
static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
-static void
-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
-static int
-dtdCopy(XML_Parser oldParser,
- DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
-static int
-copyEntityTable(XML_Parser oldParser,
- HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
-static NAMED *
-lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
-static void FASTCALL
-hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
+static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
+ const XML_Memory_Handling_Suite *ms);
+static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
+ const XML_Memory_Handling_Suite *ms);
+static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *,
+ const HASH_TABLE *);
+static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
+ size_t createSize);
+static void FASTCALL hashTableInit(HASH_TABLE *,
+ const XML_Memory_Handling_Suite *ms);
static void FASTCALL hashTableClear(HASH_TABLE *);
static void FASTCALL hashTableDestroy(HASH_TABLE *);
-static void FASTCALL
-hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
-static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
+static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
-static void FASTCALL
-poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL poolInit(STRING_POOL *,
+ const XML_Memory_Handling_Suite *ms);
static void FASTCALL poolClear(STRING_POOL *);
static void FASTCALL poolDestroy(STRING_POOL *);
-static XML_Char *
-poolAppend(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end);
-static XML_Char *
-poolStoreString(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end);
+static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end);
+static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end);
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
-static const XML_Char * FASTCALL
-poolCopyString(STRING_POOL *pool, const XML_Char *s);
-static const XML_Char *
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
-static const XML_Char * FASTCALL
-poolAppendString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
+ const XML_Char *s);
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
+ int n);
+static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
+ const XML_Char *s);
static int FASTCALL nextScaffoldPart(XML_Parser parser);
-static XML_Content * build_model(XML_Parser parser);
-static ELEMENT_TYPE *
-getElementType(XML_Parser parser, const ENCODING *enc,
- const char *ptr, const char *end);
+static XML_Content *build_model(XML_Parser parser);
+static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
+ const char *ptr, const char *end);
+
+static XML_Char *copyString(const XML_Char *s,
+ const XML_Memory_Handling_Suite *memsuite);
static unsigned long generate_hash_secret_salt(XML_Parser parser);
static XML_Bool startParsing(XML_Parser parser);
-static XML_Parser
-parserCreate(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep,
- DTD *dtd);
+static XML_Parser parserCreate(const XML_Char *encodingName,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *nameSep, DTD *dtd);
-static void
-parserInit(XML_Parser parser, const XML_Char *encodingName);
+static void parserInit(XML_Parser parser, const XML_Char *encodingName);
#define poolStart(pool) ((pool)->start)
#define poolEnd(pool) ((pool)->ptr)
@@ -460,13 +512,13 @@ parserInit(XML_Parser parser, const XML_Char *encodingName);
#define poolLastChar(pool) (((pool)->ptr)[-1])
#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
-#define poolAppendChar(pool, c) \
- (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
- ? 0 \
- : ((*((pool)->ptr)++ = c), 1))
+#define poolAppendChar(pool, c) \
+ (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \
+ ? 0 \
+ : ((*((pool)->ptr)++ = c), 1))
struct XML_ParserStruct {
- /* The first member must be userData so that the XML_GetUserData
+ /* The first member must be m_userData so that the XML_GetUserData
macro works. */
void *m_userData;
void *m_handlerArg;
@@ -476,7 +528,7 @@ struct XML_ParserStruct {
const char *m_bufferPtr;
/* past last character to be parsed */
char *m_bufferEnd;
- /* allocated end of buffer */
+ /* allocated end of m_buffer */
const char *m_bufferLim;
XML_Index m_parseEndByteIndex;
const char *m_parseEndPtr;
@@ -514,7 +566,7 @@ struct XML_ParserStruct {
void *m_unknownEncodingMem;
void *m_unknownEncodingData;
void *m_unknownEncodingHandlerData;
- void (XMLCALL *m_unknownEncodingRelease)(void *);
+ void(XMLCALL *m_unknownEncodingRelease)(void *);
PROLOG_STATE m_prologState;
Processor *m_processor;
enum XML_Error m_errorCode;
@@ -568,215 +620,274 @@ struct XML_ParserStruct {
unsigned long m_hash_secret_salt;
};
-#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
-#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
-#define FREE(p) (parser->m_mem.free_fcn((p)))
-
-#define userData (parser->m_userData)
-#define handlerArg (parser->m_handlerArg)
-#define startElementHandler (parser->m_startElementHandler)
-#define endElementHandler (parser->m_endElementHandler)
-#define characterDataHandler (parser->m_characterDataHandler)
-#define processingInstructionHandler \
- (parser->m_processingInstructionHandler)
-#define commentHandler (parser->m_commentHandler)
-#define startCdataSectionHandler \
- (parser->m_startCdataSectionHandler)
-#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
-#define defaultHandler (parser->m_defaultHandler)
-#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
-#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
-#define unparsedEntityDeclHandler \
- (parser->m_unparsedEntityDeclHandler)
-#define notationDeclHandler (parser->m_notationDeclHandler)
-#define startNamespaceDeclHandler \
- (parser->m_startNamespaceDeclHandler)
-#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
-#define notStandaloneHandler (parser->m_notStandaloneHandler)
-#define externalEntityRefHandler \
- (parser->m_externalEntityRefHandler)
-#define externalEntityRefHandlerArg \
- (parser->m_externalEntityRefHandlerArg)
-#define internalEntityRefHandler \
- (parser->m_internalEntityRefHandler)
-#define skippedEntityHandler (parser->m_skippedEntityHandler)
-#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
-#define elementDeclHandler (parser->m_elementDeclHandler)
-#define attlistDeclHandler (parser->m_attlistDeclHandler)
-#define entityDeclHandler (parser->m_entityDeclHandler)
-#define xmlDeclHandler (parser->m_xmlDeclHandler)
-#define encoding (parser->m_encoding)
-#define initEncoding (parser->m_initEncoding)
-#define internalEncoding (parser->m_internalEncoding)
-#define unknownEncodingMem (parser->m_unknownEncodingMem)
-#define unknownEncodingData (parser->m_unknownEncodingData)
-#define unknownEncodingHandlerData \
- (parser->m_unknownEncodingHandlerData)
-#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
-#define protocolEncodingName (parser->m_protocolEncodingName)
-#define ns (parser->m_ns)
-#define ns_triplets (parser->m_ns_triplets)
-#define prologState (parser->m_prologState)
-#define processor (parser->m_processor)
-#define errorCode (parser->m_errorCode)
-#define eventPtr (parser->m_eventPtr)
-#define eventEndPtr (parser->m_eventEndPtr)
-#define positionPtr (parser->m_positionPtr)
-#define position (parser->m_position)
-#define openInternalEntities (parser->m_openInternalEntities)
-#define freeInternalEntities (parser->m_freeInternalEntities)
-#define defaultExpandInternalEntities \
- (parser->m_defaultExpandInternalEntities)
-#define tagLevel (parser->m_tagLevel)
-#define buffer (parser->m_buffer)
-#define bufferPtr (parser->m_bufferPtr)
-#define bufferEnd (parser->m_bufferEnd)
-#define parseEndByteIndex (parser->m_parseEndByteIndex)
-#define parseEndPtr (parser->m_parseEndPtr)
-#define bufferLim (parser->m_bufferLim)
-#define dataBuf (parser->m_dataBuf)
-#define dataBufEnd (parser->m_dataBufEnd)
-#define _dtd (parser->m_dtd)
-#define curBase (parser->m_curBase)
-#define declEntity (parser->m_declEntity)
-#define doctypeName (parser->m_doctypeName)
-#define doctypeSysid (parser->m_doctypeSysid)
-#define doctypePubid (parser->m_doctypePubid)
-#define declAttributeType (parser->m_declAttributeType)
-#define declNotationName (parser->m_declNotationName)
-#define declNotationPublicId (parser->m_declNotationPublicId)
-#define declElementType (parser->m_declElementType)
-#define declAttributeId (parser->m_declAttributeId)
-#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
-#define declAttributeIsId (parser->m_declAttributeIsId)
-#define freeTagList (parser->m_freeTagList)
-#define freeBindingList (parser->m_freeBindingList)
-#define inheritedBindings (parser->m_inheritedBindings)
-#define tagStack (parser->m_tagStack)
-#define atts (parser->m_atts)
-#define attsSize (parser->m_attsSize)
-#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
-#define idAttIndex (parser->m_idAttIndex)
-#define nsAtts (parser->m_nsAtts)
-#define nsAttsVersion (parser->m_nsAttsVersion)
-#define nsAttsPower (parser->m_nsAttsPower)
-#define attInfo (parser->m_attInfo)
-#define tempPool (parser->m_tempPool)
-#define temp2Pool (parser->m_temp2Pool)
-#define groupConnector (parser->m_groupConnector)
-#define groupSize (parser->m_groupSize)
-#define namespaceSeparator (parser->m_namespaceSeparator)
-#define parentParser (parser->m_parentParser)
-#define ps_parsing (parser->m_parsingStatus.parsing)
-#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
-#ifdef XML_DTD
-#define isParamEntity (parser->m_isParamEntity)
-#define useForeignDTD (parser->m_useForeignDTD)
-#define paramEntityParsing (parser->m_paramEntityParsing)
-#endif /* XML_DTD */
-#define hash_secret_salt (parser->m_hash_secret_salt)
+#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
+#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
+#define FREE(parser, p) (parser->m_mem.free_fcn((p)))
XML_Parser XMLCALL
-XML_ParserCreate(const XML_Char *encodingName)
-{
+XML_ParserCreate(const XML_Char *encodingName) {
return XML_ParserCreate_MM(encodingName, NULL, NULL);
}
XML_Parser XMLCALL
-XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
-{
+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
XML_Char tmp[2];
*tmp = nsSep;
return XML_ParserCreate_MM(encodingName, NULL, tmp);
}
-static const XML_Char implicitContext[] = {
- ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
- ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
- ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
- ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
- ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
- ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
-};
+static const XML_Char implicitContext[]
+ = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h,
+ ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
+ ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD,
+ ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r,
+ ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
+ ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8,
+ ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
+ ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e,
+ '\0'};
+
+/* To avoid warnings about unused functions: */
+#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
+
+# if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+
+/* Obtain entropy on Linux 3.17+ */
+static int
+writeRandomBytes_getrandom_nonblock(void *target, size_t count) {
+ int success = 0; /* full count bytes written? */
+ size_t bytesWrittenTotal = 0;
+ const unsigned int getrandomFlags = GRND_NONBLOCK;
+
+ do {
+ void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
+ const size_t bytesToWrite = count - bytesWrittenTotal;
+
+ const int bytesWrittenMore =
+# if defined(HAVE_GETRANDOM)
+ getrandom(currentTarget, bytesToWrite, getrandomFlags);
+# else
+ syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
+# endif
+
+ if (bytesWrittenMore > 0) {
+ bytesWrittenTotal += bytesWrittenMore;
+ if (bytesWrittenTotal >= count)
+ success = 1;
+ }
+ } while (! success && (errno == EINTR));
+
+ return success;
+}
+
+# endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
+
+# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
+
+/* Extract entropy from /dev/urandom */
+static int
+writeRandomBytes_dev_urandom(void *target, size_t count) {
+ int success = 0; /* full count bytes written? */
+ size_t bytesWrittenTotal = 0;
+
+ const int fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ return 0;
+ }
+
+ do {
+ void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
+ const size_t bytesToWrite = count - bytesWrittenTotal;
+
+ const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
+
+ if (bytesWrittenMore > 0) {
+ bytesWrittenTotal += bytesWrittenMore;
+ if (bytesWrittenTotal >= count)
+ success = 1;
+ }
+ } while (! success && (errno == EINTR));
+
+ close(fd);
+ return success;
+}
+
+# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
+
+#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
+
+#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF)
+
+static void
+writeRandomBytes_arc4random(void *target, size_t count) {
+ size_t bytesWrittenTotal = 0;
+
+ while (bytesWrittenTotal < count) {
+ const uint32_t random32 = arc4random();
+ size_t i = 0;
+
+ for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
+ i++, bytesWrittenTotal++) {
+ const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
+ ((uint8_t *)target)[bytesWrittenTotal] = random8;
+ }
+ }
+}
+
+#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
+
+#ifdef _WIN32
+
+/* Obtain entropy on Windows using the rand_s() function which
+ * generates cryptographically secure random numbers. Internally it
+ * uses RtlGenRandom API which is present in Windows XP and later.
+ */
+static int
+writeRandomBytes_rand_s(void *target, size_t count) {
+ size_t bytesWrittenTotal = 0;
+
+ while (bytesWrittenTotal < count) {
+ unsigned int random32 = 0;
+ size_t i = 0;
+
+ if (rand_s(&random32))
+ return 0; /* failure */
+
+ for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
+ i++, bytesWrittenTotal++) {
+ const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
+ ((uint8_t *)target)[bytesWrittenTotal] = random8;
+ }
+ }
+ return 1; /* success */
+}
+
+#endif /* _WIN32 */
+
+#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
static unsigned long
-gather_time_entropy(void)
-{
-#ifdef WIN32
+gather_time_entropy(void) {
+# ifdef _WIN32
FILETIME ft;
GetSystemTimeAsFileTime(&ft); /* never fails */
return ft.dwHighDateTime ^ ft.dwLowDateTime;
-#else
+# else
struct timeval tv;
int gettimeofday_res;
gettimeofday_res = gettimeofday(&tv, NULL);
- assert (gettimeofday_res == 0);
+
+# if defined(NDEBUG)
+ (void)gettimeofday_res;
+# else
+ assert(gettimeofday_res == 0);
+# endif /* defined(NDEBUG) */
/* Microseconds time is <20 bits entropy */
return tv.tv_usec;
-#endif
+# endif
}
+#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
+
static unsigned long
-generate_hash_secret_salt(XML_Parser parser)
-{
- /* Process ID is 0 bits entropy if attacker has local access
- * XML_Parser address is few bits of entropy if attacker has local access */
- const unsigned long entropy =
- gather_time_entropy() ^ getpid() ^ (unsigned long)parser;
+ENTROPY_DEBUG(const char *label, unsigned long entropy) {
+ const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
+ if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
+ fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
+ (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
+ }
+ return entropy;
+}
+
+static unsigned long
+generate_hash_secret_salt(XML_Parser parser) {
+ unsigned long entropy;
+ (void)parser;
+
+ /* "Failproof" high quality providers: */
+#if defined(HAVE_ARC4RANDOM_BUF)
+ arc4random_buf(&entropy, sizeof(entropy));
+ return ENTROPY_DEBUG("arc4random_buf", entropy);
+#elif defined(HAVE_ARC4RANDOM)
+ writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
+ return ENTROPY_DEBUG("arc4random", entropy);
+#else
+ /* Try high quality providers first .. */
+# ifdef _WIN32
+ if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
+ return ENTROPY_DEBUG("rand_s", entropy);
+ }
+# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+ if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
+ return ENTROPY_DEBUG("getrandom", entropy);
+ }
+# endif
+# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
+ if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
+ return ENTROPY_DEBUG("/dev/urandom", entropy);
+ }
+# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
+ /* .. and self-made low quality for backup: */
+
+ /* Process ID is 0 bits entropy if attacker has local access */
+ entropy = gather_time_entropy() ^ getpid();
/* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
if (sizeof(unsigned long) == 4) {
- return entropy * 2147483647;
+ return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
} else {
- return entropy * (unsigned long)2305843009213693951;
+ return ENTROPY_DEBUG("fallback(8)",
+ entropy * (unsigned long)2305843009213693951ULL);
}
+#endif
}
-static XML_Bool /* only valid for root parser */
-startParsing(XML_Parser parser)
-{
- /* hash functions must be initialized before setContext() is called */
- if (hash_secret_salt == 0)
- hash_secret_salt = generate_hash_secret_salt(parser);
- if (ns) {
- /* implicit context only set for root parser, since child
- parsers (i.e. external entity parsers) will inherit it
- */
- return setContext(parser, implicitContext);
- }
- return XML_TRUE;
+static unsigned long
+get_hash_secret_salt(XML_Parser parser) {
+ if (parser->m_parentParser != NULL)
+ return get_hash_secret_salt(parser->m_parentParser);
+ return parser->m_hash_secret_salt;
+}
+
+static XML_Bool /* only valid for root parser */
+startParsing(XML_Parser parser) {
+ /* hash functions must be initialized before setContext() is called */
+ if (parser->m_hash_secret_salt == 0)
+ parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
+ if (parser->m_ns) {
+ /* implicit context only set for root parser, since child
+ parsers (i.e. external entity parsers) will inherit it
+ */
+ return setContext(parser, implicitContext);
+ }
+ return XML_TRUE;
}
XML_Parser XMLCALL
XML_ParserCreate_MM(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep)
-{
+ const XML_Char *nameSep) {
return parserCreate(encodingName, memsuite, nameSep, NULL);
}
static XML_Parser
parserCreate(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep,
- DTD *dtd)
-{
+ const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
+ DTD *dtd) {
XML_Parser parser;
if (memsuite) {
XML_Memory_Handling_Suite *mtemp;
- parser = (XML_Parser)
- memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+ parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
if (parser != NULL) {
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
mtemp->malloc_fcn = memsuite->malloc_fcn;
mtemp->realloc_fcn = memsuite->realloc_fcn;
mtemp->free_fcn = memsuite->free_fcn;
}
- }
- else {
+ } else {
XML_Memory_Handling_Suite *mtemp;
parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
if (parser != NULL) {
@@ -787,287 +898,336 @@ parserCreate(const XML_Char *encodingName,
}
}
- if (!parser)
+ if (! parser)
return parser;
- buffer = NULL;
- bufferLim = NULL;
+ parser->m_buffer = NULL;
+ parser->m_bufferLim = NULL;
- attsSize = INIT_ATTS_SIZE;
- atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
- if (atts == NULL) {
- FREE(parser);
+ parser->m_attsSize = INIT_ATTS_SIZE;
+ parser->m_atts
+ = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
+ if (parser->m_atts == NULL) {
+ FREE(parser, parser);
return NULL;
}
#ifdef XML_ATTR_INFO
- attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
- if (attInfo == NULL) {
- FREE(atts);
- FREE(parser);
+ parser->m_attInfo = (XML_AttrInfo *)MALLOC(
+ parser, parser->m_attsSize * sizeof(XML_AttrInfo));
+ if (parser->m_attInfo == NULL) {
+ FREE(parser, parser->m_atts);
+ FREE(parser, parser);
return NULL;
}
#endif
- dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
- if (dataBuf == NULL) {
- FREE(atts);
+ parser->m_dataBuf
+ = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+ if (parser->m_dataBuf == NULL) {
+ FREE(parser, parser->m_atts);
#ifdef XML_ATTR_INFO
- FREE(attInfo);
+ FREE(parser, parser->m_attInfo);
#endif
- FREE(parser);
+ FREE(parser, parser);
return NULL;
}
- dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+ parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
if (dtd)
- _dtd = dtd;
+ parser->m_dtd = dtd;
else {
- _dtd = dtdCreate(&parser->m_mem);
- if (_dtd == NULL) {
- FREE(dataBuf);
- FREE(atts);
+ parser->m_dtd = dtdCreate(&parser->m_mem);
+ if (parser->m_dtd == NULL) {
+ FREE(parser, parser->m_dataBuf);
+ FREE(parser, parser->m_atts);
#ifdef XML_ATTR_INFO
- FREE(attInfo);
+ FREE(parser, parser->m_attInfo);
#endif
- FREE(parser);
+ FREE(parser, parser);
return NULL;
}
}
- freeBindingList = NULL;
- freeTagList = NULL;
- freeInternalEntities = NULL;
+ parser->m_freeBindingList = NULL;
+ parser->m_freeTagList = NULL;
+ parser->m_freeInternalEntities = NULL;
+
+ parser->m_groupSize = 0;
+ parser->m_groupConnector = NULL;
- groupSize = 0;
- groupConnector = NULL;
+ parser->m_unknownEncodingHandler = NULL;
+ parser->m_unknownEncodingHandlerData = NULL;
- unknownEncodingHandler = NULL;
- unknownEncodingHandlerData = NULL;
+ parser->m_namespaceSeparator = ASCII_EXCL;
+ parser->m_ns = XML_FALSE;
+ parser->m_ns_triplets = XML_FALSE;
- namespaceSeparator = ASCII_EXCL;
- ns = XML_FALSE;
- ns_triplets = XML_FALSE;
+ parser->m_nsAtts = NULL;
+ parser->m_nsAttsVersion = 0;
+ parser->m_nsAttsPower = 0;
- nsAtts = NULL;
- nsAttsVersion = 0;
- nsAttsPower = 0;
+ parser->m_protocolEncodingName = NULL;
- poolInit(&tempPool, &(parser->m_mem));
- poolInit(&temp2Pool, &(parser->m_mem));
+ poolInit(&parser->m_tempPool, &(parser->m_mem));
+ poolInit(&parser->m_temp2Pool, &(parser->m_mem));
parserInit(parser, encodingName);
- if (encodingName && !protocolEncodingName) {
+ if (encodingName && ! parser->m_protocolEncodingName) {
XML_ParserFree(parser);
return NULL;
}
if (nameSep) {
- ns = XML_TRUE;
- internalEncoding = XmlGetInternalEncodingNS();
- namespaceSeparator = *nameSep;
- }
- else {
- internalEncoding = XmlGetInternalEncoding();
+ parser->m_ns = XML_TRUE;
+ parser->m_internalEncoding = XmlGetInternalEncodingNS();
+ parser->m_namespaceSeparator = *nameSep;
+ } else {
+ parser->m_internalEncoding = XmlGetInternalEncoding();
}
return parser;
}
static void
-parserInit(XML_Parser parser, const XML_Char *encodingName)
-{
- processor = prologInitProcessor;
- XmlPrologStateInit(&prologState);
- protocolEncodingName = (encodingName != NULL
- ? poolCopyString(&tempPool, encodingName)
- : NULL);
- curBase = NULL;
- XmlInitEncoding(&initEncoding, &encoding, 0);
- userData = NULL;
- handlerArg = NULL;
- startElementHandler = NULL;
- endElementHandler = NULL;
- characterDataHandler = NULL;
- processingInstructionHandler = NULL;
- commentHandler = NULL;
- startCdataSectionHandler = NULL;
- endCdataSectionHandler = NULL;
- defaultHandler = NULL;
- startDoctypeDeclHandler = NULL;
- endDoctypeDeclHandler = NULL;
- unparsedEntityDeclHandler = NULL;
- notationDeclHandler = NULL;
- startNamespaceDeclHandler = NULL;
- endNamespaceDeclHandler = NULL;
- notStandaloneHandler = NULL;
- externalEntityRefHandler = NULL;
- externalEntityRefHandlerArg = parser;
- skippedEntityHandler = NULL;
- elementDeclHandler = NULL;
- attlistDeclHandler = NULL;
- entityDeclHandler = NULL;
- xmlDeclHandler = NULL;
- bufferPtr = buffer;
- bufferEnd = buffer;
- parseEndByteIndex = 0;
- parseEndPtr = NULL;
- declElementType = NULL;
- declAttributeId = NULL;
- declEntity = NULL;
- doctypeName = NULL;
- doctypeSysid = NULL;
- doctypePubid = NULL;
- declAttributeType = NULL;
- declNotationName = NULL;
- declNotationPublicId = NULL;
- declAttributeIsCdata = XML_FALSE;
- declAttributeIsId = XML_FALSE;
- memset(&position, 0, sizeof(POSITION));
- errorCode = XML_ERROR_NONE;
- eventPtr = NULL;
- eventEndPtr = NULL;
- positionPtr = NULL;
- openInternalEntities = NULL;
- defaultExpandInternalEntities = XML_TRUE;
- tagLevel = 0;
- tagStack = NULL;
- inheritedBindings = NULL;
- nSpecifiedAtts = 0;
- unknownEncodingMem = NULL;
- unknownEncodingRelease = NULL;
- unknownEncodingData = NULL;
- parentParser = NULL;
- ps_parsing = XML_INITIALIZED;
+parserInit(XML_Parser parser, const XML_Char *encodingName) {
+ parser->m_processor = prologInitProcessor;
+ XmlPrologStateInit(&parser->m_prologState);
+ if (encodingName != NULL) {
+ parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
+ }
+ parser->m_curBase = NULL;
+ XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
+ parser->m_userData = NULL;
+ parser->m_handlerArg = NULL;
+ parser->m_startElementHandler = NULL;
+ parser->m_endElementHandler = NULL;
+ parser->m_characterDataHandler = NULL;
+ parser->m_processingInstructionHandler = NULL;
+ parser->m_commentHandler = NULL;
+ parser->m_startCdataSectionHandler = NULL;
+ parser->m_endCdataSectionHandler = NULL;
+ parser->m_defaultHandler = NULL;
+ parser->m_startDoctypeDeclHandler = NULL;
+ parser->m_endDoctypeDeclHandler = NULL;
+ parser->m_unparsedEntityDeclHandler = NULL;
+ parser->m_notationDeclHandler = NULL;
+ parser->m_startNamespaceDeclHandler = NULL;
+ parser->m_endNamespaceDeclHandler = NULL;
+ parser->m_notStandaloneHandler = NULL;
+ parser->m_externalEntityRefHandler = NULL;
+ parser->m_externalEntityRefHandlerArg = parser;
+ parser->m_skippedEntityHandler = NULL;
+ parser->m_elementDeclHandler = NULL;
+ parser->m_attlistDeclHandler = NULL;
+ parser->m_entityDeclHandler = NULL;
+ parser->m_xmlDeclHandler = NULL;
+ parser->m_bufferPtr = parser->m_buffer;
+ parser->m_bufferEnd = parser->m_buffer;
+ parser->m_parseEndByteIndex = 0;
+ parser->m_parseEndPtr = NULL;
+ parser->m_declElementType = NULL;
+ parser->m_declAttributeId = NULL;
+ parser->m_declEntity = NULL;
+ parser->m_doctypeName = NULL;
+ parser->m_doctypeSysid = NULL;
+ parser->m_doctypePubid = NULL;
+ parser->m_declAttributeType = NULL;
+ parser->m_declNotationName = NULL;
+ parser->m_declNotationPublicId = NULL;
+ parser->m_declAttributeIsCdata = XML_FALSE;
+ parser->m_declAttributeIsId = XML_FALSE;
+ memset(&parser->m_position, 0, sizeof(POSITION));
+ parser->m_errorCode = XML_ERROR_NONE;
+ parser->m_eventPtr = NULL;
+ parser->m_eventEndPtr = NULL;
+ parser->m_positionPtr = NULL;
+ parser->m_openInternalEntities = NULL;
+ parser->m_defaultExpandInternalEntities = XML_TRUE;
+ parser->m_tagLevel = 0;
+ parser->m_tagStack = NULL;
+ parser->m_inheritedBindings = NULL;
+ parser->m_nSpecifiedAtts = 0;
+ parser->m_unknownEncodingMem = NULL;
+ parser->m_unknownEncodingRelease = NULL;
+ parser->m_unknownEncodingData = NULL;
+ parser->m_parentParser = NULL;
+ parser->m_parsingStatus.parsing = XML_INITIALIZED;
#ifdef XML_DTD
- isParamEntity = XML_FALSE;
- useForeignDTD = XML_FALSE;
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+ parser->m_isParamEntity = XML_FALSE;
+ parser->m_useForeignDTD = XML_FALSE;
+ parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif
- hash_secret_salt = 0;
+ parser->m_hash_secret_salt = 0;
}
-/* moves list of bindings to freeBindingList */
+/* moves list of bindings to m_freeBindingList */
static void FASTCALL
-moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
-{
+moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
while (bindings) {
BINDING *b = bindings;
bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
+ b->nextTagBinding = parser->m_freeBindingList;
+ parser->m_freeBindingList = b;
}
}
XML_Bool XMLCALL
-XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
-{
+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
TAG *tStk;
OPEN_INTERNAL_ENTITY *openEntityList;
- if (parentParser)
+
+ if (parser == NULL)
return XML_FALSE;
- /* move tagStack to freeTagList */
- tStk = tagStack;
+
+ if (parser->m_parentParser)
+ return XML_FALSE;
+ /* move m_tagStack to m_freeTagList */
+ tStk = parser->m_tagStack;
while (tStk) {
TAG *tag = tStk;
tStk = tStk->parent;
- tag->parent = freeTagList;
+ tag->parent = parser->m_freeTagList;
moveToFreeBindingList(parser, tag->bindings);
tag->bindings = NULL;
- freeTagList = tag;
+ parser->m_freeTagList = tag;
}
- /* move openInternalEntities to freeInternalEntities */
- openEntityList = openInternalEntities;
+ /* move m_openInternalEntities to m_freeInternalEntities */
+ openEntityList = parser->m_openInternalEntities;
while (openEntityList) {
OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
openEntityList = openEntity->next;
- openEntity->next = freeInternalEntities;
- freeInternalEntities = openEntity;
- }
- moveToFreeBindingList(parser, inheritedBindings);
- FREE(unknownEncodingMem);
- if (unknownEncodingRelease)
- unknownEncodingRelease(unknownEncodingData);
- poolClear(&tempPool);
- poolClear(&temp2Pool);
+ openEntity->next = parser->m_freeInternalEntities;
+ parser->m_freeInternalEntities = openEntity;
+ }
+ moveToFreeBindingList(parser, parser->m_inheritedBindings);
+ FREE(parser, parser->m_unknownEncodingMem);
+ if (parser->m_unknownEncodingRelease)
+ parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
+ poolClear(&parser->m_tempPool);
+ poolClear(&parser->m_temp2Pool);
+ FREE(parser, (void *)parser->m_protocolEncodingName);
+ parser->m_protocolEncodingName = NULL;
parserInit(parser, encodingName);
- dtdReset(_dtd, &parser->m_mem);
+ dtdReset(parser->m_dtd, &parser->m_mem);
return XML_TRUE;
}
enum XML_Status XMLCALL
-XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
/* Block after XML_Parse()/XML_ParseBuffer() has been called.
XXX There's no way for the caller to determine which of the
XXX possible error cases caused the XML_STATUS_ERROR return.
*/
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ if (parser->m_parsingStatus.parsing == XML_PARSING
+ || parser->m_parsingStatus.parsing == XML_SUSPENDED)
return XML_STATUS_ERROR;
+
+ /* Get rid of any previous encoding name */
+ FREE(parser, (void *)parser->m_protocolEncodingName);
+
if (encodingName == NULL)
- protocolEncodingName = NULL;
+ /* No new encoding name */
+ parser->m_protocolEncodingName = NULL;
else {
- protocolEncodingName = poolCopyString(&tempPool, encodingName);
- if (!protocolEncodingName)
+ /* Copy the new encoding name into allocated memory */
+ parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
+ if (! parser->m_protocolEncodingName)
return XML_STATUS_ERROR;
}
return XML_STATUS_OK;
}
XML_Parser XMLCALL
-XML_ExternalEntityParserCreate(XML_Parser oldParser,
- const XML_Char *context,
- const XML_Char *encodingName)
-{
+XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
+ const XML_Char *encodingName) {
XML_Parser parser = oldParser;
DTD *newDtd = NULL;
- DTD *oldDtd = _dtd;
- XML_StartElementHandler oldStartElementHandler = startElementHandler;
- XML_EndElementHandler oldEndElementHandler = endElementHandler;
- XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
- XML_ProcessingInstructionHandler oldProcessingInstructionHandler
- = processingInstructionHandler;
- XML_CommentHandler oldCommentHandler = commentHandler;
- XML_StartCdataSectionHandler oldStartCdataSectionHandler
- = startCdataSectionHandler;
- XML_EndCdataSectionHandler oldEndCdataSectionHandler
- = endCdataSectionHandler;
- XML_DefaultHandler oldDefaultHandler = defaultHandler;
- XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
- = unparsedEntityDeclHandler;
- XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
- XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
- = startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
- = endNamespaceDeclHandler;
- XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
- XML_ExternalEntityRefHandler oldExternalEntityRefHandler
- = externalEntityRefHandler;
- XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
- XML_UnknownEncodingHandler oldUnknownEncodingHandler
- = unknownEncodingHandler;
- XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
- XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
- XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
- XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
- ELEMENT_TYPE * oldDeclElementType = declElementType;
-
- void *oldUserData = userData;
- void *oldHandlerArg = handlerArg;
- XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
- XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+ DTD *oldDtd;
+ XML_StartElementHandler oldStartElementHandler;
+ XML_EndElementHandler oldEndElementHandler;
+ XML_CharacterDataHandler oldCharacterDataHandler;
+ XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
+ XML_CommentHandler oldCommentHandler;
+ XML_StartCdataSectionHandler oldStartCdataSectionHandler;
+ XML_EndCdataSectionHandler oldEndCdataSectionHandler;
+ XML_DefaultHandler oldDefaultHandler;
+ XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
+ XML_NotationDeclHandler oldNotationDeclHandler;
+ XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
+ XML_NotStandaloneHandler oldNotStandaloneHandler;
+ XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
+ XML_SkippedEntityHandler oldSkippedEntityHandler;
+ XML_UnknownEncodingHandler oldUnknownEncodingHandler;
+ XML_ElementDeclHandler oldElementDeclHandler;
+ XML_AttlistDeclHandler oldAttlistDeclHandler;
+ XML_EntityDeclHandler oldEntityDeclHandler;
+ XML_XmlDeclHandler oldXmlDeclHandler;
+ ELEMENT_TYPE *oldDeclElementType;
+
+ void *oldUserData;
+ void *oldHandlerArg;
+ XML_Bool oldDefaultExpandInternalEntities;
+ XML_Parser oldExternalEntityRefHandlerArg;
+#ifdef XML_DTD
+ enum XML_ParamEntityParsing oldParamEntityParsing;
+ int oldInEntityValue;
+#endif
+ XML_Bool oldns_triplets;
+ /* Note that the new parser shares the same hash secret as the old
+ parser, so that dtdCopy and copyEntityTable can lookup values
+ from hash tables associated with either parser without us having
+ to worry which hash secrets each table has.
+ */
+ unsigned long oldhash_secret_salt;
+
+ /* Validate the oldParser parameter before we pull everything out of it */
+ if (oldParser == NULL)
+ return NULL;
+
+ /* Stash the original parser contents on the stack */
+ oldDtd = parser->m_dtd;
+ oldStartElementHandler = parser->m_startElementHandler;
+ oldEndElementHandler = parser->m_endElementHandler;
+ oldCharacterDataHandler = parser->m_characterDataHandler;
+ oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
+ oldCommentHandler = parser->m_commentHandler;
+ oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
+ oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
+ oldDefaultHandler = parser->m_defaultHandler;
+ oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
+ oldNotationDeclHandler = parser->m_notationDeclHandler;
+ oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
+ oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
+ oldNotStandaloneHandler = parser->m_notStandaloneHandler;
+ oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
+ oldSkippedEntityHandler = parser->m_skippedEntityHandler;
+ oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
+ oldElementDeclHandler = parser->m_elementDeclHandler;
+ oldAttlistDeclHandler = parser->m_attlistDeclHandler;
+ oldEntityDeclHandler = parser->m_entityDeclHandler;
+ oldXmlDeclHandler = parser->m_xmlDeclHandler;
+ oldDeclElementType = parser->m_declElementType;
+
+ oldUserData = parser->m_userData;
+ oldHandlerArg = parser->m_handlerArg;
+ oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
+ oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
#ifdef XML_DTD
- enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
- int oldInEntityValue = prologState.inEntityValue;
+ oldParamEntityParsing = parser->m_paramEntityParsing;
+ oldInEntityValue = parser->m_prologState.inEntityValue;
#endif
- XML_Bool oldns_triplets = ns_triplets;
+ oldns_triplets = parser->m_ns_triplets;
/* Note that the new parser shares the same hash secret as the old
parser, so that dtdCopy and copyEntityTable can lookup values
from hash tables associated with either parser without us having
to worry which hash secrets each table has.
*/
- unsigned long oldhash_secret_salt = hash_secret_salt;
+ oldhash_secret_salt = parser->m_hash_secret_salt;
#ifdef XML_DTD
- if (!context)
+ if (! context)
newDtd = oldDtd;
#endif /* XML_DTD */
@@ -1076,171 +1236,171 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
here. This makes this function more painful to follow than it
would be otherwise.
*/
- if (ns) {
+ if (parser->m_ns) {
XML_Char tmp[2];
- *tmp = namespaceSeparator;
+ *tmp = parser->m_namespaceSeparator;
parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
- }
- else {
+ } else {
parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
}
- if (!parser)
+ if (! parser)
return NULL;
- startElementHandler = oldStartElementHandler;
- endElementHandler = oldEndElementHandler;
- characterDataHandler = oldCharacterDataHandler;
- processingInstructionHandler = oldProcessingInstructionHandler;
- commentHandler = oldCommentHandler;
- startCdataSectionHandler = oldStartCdataSectionHandler;
- endCdataSectionHandler = oldEndCdataSectionHandler;
- defaultHandler = oldDefaultHandler;
- unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
- notationDeclHandler = oldNotationDeclHandler;
- startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
- endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
- notStandaloneHandler = oldNotStandaloneHandler;
- externalEntityRefHandler = oldExternalEntityRefHandler;
- skippedEntityHandler = oldSkippedEntityHandler;
- unknownEncodingHandler = oldUnknownEncodingHandler;
- elementDeclHandler = oldElementDeclHandler;
- attlistDeclHandler = oldAttlistDeclHandler;
- entityDeclHandler = oldEntityDeclHandler;
- xmlDeclHandler = oldXmlDeclHandler;
- declElementType = oldDeclElementType;
- userData = oldUserData;
+ parser->m_startElementHandler = oldStartElementHandler;
+ parser->m_endElementHandler = oldEndElementHandler;
+ parser->m_characterDataHandler = oldCharacterDataHandler;
+ parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
+ parser->m_commentHandler = oldCommentHandler;
+ parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
+ parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
+ parser->m_defaultHandler = oldDefaultHandler;
+ parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+ parser->m_notationDeclHandler = oldNotationDeclHandler;
+ parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+ parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+ parser->m_notStandaloneHandler = oldNotStandaloneHandler;
+ parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
+ parser->m_skippedEntityHandler = oldSkippedEntityHandler;
+ parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
+ parser->m_elementDeclHandler = oldElementDeclHandler;
+ parser->m_attlistDeclHandler = oldAttlistDeclHandler;
+ parser->m_entityDeclHandler = oldEntityDeclHandler;
+ parser->m_xmlDeclHandler = oldXmlDeclHandler;
+ parser->m_declElementType = oldDeclElementType;
+ parser->m_userData = oldUserData;
if (oldUserData == oldHandlerArg)
- handlerArg = userData;
+ parser->m_handlerArg = parser->m_userData;
else
- handlerArg = parser;
+ parser->m_handlerArg = parser;
if (oldExternalEntityRefHandlerArg != oldParser)
- externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
- defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
- ns_triplets = oldns_triplets;
- hash_secret_salt = oldhash_secret_salt;
- parentParser = oldParser;
+ parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+ parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+ parser->m_ns_triplets = oldns_triplets;
+ parser->m_hash_secret_salt = oldhash_secret_salt;
+ parser->m_parentParser = oldParser;
#ifdef XML_DTD
- paramEntityParsing = oldParamEntityParsing;
- prologState.inEntityValue = oldInEntityValue;
+ parser->m_paramEntityParsing = oldParamEntityParsing;
+ parser->m_prologState.inEntityValue = oldInEntityValue;
if (context) {
#endif /* XML_DTD */
- if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
- || !setContext(parser, context)) {
+ if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
+ || ! setContext(parser, context)) {
XML_ParserFree(parser);
return NULL;
}
- processor = externalEntityInitProcessor;
+ parser->m_processor = externalEntityInitProcessor;
#ifdef XML_DTD
- }
- else {
- /* The DTD instance referenced by _dtd is shared between the document's
- root parser and external PE parsers, therefore one does not need to
- call setContext. In addition, one also *must* not call setContext,
- because this would overwrite existing prefix->binding pointers in
- _dtd with ones that get destroyed with the external PE parser.
- This would leave those prefixes with dangling pointers.
+ } else {
+ /* The DTD instance referenced by parser->m_dtd is shared between the
+ document's root parser and external PE parsers, therefore one does not
+ need to call setContext. In addition, one also *must* not call
+ setContext, because this would overwrite existing prefix->binding
+ pointers in parser->m_dtd with ones that get destroyed with the external
+ PE parser. This would leave those prefixes with dangling pointers.
*/
- isParamEntity = XML_TRUE;
- XmlPrologStateInitExternalEntity(&prologState);
- processor = externalParEntInitProcessor;
+ parser->m_isParamEntity = XML_TRUE;
+ XmlPrologStateInitExternalEntity(&parser->m_prologState);
+ parser->m_processor = externalParEntInitProcessor;
}
#endif /* XML_DTD */
return parser;
}
static void FASTCALL
-destroyBindings(BINDING *bindings, XML_Parser parser)
-{
+destroyBindings(BINDING *bindings, XML_Parser parser) {
for (;;) {
BINDING *b = bindings;
- if (!b)
+ if (! b)
break;
bindings = b->nextTagBinding;
- FREE(b->uri);
- FREE(b);
+ FREE(parser, b->uri);
+ FREE(parser, b);
}
}
void XMLCALL
-XML_ParserFree(XML_Parser parser)
-{
+XML_ParserFree(XML_Parser parser) {
TAG *tagList;
OPEN_INTERNAL_ENTITY *entityList;
if (parser == NULL)
return;
- /* free tagStack and freeTagList */
- tagList = tagStack;
+ /* free m_tagStack and m_freeTagList */
+ tagList = parser->m_tagStack;
for (;;) {
TAG *p;
if (tagList == NULL) {
- if (freeTagList == NULL)
+ if (parser->m_freeTagList == NULL)
break;
- tagList = freeTagList;
- freeTagList = NULL;
+ tagList = parser->m_freeTagList;
+ parser->m_freeTagList = NULL;
}
p = tagList;
tagList = tagList->parent;
- FREE(p->buf);
+ FREE(parser, p->buf);
destroyBindings(p->bindings, parser);
- FREE(p);
+ FREE(parser, p);
}
- /* free openInternalEntities and freeInternalEntities */
- entityList = openInternalEntities;
+ /* free m_openInternalEntities and m_freeInternalEntities */
+ entityList = parser->m_openInternalEntities;
for (;;) {
OPEN_INTERNAL_ENTITY *openEntity;
if (entityList == NULL) {
- if (freeInternalEntities == NULL)
+ if (parser->m_freeInternalEntities == NULL)
break;
- entityList = freeInternalEntities;
- freeInternalEntities = NULL;
+ entityList = parser->m_freeInternalEntities;
+ parser->m_freeInternalEntities = NULL;
}
openEntity = entityList;
entityList = entityList->next;
- FREE(openEntity);
+ FREE(parser, openEntity);
}
- destroyBindings(freeBindingList, parser);
- destroyBindings(inheritedBindings, parser);
- poolDestroy(&tempPool);
- poolDestroy(&temp2Pool);
+ destroyBindings(parser->m_freeBindingList, parser);
+ destroyBindings(parser->m_inheritedBindings, parser);
+ poolDestroy(&parser->m_tempPool);
+ poolDestroy(&parser->m_temp2Pool);
+ FREE(parser, (void *)parser->m_protocolEncodingName);
#ifdef XML_DTD
/* external parameter entity parsers share the DTD structure
parser->m_dtd with the root parser, so we must not destroy it
*/
- if (!isParamEntity && _dtd)
+ if (! parser->m_isParamEntity && parser->m_dtd)
#else
- if (_dtd)
+ if (parser->m_dtd)
#endif /* XML_DTD */
- dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
- FREE((void *)atts);
+ dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
+ &parser->m_mem);
+ FREE(parser, (void *)parser->m_atts);
#ifdef XML_ATTR_INFO
- FREE((void *)attInfo);
+ FREE(parser, (void *)parser->m_attInfo);
#endif
- FREE(groupConnector);
- FREE(buffer);
- FREE(dataBuf);
- FREE(nsAtts);
- FREE(unknownEncodingMem);
- if (unknownEncodingRelease)
- unknownEncodingRelease(unknownEncodingData);
- FREE(parser);
+ FREE(parser, parser->m_groupConnector);
+ FREE(parser, parser->m_buffer);
+ FREE(parser, parser->m_dataBuf);
+ FREE(parser, parser->m_nsAtts);
+ FREE(parser, parser->m_unknownEncodingMem);
+ if (parser->m_unknownEncodingRelease)
+ parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
+ FREE(parser, parser);
}
void XMLCALL
-XML_UseParserAsHandlerArg(XML_Parser parser)
-{
- handlerArg = parser;
+XML_UseParserAsHandlerArg(XML_Parser parser) {
+ if (parser != NULL)
+ parser->m_handlerArg = parser;
}
enum XML_Error XMLCALL
-XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
-{
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
+ if (parser == NULL)
+ return XML_ERROR_INVALID_ARGUMENT;
#ifdef XML_DTD
/* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ if (parser->m_parsingStatus.parsing == XML_PARSING
+ || parser->m_parsingStatus.parsing == XML_SUSPENDED)
return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
- useForeignDTD = useDTD;
+ parser->m_useForeignDTD = useDTD;
return XML_ERROR_NONE;
#else
return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
@@ -1248,273 +1408,285 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
}
void XMLCALL
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
-{
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
+ if (parser == NULL)
+ return;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ if (parser->m_parsingStatus.parsing == XML_PARSING
+ || parser->m_parsingStatus.parsing == XML_SUSPENDED)
return;
- ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
+ parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
}
void XMLCALL
-XML_SetUserData(XML_Parser parser, void *p)
-{
- if (handlerArg == userData)
- handlerArg = userData = p;
+XML_SetUserData(XML_Parser parser, void *p) {
+ if (parser == NULL)
+ return;
+ if (parser->m_handlerArg == parser->m_userData)
+ parser->m_handlerArg = parser->m_userData = p;
else
- userData = p;
+ parser->m_userData = p;
}
enum XML_Status XMLCALL
-XML_SetBase(XML_Parser parser, const XML_Char *p)
-{
+XML_SetBase(XML_Parser parser, const XML_Char *p) {
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
if (p) {
- p = poolCopyString(&_dtd->pool, p);
- if (!p)
+ p = poolCopyString(&parser->m_dtd->pool, p);
+ if (! p)
return XML_STATUS_ERROR;
- curBase = p;
- }
- else
- curBase = NULL;
+ parser->m_curBase = p;
+ } else
+ parser->m_curBase = NULL;
return XML_STATUS_OK;
}
-const XML_Char * XMLCALL
-XML_GetBase(XML_Parser parser)
-{
- return curBase;
+const XML_Char *XMLCALL
+XML_GetBase(XML_Parser parser) {
+ if (parser == NULL)
+ return NULL;
+ return parser->m_curBase;
}
int XMLCALL
-XML_GetSpecifiedAttributeCount(XML_Parser parser)
-{
- return nSpecifiedAtts;
+XML_GetSpecifiedAttributeCount(XML_Parser parser) {
+ if (parser == NULL)
+ return -1;
+ return parser->m_nSpecifiedAtts;
}
int XMLCALL
-XML_GetIdAttributeIndex(XML_Parser parser)
-{
- return idAttIndex;
+XML_GetIdAttributeIndex(XML_Parser parser) {
+ if (parser == NULL)
+ return -1;
+ return parser->m_idAttIndex;
}
#ifdef XML_ATTR_INFO
-const XML_AttrInfo * XMLCALL
-XML_GetAttributeInfo(XML_Parser parser)
-{
- return attInfo;
+const XML_AttrInfo *XMLCALL
+XML_GetAttributeInfo(XML_Parser parser) {
+ if (parser == NULL)
+ return NULL;
+ return parser->m_attInfo;
}
#endif
void XMLCALL
-XML_SetElementHandler(XML_Parser parser,
- XML_StartElementHandler start,
- XML_EndElementHandler end)
-{
- startElementHandler = start;
- endElementHandler = end;
+XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
+ XML_EndElementHandler end) {
+ if (parser == NULL)
+ return;
+ parser->m_startElementHandler = start;
+ parser->m_endElementHandler = end;
}
void XMLCALL
-XML_SetStartElementHandler(XML_Parser parser,
- XML_StartElementHandler start) {
- startElementHandler = start;
+XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
+ if (parser != NULL)
+ parser->m_startElementHandler = start;
}
void XMLCALL
-XML_SetEndElementHandler(XML_Parser parser,
- XML_EndElementHandler end) {
- endElementHandler = end;
+XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
+ if (parser != NULL)
+ parser->m_endElementHandler = end;
}
void XMLCALL
XML_SetCharacterDataHandler(XML_Parser parser,
- XML_CharacterDataHandler handler)
-{
- characterDataHandler = handler;
+ XML_CharacterDataHandler handler) {
+ if (parser != NULL)
+ parser->m_characterDataHandler = handler;
}
void XMLCALL
XML_SetProcessingInstructionHandler(XML_Parser parser,
- XML_ProcessingInstructionHandler handler)
-{
- processingInstructionHandler = handler;
+ XML_ProcessingInstructionHandler handler) {
+ if (parser != NULL)
+ parser->m_processingInstructionHandler = handler;
}
void XMLCALL
-XML_SetCommentHandler(XML_Parser parser,
- XML_CommentHandler handler)
-{
- commentHandler = handler;
+XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
+ if (parser != NULL)
+ parser->m_commentHandler = handler;
}
void XMLCALL
XML_SetCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start,
- XML_EndCdataSectionHandler end)
-{
- startCdataSectionHandler = start;
- endCdataSectionHandler = end;
+ XML_EndCdataSectionHandler end) {
+ if (parser == NULL)
+ return;
+ parser->m_startCdataSectionHandler = start;
+ parser->m_endCdataSectionHandler = end;
}
void XMLCALL
XML_SetStartCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start) {
- startCdataSectionHandler = start;
+ if (parser != NULL)
+ parser->m_startCdataSectionHandler = start;
}
void XMLCALL
XML_SetEndCdataSectionHandler(XML_Parser parser,
XML_EndCdataSectionHandler end) {
- endCdataSectionHandler = end;
+ if (parser != NULL)
+ parser->m_endCdataSectionHandler = end;
}
void XMLCALL
-XML_SetDefaultHandler(XML_Parser parser,
- XML_DefaultHandler handler)
-{
- defaultHandler = handler;
- defaultExpandInternalEntities = XML_FALSE;
+XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
+ if (parser == NULL)
+ return;
+ parser->m_defaultHandler = handler;
+ parser->m_defaultExpandInternalEntities = XML_FALSE;
}
void XMLCALL
-XML_SetDefaultHandlerExpand(XML_Parser parser,
- XML_DefaultHandler handler)
-{
- defaultHandler = handler;
- defaultExpandInternalEntities = XML_TRUE;
+XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
+ if (parser == NULL)
+ return;
+ parser->m_defaultHandler = handler;
+ parser->m_defaultExpandInternalEntities = XML_TRUE;
}
void XMLCALL
-XML_SetDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start,
- XML_EndDoctypeDeclHandler end)
-{
- startDoctypeDeclHandler = start;
- endDoctypeDeclHandler = end;
+XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
+ XML_EndDoctypeDeclHandler end) {
+ if (parser == NULL)
+ return;
+ parser->m_startDoctypeDeclHandler = start;
+ parser->m_endDoctypeDeclHandler = end;
}
void XMLCALL
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start) {
- startDoctypeDeclHandler = start;
+ if (parser != NULL)
+ parser->m_startDoctypeDeclHandler = start;
}
void XMLCALL
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
- XML_EndDoctypeDeclHandler end) {
- endDoctypeDeclHandler = end;
+XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
+ if (parser != NULL)
+ parser->m_endDoctypeDeclHandler = end;
}
void XMLCALL
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
- XML_UnparsedEntityDeclHandler handler)
-{
- unparsedEntityDeclHandler = handler;
+ XML_UnparsedEntityDeclHandler handler) {
+ if (parser != NULL)
+ parser->m_unparsedEntityDeclHandler = handler;
}
void XMLCALL
-XML_SetNotationDeclHandler(XML_Parser parser,
- XML_NotationDeclHandler handler)
-{
- notationDeclHandler = handler;
+XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
+ if (parser != NULL)
+ parser->m_notationDeclHandler = handler;
}
void XMLCALL
XML_SetNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start,
- XML_EndNamespaceDeclHandler end)
-{
- startNamespaceDeclHandler = start;
- endNamespaceDeclHandler = end;
+ XML_EndNamespaceDeclHandler end) {
+ if (parser == NULL)
+ return;
+ parser->m_startNamespaceDeclHandler = start;
+ parser->m_endNamespaceDeclHandler = end;
}
void XMLCALL
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start) {
- startNamespaceDeclHandler = start;
+ if (parser != NULL)
+ parser->m_startNamespaceDeclHandler = start;
}
void XMLCALL
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
XML_EndNamespaceDeclHandler end) {
- endNamespaceDeclHandler = end;
+ if (parser != NULL)
+ parser->m_endNamespaceDeclHandler = end;
}
void XMLCALL
XML_SetNotStandaloneHandler(XML_Parser parser,
- XML_NotStandaloneHandler handler)
-{
- notStandaloneHandler = handler;
+ XML_NotStandaloneHandler handler) {
+ if (parser != NULL)
+ parser->m_notStandaloneHandler = handler;
}
void XMLCALL
XML_SetExternalEntityRefHandler(XML_Parser parser,
- XML_ExternalEntityRefHandler handler)
-{
- externalEntityRefHandler = handler;
+ XML_ExternalEntityRefHandler handler) {
+ if (parser != NULL)
+ parser->m_externalEntityRefHandler = handler;
}
void XMLCALL
-XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
-{
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
+ if (parser == NULL)
+ return;
if (arg)
- externalEntityRefHandlerArg = (XML_Parser)arg;
+ parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
else
- externalEntityRefHandlerArg = parser;
+ parser->m_externalEntityRefHandlerArg = parser;
}
void XMLCALL
XML_SetSkippedEntityHandler(XML_Parser parser,
- XML_SkippedEntityHandler handler)
-{
- skippedEntityHandler = handler;
+ XML_SkippedEntityHandler handler) {
+ if (parser != NULL)
+ parser->m_skippedEntityHandler = handler;
}
void XMLCALL
XML_SetUnknownEncodingHandler(XML_Parser parser,
- XML_UnknownEncodingHandler handler,
- void *data)
-{
- unknownEncodingHandler = handler;
- unknownEncodingHandlerData = data;
+ XML_UnknownEncodingHandler handler, void *data) {
+ if (parser == NULL)
+ return;
+ parser->m_unknownEncodingHandler = handler;
+ parser->m_unknownEncodingHandlerData = data;
}
void XMLCALL
-XML_SetElementDeclHandler(XML_Parser parser,
- XML_ElementDeclHandler eldecl)
-{
- elementDeclHandler = eldecl;
+XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
+ if (parser != NULL)
+ parser->m_elementDeclHandler = eldecl;
}
void XMLCALL
-XML_SetAttlistDeclHandler(XML_Parser parser,
- XML_AttlistDeclHandler attdecl)
-{
- attlistDeclHandler = attdecl;
+XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
+ if (parser != NULL)
+ parser->m_attlistDeclHandler = attdecl;
}
void XMLCALL
-XML_SetEntityDeclHandler(XML_Parser parser,
- XML_EntityDeclHandler handler)
-{
- entityDeclHandler = handler;
+XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
+ if (parser != NULL)
+ parser->m_entityDeclHandler = handler;
}
void XMLCALL
-XML_SetXmlDeclHandler(XML_Parser parser,
- XML_XmlDeclHandler handler) {
- xmlDeclHandler = handler;
+XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
+ if (parser != NULL)
+ parser->m_xmlDeclHandler = handler;
}
int XMLCALL
XML_SetParamEntityParsing(XML_Parser parser,
- enum XML_ParamEntityParsing peParsing)
-{
+ enum XML_ParamEntityParsing peParsing) {
+ if (parser == NULL)
+ return 0;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ if (parser->m_parsingStatus.parsing == XML_PARSING
+ || parser->m_parsingStatus.parsing == XML_SUSPENDED)
return 0;
#ifdef XML_DTD
- paramEntityParsing = peParsing;
+ parser->m_paramEntityParsing = peParsing;
return 1;
#else
return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
@@ -1522,91 +1694,122 @@ XML_SetParamEntityParsing(XML_Parser parser,
}
int XMLCALL
-XML_SetHashSalt(XML_Parser parser,
- unsigned long hash_salt)
-{
+XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
+ if (parser == NULL)
+ return 0;
+ if (parser->m_parentParser)
+ return XML_SetHashSalt(parser->m_parentParser, hash_salt);
/* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
+ if (parser->m_parsingStatus.parsing == XML_PARSING
+ || parser->m_parsingStatus.parsing == XML_SUSPENDED)
return 0;
- hash_secret_salt = hash_salt;
+ parser->m_hash_secret_salt = hash_salt;
return 1;
}
enum XML_Status XMLCALL
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
-{
- switch (ps_parsing) {
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
+ if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
+ if (parser != NULL)
+ parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
+ return XML_STATUS_ERROR;
+ }
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
+ parser->m_errorCode = XML_ERROR_SUSPENDED;
return XML_STATUS_ERROR;
case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
+ parser->m_errorCode = XML_ERROR_FINISHED;
return XML_STATUS_ERROR;
case XML_INITIALIZED:
- if (parentParser == NULL && !startParsing(parser)) {
- errorCode = XML_ERROR_NO_MEMORY;
+ if (parser->m_parentParser == NULL && ! startParsing(parser)) {
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
return XML_STATUS_ERROR;
}
+ /* fall through */
default:
- ps_parsing = XML_PARSING;
+ parser->m_parsingStatus.parsing = XML_PARSING;
}
if (len == 0) {
- ps_finalBuffer = (XML_Bool)isFinal;
- if (!isFinal)
+ parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
+ if (! isFinal)
return XML_STATUS_OK;
- positionPtr = bufferPtr;
- parseEndPtr = bufferEnd;
+ parser->m_positionPtr = parser->m_bufferPtr;
+ parser->m_parseEndPtr = parser->m_bufferEnd;
/* If data are left over from last buffer, and we now know that these
data are the final chunk of input, then we have to check them again
to detect errors based on that fact.
*/
- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
+ parser->m_errorCode
+ = parser->m_processor(parser, parser->m_bufferPtr,
+ parser->m_parseEndPtr, &parser->m_bufferPtr);
- if (errorCode == XML_ERROR_NONE) {
- switch (ps_parsing) {
+ if (parser->m_errorCode == XML_ERROR_NONE) {
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
+ /* It is hard to be certain, but it seems that this case
+ * cannot occur. This code is cleaning up a previous parse
+ * with no new data (since len == 0). Changing the parsing
+ * state requires getting to execute a handler function, and
+ * there doesn't seem to be an opportunity for that while in
+ * this circumstance.
+ *
+ * Given the uncertainty, we retain the code but exclude it
+ * from coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
+ XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+ parser->m_bufferPtr, &parser->m_position);
+ parser->m_positionPtr = parser->m_bufferPtr;
return XML_STATUS_SUSPENDED;
+ /* LCOV_EXCL_STOP */
case XML_INITIALIZED:
case XML_PARSING:
- ps_parsing = XML_FINISHED;
+ parser->m_parsingStatus.parsing = XML_FINISHED;
/* fall through */
default:
return XML_STATUS_OK;
}
}
- eventEndPtr = eventPtr;
- processor = errorProcessor;
+ parser->m_eventEndPtr = parser->m_eventPtr;
+ parser->m_processor = errorProcessor;
return XML_STATUS_ERROR;
}
#ifndef XML_CONTEXT_BYTES
- else if (bufferPtr == bufferEnd) {
+ else if (parser->m_bufferPtr == parser->m_bufferEnd) {
const char *end;
int nLeftOver;
enum XML_Status result;
- parseEndByteIndex += len;
- positionPtr = s;
- ps_finalBuffer = (XML_Bool)isFinal;
+ /* Detect overflow (a+b > MAX <==> b > MAX-a) */
+ if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
+ parser->m_eventPtr = parser->m_eventEndPtr = NULL;
+ parser->m_processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
+ parser->m_parseEndByteIndex += len;
+ parser->m_positionPtr = s;
+ parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
- errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+ parser->m_errorCode
+ = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
+ if (parser->m_errorCode != XML_ERROR_NONE) {
+ parser->m_eventEndPtr = parser->m_eventPtr;
+ parser->m_processor = errorProcessor;
return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
+ } else {
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_PARSING:
if (isFinal) {
- ps_parsing = XML_FINISHED;
+ parser->m_parsingStatus.parsing = XML_FINISHED;
return XML_STATUS_OK;
}
/* fall through */
@@ -1615,35 +1818,38 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
}
}
- XmlUpdatePosition(encoding, positionPtr, end, &position);
+ XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
+ &parser->m_position);
nLeftOver = s + len - end;
if (nLeftOver) {
- if (buffer == NULL || nLeftOver > bufferLim - buffer) {
- /* FIXME avoid integer overflow */
- char *temp;
- temp = (buffer == NULL
- ? (char *)MALLOC(len * 2)
- : (char *)REALLOC(buffer, len * 2));
+ if (parser->m_buffer == NULL
+ || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
+ /* avoid _signed_ integer overflow */
+ char *temp = NULL;
+ const int bytesToAllocate = (int)((unsigned)len * 2U);
+ if (bytesToAllocate > 0) {
+ temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
+ }
if (temp == NULL) {
- errorCode = XML_ERROR_NO_MEMORY;
- eventPtr = eventEndPtr = NULL;
- processor = errorProcessor;
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
+ parser->m_eventPtr = parser->m_eventEndPtr = NULL;
+ parser->m_processor = errorProcessor;
return XML_STATUS_ERROR;
}
- buffer = temp;
- bufferLim = buffer + len * 2;
+ parser->m_buffer = temp;
+ parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
}
- memcpy(buffer, end, nLeftOver);
+ memcpy(parser->m_buffer, end, nLeftOver);
}
- bufferPtr = buffer;
- bufferEnd = buffer + nLeftOver;
- positionPtr = bufferPtr;
- parseEndPtr = bufferEnd;
- eventPtr = bufferPtr;
- eventEndPtr = bufferPtr;
+ parser->m_bufferPtr = parser->m_buffer;
+ parser->m_bufferEnd = parser->m_buffer + nLeftOver;
+ parser->m_positionPtr = parser->m_bufferPtr;
+ parser->m_parseEndPtr = parser->m_bufferEnd;
+ parser->m_eventPtr = parser->m_bufferPtr;
+ parser->m_eventEndPtr = parser->m_bufferPtr;
return result;
}
-#endif /* not defined XML_CONTEXT_BYTES */
+#endif /* not defined XML_CONTEXT_BYTES */
else {
void *buff = XML_GetBuffer(parser, len);
if (buff == NULL)
@@ -1656,379 +1862,470 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
}
enum XML_Status XMLCALL
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
-{
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
const char *start;
enum XML_Status result = XML_STATUS_OK;
- switch (ps_parsing) {
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
+ parser->m_errorCode = XML_ERROR_SUSPENDED;
return XML_STATUS_ERROR;
case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
+ parser->m_errorCode = XML_ERROR_FINISHED;
return XML_STATUS_ERROR;
case XML_INITIALIZED:
- if (parentParser == NULL && !startParsing(parser)) {
- errorCode = XML_ERROR_NO_MEMORY;
+ if (parser->m_parentParser == NULL && ! startParsing(parser)) {
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
return XML_STATUS_ERROR;
}
+ /* fall through */
default:
- ps_parsing = XML_PARSING;
+ parser->m_parsingStatus.parsing = XML_PARSING;
}
- start = bufferPtr;
- positionPtr = start;
- bufferEnd += len;
- parseEndPtr = bufferEnd;
- parseEndByteIndex += len;
- ps_finalBuffer = (XML_Bool)isFinal;
+ start = parser->m_bufferPtr;
+ parser->m_positionPtr = start;
+ parser->m_bufferEnd += len;
+ parser->m_parseEndPtr = parser->m_bufferEnd;
+ parser->m_parseEndByteIndex += len;
+ parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
- errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
+ parser->m_errorCode = parser->m_processor(
+ parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
+ if (parser->m_errorCode != XML_ERROR_NONE) {
+ parser->m_eventEndPtr = parser->m_eventPtr;
+ parser->m_processor = errorProcessor;
return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
+ } else {
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_PARSING:
if (isFinal) {
- ps_parsing = XML_FINISHED;
+ parser->m_parsingStatus.parsing = XML_FINISHED;
return result;
}
- default: ; /* should not happen */
+ default:; /* should not happen */
}
}
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
+ XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+ parser->m_bufferPtr, &parser->m_position);
+ parser->m_positionPtr = parser->m_bufferPtr;
return result;
}
-void * XMLCALL
-XML_GetBuffer(XML_Parser parser, int len)
-{
+void *XMLCALL
+XML_GetBuffer(XML_Parser parser, int len) {
+ if (parser == NULL)
+ return NULL;
if (len < 0) {
- errorCode = XML_ERROR_NO_MEMORY;
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
return NULL;
}
- switch (ps_parsing) {
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
- errorCode = XML_ERROR_SUSPENDED;
+ parser->m_errorCode = XML_ERROR_SUSPENDED;
return NULL;
case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
+ parser->m_errorCode = XML_ERROR_FINISHED;
return NULL;
- default: ;
+ default:;
}
- if (len > bufferLim - bufferEnd) {
+ if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
#ifdef XML_CONTEXT_BYTES
int keep;
-#endif /* defined XML_CONTEXT_BYTES */
+#endif /* defined XML_CONTEXT_BYTES */
/* Do not invoke signed arithmetic overflow: */
- int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
+ int neededSize = (int)((unsigned)len
+ + (unsigned)EXPAT_SAFE_PTR_DIFF(
+ parser->m_bufferEnd, parser->m_bufferPtr));
if (neededSize < 0) {
- errorCode = XML_ERROR_NO_MEMORY;
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
return NULL;
}
#ifdef XML_CONTEXT_BYTES
- keep = (int)(bufferPtr - buffer);
+ keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
if (keep > XML_CONTEXT_BYTES)
keep = XML_CONTEXT_BYTES;
neededSize += keep;
-#endif /* defined XML_CONTEXT_BYTES */
- if (neededSize <= bufferLim - buffer) {
+#endif /* defined XML_CONTEXT_BYTES */
+ if (neededSize
+ <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
#ifdef XML_CONTEXT_BYTES
- if (keep < bufferPtr - buffer) {
- int offset = (int)(bufferPtr - buffer) - keep;
- memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
- bufferEnd -= offset;
- bufferPtr -= offset;
+ if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
+ int offset
+ = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
+ - keep;
+ /* The buffer pointers cannot be NULL here; we have at least some bytes
+ * in the buffer */
+ memmove(parser->m_buffer, &parser->m_buffer[offset],
+ parser->m_bufferEnd - parser->m_bufferPtr + keep);
+ parser->m_bufferEnd -= offset;
+ parser->m_bufferPtr -= offset;
}
#else
- memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
- bufferEnd = buffer + (bufferEnd - bufferPtr);
- bufferPtr = buffer;
-#endif /* not defined XML_CONTEXT_BYTES */
- }
- else {
+ if (parser->m_buffer && parser->m_bufferPtr) {
+ memmove(parser->m_buffer, parser->m_bufferPtr,
+ EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
+ parser->m_bufferEnd
+ = parser->m_buffer
+ + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
+ parser->m_bufferPtr = parser->m_buffer;
+ }
+#endif /* not defined XML_CONTEXT_BYTES */
+ } else {
char *newBuf;
- int bufferSize = (int)(bufferLim - bufferPtr);
+ int bufferSize
+ = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
if (bufferSize == 0)
bufferSize = INIT_BUFFER_SIZE;
do {
/* Do not invoke signed arithmetic overflow: */
- bufferSize = (int) (2U * (unsigned) bufferSize);
+ bufferSize = (int)(2U * (unsigned)bufferSize);
} while (bufferSize < neededSize && bufferSize > 0);
if (bufferSize <= 0) {
- errorCode = XML_ERROR_NO_MEMORY;
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
return NULL;
}
- newBuf = (char *)MALLOC(bufferSize);
+ newBuf = (char *)MALLOC(parser, bufferSize);
if (newBuf == 0) {
- errorCode = XML_ERROR_NO_MEMORY;
+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
return NULL;
}
- bufferLim = newBuf + bufferSize;
+ parser->m_bufferLim = newBuf + bufferSize;
#ifdef XML_CONTEXT_BYTES
- if (bufferPtr) {
- int keep = (int)(bufferPtr - buffer);
- if (keep > XML_CONTEXT_BYTES)
- keep = XML_CONTEXT_BYTES;
- memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
- FREE(buffer);
- buffer = newBuf;
- bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
- bufferPtr = buffer + keep;
- }
- else {
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
+ if (parser->m_bufferPtr) {
+ memcpy(newBuf, &parser->m_bufferPtr[-keep],
+ EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
+ + keep);
+ FREE(parser, parser->m_buffer);
+ parser->m_buffer = newBuf;
+ parser->m_bufferEnd
+ = parser->m_buffer
+ + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
+ + keep;
+ parser->m_bufferPtr = parser->m_buffer + keep;
+ } else {
+ /* This must be a brand new buffer with no data in it yet */
+ parser->m_bufferEnd = newBuf;
+ parser->m_bufferPtr = parser->m_buffer = newBuf;
}
#else
- if (bufferPtr) {
- memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
- FREE(buffer);
+ if (parser->m_bufferPtr) {
+ memcpy(newBuf, parser->m_bufferPtr,
+ EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
+ FREE(parser, parser->m_buffer);
+ parser->m_bufferEnd
+ = newBuf
+ + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
+ } else {
+ /* This must be a brand new buffer with no data in it yet */
+ parser->m_bufferEnd = newBuf;
}
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
-#endif /* not defined XML_CONTEXT_BYTES */
+ parser->m_bufferPtr = parser->m_buffer = newBuf;
+#endif /* not defined XML_CONTEXT_BYTES */
}
- eventPtr = eventEndPtr = NULL;
- positionPtr = NULL;
+ parser->m_eventPtr = parser->m_eventEndPtr = NULL;
+ parser->m_positionPtr = NULL;
}
- return bufferEnd;
+ return parser->m_bufferEnd;
}
enum XML_Status XMLCALL
-XML_StopParser(XML_Parser parser, XML_Bool resumable)
-{
- switch (ps_parsing) {
+XML_StopParser(XML_Parser parser, XML_Bool resumable) {
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
if (resumable) {
- errorCode = XML_ERROR_SUSPENDED;
+ parser->m_errorCode = XML_ERROR_SUSPENDED;
return XML_STATUS_ERROR;
}
- ps_parsing = XML_FINISHED;
+ parser->m_parsingStatus.parsing = XML_FINISHED;
break;
case XML_FINISHED:
- errorCode = XML_ERROR_FINISHED;
+ parser->m_errorCode = XML_ERROR_FINISHED;
return XML_STATUS_ERROR;
default:
if (resumable) {
#ifdef XML_DTD
- if (isParamEntity) {
- errorCode = XML_ERROR_SUSPEND_PE;
+ if (parser->m_isParamEntity) {
+ parser->m_errorCode = XML_ERROR_SUSPEND_PE;
return XML_STATUS_ERROR;
}
#endif
- ps_parsing = XML_SUSPENDED;
- }
- else
- ps_parsing = XML_FINISHED;
+ parser->m_parsingStatus.parsing = XML_SUSPENDED;
+ } else
+ parser->m_parsingStatus.parsing = XML_FINISHED;
}
return XML_STATUS_OK;
}
enum XML_Status XMLCALL
-XML_ResumeParser(XML_Parser parser)
-{
+XML_ResumeParser(XML_Parser parser) {
enum XML_Status result = XML_STATUS_OK;
- if (ps_parsing != XML_SUSPENDED) {
- errorCode = XML_ERROR_NOT_SUSPENDED;
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
+ if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
+ parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
return XML_STATUS_ERROR;
}
- ps_parsing = XML_PARSING;
+ parser->m_parsingStatus.parsing = XML_PARSING;
- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
+ parser->m_errorCode = parser->m_processor(
+ parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
+ if (parser->m_errorCode != XML_ERROR_NONE) {
+ parser->m_eventEndPtr = parser->m_eventPtr;
+ parser->m_processor = errorProcessor;
return XML_STATUS_ERROR;
- }
- else {
- switch (ps_parsing) {
+ } else {
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_PARSING:
- if (ps_finalBuffer) {
- ps_parsing = XML_FINISHED;
+ if (parser->m_parsingStatus.finalBuffer) {
+ parser->m_parsingStatus.parsing = XML_FINISHED;
return result;
}
- default: ;
+ default:;
}
}
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- positionPtr = bufferPtr;
+ XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+ parser->m_bufferPtr, &parser->m_position);
+ parser->m_positionPtr = parser->m_bufferPtr;
return result;
}
void XMLCALL
-XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
-{
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
+ if (parser == NULL)
+ return;
assert(status != NULL);
*status = parser->m_parsingStatus;
}
enum XML_Error XMLCALL
-XML_GetErrorCode(XML_Parser parser)
-{
- return errorCode;
+XML_GetErrorCode(XML_Parser parser) {
+ if (parser == NULL)
+ return XML_ERROR_INVALID_ARGUMENT;
+ return parser->m_errorCode;
}
XML_Index XMLCALL
-XML_GetCurrentByteIndex(XML_Parser parser)
-{
- if (eventPtr)
- return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
+XML_GetCurrentByteIndex(XML_Parser parser) {
+ if (parser == NULL)
+ return -1;
+ if (parser->m_eventPtr)
+ return (XML_Index)(parser->m_parseEndByteIndex
+ - (parser->m_parseEndPtr - parser->m_eventPtr));
return -1;
}
int XMLCALL
-XML_GetCurrentByteCount(XML_Parser parser)
-{
- if (eventEndPtr && eventPtr)
- return (int)(eventEndPtr - eventPtr);
+XML_GetCurrentByteCount(XML_Parser parser) {
+ if (parser == NULL)
+ return 0;
+ if (parser->m_eventEndPtr && parser->m_eventPtr)
+ return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
return 0;
}
-const char * XMLCALL
-XML_GetInputContext(XML_Parser parser, int *offset, int *size)
-{
+const char *XMLCALL
+XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
#ifdef XML_CONTEXT_BYTES
- if (eventPtr && buffer) {
- *offset = (int)(eventPtr - buffer);
- *size = (int)(bufferEnd - buffer);
- return buffer;
+ if (parser == NULL)
+ return NULL;
+ if (parser->m_eventPtr && parser->m_buffer) {
+ if (offset != NULL)
+ *offset = (int)(parser->m_eventPtr - parser->m_buffer);
+ if (size != NULL)
+ *size = (int)(parser->m_bufferEnd - parser->m_buffer);
+ return parser->m_buffer;
}
+#else
+ (void)parser;
+ (void)offset;
+ (void)size;
#endif /* defined XML_CONTEXT_BYTES */
- return (char *) 0;
+ return (char *)0;
}
XML_Size XMLCALL
-XML_GetCurrentLineNumber(XML_Parser parser)
-{
- if (eventPtr && eventPtr >= positionPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
+XML_GetCurrentLineNumber(XML_Parser parser) {
+ if (parser == NULL)
+ return 0;
+ if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
+ XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+ parser->m_eventPtr, &parser->m_position);
+ parser->m_positionPtr = parser->m_eventPtr;
}
- return position.lineNumber + 1;
+ return parser->m_position.lineNumber + 1;
}
XML_Size XMLCALL
-XML_GetCurrentColumnNumber(XML_Parser parser)
-{
- if (eventPtr && eventPtr >= positionPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
+XML_GetCurrentColumnNumber(XML_Parser parser) {
+ if (parser == NULL)
+ return 0;
+ if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
+ XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
+ parser->m_eventPtr, &parser->m_position);
+ parser->m_positionPtr = parser->m_eventPtr;
}
- return position.columnNumber;
+ return parser->m_position.columnNumber;
}
void XMLCALL
-XML_FreeContentModel(XML_Parser parser, XML_Content *model)
-{
- FREE(model);
+XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
+ if (parser != NULL)
+ FREE(parser, model);
}
-void * XMLCALL
-XML_MemMalloc(XML_Parser parser, size_t size)
-{
- return MALLOC(size);
+void *XMLCALL
+XML_MemMalloc(XML_Parser parser, size_t size) {
+ if (parser == NULL)
+ return NULL;
+ return MALLOC(parser, size);
}
-void * XMLCALL
-XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
-{
- return REALLOC(ptr, size);
+void *XMLCALL
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
+ if (parser == NULL)
+ return NULL;
+ return REALLOC(parser, ptr, size);
}
void XMLCALL
-XML_MemFree(XML_Parser parser, void *ptr)
-{
- FREE(ptr);
+XML_MemFree(XML_Parser parser, void *ptr) {
+ if (parser != NULL)
+ FREE(parser, ptr);
}
void XMLCALL
-XML_DefaultCurrent(XML_Parser parser)
-{
- if (defaultHandler) {
- if (openInternalEntities)
- reportDefault(parser,
- internalEncoding,
- openInternalEntities->internalEventPtr,
- openInternalEntities->internalEventEndPtr);
+XML_DefaultCurrent(XML_Parser parser) {
+ if (parser == NULL)
+ return;
+ if (parser->m_defaultHandler) {
+ if (parser->m_openInternalEntities)
+ reportDefault(parser, parser->m_internalEncoding,
+ parser->m_openInternalEntities->internalEventPtr,
+ parser->m_openInternalEntities->internalEventEndPtr);
else
- reportDefault(parser, encoding, eventPtr, eventEndPtr);
+ reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
+ parser->m_eventEndPtr);
}
}
-const XML_LChar * XMLCALL
-XML_ErrorString(enum XML_Error code)
-{
- static const XML_LChar* const message[] = {
- 0,
- XML_L("out of memory"),
- XML_L("syntax error"),
- XML_L("no element found"),
- XML_L("not well-formed (invalid token)"),
- XML_L("unclosed token"),
- XML_L("partial character"),
- XML_L("mismatched tag"),
- XML_L("duplicate attribute"),
- XML_L("junk after document element"),
- XML_L("illegal parameter entity reference"),
- XML_L("undefined entity"),
- XML_L("recursive entity reference"),
- XML_L("asynchronous entity"),
- XML_L("reference to invalid character number"),
- XML_L("reference to binary entity"),
- XML_L("reference to external entity in attribute"),
- XML_L("XML or text declaration not at start of entity"),
- XML_L("unknown encoding"),
- XML_L("encoding specified in XML declaration is incorrect"),
- XML_L("unclosed CDATA section"),
- XML_L("error in processing external entity reference"),
- XML_L("document is not standalone"),
- XML_L("unexpected parser state - please send a bug report"),
- XML_L("entity declared in parameter entity"),
- XML_L("requested feature requires XML_DTD support in Expat"),
- XML_L("cannot change setting once parsing has begun"),
- XML_L("unbound prefix"),
- XML_L("must not undeclare prefix"),
- XML_L("incomplete markup in parameter entity"),
- XML_L("XML declaration not well-formed"),
- XML_L("text declaration not well-formed"),
- XML_L("illegal character(s) in public id"),
- XML_L("parser suspended"),
- XML_L("parser not suspended"),
- XML_L("parsing aborted"),
- XML_L("parsing finished"),
- XML_L("cannot suspend in external parameter entity"),
- XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
- XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
- XML_L("prefix must not be bound to one of the reserved namespace names")
- };
- if (code > 0 && code < sizeof(message)/sizeof(message[0]))
- return message[code];
+const XML_LChar *XMLCALL
+XML_ErrorString(enum XML_Error code) {
+ switch (code) {
+ case XML_ERROR_NONE:
+ return NULL;
+ case XML_ERROR_NO_MEMORY:
+ return XML_L("out of memory");
+ case XML_ERROR_SYNTAX:
+ return XML_L("syntax error");
+ case XML_ERROR_NO_ELEMENTS:
+ return XML_L("no element found");
+ case XML_ERROR_INVALID_TOKEN:
+ return XML_L("not well-formed (invalid token)");
+ case XML_ERROR_UNCLOSED_TOKEN:
+ return XML_L("unclosed token");
+ case XML_ERROR_PARTIAL_CHAR:
+ return XML_L("partial character");
+ case XML_ERROR_TAG_MISMATCH:
+ return XML_L("mismatched tag");
+ case XML_ERROR_DUPLICATE_ATTRIBUTE:
+ return XML_L("duplicate attribute");
+ case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
+ return XML_L("junk after document element");
+ case XML_ERROR_PARAM_ENTITY_REF:
+ return XML_L("illegal parameter entity reference");
+ case XML_ERROR_UNDEFINED_ENTITY:
+ return XML_L("undefined entity");
+ case XML_ERROR_RECURSIVE_ENTITY_REF:
+ return XML_L("recursive entity reference");
+ case XML_ERROR_ASYNC_ENTITY:
+ return XML_L("asynchronous entity");
+ case XML_ERROR_BAD_CHAR_REF:
+ return XML_L("reference to invalid character number");
+ case XML_ERROR_BINARY_ENTITY_REF:
+ return XML_L("reference to binary entity");
+ case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
+ return XML_L("reference to external entity in attribute");
+ case XML_ERROR_MISPLACED_XML_PI:
+ return XML_L("XML or text declaration not at start of entity");
+ case XML_ERROR_UNKNOWN_ENCODING:
+ return XML_L("unknown encoding");
+ case XML_ERROR_INCORRECT_ENCODING:
+ return XML_L("encoding specified in XML declaration is incorrect");
+ case XML_ERROR_UNCLOSED_CDATA_SECTION:
+ return XML_L("unclosed CDATA section");
+ case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
+ return XML_L("error in processing external entity reference");
+ case XML_ERROR_NOT_STANDALONE:
+ return XML_L("document is not standalone");
+ case XML_ERROR_UNEXPECTED_STATE:
+ return XML_L("unexpected parser state - please send a bug report");
+ case XML_ERROR_ENTITY_DECLARED_IN_PE:
+ return XML_L("entity declared in parameter entity");
+ case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
+ return XML_L("requested feature requires XML_DTD support in Expat");
+ case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
+ return XML_L("cannot change setting once parsing has begun");
+ /* Added in 1.95.7. */
+ case XML_ERROR_UNBOUND_PREFIX:
+ return XML_L("unbound prefix");
+ /* Added in 1.95.8. */
+ case XML_ERROR_UNDECLARING_PREFIX:
+ return XML_L("must not undeclare prefix");
+ case XML_ERROR_INCOMPLETE_PE:
+ return XML_L("incomplete markup in parameter entity");
+ case XML_ERROR_XML_DECL:
+ return XML_L("XML declaration not well-formed");
+ case XML_ERROR_TEXT_DECL:
+ return XML_L("text declaration not well-formed");
+ case XML_ERROR_PUBLICID:
+ return XML_L("illegal character(s) in public id");
+ case XML_ERROR_SUSPENDED:
+ return XML_L("parser suspended");
+ case XML_ERROR_NOT_SUSPENDED:
+ return XML_L("parser not suspended");
+ case XML_ERROR_ABORTED:
+ return XML_L("parsing aborted");
+ case XML_ERROR_FINISHED:
+ return XML_L("parsing finished");
+ case XML_ERROR_SUSPEND_PE:
+ return XML_L("cannot suspend in external parameter entity");
+ /* Added in 2.0.0. */
+ case XML_ERROR_RESERVED_PREFIX_XML:
+ return XML_L(
+ "reserved prefix (xml) must not be undeclared or bound to another namespace name");
+ case XML_ERROR_RESERVED_PREFIX_XMLNS:
+ return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
+ case XML_ERROR_RESERVED_NAMESPACE_URI:
+ return XML_L(
+ "prefix must not be bound to one of the reserved namespace names");
+ /* Added in 2.2.5. */
+ case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
+ return XML_L("invalid argument");
+ }
return NULL;
}
-const XML_LChar * XMLCALL
+const XML_LChar *XMLCALL
XML_ExpatVersion(void) {
-
/* V1 is used to string-ize the version number. However, it would
string-ize the actual version macro *names* unless we get them
substituted before being passed to V1. CPP is defined to expand
@@ -2037,8 +2334,8 @@ XML_ExpatVersion(void) {
with the correct numerals. */
/* ### I'm assuming cpp is portable in this respect... */
-#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
-#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
+#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
+#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
@@ -2047,8 +2344,7 @@ XML_ExpatVersion(void) {
}
XML_Expat_Version XMLCALL
-XML_ExpatVersionInfo(void)
-{
+XML_ExpatVersionInfo(void) {
XML_Expat_Version version;
version.major = XML_MAJOR_VERSION;
@@ -2058,41 +2354,39 @@ XML_ExpatVersionInfo(void)
return version;
}
-const XML_Feature * XMLCALL
-XML_GetFeatureList(void)
-{
- static const XML_Feature features[] = {
- {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
- sizeof(XML_Char)},
- {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
- sizeof(XML_LChar)},
+const XML_Feature *XMLCALL
+XML_GetFeatureList(void) {
+ static const XML_Feature features[]
+ = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
+ sizeof(XML_Char)},
+ {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
+ sizeof(XML_LChar)},
#ifdef XML_UNICODE
- {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
+ {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
#endif
#ifdef XML_UNICODE_WCHAR_T
- {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
+ {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
#endif
#ifdef XML_DTD
- {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
+ {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
#endif
#ifdef XML_CONTEXT_BYTES
- {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
- XML_CONTEXT_BYTES},
+ {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
+ XML_CONTEXT_BYTES},
#endif
#ifdef XML_MIN_SIZE
- {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
+ {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
#endif
#ifdef XML_NS
- {XML_FEATURE_NS, XML_L("XML_NS"), 0},
+ {XML_FEATURE_NS, XML_L("XML_NS"), 0},
#endif
#ifdef XML_LARGE_SIZE
- {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
+ {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
#endif
#ifdef XML_ATTR_INFO
- {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
+ {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
#endif
- {XML_FEATURE_END, NULL, 0}
- };
+ {XML_FEATURE_END, NULL, 0}};
return features;
}
@@ -2103,14 +2397,13 @@ XML_GetFeatureList(void)
permanent location, since the parse buffer is about to be discarded.
*/
static XML_Bool
-storeRawNames(XML_Parser parser)
-{
- TAG *tag = tagStack;
+storeRawNames(XML_Parser parser) {
+ TAG *tag = parser->m_tagStack;
while (tag) {
int bufSize;
int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
char *rawNameBuf = tag->buf + nameLen;
- /* Stop if already stored. Since tagStack is a stack, we can stop
+ /* Stop if already stored. Since m_tagStack is a stack, we can stop
at the first entry that has already been copied; everything
below it in the stack is already been accounted for in a
previous call to this function.
@@ -2122,7 +2415,7 @@ storeRawNames(XML_Parser parser)
*/
bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
if (bufSize > tag->bufEnd - tag->buf) {
- char *temp = (char *)REALLOC(tag->buf, bufSize);
+ char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
if (temp == NULL)
return XML_FALSE;
/* if tag->name.str points to tag->buf (only when namespace
@@ -2134,8 +2427,8 @@ storeRawNames(XML_Parser parser)
then update it as well, since it will always point into tag->buf
*/
if (tag->name.localPart)
- tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
- (XML_Char *)tag->buf);
+ tag->name.localPart
+ = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
tag->buf = temp;
tag->bufEnd = temp + bufSize;
rawNameBuf = temp + nameLen;
@@ -2148,41 +2441,33 @@ storeRawNames(XML_Parser parser)
}
static enum XML_Error PTRCALL
-contentProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doContent(parser, 0, encoding, start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
+contentProcessor(XML_Parser parser, const char *start, const char *end,
+ const char **endPtr) {
+ enum XML_Error result
+ = doContent(parser, 0, parser->m_encoding, start, end, endPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer);
if (result == XML_ERROR_NONE) {
- if (!storeRawNames(parser))
+ if (! storeRawNames(parser))
return XML_ERROR_NO_MEMORY;
}
return result;
}
static enum XML_Error PTRCALL
-externalEntityInitProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
+externalEntityInitProcessor(XML_Parser parser, const char *start,
+ const char *end, const char **endPtr) {
enum XML_Error result = initializeEncoding(parser);
if (result != XML_ERROR_NONE)
return result;
- processor = externalEntityInitProcessor2;
+ parser->m_processor = externalEntityInitProcessor2;
return externalEntityInitProcessor2(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
-externalEntityInitProcessor2(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
+externalEntityInitProcessor2(XML_Parser parser, const char *start,
+ const char *end, const char **endPtr) {
const char *next = start; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(encoding, start, end, &next);
+ int tok = XmlContentTok(parser->m_encoding, start, end, &next);
switch (tok) {
case XML_TOK_BOM:
/* If we are at the end of the buffer, this would cause the next stage,
@@ -2190,115 +2475,102 @@ externalEntityInitProcessor2(XML_Parser parser,
doContent (by detecting XML_TOK_NONE) without processing any xml text
declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
*/
- if (next == end && !ps_finalBuffer) {
+ if (next == end && ! parser->m_parsingStatus.finalBuffer) {
*endPtr = next;
return XML_ERROR_NONE;
}
start = next;
break;
case XML_TOK_PARTIAL:
- if (!ps_finalBuffer) {
+ if (! parser->m_parsingStatus.finalBuffer) {
*endPtr = start;
return XML_ERROR_NONE;
}
- eventPtr = start;
+ parser->m_eventPtr = start;
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
- if (!ps_finalBuffer) {
+ if (! parser->m_parsingStatus.finalBuffer) {
*endPtr = start;
return XML_ERROR_NONE;
}
- eventPtr = start;
+ parser->m_eventPtr = start;
return XML_ERROR_PARTIAL_CHAR;
}
- processor = externalEntityInitProcessor3;
+ parser->m_processor = externalEntityInitProcessor3;
return externalEntityInitProcessor3(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
-externalEntityInitProcessor3(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
+externalEntityInitProcessor3(XML_Parser parser, const char *start,
+ const char *end, const char **endPtr) {
int tok;
const char *next = start; /* XmlContentTok doesn't always set the last arg */
- eventPtr = start;
- tok = XmlContentTok(encoding, start, end, &next);
- eventEndPtr = next;
+ parser->m_eventPtr = start;
+ tok = XmlContentTok(parser->m_encoding, start, end, &next);
+ parser->m_eventEndPtr = next;
switch (tok) {
- case XML_TOK_XML_DECL:
- {
- enum XML_Error result;
- result = processXmlDecl(parser, 1, start, next);
- if (result != XML_ERROR_NONE)
- return result;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *endPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
- return XML_ERROR_ABORTED;
- default:
- start = next;
- }
+ case XML_TOK_XML_DECL: {
+ enum XML_Error result;
+ result = processXmlDecl(parser, 1, start, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ switch (parser->m_parsingStatus.parsing) {
+ case XML_SUSPENDED:
+ *endPtr = next;
+ return XML_ERROR_NONE;
+ case XML_FINISHED:
+ return XML_ERROR_ABORTED;
+ default:
+ start = next;
}
- break;
+ } break;
case XML_TOK_PARTIAL:
- if (!ps_finalBuffer) {
+ if (! parser->m_parsingStatus.finalBuffer) {
*endPtr = start;
return XML_ERROR_NONE;
}
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
- if (!ps_finalBuffer) {
+ if (! parser->m_parsingStatus.finalBuffer) {
*endPtr = start;
return XML_ERROR_NONE;
}
return XML_ERROR_PARTIAL_CHAR;
}
- processor = externalEntityContentProcessor;
- tagLevel = 1;
+ parser->m_processor = externalEntityContentProcessor;
+ parser->m_tagLevel = 1;
return externalEntityContentProcessor(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
-externalEntityContentProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doContent(parser, 1, encoding, start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
+externalEntityContentProcessor(XML_Parser parser, const char *start,
+ const char *end, const char **endPtr) {
+ enum XML_Error result
+ = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer);
if (result == XML_ERROR_NONE) {
- if (!storeRawNames(parser))
+ if (! storeRawNames(parser))
return XML_ERROR_NO_MEMORY;
}
return result;
}
static enum XML_Error
-doContent(XML_Parser parser,
- int startTagLevel,
- const ENCODING *enc,
- const char *s,
- const char *end,
- const char **nextPtr,
- XML_Bool haveMore)
-{
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+ const char *s, const char *end, const char **nextPtr,
+ XML_Bool haveMore) {
/* save one level of indirection */
- DTD * const dtd = _dtd;
+ DTD *const dtd = parser->m_dtd;
const char **eventPP;
const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ if (enc == parser->m_encoding) {
+ eventPP = &parser->m_eventPtr;
+ eventEndPP = &parser->m_eventEndPtr;
+ } else {
+ eventPP = &(parser->m_openInternalEntities->internalEventPtr);
+ eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
}
*eventPP = s;
@@ -2313,18 +2585,17 @@ doContent(XML_Parser parser,
return XML_ERROR_NONE;
}
*eventEndPP = end;
- if (characterDataHandler) {
+ if (parser->m_characterDataHandler) {
XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
+ parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
+ } else if (parser->m_defaultHandler)
reportDefault(parser, enc, s, end);
/* We are at the end of the final buffer, should we check for
XML_SUSPENDED, XML_FINISHED?
*/
if (startTagLevel == 0)
return XML_ERROR_NO_ELEMENTS;
- if (tagLevel != startTagLevel)
+ if (parser->m_tagLevel != startTagLevel)
return XML_ERROR_ASYNC_ENTITY;
*nextPtr = end;
return XML_ERROR_NONE;
@@ -2334,7 +2605,7 @@ doContent(XML_Parser parser,
return XML_ERROR_NONE;
}
if (startTagLevel > 0) {
- if (tagLevel != startTagLevel)
+ if (parser->m_tagLevel != startTagLevel)
return XML_ERROR_ASYNC_ENTITY;
*nextPtr = s;
return XML_ERROR_NONE;
@@ -2355,321 +2626,314 @@ doContent(XML_Parser parser,
return XML_ERROR_NONE;
}
return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- ENTITY *entity;
- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (characterDataHandler)
- characterDataHandler(handlerArg, &ch, 1);
- else if (defaultHandler)
+ case XML_TOK_ENTITY_REF: {
+ const XML_Char *name;
+ ENTITY *entity;
+ XML_Char ch = (XML_Char)XmlPredefinedEntityName(
+ enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
+ if (ch) {
+ if (parser->m_characterDataHandler)
+ parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
+ else if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (! name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
+ poolDiscard(&dtd->pool);
+ /* First, determine if a check for an existing declaration is needed;
+ if yes, check that the entity exists, and that it is internal,
+ otherwise call the skipped entity or default handler.
+ */
+ if (! dtd->hasParamEntityRefs || dtd->standalone) {
+ if (! entity)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ else if (! entity->is_internal)
+ return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ } else if (! entity) {
+ if (parser->m_skippedEntityHandler)
+ parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
+ else if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ if (entity->open)
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ if (entity->notation)
+ return XML_ERROR_BINARY_ENTITY_REF;
+ if (entity->textPtr) {
+ enum XML_Error result;
+ if (! parser->m_defaultExpandInternalEntities) {
+ if (parser->m_skippedEntityHandler)
+ parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
+ 0);
+ else if (parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
break;
}
- name = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
+ result = processInternalEntity(parser, entity, XML_FALSE);
+ if (result != XML_ERROR_NONE)
+ return result;
+ } else if (parser->m_externalEntityRefHandler) {
+ const XML_Char *context;
+ entity->open = XML_TRUE;
+ context = getContext(parser);
+ entity->open = XML_FALSE;
+ if (! context)
return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
- poolDiscard(&dtd->pool);
- /* First, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the skipped entity or default handler.
- */
- if (!dtd->hasParamEntityRefs || dtd->standalone) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- if (entity->open)
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- if (entity->notation)
- return XML_ERROR_BINARY_ENTITY_REF;
- if (entity->textPtr) {
- enum XML_Error result;
- if (!defaultExpandInternalEntities) {
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, entity->name, 0);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- result = processInternalEntity(parser, entity, XML_FALSE);
- if (result != XML_ERROR_NONE)
- return result;
- }
- else if (externalEntityRefHandler) {
- const XML_Char *context;
- entity->open = XML_TRUE;
- context = getContext(parser);
- entity->open = XML_FALSE;
- if (!context)
- return XML_ERROR_NO_MEMORY;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- context,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- poolDiscard(&tempPool);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
+ if (! parser->m_externalEntityRefHandler(
+ parser->m_externalEntityRefHandlerArg, context, entity->base,
+ entity->systemId, entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ poolDiscard(&parser->m_tempPool);
+ } else if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
case XML_TOK_START_TAG_NO_ATTS:
/* fall through */
- case XML_TOK_START_TAG_WITH_ATTS:
- {
- TAG *tag;
- enum XML_Error result;
- XML_Char *toPtr;
- if (freeTagList) {
- tag = freeTagList;
- freeTagList = freeTagList->parent;
+ case XML_TOK_START_TAG_WITH_ATTS: {
+ TAG *tag;
+ enum XML_Error result;
+ XML_Char *toPtr;
+ if (parser->m_freeTagList) {
+ tag = parser->m_freeTagList;
+ parser->m_freeTagList = parser->m_freeTagList->parent;
+ } else {
+ tag = (TAG *)MALLOC(parser, sizeof(TAG));
+ if (! tag)
+ return XML_ERROR_NO_MEMORY;
+ tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
+ if (! tag->buf) {
+ FREE(parser, tag);
+ return XML_ERROR_NO_MEMORY;
}
- else {
- tag = (TAG *)MALLOC(sizeof(TAG));
- if (!tag)
- return XML_ERROR_NO_MEMORY;
- tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
- if (!tag->buf) {
- FREE(tag);
- return XML_ERROR_NO_MEMORY;
+ tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+ }
+ tag->bindings = NULL;
+ tag->parent = parser->m_tagStack;
+ parser->m_tagStack = tag;
+ tag->name.localPart = NULL;
+ tag->name.prefix = NULL;
+ tag->rawName = s + enc->minBytesPerChar;
+ tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+ ++parser->m_tagLevel;
+ {
+ const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+ const char *fromPtr = tag->rawName;
+ toPtr = (XML_Char *)tag->buf;
+ for (;;) {
+ int bufSize;
+ int convLen;
+ const enum XML_Convert_Result convert_res
+ = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
+ (ICHAR *)tag->bufEnd - 1);
+ convLen = (int)(toPtr - (XML_Char *)tag->buf);
+ if ((fromPtr >= rawNameEnd)
+ || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
+ tag->name.strLen = convLen;
+ break;
}
- tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
- }
- tag->bindings = NULL;
- tag->parent = tagStack;
- tagStack = tag;
- tag->name.localPart = NULL;
- tag->name.prefix = NULL;
- tag->rawName = s + enc->minBytesPerChar;
- tag->rawNameLength = XmlNameLength(enc, tag->rawName);
- ++tagLevel;
- {
- const char *rawNameEnd = tag->rawName + tag->rawNameLength;
- const char *fromPtr = tag->rawName;
- toPtr = (XML_Char *)tag->buf;
- for (;;) {
- int bufSize;
- int convLen;
- const enum XML_Convert_Result convert_res = XmlConvert(enc,
- &fromPtr, rawNameEnd,
- (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
- convLen = (int)(toPtr - (XML_Char *)tag->buf);
- if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
- tag->name.strLen = convLen;
- break;
- }
- bufSize = (int)(tag->bufEnd - tag->buf) << 1;
- {
- char *temp = (char *)REALLOC(tag->buf, bufSize);
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- tag->buf = temp;
- tag->bufEnd = temp + bufSize;
- toPtr = (XML_Char *)temp + convLen;
- }
+ bufSize = (int)(tag->bufEnd - tag->buf) << 1;
+ {
+ char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
+ if (temp == NULL)
+ return XML_ERROR_NO_MEMORY;
+ tag->buf = temp;
+ tag->bufEnd = temp + bufSize;
+ toPtr = (XML_Char *)temp + convLen;
}
}
- tag->name.str = (XML_Char *)tag->buf;
- *toPtr = XML_T('\0');
- result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
- if (result)
- return result;
- if (startElementHandler)
- startElementHandler(handlerArg, tag->name.str,
- (const XML_Char **)atts);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- poolClear(&tempPool);
- break;
}
+ tag->name.str = (XML_Char *)tag->buf;
+ *toPtr = XML_T('\0');
+ result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+ if (result)
+ return result;
+ if (parser->m_startElementHandler)
+ parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
+ (const XML_Char **)parser->m_atts);
+ else if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ poolClear(&parser->m_tempPool);
+ break;
+ }
case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
/* fall through */
- case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
- {
- const char *rawName = s + enc->minBytesPerChar;
- enum XML_Error result;
- BINDING *bindings = NULL;
- XML_Bool noElmHandlers = XML_TRUE;
- TAG_NAME name;
- name.str = poolStoreString(&tempPool, enc, rawName,
- rawName + XmlNameLength(enc, rawName));
- if (!name.str)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- result = storeAtts(parser, enc, s, &name, &bindings);
- if (result)
- return result;
- poolFinish(&tempPool);
- if (startElementHandler) {
- startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
- noElmHandlers = XML_FALSE;
- }
- if (endElementHandler) {
- if (startElementHandler)
- *eventPP = *eventEndPP;
- endElementHandler(handlerArg, name.str);
- noElmHandlers = XML_FALSE;
- }
- if (noElmHandlers && defaultHandler)
- reportDefault(parser, enc, s, next);
- poolClear(&tempPool);
- while (bindings) {
- BINDING *b = bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
+ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
+ const char *rawName = s + enc->minBytesPerChar;
+ enum XML_Error result;
+ BINDING *bindings = NULL;
+ XML_Bool noElmHandlers = XML_TRUE;
+ TAG_NAME name;
+ name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
+ rawName + XmlNameLength(enc, rawName));
+ if (! name.str)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&parser->m_tempPool);
+ result = storeAtts(parser, enc, s, &name, &bindings);
+ if (result != XML_ERROR_NONE) {
+ freeBindings(parser, bindings);
+ return result;
+ }
+ poolFinish(&parser->m_tempPool);
+ if (parser->m_startElementHandler) {
+ parser->m_startElementHandler(parser->m_handlerArg, name.str,
+ (const XML_Char **)parser->m_atts);
+ noElmHandlers = XML_FALSE;
+ }
+ if (parser->m_endElementHandler) {
+ if (parser->m_startElementHandler)
+ *eventPP = *eventEndPP;
+ parser->m_endElementHandler(parser->m_handlerArg, name.str);
+ noElmHandlers = XML_FALSE;
+ }
+ if (noElmHandlers && parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ poolClear(&parser->m_tempPool);
+ freeBindings(parser, bindings);
+ }
+ if ((parser->m_tagLevel == 0)
+ && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
+ if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
+ parser->m_processor = epilogProcessor;
+ else
+ return epilogProcessor(parser, next, end, nextPtr);
}
- if (tagLevel == 0)
- return epilogProcessor(parser, next, end, nextPtr);
break;
case XML_TOK_END_TAG:
- if (tagLevel == startTagLevel)
+ if (parser->m_tagLevel == startTagLevel)
return XML_ERROR_ASYNC_ENTITY;
else {
int len;
const char *rawName;
- TAG *tag = tagStack;
- tagStack = tag->parent;
- tag->parent = freeTagList;
- freeTagList = tag;
- rawName = s + enc->minBytesPerChar*2;
+ TAG *tag = parser->m_tagStack;
+ parser->m_tagStack = tag->parent;
+ tag->parent = parser->m_freeTagList;
+ parser->m_freeTagList = tag;
+ rawName = s + enc->minBytesPerChar * 2;
len = XmlNameLength(enc, rawName);
if (len != tag->rawNameLength
|| memcmp(tag->rawName, rawName, len) != 0) {
*eventPP = rawName;
return XML_ERROR_TAG_MISMATCH;
}
- --tagLevel;
- if (endElementHandler) {
+ --parser->m_tagLevel;
+ if (parser->m_endElementHandler) {
const XML_Char *localPart;
const XML_Char *prefix;
XML_Char *uri;
localPart = tag->name.localPart;
- if (ns && localPart) {
+ if (parser->m_ns && localPart) {
/* localPart and prefix may have been overwritten in
tag->name.str, since this points to the binding->uri
buffer which gets re-used; so we have to add them again
*/
uri = (XML_Char *)tag->name.str + tag->name.uriLen;
/* don't need to check for space - already done in storeAtts() */
- while (*localPart) *uri++ = *localPart++;
+ while (*localPart)
+ *uri++ = *localPart++;
prefix = (XML_Char *)tag->name.prefix;
- if (ns_triplets && prefix) {
- *uri++ = namespaceSeparator;
- while (*prefix) *uri++ = *prefix++;
- }
+ if (parser->m_ns_triplets && prefix) {
+ *uri++ = parser->m_namespaceSeparator;
+ while (*prefix)
+ *uri++ = *prefix++;
+ }
*uri = XML_T('\0');
}
- endElementHandler(handlerArg, tag->name.str);
- }
- else if (defaultHandler)
+ parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
+ } else if (parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
while (tag->bindings) {
BINDING *b = tag->bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
+ if (parser->m_endNamespaceDeclHandler)
+ parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
+ b->prefix->name);
tag->bindings = tag->bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
+ b->nextTagBinding = parser->m_freeBindingList;
+ parser->m_freeBindingList = b;
b->prefix->binding = b->prevPrefixBinding;
}
- if (tagLevel == 0)
- return epilogProcessor(parser, next, end, nextPtr);
- }
- break;
- case XML_TOK_CHAR_REF:
- {
- int n = XmlCharRefNumber(enc, s);
- if (n < 0)
- return XML_ERROR_BAD_CHAR_REF;
- if (characterDataHandler) {
- XML_Char buf[XML_ENCODE_MAX];
- characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+ if ((parser->m_tagLevel == 0)
+ && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
+ if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
+ parser->m_processor = epilogProcessor;
+ else
+ return epilogProcessor(parser, next, end, nextPtr);
}
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
}
break;
+ case XML_TOK_CHAR_REF: {
+ int n = XmlCharRefNumber(enc, s);
+ if (n < 0)
+ return XML_ERROR_BAD_CHAR_REF;
+ if (parser->m_characterDataHandler) {
+ XML_Char buf[XML_ENCODE_MAX];
+ parser->m_characterDataHandler(parser->m_handlerArg, buf,
+ XmlEncode(n, (ICHAR *)buf));
+ } else if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ } break;
case XML_TOK_XML_DECL:
return XML_ERROR_MISPLACED_XML_PI;
case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
+ if (parser->m_characterDataHandler) {
XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
+ parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
+ } else if (parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
break;
- case XML_TOK_CDATA_SECT_OPEN:
- {
- enum XML_Error result;
- if (startCdataSectionHandler)
- startCdataSectionHandler(handlerArg);
-#if 0
- /* Suppose you doing a transformation on a document that involves
- changing only the character data. You set up a defaultHandler
- and a characterDataHandler. The defaultHandler simply copies
- characters through. The characterDataHandler does the
- transformation and writes the characters out escaping them as
- necessary. This case will fail to work if we leave out the
- following two lines (because & and < inside CDATA sections will
- be incorrectly escaped).
-
- However, now we have a start/endCdataSectionHandler, so it seems
- easier to let the user deal with this.
- */
- else if (characterDataHandler)
- characterDataHandler(handlerArg, dataBuf, 0);
-#endif
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
- if (result != XML_ERROR_NONE)
- return result;
- else if (!next) {
- processor = cdataSectionProcessor;
- return result;
- }
+ case XML_TOK_CDATA_SECT_OPEN: {
+ enum XML_Error result;
+ if (parser->m_startCdataSectionHandler)
+ parser->m_startCdataSectionHandler(parser->m_handlerArg);
+ /* BEGIN disabled code */
+ /* Suppose you doing a transformation on a document that involves
+ changing only the character data. You set up a defaultHandler
+ and a characterDataHandler. The defaultHandler simply copies
+ characters through. The characterDataHandler does the
+ transformation and writes the characters out escaping them as
+ necessary. This case will fail to work if we leave out the
+ following two lines (because & and < inside CDATA sections will
+ be incorrectly escaped).
+
+ However, now we have a start/endCdataSectionHandler, so it seems
+ easier to let the user deal with this.
+ */
+ else if (0 && parser->m_characterDataHandler)
+ parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
+ 0);
+ /* END disabled code */
+ else if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
+ if (result != XML_ERROR_NONE)
+ return result;
+ else if (! next) {
+ parser->m_processor = cdataSectionProcessor;
+ return result;
}
- break;
+ } break;
case XML_TOK_TRAILING_RSQB:
if (haveMore) {
*nextPtr = s;
return XML_ERROR_NONE;
}
- if (characterDataHandler) {
+ if (parser->m_characterDataHandler) {
if (MUST_CONVERT(enc, s)) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
- characterDataHandler(handlerArg, dataBuf,
- (int)(dataPtr - (ICHAR *)dataBuf));
- }
- else
- characterDataHandler(handlerArg,
- (XML_Char *)s,
- (int)((XML_Char *)end - (XML_Char *)s));
- }
- else if (defaultHandler)
+ ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
+ parser->m_characterDataHandler(
+ parser->m_handlerArg, parser->m_dataBuf,
+ (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
+ } else
+ parser->m_characterDataHandler(
+ parser->m_handlerArg, (XML_Char *)s,
+ (int)((XML_Char *)end - (XML_Char *)s));
+ } else if (parser->m_defaultHandler)
reportDefault(parser, enc, s, end);
/* We are at the end of the final buffer, should we check for
XML_SUSPENDED, XML_FINISHED?
@@ -2678,63 +2942,90 @@ doContent(XML_Parser parser,
*eventPP = end;
return XML_ERROR_NO_ELEMENTS;
}
- if (tagLevel != startTagLevel) {
+ if (parser->m_tagLevel != startTagLevel) {
*eventPP = end;
return XML_ERROR_ASYNC_ENTITY;
}
*nextPtr = end;
return XML_ERROR_NONE;
- case XML_TOK_DATA_CHARS:
- {
- XML_CharacterDataHandler charDataHandler = characterDataHandler;
- if (charDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = s;
- charDataHandler(handlerArg, dataBuf,
- (int)(dataPtr - (ICHAR *)dataBuf));
- if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
- break;
- *eventPP = s;
- }
+ case XML_TOK_DATA_CHARS: {
+ XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
+ if (charDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ for (;;) {
+ ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
+ const enum XML_Convert_Result convert_res = XmlConvert(
+ enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
+ *eventEndPP = s;
+ charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
+ (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
+ if ((convert_res == XML_CONVERT_COMPLETED)
+ || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
+ break;
+ *eventPP = s;
}
- else
- charDataHandler(handlerArg,
- (XML_Char *)s,
- (int)((XML_Char *)next - (XML_Char *)s));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- }
- break;
+ } else
+ charDataHandler(parser->m_handlerArg, (XML_Char *)s,
+ (int)((XML_Char *)next - (XML_Char *)s));
+ } else if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ } break;
case XML_TOK_PI:
- if (!reportProcessingInstruction(parser, enc, s, next))
+ if (! reportProcessingInstruction(parser, enc, s, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_COMMENT:
- if (!reportComment(parser, enc, s, next))
+ if (! reportComment(parser, enc, s, next))
return XML_ERROR_NO_MEMORY;
break;
default:
- if (defaultHandler)
+ /* All of the tokens produced by XmlContentTok() have their own
+ * explicit cases, so this default is not strictly necessary.
+ * However it is a useful safety net, so we retain the code and
+ * simply exclude it from the coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
+ if (parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
break;
+ /* LCOV_EXCL_STOP */
}
*eventPP = s = next;
- switch (ps_parsing) {
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
return XML_ERROR_ABORTED;
- default: ;
+ default:;
}
}
/* not reached */
}
+/* This function does not call free() on the allocated memory, merely
+ * moving it to the parser's m_freeBindingList where it can be freed or
+ * reused as appropriate.
+ */
+static void
+freeBindings(XML_Parser parser, BINDING *bindings) {
+ while (bindings) {
+ BINDING *b = bindings;
+
+ /* m_startNamespaceDeclHandler will have been called for this
+ * binding in addBindings(), so call the end handler now.
+ */
+ if (parser->m_endNamespaceDeclHandler)
+ parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
+
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = parser->m_freeBindingList;
+ parser->m_freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+}
+
/* Precondition: all arguments must be non-NULL;
Purpose:
- normalize attributes
@@ -2746,14 +3037,12 @@ doContent(XML_Parser parser,
- generate namespace aware element name (URI, prefix)
*/
static enum XML_Error
-storeAtts(XML_Parser parser, const ENCODING *enc,
- const char *attStr, TAG_NAME *tagNamePtr,
- BINDING **bindingsPtr)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
+ TAG_NAME *tagNamePtr, BINDING **bindingsPtr) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
ELEMENT_TYPE *elementType;
int nDefaultAtts;
- const XML_Char **appAtts; /* the attribute list for the application */
+ const XML_Char **appAtts; /* the attribute list for the application */
int attIndex = 0;
int prefixLen;
int i;
@@ -2764,75 +3053,84 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
const XML_Char *localPart;
/* lookup the element type name */
- elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
- if (!elementType) {
+ elementType
+ = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
+ if (! elementType) {
const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
- if (!name)
+ if (! name)
return XML_ERROR_NO_MEMORY;
elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
sizeof(ELEMENT_TYPE));
- if (!elementType)
+ if (! elementType)
return XML_ERROR_NO_MEMORY;
- if (ns && !setElementTypePrefix(parser, elementType))
+ if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
return XML_ERROR_NO_MEMORY;
}
nDefaultAtts = elementType->nDefaultAtts;
/* get the attributes from the tokenizer */
- n = XmlGetAttributes(enc, attStr, attsSize, atts);
- if (n + nDefaultAtts > attsSize) {
- int oldAttsSize = attsSize;
+ n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
+ if (n + nDefaultAtts > parser->m_attsSize) {
+ int oldAttsSize = parser->m_attsSize;
ATTRIBUTE *temp;
#ifdef XML_ATTR_INFO
XML_AttrInfo *temp2;
#endif
- attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
- temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
- if (temp == NULL)
+ parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+ temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
+ parser->m_attsSize * sizeof(ATTRIBUTE));
+ if (temp == NULL) {
+ parser->m_attsSize = oldAttsSize;
return XML_ERROR_NO_MEMORY;
- atts = temp;
+ }
+ parser->m_atts = temp;
#ifdef XML_ATTR_INFO
- temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
- if (temp2 == NULL)
+ temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
+ parser->m_attsSize * sizeof(XML_AttrInfo));
+ if (temp2 == NULL) {
+ parser->m_attsSize = oldAttsSize;
return XML_ERROR_NO_MEMORY;
- attInfo = temp2;
+ }
+ parser->m_attInfo = temp2;
#endif
if (n > oldAttsSize)
- XmlGetAttributes(enc, attStr, n, atts);
+ XmlGetAttributes(enc, attStr, n, parser->m_atts);
}
- appAtts = (const XML_Char **)atts;
+ appAtts = (const XML_Char **)parser->m_atts;
for (i = 0; i < n; i++) {
- ATTRIBUTE *currAtt = &atts[i];
+ ATTRIBUTE *currAtt = &parser->m_atts[i];
#ifdef XML_ATTR_INFO
- XML_AttrInfo *currAttInfo = &attInfo[i];
+ XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
#endif
/* add the name and value to the attribute list */
- ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
- currAtt->name
- + XmlNameLength(enc, currAtt->name));
- if (!attId)
+ ATTRIBUTE_ID *attId
+ = getAttributeId(parser, enc, currAtt->name,
+ currAtt->name + XmlNameLength(enc, currAtt->name));
+ if (! attId)
return XML_ERROR_NO_MEMORY;
#ifdef XML_ATTR_INFO
- currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
- currAttInfo->nameEnd = currAttInfo->nameStart +
- XmlNameLength(enc, currAtt->name);
- currAttInfo->valueStart = parseEndByteIndex -
- (parseEndPtr - currAtt->valuePtr);
- currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
+ currAttInfo->nameStart
+ = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
+ currAttInfo->nameEnd
+ = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
+ currAttInfo->valueStart = parser->m_parseEndByteIndex
+ - (parser->m_parseEndPtr - currAtt->valuePtr);
+ currAttInfo->valueEnd = parser->m_parseEndByteIndex
+ - (parser->m_parseEndPtr - currAtt->valueEnd);
#endif
/* Detect duplicate attributes by their QNames. This does not work when
namespace processing is turned on and different prefixes for the same
namespace are used. For this case we have a check further down.
*/
if ((attId->name)[-1]) {
- if (enc == encoding)
- eventPtr = atts[i].name;
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = parser->m_atts[i].name;
return XML_ERROR_DUPLICATE_ATTRIBUTE;
}
(attId->name)[-1] = 1;
appAtts[attIndex++] = attId->name;
- if (!atts[i].normalized) {
+ if (! parser->m_atts[i].normalized) {
enum XML_Error result;
XML_Bool isCdata = XML_TRUE;
@@ -2848,21 +3146,21 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
}
/* normalize the attribute value */
- result = storeAttributeValue(parser, enc, isCdata,
- atts[i].valuePtr, atts[i].valueEnd,
- &tempPool);
+ result = storeAttributeValue(
+ parser, enc, isCdata, parser->m_atts[i].valuePtr,
+ parser->m_atts[i].valueEnd, &parser->m_tempPool);
if (result)
return result;
- appAtts[attIndex] = poolStart(&tempPool);
- poolFinish(&tempPool);
- }
- else {
+ appAtts[attIndex] = poolStart(&parser->m_tempPool);
+ poolFinish(&parser->m_tempPool);
+ } else {
/* the value did not need normalizing */
- appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
- atts[i].valueEnd);
+ appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
+ parser->m_atts[i].valuePtr,
+ parser->m_atts[i].valueEnd);
if (appAtts[attIndex] == 0)
return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
+ poolFinish(&parser->m_tempPool);
}
/* handle prefixed attribute names */
if (attId->prefix) {
@@ -2873,49 +3171,44 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
if (result)
return result;
--attIndex;
- }
- else {
+ } else {
/* deal with other prefixed names later */
attIndex++;
nPrefixes++;
(attId->name)[-1] = 2;
}
- }
- else
+ } else
attIndex++;
}
/* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
- nSpecifiedAtts = attIndex;
+ parser->m_nSpecifiedAtts = attIndex;
if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
for (i = 0; i < attIndex; i += 2)
if (appAtts[i] == elementType->idAtt->name) {
- idAttIndex = i;
+ parser->m_idAttIndex = i;
break;
}
- }
- else
- idAttIndex = -1;
+ } else
+ parser->m_idAttIndex = -1;
/* do attribute defaulting */
for (i = 0; i < nDefaultAtts; i++) {
const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
- if (!(da->id->name)[-1] && da->value) {
+ if (! (da->id->name)[-1] && da->value) {
if (da->id->prefix) {
if (da->id->xmlns) {
enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
da->value, bindingsPtr);
if (result)
return result;
- }
- else {
+ } else {
(da->id->name)[-1] = 2;
nPrefixes++;
appAtts[attIndex++] = da->id->name;
appAtts[attIndex++] = da->value;
}
- }
- else {
+ } else {
(da->id->name)[-1] = 1;
appAtts[attIndex++] = da->id->name;
appAtts[attIndex++] = da->value;
@@ -2928,110 +3221,142 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
and clear flags that say whether attributes were specified */
i = 0;
if (nPrefixes) {
- int j; /* hash table index */
- unsigned long version = nsAttsVersion;
- int nsAttsSize = (int)1 << nsAttsPower;
+ int j; /* hash table index */
+ unsigned long version = parser->m_nsAttsVersion;
+ int nsAttsSize = (int)1 << parser->m_nsAttsPower;
+ unsigned char oldNsAttsPower = parser->m_nsAttsPower;
/* size of hash table must be at least 2 * (# of prefixed attributes) */
- if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
+ if ((nPrefixes << 1)
+ >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
NS_ATT *temp;
/* hash table size must also be a power of 2 and >= 8 */
- while (nPrefixes >> nsAttsPower++);
- if (nsAttsPower < 3)
- nsAttsPower = 3;
- nsAttsSize = (int)1 << nsAttsPower;
- temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
- if (!temp)
+ while (nPrefixes >> parser->m_nsAttsPower++)
+ ;
+ if (parser->m_nsAttsPower < 3)
+ parser->m_nsAttsPower = 3;
+ nsAttsSize = (int)1 << parser->m_nsAttsPower;
+ temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
+ nsAttsSize * sizeof(NS_ATT));
+ if (! temp) {
+ /* Restore actual size of memory in m_nsAtts */
+ parser->m_nsAttsPower = oldNsAttsPower;
return XML_ERROR_NO_MEMORY;
- nsAtts = temp;
- version = 0; /* force re-initialization of nsAtts hash table */
+ }
+ parser->m_nsAtts = temp;
+ version = 0; /* force re-initialization of m_nsAtts hash table */
}
- /* using a version flag saves us from initializing nsAtts every time */
- if (!version) { /* initialize version flags when version wraps around */
+ /* using a version flag saves us from initializing m_nsAtts every time */
+ if (! version) { /* initialize version flags when version wraps around */
version = INIT_ATTS_VERSION;
- for (j = nsAttsSize; j != 0; )
- nsAtts[--j].version = version;
+ for (j = nsAttsSize; j != 0;)
+ parser->m_nsAtts[--j].version = version;
}
- nsAttsVersion = --version;
+ parser->m_nsAttsVersion = --version;
/* expand prefixed names and check for duplicates */
for (; i < attIndex; i += 2) {
const XML_Char *s = appAtts[i];
- if (s[-1] == 2) { /* prefixed */
+ if (s[-1] == 2) { /* prefixed */
ATTRIBUTE_ID *id;
const BINDING *b;
- unsigned long uriHash = hash_secret_salt;
- ((XML_Char *)s)[-1] = 0; /* clear flag */
+ unsigned long uriHash;
+ struct siphash sip_state;
+ struct sipkey sip_key;
+
+ copy_salt_to_sipkey(parser, &sip_key);
+ sip24_init(&sip_state, &sip_key);
+
+ ((XML_Char *)s)[-1] = 0; /* clear flag */
id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
- if (!id || !id->prefix)
- return XML_ERROR_NO_MEMORY;
+ if (! id || ! id->prefix) {
+ /* This code is walking through the appAtts array, dealing
+ * with (in this case) a prefixed attribute name. To be in
+ * the array, the attribute must have already been bound, so
+ * has to have passed through the hash table lookup once
+ * already. That implies that an entry for it already
+ * exists, so the lookup above will return a pointer to
+ * already allocated memory. There is no opportunaity for
+ * the allocator to fail, so the condition above cannot be
+ * fulfilled.
+ *
+ * Since it is difficult to be certain that the above
+ * analysis is complete, we retain the test and merely
+ * remove the code from coverage tests.
+ */
+ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
+ }
b = id->prefix->binding;
- if (!b)
+ if (! b)
return XML_ERROR_UNBOUND_PREFIX;
- /* as we expand the name we also calculate its hash value */
for (j = 0; j < b->uriLen; j++) {
const XML_Char c = b->uri[j];
- if (!poolAppendChar(&tempPool, c))
+ if (! poolAppendChar(&parser->m_tempPool, c))
return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
}
+
+ sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
+
while (*s++ != XML_T(ASCII_COLON))
;
- do { /* copies null terminator */
- const XML_Char c = *s;
- if (!poolAppendChar(&tempPool, *s))
+
+ sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
+
+ do { /* copies null terminator */
+ if (! poolAppendChar(&parser->m_tempPool, *s))
return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
} while (*s++);
+ uriHash = (unsigned long)sip24_final(&sip_state);
+
{ /* Check hash table for duplicate of expanded name (uriName).
Derived from code in lookup(parser, HASH_TABLE *table, ...).
*/
unsigned char step = 0;
unsigned long mask = nsAttsSize - 1;
- j = uriHash & mask; /* index into hash table */
- while (nsAtts[j].version == version) {
+ j = uriHash & mask; /* index into hash table */
+ while (parser->m_nsAtts[j].version == version) {
/* for speed we compare stored hash values first */
- if (uriHash == nsAtts[j].hash) {
- const XML_Char *s1 = poolStart(&tempPool);
- const XML_Char *s2 = nsAtts[j].uriName;
+ if (uriHash == parser->m_nsAtts[j].hash) {
+ const XML_Char *s1 = poolStart(&parser->m_tempPool);
+ const XML_Char *s2 = parser->m_nsAtts[j].uriName;
/* s1 is null terminated, but not s2 */
- for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
+ for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
+ ;
if (*s1 == 0)
return XML_ERROR_DUPLICATE_ATTRIBUTE;
}
- if (!step)
- step = PROBE_STEP(uriHash, mask, nsAttsPower);
+ if (! step)
+ step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
j < step ? (j += nsAttsSize - step) : (j -= step);
}
}
- if (ns_triplets) { /* append namespace separator and prefix */
- tempPool.ptr[-1] = namespaceSeparator;
+ if (parser->m_ns_triplets) { /* append namespace separator and prefix */
+ parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
s = b->prefix->name;
do {
- if (!poolAppendChar(&tempPool, *s))
+ if (! poolAppendChar(&parser->m_tempPool, *s))
return XML_ERROR_NO_MEMORY;
} while (*s++);
}
/* store expanded name in attribute list */
- s = poolStart(&tempPool);
- poolFinish(&tempPool);
+ s = poolStart(&parser->m_tempPool);
+ poolFinish(&parser->m_tempPool);
appAtts[i] = s;
/* fill empty slot with new version, uriName and hash value */
- nsAtts[j].version = version;
- nsAtts[j].hash = uriHash;
- nsAtts[j].uriName = s;
+ parser->m_nsAtts[j].version = version;
+ parser->m_nsAtts[j].hash = uriHash;
+ parser->m_nsAtts[j].uriName = s;
- if (!--nPrefixes) {
+ if (! --nPrefixes) {
i += 2;
break;
}
- }
- else /* not prefixed */
- ((XML_Char *)s)[-1] = 0; /* clear flag */
+ } else /* not prefixed */
+ ((XML_Char *)s)[-1] = 0; /* clear flag */
}
}
/* clear flags for the remaining attributes */
@@ -3040,56 +3365,54 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
binding->attId->name[-1] = 0;
- if (!ns)
+ if (! parser->m_ns)
return XML_ERROR_NONE;
/* expand the element type name */
if (elementType->prefix) {
binding = elementType->prefix->binding;
- if (!binding)
+ if (! binding)
return XML_ERROR_UNBOUND_PREFIX;
localPart = tagNamePtr->str;
while (*localPart++ != XML_T(ASCII_COLON))
;
- }
- else if (dtd->defaultPrefix.binding) {
+ } else if (dtd->defaultPrefix.binding) {
binding = dtd->defaultPrefix.binding;
localPart = tagNamePtr->str;
- }
- else
+ } else
return XML_ERROR_NONE;
prefixLen = 0;
- if (ns_triplets && binding->prefix->name) {
+ if (parser->m_ns_triplets && binding->prefix->name) {
for (; binding->prefix->name[prefixLen++];)
- ; /* prefixLen includes null terminator */
+ ; /* prefixLen includes null terminator */
}
tagNamePtr->localPart = localPart;
tagNamePtr->uriLen = binding->uriLen;
tagNamePtr->prefix = binding->prefix->name;
tagNamePtr->prefixLen = prefixLen;
for (i = 0; localPart[i++];)
- ; /* i includes null terminator */
+ ; /* i includes null terminator */
n = i + binding->uriLen + prefixLen;
if (n > binding->uriAlloc) {
TAG *p;
- uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
- if (!uri)
+ uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
+ if (! uri)
return XML_ERROR_NO_MEMORY;
binding->uriAlloc = n + EXPAND_SPARE;
memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
- for (p = tagStack; p; p = p->parent)
+ for (p = parser->m_tagStack; p; p = p->parent)
if (p->name.str == binding->uri)
p->name.str = uri;
- FREE(binding->uri);
+ FREE(parser, binding->uri);
binding->uri = uri;
}
- /* if namespaceSeparator != '\0' then uri includes it already */
+ /* if m_namespaceSeparator != '\0' then uri includes it already */
uri = binding->uri + binding->uriLen;
memcpy(uri, localPart, i * sizeof(XML_Char));
/* we always have a namespace separator between localPart and prefix */
if (prefixLen) {
uri += i - 1;
- *uri = namespaceSeparator; /* replace null terminator */
+ *uri = parser->m_namespaceSeparator; /* replace null terminator */
memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
}
tagNamePtr->str = binding->uri;
@@ -3101,27 +3424,25 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
*/
static enum XML_Error
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- const XML_Char *uri, BINDING **bindingsPtr)
-{
- static const XML_Char xmlNamespace[] = {
- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
- ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
- ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
- ASCII_e, '\0'
- };
- static const int xmlLen =
- (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
- static const XML_Char xmlnsNamespace[] = {
- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
- ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
- ASCII_SLASH, '\0'
- };
- static const int xmlnsLen =
- (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
+ const XML_Char *uri, BINDING **bindingsPtr) {
+ static const XML_Char xmlNamespace[]
+ = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON,
+ ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
+ ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o,
+ ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M,
+ ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9,
+ ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m,
+ ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
+ ASCII_e, '\0'};
+ static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
+ static const XML_Char xmlnsNamespace[]
+ = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
+ ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
+ ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH,
+ ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x,
+ ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'};
+ static const int xmlnsLen
+ = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
XML_Bool mustBeXML = XML_FALSE;
XML_Bool isXML = XML_TRUE;
@@ -3134,14 +3455,11 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
if (*uri == XML_T('\0') && prefix->name)
return XML_ERROR_UNDECLARING_PREFIX;
- if (prefix->name
- && prefix->name[0] == XML_T(ASCII_x)
+ if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
&& prefix->name[1] == XML_T(ASCII_m)
&& prefix->name[2] == XML_T(ASCII_l)) {
-
/* Not allowed to bind xmlns */
- if (prefix->name[3] == XML_T(ASCII_n)
- && prefix->name[4] == XML_T(ASCII_s)
+ if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s)
&& prefix->name[5] == XML_T('\0'))
return XML_ERROR_RESERVED_PREFIX_XMLNS;
@@ -3153,7 +3471,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
isXML = XML_FALSE;
- if (!mustBeXML && isXMLNS
+ if (! mustBeXML && isXMLNS
&& (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
isXMLNS = XML_FALSE;
}
@@ -3167,49 +3485,49 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
if (isXMLNS)
return XML_ERROR_RESERVED_NAMESPACE_URI;
- if (namespaceSeparator)
+ if (parser->m_namespaceSeparator)
len++;
- if (freeBindingList) {
- b = freeBindingList;
+ if (parser->m_freeBindingList) {
+ b = parser->m_freeBindingList;
if (len > b->uriAlloc) {
- XML_Char *temp = (XML_Char *)REALLOC(b->uri,
- sizeof(XML_Char) * (len + EXPAND_SPARE));
+ XML_Char *temp = (XML_Char *)REALLOC(
+ parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
if (temp == NULL)
return XML_ERROR_NO_MEMORY;
b->uri = temp;
b->uriAlloc = len + EXPAND_SPARE;
}
- freeBindingList = b->nextTagBinding;
- }
- else {
- b = (BINDING *)MALLOC(sizeof(BINDING));
- if (!b)
+ parser->m_freeBindingList = b->nextTagBinding;
+ } else {
+ b = (BINDING *)MALLOC(parser, sizeof(BINDING));
+ if (! b)
return XML_ERROR_NO_MEMORY;
- b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (!b->uri) {
- FREE(b);
+ b->uri
+ = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
+ if (! b->uri) {
+ FREE(parser, b);
return XML_ERROR_NO_MEMORY;
}
b->uriAlloc = len + EXPAND_SPARE;
}
b->uriLen = len;
memcpy(b->uri, uri, len * sizeof(XML_Char));
- if (namespaceSeparator)
- b->uri[len - 1] = namespaceSeparator;
+ if (parser->m_namespaceSeparator)
+ b->uri[len - 1] = parser->m_namespaceSeparator;
b->prefix = prefix;
b->attId = attId;
b->prevPrefixBinding = prefix->binding;
/* NULL binding when default namespace undeclared */
- if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
+ if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
prefix->binding = NULL;
else
prefix->binding = b;
b->nextTagBinding = *bindingsPtr;
*bindingsPtr = b;
/* if attId == NULL then we are not starting a namespace scope */
- if (attId && startNamespaceDeclHandler)
- startNamespaceDeclHandler(handlerArg, prefix->name,
- prefix->binding ? uri : 0);
+ if (attId && parser->m_startNamespaceDeclHandler)
+ parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
+ prefix->binding ? uri : 0);
return XML_ERROR_NONE;
}
@@ -3217,22 +3535,19 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
the whole file is parsed with one call.
*/
static enum XML_Error PTRCALL
-cdataSectionProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doCdataSection(parser, encoding, &start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
+cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
+ const char **endPtr) {
+ enum XML_Error result
+ = doCdataSection(parser, parser->m_encoding, &start, end, endPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer);
if (result != XML_ERROR_NONE)
return result;
if (start) {
- if (parentParser) { /* we are parsing an external entity */
- processor = externalEntityContentProcessor;
+ if (parser->m_parentParser) { /* we are parsing an external entity */
+ parser->m_processor = externalEntityContentProcessor;
return externalEntityContentProcessor(parser, start, end, endPtr);
- }
- else {
- processor = contentProcessor;
+ } else {
+ parser->m_processor = contentProcessor;
return contentProcessor(parser, start, end, endPtr);
}
}
@@ -3243,24 +3558,18 @@ cdataSectionProcessor(XML_Parser parser,
the section is not yet closed.
*/
static enum XML_Error
-doCdataSection(XML_Parser parser,
- const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr,
- XML_Bool haveMore)
-{
+doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
+ const char *end, const char **nextPtr, XML_Bool haveMore) {
const char *s = *startPtr;
const char **eventPP;
const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
+ if (enc == parser->m_encoding) {
+ eventPP = &parser->m_eventPtr;
*eventPP = s;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ eventEndPP = &parser->m_eventEndPtr;
+ } else {
+ eventPP = &(parser->m_openInternalEntities->internalEventPtr);
+ eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
}
*eventPP = s;
*startPtr = NULL;
@@ -3271,54 +3580,51 @@ doCdataSection(XML_Parser parser,
*eventEndPP = next;
switch (tok) {
case XML_TOK_CDATA_SECT_CLOSE:
- if (endCdataSectionHandler)
- endCdataSectionHandler(handlerArg);
-#if 0
+ if (parser->m_endCdataSectionHandler)
+ parser->m_endCdataSectionHandler(parser->m_handlerArg);
+ /* BEGIN disabled code */
/* see comment under XML_TOK_CDATA_SECT_OPEN */
- else if (characterDataHandler)
- characterDataHandler(handlerArg, dataBuf, 0);
-#endif
- else if (defaultHandler)
+ else if (0 && parser->m_characterDataHandler)
+ parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
+ 0);
+ /* END disabled code */
+ else if (parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
*startPtr = next;
*nextPtr = next;
- if (ps_parsing == XML_FINISHED)
+ if (parser->m_parsingStatus.parsing == XML_FINISHED)
return XML_ERROR_ABORTED;
else
return XML_ERROR_NONE;
case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
+ if (parser->m_characterDataHandler) {
XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
+ parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
+ } else if (parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
break;
- case XML_TOK_DATA_CHARS:
- {
- XML_CharacterDataHandler charDataHandler = characterDataHandler;
- if (charDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = next;
- charDataHandler(handlerArg, dataBuf,
- (int)(dataPtr - (ICHAR *)dataBuf));
- if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
- break;
- *eventPP = s;
- }
+ case XML_TOK_DATA_CHARS: {
+ XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
+ if (charDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ for (;;) {
+ ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
+ const enum XML_Convert_Result convert_res = XmlConvert(
+ enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
+ *eventEndPP = next;
+ charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
+ (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
+ if ((convert_res == XML_CONVERT_COMPLETED)
+ || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
+ break;
+ *eventPP = s;
}
- else
- charDataHandler(handlerArg,
- (XML_Char *)s,
- (int)((XML_Char *)next - (XML_Char *)s));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- }
- break;
+ } else
+ charDataHandler(parser->m_handlerArg, (XML_Char *)s,
+ (int)((XML_Char *)next - (XML_Char *)s));
+ } else if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ } break;
case XML_TOK_INVALID:
*eventPP = next;
return XML_ERROR_INVALID_TOKEN;
@@ -3336,18 +3642,26 @@ doCdataSection(XML_Parser parser,
}
return XML_ERROR_UNCLOSED_CDATA_SECTION;
default:
+ /* Every token returned by XmlCdataSectionTok() has its own
+ * explicit case, so this default case will never be executed.
+ * We retain it as a safety net and exclude it from the coverage
+ * statistics.
+ *
+ * LCOV_EXCL_START
+ */
*eventPP = next;
return XML_ERROR_UNEXPECTED_STATE;
+ /* LCOV_EXCL_STOP */
}
*eventPP = s = next;
- switch (ps_parsing) {
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
return XML_ERROR_ABORTED;
- default: ;
+ default:;
}
}
/* not reached */
@@ -3359,17 +3673,15 @@ doCdataSection(XML_Parser parser,
the whole file is parsed with one call.
*/
static enum XML_Error PTRCALL
-ignoreSectionProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
- endPtr, (XML_Bool)!ps_finalBuffer);
+ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
+ const char **endPtr) {
+ enum XML_Error result
+ = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer);
if (result != XML_ERROR_NONE)
return result;
if (start) {
- processor = prologProcessor;
+ parser->m_processor = prologProcessor;
return prologProcessor(parser, start, end, endPtr);
}
return result;
@@ -3379,26 +3691,32 @@ ignoreSectionProcessor(XML_Parser parser,
if the section is not yet closed.
*/
static enum XML_Error
-doIgnoreSection(XML_Parser parser,
- const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr,
- XML_Bool haveMore)
-{
+doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
+ const char *end, const char **nextPtr, XML_Bool haveMore) {
const char *next;
int tok;
const char *s = *startPtr;
const char **eventPP;
const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
+ if (enc == parser->m_encoding) {
+ eventPP = &parser->m_eventPtr;
*eventPP = s;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ eventEndPP = &parser->m_eventEndPtr;
+ } else {
+ /* It's not entirely clear, but it seems the following two lines
+ * of code cannot be executed. The only occasions on which 'enc'
+ * is not 'encoding' are when this function is called
+ * from the internal entity processing, and IGNORE sections are an
+ * error in internal entities.
+ *
+ * Since it really isn't clear that this is true, we keep the code
+ * and just remove it from our coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
+ eventPP = &(parser->m_openInternalEntities->internalEventPtr);
+ eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
+ /* LCOV_EXCL_STOP */
}
*eventPP = s;
*startPtr = NULL;
@@ -3406,11 +3724,11 @@ doIgnoreSection(XML_Parser parser,
*eventEndPP = next;
switch (tok) {
case XML_TOK_IGNORE_SECT:
- if (defaultHandler)
+ if (parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
*startPtr = next;
*nextPtr = next;
- if (ps_parsing == XML_FINISHED)
+ if (parser->m_parsingStatus.parsing == XML_FINISHED)
return XML_ERROR_ABORTED;
else
return XML_ERROR_NONE;
@@ -3431,8 +3749,16 @@ doIgnoreSection(XML_Parser parser,
}
return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
default:
+ /* All of the tokens that XmlIgnoreSectionTok() returns have
+ * explicit cases to handle them, so this default case is never
+ * executed. We keep it as a safety net anyway, and remove it
+ * from our test coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
*eventPP = next;
return XML_ERROR_UNEXPECTED_STATE;
+ /* LCOV_EXCL_STOP */
}
/* not reached */
}
@@ -3440,38 +3766,38 @@ doIgnoreSection(XML_Parser parser,
#endif /* XML_DTD */
static enum XML_Error
-initializeEncoding(XML_Parser parser)
-{
+initializeEncoding(XML_Parser parser) {
const char *s;
#ifdef XML_UNICODE
char encodingBuf[128];
- if (!protocolEncodingName)
+ /* See comments abount `protoclEncodingName` in parserInit() */
+ if (! parser->m_protocolEncodingName)
s = NULL;
else {
int i;
- for (i = 0; protocolEncodingName[i]; i++) {
+ for (i = 0; parser->m_protocolEncodingName[i]; i++) {
if (i == sizeof(encodingBuf) - 1
- || (protocolEncodingName[i] & ~0x7f) != 0) {
+ || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
encodingBuf[0] = '\0';
break;
}
- encodingBuf[i] = (char)protocolEncodingName[i];
+ encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
}
encodingBuf[i] = '\0';
s = encodingBuf;
}
#else
- s = protocolEncodingName;
+ s = parser->m_protocolEncodingName;
#endif
- if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+ if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
+ &parser->m_initEncoding, &parser->m_encoding, s))
return XML_ERROR_NONE;
- return handleUnknownEncoding(parser, protocolEncodingName);
+ return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
}
static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
- const char *s, const char *next)
-{
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
+ const char *next) {
const char *encodingName = NULL;
const XML_Char *storedEncName = NULL;
const ENCODING *newEncoding = NULL;
@@ -3479,88 +3805,82 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
const char *versionend;
const XML_Char *storedversion = NULL;
int standalone = -1;
- if (!(ns
- ? XmlParseXmlDeclNS
- : XmlParseXmlDecl)(isGeneralTextEntity,
- encoding,
- s,
- next,
- &eventPtr,
- &version,
- &versionend,
- &encodingName,
- &newEncoding,
- &standalone)) {
+ if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
+ isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
+ &version, &versionend, &encodingName, &newEncoding, &standalone)) {
if (isGeneralTextEntity)
return XML_ERROR_TEXT_DECL;
else
return XML_ERROR_XML_DECL;
}
- if (!isGeneralTextEntity && standalone == 1) {
- _dtd->standalone = XML_TRUE;
+ if (! isGeneralTextEntity && standalone == 1) {
+ parser->m_dtd->standalone = XML_TRUE;
#ifdef XML_DTD
- if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+ if (parser->m_paramEntityParsing
+ == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+ parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif /* XML_DTD */
}
- if (xmlDeclHandler) {
+ if (parser->m_xmlDeclHandler) {
if (encodingName != NULL) {
- storedEncName = poolStoreString(&temp2Pool,
- encoding,
- encodingName,
- encodingName
- + XmlNameLength(encoding, encodingName));
- if (!storedEncName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&temp2Pool);
+ storedEncName = poolStoreString(
+ &parser->m_temp2Pool, parser->m_encoding, encodingName,
+ encodingName + XmlNameLength(parser->m_encoding, encodingName));
+ if (! storedEncName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&parser->m_temp2Pool);
}
if (version) {
- storedversion = poolStoreString(&temp2Pool,
- encoding,
- version,
- versionend - encoding->minBytesPerChar);
- if (!storedversion)
+ storedversion
+ = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
+ versionend - parser->m_encoding->minBytesPerChar);
+ if (! storedversion)
return XML_ERROR_NO_MEMORY;
}
- xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
- }
- else if (defaultHandler)
- reportDefault(parser, encoding, s, next);
- if (protocolEncodingName == NULL) {
+ parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
+ standalone);
+ } else if (parser->m_defaultHandler)
+ reportDefault(parser, parser->m_encoding, s, next);
+ if (parser->m_protocolEncodingName == NULL) {
if (newEncoding) {
- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
- eventPtr = encodingName;
+ /* Check that the specified encoding does not conflict with what
+ * the parser has already deduced. Do we have the same number
+ * of bytes in the smallest representation of a character? If
+ * this is UTF-16, is it the same endianness?
+ */
+ if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
+ || (newEncoding->minBytesPerChar == 2
+ && newEncoding != parser->m_encoding)) {
+ parser->m_eventPtr = encodingName;
return XML_ERROR_INCORRECT_ENCODING;
}
- encoding = newEncoding;
- }
- else if (encodingName) {
+ parser->m_encoding = newEncoding;
+ } else if (encodingName) {
enum XML_Error result;
- if (!storedEncName) {
+ if (! storedEncName) {
storedEncName = poolStoreString(
- &temp2Pool, encoding, encodingName,
- encodingName + XmlNameLength(encoding, encodingName));
- if (!storedEncName)
+ &parser->m_temp2Pool, parser->m_encoding, encodingName,
+ encodingName + XmlNameLength(parser->m_encoding, encodingName));
+ if (! storedEncName)
return XML_ERROR_NO_MEMORY;
}
result = handleUnknownEncoding(parser, storedEncName);
- poolClear(&temp2Pool);
+ poolClear(&parser->m_temp2Pool);
if (result == XML_ERROR_UNKNOWN_ENCODING)
- eventPtr = encodingName;
+ parser->m_eventPtr = encodingName;
return result;
}
}
if (storedEncName || storedversion)
- poolClear(&temp2Pool);
+ poolClear(&parser->m_temp2Pool);
return XML_ERROR_NONE;
}
static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
- if (unknownEncodingHandler) {
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
+ if (parser->m_unknownEncodingHandler) {
XML_Encoding info;
int i;
for (i = 0; i < 256; i++)
@@ -3568,25 +3888,21 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
info.convert = NULL;
info.data = NULL;
info.release = NULL;
- if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
- &info)) {
+ if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
+ encodingName, &info)) {
ENCODING *enc;
- unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
- if (!unknownEncodingMem) {
+ parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
+ if (! parser->m_unknownEncodingMem) {
if (info.release)
info.release(info.data);
return XML_ERROR_NO_MEMORY;
}
- enc = (ns
- ? XmlInitUnknownEncodingNS
- : XmlInitUnknownEncoding)(unknownEncodingMem,
- info.map,
- info.convert,
- info.data);
+ enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
+ parser->m_unknownEncodingMem, info.map, info.convert, info.data);
if (enc) {
- unknownEncodingData = info.data;
- unknownEncodingRelease = info.release;
- encoding = enc;
+ parser->m_unknownEncodingData = info.data;
+ parser->m_unknownEncodingRelease = info.release;
+ parser->m_encoding = enc;
return XML_ERROR_NONE;
}
}
@@ -3597,60 +3913,50 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
}
static enum XML_Error PTRCALL
-prologInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
+prologInitProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
enum XML_Error result = initializeEncoding(parser);
if (result != XML_ERROR_NONE)
return result;
- processor = prologProcessor;
+ parser->m_processor = prologProcessor;
return prologProcessor(parser, s, end, nextPtr);
}
#ifdef XML_DTD
static enum XML_Error PTRCALL
-externalParEntInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
+externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
enum XML_Error result = initializeEncoding(parser);
if (result != XML_ERROR_NONE)
return result;
/* we know now that XML_Parse(Buffer) has been called,
so we consider the external parameter entity read */
- _dtd->paramEntityRead = XML_TRUE;
+ parser->m_dtd->paramEntityRead = XML_TRUE;
- if (prologState.inEntityValue) {
- processor = entityValueInitProcessor;
+ if (parser->m_prologState.inEntityValue) {
+ parser->m_processor = entityValueInitProcessor;
return entityValueInitProcessor(parser, s, end, nextPtr);
- }
- else {
- processor = externalParEntProcessor;
+ } else {
+ parser->m_processor = externalParEntProcessor;
return externalParEntProcessor(parser, s, end, nextPtr);
}
}
static enum XML_Error PTRCALL
-entityValueInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
+entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
int tok;
const char *start = s;
const char *next = start;
- eventPtr = start;
+ parser->m_eventPtr = start;
for (;;) {
- tok = XmlPrologTok(encoding, start, end, &next);
- eventEndPtr = next;
+ tok = XmlPrologTok(parser->m_encoding, start, end, &next);
+ parser->m_eventEndPtr = next;
if (tok <= 0) {
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
*nextPtr = s;
return XML_ERROR_NONE;
}
@@ -3661,29 +3967,27 @@ entityValueInitProcessor(XML_Parser parser,
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
+ case XML_TOK_NONE: /* start == end */
default:
break;
}
/* found end of entity value - can store it now */
- return storeEntityValue(parser, encoding, s, end);
- }
- else if (tok == XML_TOK_XML_DECL) {
+ return storeEntityValue(parser, parser->m_encoding, s, end);
+ } else if (tok == XML_TOK_XML_DECL) {
enum XML_Error result;
result = processXmlDecl(parser, 0, start, next);
if (result != XML_ERROR_NONE)
return result;
- switch (ps_parsing) {
- case XML_SUSPENDED:
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_FINISHED:
+ /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For
+ * that to happen, a parameter entity parsing handler must have attempted
+ * to suspend the parser, which fails and raises an error. The parser can
+ * be aborted, but can't be suspended.
+ */
+ if (parser->m_parsingStatus.parsing == XML_FINISHED)
return XML_ERROR_ABORTED;
- default:
- *nextPtr = next;
- }
+ *nextPtr = next;
/* stop scanning for text declaration - we found one */
- processor = entityValueProcessor;
+ parser->m_processor = entityValueProcessor;
return entityValueProcessor(parser, next, end, nextPtr);
}
/* If we are at the end of the buffer, this would cause XmlPrologTok to
@@ -3693,27 +3997,33 @@ entityValueInitProcessor(XML_Parser parser,
then, when this routine is entered the next time, XmlPrologTok will
return XML_TOK_INVALID, since the BOM is still in the buffer
*/
- else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
+ else if (tok == XML_TOK_BOM && next == end
+ && ! parser->m_parsingStatus.finalBuffer) {
*nextPtr = next;
return XML_ERROR_NONE;
}
+ /* If we get this token, we have the start of what might be a
+ normal tag, but not a declaration (i.e. it doesn't begin with
+ "<!"). In a DTD context, that isn't legal.
+ */
+ else if (tok == XML_TOK_INSTANCE_START) {
+ *nextPtr = next;
+ return XML_ERROR_SYNTAX;
+ }
start = next;
- eventPtr = start;
+ parser->m_eventPtr = start;
}
}
static enum XML_Error PTRCALL
-externalParEntProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
+externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
const char *next = s;
int tok;
- tok = XmlPrologTok(encoding, s, end, &next);
+ tok = XmlPrologTok(parser->m_encoding, s, end, &next);
if (tok <= 0) {
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
*nextPtr = s;
return XML_ERROR_NONE;
}
@@ -3724,7 +4034,7 @@ externalParEntProcessor(XML_Parser parser,
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
+ case XML_TOK_NONE: /* start == end */
default:
break;
}
@@ -3735,29 +4045,26 @@ externalParEntProcessor(XML_Parser parser,
*/
else if (tok == XML_TOK_BOM) {
s = next;
- tok = XmlPrologTok(encoding, s, end, &next);
+ tok = XmlPrologTok(parser->m_encoding, s, end, &next);
}
- processor = prologProcessor;
- return doProlog(parser, encoding, s, end, tok, next,
- nextPtr, (XML_Bool)!ps_finalBuffer);
+ parser->m_processor = prologProcessor;
+ return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
}
static enum XML_Error PTRCALL
-entityValueProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
+entityValueProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
const char *start = s;
const char *next = s;
- const ENCODING *enc = encoding;
+ const ENCODING *enc = parser->m_encoding;
int tok;
for (;;) {
tok = XmlPrologTok(enc, start, end, &next);
if (tok <= 0) {
- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
+ if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
*nextPtr = s;
return XML_ERROR_NONE;
}
@@ -3768,7 +4075,7 @@ entityValueProcessor(XML_Parser parser,
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
+ case XML_TOK_NONE: /* start == end */
default:
break;
}
@@ -3782,64 +4089,57 @@ entityValueProcessor(XML_Parser parser,
#endif /* XML_DTD */
static enum XML_Error PTRCALL
-prologProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
+prologProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
const char *next = s;
- int tok = XmlPrologTok(encoding, s, end, &next);
- return doProlog(parser, encoding, s, end, tok, next,
- nextPtr, (XML_Bool)!ps_finalBuffer);
+ int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
+ return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
}
static enum XML_Error
-doProlog(XML_Parser parser,
- const ENCODING *enc,
- const char *s,
- const char *end,
- int tok,
- const char *next,
- const char **nextPtr,
- XML_Bool haveMore)
-{
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
+ int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
+ XML_Bool allowClosingDoctype) {
#ifdef XML_DTD
- static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
+ static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
#endif /* XML_DTD */
- static const XML_Char atypeCDATA[] =
- { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
- static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
- static const XML_Char atypeIDREF[] =
- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
- static const XML_Char atypeIDREFS[] =
- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
- static const XML_Char atypeENTITY[] =
- { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
- static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
- ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
- static const XML_Char atypeNMTOKEN[] = {
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
- static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
- ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
- static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
- ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
- static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
- static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
+ static const XML_Char atypeCDATA[]
+ = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
+ static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
+ static const XML_Char atypeIDREF[]
+ = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
+ static const XML_Char atypeIDREFS[]
+ = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
+ static const XML_Char atypeENTITY[]
+ = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
+ static const XML_Char atypeENTITIES[]
+ = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
+ ASCII_I, ASCII_E, ASCII_S, '\0'};
+ static const XML_Char atypeNMTOKEN[]
+ = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
+ static const XML_Char atypeNMTOKENS[]
+ = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
+ ASCII_E, ASCII_N, ASCII_S, '\0'};
+ static const XML_Char notationPrefix[]
+ = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
+ ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
+ static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
+ static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
/* save one level of indirection */
- DTD * const dtd = _dtd;
+ DTD *const dtd = parser->m_dtd;
const char **eventPP;
const char **eventEndPP;
enum XML_Content_Quant quant;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ if (enc == parser->m_encoding) {
+ eventPP = &parser->m_eventPtr;
+ eventEndPP = &parser->m_eventEndPtr;
+ } else {
+ eventPP = &(parser->m_openInternalEntities->internalEventPtr);
+ eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
}
for (;;) {
@@ -3866,7 +4166,8 @@ doProlog(XML_Parser parser,
case XML_TOK_NONE:
#ifdef XML_DTD
/* for internal PE NOT referenced between declarations */
- if (enc != encoding && !openInternalEntities->betweenDecl) {
+ if (enc != parser->m_encoding
+ && ! parser->m_openInternalEntities->betweenDecl) {
*nextPtr = s;
return XML_ERROR_NONE;
}
@@ -3874,8 +4175,8 @@ doProlog(XML_Parser parser,
complete markup, not only for external PEs, but also for
internal PEs if the reference occurs between declarations.
*/
- if (isParamEntity || enc != encoding) {
- if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+ if (parser->m_isParamEntity || enc != parser->m_encoding) {
+ if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
== XML_ROLE_ERROR)
return XML_ERROR_INCOMPLETE_PE;
*nextPtr = s;
@@ -3889,142 +4190,148 @@ doProlog(XML_Parser parser,
break;
}
}
- role = XmlTokenRole(&prologState, tok, s, next, enc);
+ role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
switch (role) {
- case XML_ROLE_XML_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 0, s, next);
- if (result != XML_ERROR_NONE)
- return result;
- enc = encoding;
- handleDefault = XML_FALSE;
- }
- break;
+ case XML_ROLE_XML_DECL: {
+ enum XML_Error result = processXmlDecl(parser, 0, s, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ enc = parser->m_encoding;
+ handleDefault = XML_FALSE;
+ } break;
case XML_ROLE_DOCTYPE_NAME:
- if (startDoctypeDeclHandler) {
- doctypeName = poolStoreString(&tempPool, enc, s, next);
- if (!doctypeName)
+ if (parser->m_startDoctypeDeclHandler) {
+ parser->m_doctypeName
+ = poolStoreString(&parser->m_tempPool, enc, s, next);
+ if (! parser->m_doctypeName)
return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- doctypePubid = NULL;
+ poolFinish(&parser->m_tempPool);
+ parser->m_doctypePubid = NULL;
handleDefault = XML_FALSE;
}
- doctypeSysid = NULL; /* always initialize to NULL */
+ parser->m_doctypeSysid = NULL; /* always initialize to NULL */
break;
case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
- if (startDoctypeDeclHandler) {
- startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
- doctypePubid, 1);
- doctypeName = NULL;
- poolClear(&tempPool);
+ if (parser->m_startDoctypeDeclHandler) {
+ parser->m_startDoctypeDeclHandler(
+ parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
+ parser->m_doctypePubid, 1);
+ parser->m_doctypeName = NULL;
+ poolClear(&parser->m_tempPool);
handleDefault = XML_FALSE;
}
break;
#ifdef XML_DTD
- case XML_ROLE_TEXT_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 1, s, next);
- if (result != XML_ERROR_NONE)
- return result;
- enc = encoding;
- handleDefault = XML_FALSE;
- }
- break;
+ case XML_ROLE_TEXT_DECL: {
+ enum XML_Error result = processXmlDecl(parser, 1, s, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ enc = parser->m_encoding;
+ handleDefault = XML_FALSE;
+ } break;
#endif /* XML_DTD */
case XML_ROLE_DOCTYPE_PUBLIC_ID:
#ifdef XML_DTD
- useForeignDTD = XML_FALSE;
- declEntity = (ENTITY *)lookup(parser,
- &dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!declEntity)
+ parser->m_useForeignDTD = XML_FALSE;
+ parser->m_declEntity = (ENTITY *)lookup(
+ parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
+ if (! parser->m_declEntity)
return XML_ERROR_NO_MEMORY;
#endif /* XML_DTD */
dtd->hasParamEntityRefs = XML_TRUE;
- if (startDoctypeDeclHandler) {
+ if (parser->m_startDoctypeDeclHandler) {
XML_Char *pubId;
- if (!XmlIsPublicId(enc, s, next, eventPP))
+ if (! XmlIsPublicId(enc, s, next, eventPP))
return XML_ERROR_PUBLICID;
- pubId = poolStoreString(&tempPool, enc,
+ pubId = poolStoreString(&parser->m_tempPool, enc,
s + enc->minBytesPerChar,
next - enc->minBytesPerChar);
- if (!pubId)
+ if (! pubId)
return XML_ERROR_NO_MEMORY;
normalizePublicId(pubId);
- poolFinish(&tempPool);
- doctypePubid = pubId;
+ poolFinish(&parser->m_tempPool);
+ parser->m_doctypePubid = pubId;
handleDefault = XML_FALSE;
goto alreadyChecked;
}
/* fall through */
case XML_ROLE_ENTITY_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
+ if (! XmlIsPublicId(enc, s, next, eventPP))
return XML_ERROR_PUBLICID;
alreadyChecked:
- if (dtd->keepProcessing && declEntity) {
- XML_Char *tem = poolStoreString(&dtd->pool,
- enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
+ if (dtd->keepProcessing && parser->m_declEntity) {
+ XML_Char *tem
+ = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (! tem)
return XML_ERROR_NO_MEMORY;
normalizePublicId(tem);
- declEntity->publicId = tem;
+ parser->m_declEntity->publicId = tem;
poolFinish(&dtd->pool);
- if (entityDeclHandler)
+ /* Don't suppress the default handler if we fell through from
+ * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
+ */
+ if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
handleDefault = XML_FALSE;
}
break;
case XML_ROLE_DOCTYPE_CLOSE:
- if (doctypeName) {
- startDoctypeDeclHandler(handlerArg, doctypeName,
- doctypeSysid, doctypePubid, 0);
- poolClear(&tempPool);
+ if (allowClosingDoctype != XML_TRUE) {
+ /* Must not close doctype from within expanded parameter entities */
+ return XML_ERROR_INVALID_TOKEN;
+ }
+
+ if (parser->m_doctypeName) {
+ parser->m_startDoctypeDeclHandler(
+ parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
+ parser->m_doctypePubid, 0);
+ poolClear(&parser->m_tempPool);
handleDefault = XML_FALSE;
}
- /* doctypeSysid will be non-NULL in the case of a previous
- XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
+ /* parser->m_doctypeSysid will be non-NULL in the case of a previous
+ XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
was not set, indicating an external subset
*/
#ifdef XML_DTD
- if (doctypeSysid || useForeignDTD) {
+ if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
dtd->hasParamEntityRefs = XML_TRUE;
- if (paramEntityParsing && externalEntityRefHandler) {
- ENTITY *entity = (ENTITY *)lookup(parser,
- &dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!entity)
- return XML_ERROR_NO_MEMORY;
- if (useForeignDTD)
- entity->base = curBase;
+ if (parser->m_paramEntityParsing
+ && parser->m_externalEntityRefHandler) {
+ ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
+ externalSubsetName, sizeof(ENTITY));
+ if (! entity) {
+ /* The external subset name "#" will have already been
+ * inserted into the hash table at the start of the
+ * external entity parsing, so no allocation will happen
+ * and lookup() cannot fail.
+ */
+ return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
+ }
+ if (parser->m_useForeignDTD)
+ entity->base = parser->m_curBase;
dtd->paramEntityRead = XML_FALSE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
+ if (! parser->m_externalEntityRefHandler(
+ parser->m_externalEntityRefHandlerArg, 0, entity->base,
+ entity->systemId, entity->publicId))
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
if (dtd->paramEntityRead) {
- if (!dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
+ if (! dtd->standalone && parser->m_notStandaloneHandler
+ && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
return XML_ERROR_NOT_STANDALONE;
}
/* if we didn't read the foreign DTD then this means that there
is no external subset and we must reset dtd->hasParamEntityRefs
*/
- else if (!doctypeSysid)
+ else if (! parser->m_doctypeSysid)
dtd->hasParamEntityRefs = hadParamEntityRefs;
/* end of DTD - no need to update dtd->keepProcessing */
}
- useForeignDTD = XML_FALSE;
+ parser->m_useForeignDTD = XML_FALSE;
}
#endif /* XML_DTD */
- if (endDoctypeDeclHandler) {
- endDoctypeDeclHandler(handlerArg);
+ if (parser->m_endDoctypeDeclHandler) {
+ parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
handleDefault = XML_FALSE;
}
break;
@@ -4033,27 +4340,24 @@ doProlog(XML_Parser parser,
/* if there is no DOCTYPE declaration then now is the
last chance to read the foreign DTD
*/
- if (useForeignDTD) {
+ if (parser->m_useForeignDTD) {
XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
dtd->hasParamEntityRefs = XML_TRUE;
- if (paramEntityParsing && externalEntityRefHandler) {
+ if (parser->m_paramEntityParsing
+ && parser->m_externalEntityRefHandler) {
ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!entity)
+ externalSubsetName, sizeof(ENTITY));
+ if (! entity)
return XML_ERROR_NO_MEMORY;
- entity->base = curBase;
+ entity->base = parser->m_curBase;
dtd->paramEntityRead = XML_FALSE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
+ if (! parser->m_externalEntityRefHandler(
+ parser->m_externalEntityRefHandlerArg, 0, entity->base,
+ entity->systemId, entity->publicId))
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
if (dtd->paramEntityRead) {
- if (!dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
+ if (! dtd->standalone && parser->m_notStandaloneHandler
+ && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
return XML_ERROR_NOT_STANDALONE;
}
/* if we didn't read the foreign DTD then this means that there
@@ -4065,93 +4369,93 @@ doProlog(XML_Parser parser,
}
}
#endif /* XML_DTD */
- processor = contentProcessor;
+ parser->m_processor = contentProcessor;
return contentProcessor(parser, s, end, nextPtr);
case XML_ROLE_ATTLIST_ELEMENT_NAME:
- declElementType = getElementType(parser, enc, s, next);
- if (!declElementType)
+ parser->m_declElementType = getElementType(parser, enc, s, next);
+ if (! parser->m_declElementType)
return XML_ERROR_NO_MEMORY;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_NAME:
- declAttributeId = getAttributeId(parser, enc, s, next);
- if (!declAttributeId)
+ parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
+ if (! parser->m_declAttributeId)
return XML_ERROR_NO_MEMORY;
- declAttributeIsCdata = XML_FALSE;
- declAttributeType = NULL;
- declAttributeIsId = XML_FALSE;
+ parser->m_declAttributeIsCdata = XML_FALSE;
+ parser->m_declAttributeType = NULL;
+ parser->m_declAttributeIsId = XML_FALSE;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
- declAttributeIsCdata = XML_TRUE;
- declAttributeType = atypeCDATA;
+ parser->m_declAttributeIsCdata = XML_TRUE;
+ parser->m_declAttributeType = atypeCDATA;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_TYPE_ID:
- declAttributeIsId = XML_TRUE;
- declAttributeType = atypeID;
+ parser->m_declAttributeIsId = XML_TRUE;
+ parser->m_declAttributeType = atypeID;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
- declAttributeType = atypeIDREF;
+ parser->m_declAttributeType = atypeIDREF;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
- declAttributeType = atypeIDREFS;
+ parser->m_declAttributeType = atypeIDREFS;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
- declAttributeType = atypeENTITY;
+ parser->m_declAttributeType = atypeENTITY;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
- declAttributeType = atypeENTITIES;
+ parser->m_declAttributeType = atypeENTITIES;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
- declAttributeType = atypeNMTOKEN;
+ parser->m_declAttributeType = atypeNMTOKEN;
goto checkAttListDeclHandler;
case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
- declAttributeType = atypeNMTOKENS;
+ parser->m_declAttributeType = atypeNMTOKENS;
checkAttListDeclHandler:
- if (dtd->keepProcessing && attlistDeclHandler)
+ if (dtd->keepProcessing && parser->m_attlistDeclHandler)
handleDefault = XML_FALSE;
break;
case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
- if (dtd->keepProcessing && attlistDeclHandler) {
+ if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
const XML_Char *prefix;
- if (declAttributeType) {
+ if (parser->m_declAttributeType) {
prefix = enumValueSep;
+ } else {
+ prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
+ : enumValueStart);
}
- else {
- prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
- ? notationPrefix
- : enumValueStart);
- }
- if (!poolAppendString(&tempPool, prefix))
+ if (! poolAppendString(&parser->m_tempPool, prefix))
return XML_ERROR_NO_MEMORY;
- if (!poolAppend(&tempPool, enc, s, next))
+ if (! poolAppend(&parser->m_tempPool, enc, s, next))
return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
+ parser->m_declAttributeType = parser->m_tempPool.start;
handleDefault = XML_FALSE;
}
break;
case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
if (dtd->keepProcessing) {
- if (!defineAttribute(declElementType, declAttributeId,
- declAttributeIsCdata, declAttributeIsId,
- 0, parser))
+ if (! defineAttribute(parser->m_declElementType,
+ parser->m_declAttributeId,
+ parser->m_declAttributeIsCdata,
+ parser->m_declAttributeIsId, 0, parser))
return XML_ERROR_NO_MEMORY;
- if (attlistDeclHandler && declAttributeType) {
- if (*declAttributeType == XML_T(ASCII_LPAREN)
- || (*declAttributeType == XML_T(ASCII_N)
- && declAttributeType[1] == XML_T(ASCII_O))) {
+ if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
+ if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
+ || (*parser->m_declAttributeType == XML_T(ASCII_N)
+ && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
/* Enumerated or Notation type */
- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
- || !poolAppendChar(&tempPool, XML_T('\0')))
+ if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
+ || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- poolFinish(&tempPool);
+ parser->m_declAttributeType = parser->m_tempPool.start;
+ poolFinish(&parser->m_tempPool);
}
*eventEndPP = s;
- attlistDeclHandler(handlerArg, declElementType->name,
- declAttributeId->name, declAttributeType,
- 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
+ parser->m_attlistDeclHandler(
+ parser->m_handlerArg, parser->m_declElementType->name,
+ parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
+ role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+ poolClear(&parser->m_tempPool);
handleDefault = XML_FALSE;
}
}
@@ -4160,61 +4464,57 @@ doProlog(XML_Parser parser,
case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
if (dtd->keepProcessing) {
const XML_Char *attVal;
- enum XML_Error result =
- storeAttributeValue(parser, enc, declAttributeIsCdata,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar,
- &dtd->pool);
+ enum XML_Error result = storeAttributeValue(
+ parser, enc, parser->m_declAttributeIsCdata,
+ s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool);
if (result)
return result;
attVal = poolStart(&dtd->pool);
poolFinish(&dtd->pool);
/* ID attributes aren't allowed to have a default */
- if (!defineAttribute(declElementType, declAttributeId,
- declAttributeIsCdata, XML_FALSE, attVal, parser))
+ if (! defineAttribute(
+ parser->m_declElementType, parser->m_declAttributeId,
+ parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
return XML_ERROR_NO_MEMORY;
- if (attlistDeclHandler && declAttributeType) {
- if (*declAttributeType == XML_T(ASCII_LPAREN)
- || (*declAttributeType == XML_T(ASCII_N)
- && declAttributeType[1] == XML_T(ASCII_O))) {
+ if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
+ if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
+ || (*parser->m_declAttributeType == XML_T(ASCII_N)
+ && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
/* Enumerated or Notation type */
- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
- || !poolAppendChar(&tempPool, XML_T('\0')))
+ if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
+ || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- poolFinish(&tempPool);
+ parser->m_declAttributeType = parser->m_tempPool.start;
+ poolFinish(&parser->m_tempPool);
}
*eventEndPP = s;
- attlistDeclHandler(handlerArg, declElementType->name,
- declAttributeId->name, declAttributeType,
- attVal,
- role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
+ parser->m_attlistDeclHandler(
+ parser->m_handlerArg, parser->m_declElementType->name,
+ parser->m_declAttributeId->name, parser->m_declAttributeType,
+ attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+ poolClear(&parser->m_tempPool);
handleDefault = XML_FALSE;
}
}
break;
case XML_ROLE_ENTITY_VALUE:
if (dtd->keepProcessing) {
- enum XML_Error result = storeEntityValue(parser, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (declEntity) {
- declEntity->textPtr = poolStart(&dtd->entityValuePool);
- declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
+ enum XML_Error result = storeEntityValue(
+ parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
+ if (parser->m_declEntity) {
+ parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
+ parser->m_declEntity->textLen
+ = (int)(poolLength(&dtd->entityValuePool));
poolFinish(&dtd->entityValuePool);
- if (entityDeclHandler) {
+ if (parser->m_entityDeclHandler) {
*eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->is_param,
- declEntity->textPtr,
- declEntity->textLen,
- curBase, 0, 0, 0);
+ parser->m_entityDeclHandler(
+ parser->m_handlerArg, parser->m_declEntity->name,
+ parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
+ parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
handleDefault = XML_FALSE;
}
- }
- else
+ } else
poolDiscard(&dtd->entityValuePool);
if (result != XML_ERROR_NONE)
return result;
@@ -4222,227 +4522,212 @@ doProlog(XML_Parser parser,
break;
case XML_ROLE_DOCTYPE_SYSTEM_ID:
#ifdef XML_DTD
- useForeignDTD = XML_FALSE;
+ parser->m_useForeignDTD = XML_FALSE;
#endif /* XML_DTD */
dtd->hasParamEntityRefs = XML_TRUE;
- if (startDoctypeDeclHandler) {
- doctypeSysid = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (doctypeSysid == NULL)
+ if (parser->m_startDoctypeDeclHandler) {
+ parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (parser->m_doctypeSysid == NULL)
return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
+ poolFinish(&parser->m_tempPool);
handleDefault = XML_FALSE;
}
#ifdef XML_DTD
else
- /* use externalSubsetName to make doctypeSysid non-NULL
- for the case where no startDoctypeDeclHandler is set */
- doctypeSysid = externalSubsetName;
+ /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
+ for the case where no parser->m_startDoctypeDeclHandler is set */
+ parser->m_doctypeSysid = externalSubsetName;
#endif /* XML_DTD */
- if (!dtd->standalone
+ if (! dtd->standalone
#ifdef XML_DTD
- && !paramEntityParsing
+ && ! parser->m_paramEntityParsing
#endif /* XML_DTD */
- && notStandaloneHandler
- && !notStandaloneHandler(handlerArg))
+ && parser->m_notStandaloneHandler
+ && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
return XML_ERROR_NOT_STANDALONE;
#ifndef XML_DTD
break;
-#else /* XML_DTD */
- if (!declEntity) {
- declEntity = (ENTITY *)lookup(parser,
- &dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!declEntity)
+#else /* XML_DTD */
+ if (! parser->m_declEntity) {
+ parser->m_declEntity = (ENTITY *)lookup(
+ parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
+ if (! parser->m_declEntity)
return XML_ERROR_NO_MEMORY;
- declEntity->publicId = NULL;
+ parser->m_declEntity->publicId = NULL;
}
- /* fall through */
#endif /* XML_DTD */
+ /* fall through */
case XML_ROLE_ENTITY_SYSTEM_ID:
- if (dtd->keepProcessing && declEntity) {
- declEntity->systemId = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!declEntity->systemId)
+ if (dtd->keepProcessing && parser->m_declEntity) {
+ parser->m_declEntity->systemId
+ = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (! parser->m_declEntity->systemId)
return XML_ERROR_NO_MEMORY;
- declEntity->base = curBase;
+ parser->m_declEntity->base = parser->m_curBase;
poolFinish(&dtd->pool);
- if (entityDeclHandler)
+ /* Don't suppress the default handler if we fell through from
+ * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
+ */
+ if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
handleDefault = XML_FALSE;
}
break;
case XML_ROLE_ENTITY_COMPLETE:
- if (dtd->keepProcessing && declEntity && entityDeclHandler) {
+ if (dtd->keepProcessing && parser->m_declEntity
+ && parser->m_entityDeclHandler) {
*eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->is_param,
- 0,0,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- 0);
+ parser->m_entityDeclHandler(
+ parser->m_handlerArg, parser->m_declEntity->name,
+ parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
+ parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
handleDefault = XML_FALSE;
}
break;
case XML_ROLE_ENTITY_NOTATION_NAME:
- if (dtd->keepProcessing && declEntity) {
- declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
- if (!declEntity->notation)
+ if (dtd->keepProcessing && parser->m_declEntity) {
+ parser->m_declEntity->notation
+ = poolStoreString(&dtd->pool, enc, s, next);
+ if (! parser->m_declEntity->notation)
return XML_ERROR_NO_MEMORY;
poolFinish(&dtd->pool);
- if (unparsedEntityDeclHandler) {
+ if (parser->m_unparsedEntityDeclHandler) {
*eventEndPP = s;
- unparsedEntityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
+ parser->m_unparsedEntityDeclHandler(
+ parser->m_handlerArg, parser->m_declEntity->name,
+ parser->m_declEntity->base, parser->m_declEntity->systemId,
+ parser->m_declEntity->publicId, parser->m_declEntity->notation);
handleDefault = XML_FALSE;
- }
- else if (entityDeclHandler) {
+ } else if (parser->m_entityDeclHandler) {
*eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- 0,0,0,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
+ parser->m_entityDeclHandler(
+ parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
+ parser->m_declEntity->base, parser->m_declEntity->systemId,
+ parser->m_declEntity->publicId, parser->m_declEntity->notation);
handleDefault = XML_FALSE;
}
}
break;
- case XML_ROLE_GENERAL_ENTITY_NAME:
- {
- if (XmlPredefinedEntityName(enc, s, next)) {
- declEntity = NULL;
- break;
- }
- if (dtd->keepProcessing) {
- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- else {
- poolFinish(&dtd->pool);
- declEntity->publicId = NULL;
- declEntity->is_param = XML_FALSE;
- /* if we have a parent parser or are reading an internal parameter
- entity, then the entity declaration is not considered "internal"
- */
- declEntity->is_internal = !(parentParser || openInternalEntities);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- }
- else {
+ case XML_ROLE_GENERAL_ENTITY_NAME: {
+ if (XmlPredefinedEntityName(enc, s, next)) {
+ parser->m_declEntity = NULL;
+ break;
+ }
+ if (dtd->keepProcessing) {
+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+ if (! name)
+ return XML_ERROR_NO_MEMORY;
+ parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
+ name, sizeof(ENTITY));
+ if (! parser->m_declEntity)
+ return XML_ERROR_NO_MEMORY;
+ if (parser->m_declEntity->name != name) {
poolDiscard(&dtd->pool);
- declEntity = NULL;
+ parser->m_declEntity = NULL;
+ } else {
+ poolFinish(&dtd->pool);
+ parser->m_declEntity->publicId = NULL;
+ parser->m_declEntity->is_param = XML_FALSE;
+ /* if we have a parent parser or are reading an internal parameter
+ entity, then the entity declaration is not considered "internal"
+ */
+ parser->m_declEntity->is_internal
+ = ! (parser->m_parentParser || parser->m_openInternalEntities);
+ if (parser->m_entityDeclHandler)
+ handleDefault = XML_FALSE;
}
+ } else {
+ poolDiscard(&dtd->pool);
+ parser->m_declEntity = NULL;
}
- break;
+ } break;
case XML_ROLE_PARAM_ENTITY_NAME:
#ifdef XML_DTD
if (dtd->keepProcessing) {
const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
- if (!name)
+ if (! name)
return XML_ERROR_NO_MEMORY;
- declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
- name, sizeof(ENTITY));
- if (!declEntity)
+ parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
+ name, sizeof(ENTITY));
+ if (! parser->m_declEntity)
return XML_ERROR_NO_MEMORY;
- if (declEntity->name != name) {
+ if (parser->m_declEntity->name != name) {
poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- else {
+ parser->m_declEntity = NULL;
+ } else {
poolFinish(&dtd->pool);
- declEntity->publicId = NULL;
- declEntity->is_param = XML_TRUE;
+ parser->m_declEntity->publicId = NULL;
+ parser->m_declEntity->is_param = XML_TRUE;
/* if we have a parent parser or are reading an internal parameter
entity, then the entity declaration is not considered "internal"
*/
- declEntity->is_internal = !(parentParser || openInternalEntities);
- if (entityDeclHandler)
+ parser->m_declEntity->is_internal
+ = ! (parser->m_parentParser || parser->m_openInternalEntities);
+ if (parser->m_entityDeclHandler)
handleDefault = XML_FALSE;
}
- }
- else {
+ } else {
poolDiscard(&dtd->pool);
- declEntity = NULL;
+ parser->m_declEntity = NULL;
}
-#else /* not XML_DTD */
- declEntity = NULL;
+#else /* not XML_DTD */
+ parser->m_declEntity = NULL;
#endif /* XML_DTD */
break;
case XML_ROLE_NOTATION_NAME:
- declNotationPublicId = NULL;
- declNotationName = NULL;
- if (notationDeclHandler) {
- declNotationName = poolStoreString(&tempPool, enc, s, next);
- if (!declNotationName)
+ parser->m_declNotationPublicId = NULL;
+ parser->m_declNotationName = NULL;
+ if (parser->m_notationDeclHandler) {
+ parser->m_declNotationName
+ = poolStoreString(&parser->m_tempPool, enc, s, next);
+ if (! parser->m_declNotationName)
return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
+ poolFinish(&parser->m_tempPool);
handleDefault = XML_FALSE;
}
break;
case XML_ROLE_NOTATION_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
+ if (! XmlIsPublicId(enc, s, next, eventPP))
return XML_ERROR_PUBLICID;
- if (declNotationName) { /* means notationDeclHandler != NULL */
- XML_Char *tem = poolStoreString(&tempPool,
- enc,
+ if (parser
+ ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
+ XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
s + enc->minBytesPerChar,
next - enc->minBytesPerChar);
- if (!tem)
+ if (! tem)
return XML_ERROR_NO_MEMORY;
normalizePublicId(tem);
- declNotationPublicId = tem;
- poolFinish(&tempPool);
+ parser->m_declNotationPublicId = tem;
+ poolFinish(&parser->m_tempPool);
handleDefault = XML_FALSE;
}
break;
case XML_ROLE_NOTATION_SYSTEM_ID:
- if (declNotationName && notationDeclHandler) {
- const XML_Char *systemId
- = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!systemId)
+ if (parser->m_declNotationName && parser->m_notationDeclHandler) {
+ const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (! systemId)
return XML_ERROR_NO_MEMORY;
*eventEndPP = s;
- notationDeclHandler(handlerArg,
- declNotationName,
- curBase,
- systemId,
- declNotationPublicId);
+ parser->m_notationDeclHandler(
+ parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
+ systemId, parser->m_declNotationPublicId);
handleDefault = XML_FALSE;
}
- poolClear(&tempPool);
+ poolClear(&parser->m_tempPool);
break;
case XML_ROLE_NOTATION_NO_SYSTEM_ID:
- if (declNotationPublicId && notationDeclHandler) {
+ if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
*eventEndPP = s;
- notationDeclHandler(handlerArg,
- declNotationName,
- curBase,
- 0,
- declNotationPublicId);
+ parser->m_notationDeclHandler(
+ parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
+ 0, parser->m_declNotationPublicId);
handleDefault = XML_FALSE;
}
- poolClear(&tempPool);
+ poolClear(&parser->m_tempPool);
break;
case XML_ROLE_ERROR:
switch (tok) {
@@ -4456,90 +4741,95 @@ doProlog(XML_Parser parser,
return XML_ERROR_SYNTAX;
}
#ifdef XML_DTD
- case XML_ROLE_IGNORE_SECT:
- {
- enum XML_Error result;
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- handleDefault = XML_FALSE;
- result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
- if (result != XML_ERROR_NONE)
- return result;
- else if (!next) {
- processor = ignoreSectionProcessor;
- return result;
- }
+ case XML_ROLE_IGNORE_SECT: {
+ enum XML_Error result;
+ if (parser->m_defaultHandler)
+ reportDefault(parser, enc, s, next);
+ handleDefault = XML_FALSE;
+ result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
+ if (result != XML_ERROR_NONE)
+ return result;
+ else if (! next) {
+ parser->m_processor = ignoreSectionProcessor;
+ return result;
}
- break;
+ } break;
#endif /* XML_DTD */
case XML_ROLE_GROUP_OPEN:
- if (prologState.level >= groupSize) {
- if (groupSize) {
- char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- groupConnector = temp;
+ if (parser->m_prologState.level >= parser->m_groupSize) {
+ if (parser->m_groupSize) {
+ {
+ char *const new_connector = (char *)REALLOC(
+ parser, parser->m_groupConnector, parser->m_groupSize *= 2);
+ if (new_connector == NULL) {
+ parser->m_groupSize /= 2;
+ return XML_ERROR_NO_MEMORY;
+ }
+ parser->m_groupConnector = new_connector;
+ }
+
if (dtd->scaffIndex) {
- int *temp = (int *)REALLOC(dtd->scaffIndex,
- groupSize * sizeof(int));
- if (temp == NULL)
+ int *const new_scaff_index = (int *)REALLOC(
+ parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
+ if (new_scaff_index == NULL)
return XML_ERROR_NO_MEMORY;
- dtd->scaffIndex = temp;
+ dtd->scaffIndex = new_scaff_index;
}
- }
- else {
- groupConnector = (char *)MALLOC(groupSize = 32);
- if (!groupConnector)
+ } else {
+ parser->m_groupConnector
+ = (char *)MALLOC(parser, parser->m_groupSize = 32);
+ if (! parser->m_groupConnector) {
+ parser->m_groupSize = 0;
return XML_ERROR_NO_MEMORY;
+ }
}
}
- groupConnector[prologState.level] = 0;
+ parser->m_groupConnector[parser->m_prologState.level] = 0;
if (dtd->in_eldecl) {
int myindex = nextScaffoldPart(parser);
if (myindex < 0)
return XML_ERROR_NO_MEMORY;
+ assert(dtd->scaffIndex != NULL);
dtd->scaffIndex[dtd->scaffLevel] = myindex;
dtd->scaffLevel++;
dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
- if (elementDeclHandler)
+ if (parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
}
break;
case XML_ROLE_GROUP_SEQUENCE:
- if (groupConnector[prologState.level] == ASCII_PIPE)
+ if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
return XML_ERROR_SYNTAX;
- groupConnector[prologState.level] = ASCII_COMMA;
- if (dtd->in_eldecl && elementDeclHandler)
+ parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
+ if (dtd->in_eldecl && parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
break;
case XML_ROLE_GROUP_CHOICE:
- if (groupConnector[prologState.level] == ASCII_COMMA)
+ if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
return XML_ERROR_SYNTAX;
if (dtd->in_eldecl
- && !groupConnector[prologState.level]
+ && ! parser->m_groupConnector[parser->m_prologState.level]
&& (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
- != XML_CTYPE_MIXED)
- ) {
+ != XML_CTYPE_MIXED)) {
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
= XML_CTYPE_CHOICE;
- if (elementDeclHandler)
+ if (parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
}
- groupConnector[prologState.level] = ASCII_PIPE;
+ parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
break;
case XML_ROLE_PARAM_ENTITY_REF:
#ifdef XML_DTD
case XML_ROLE_INNER_PARAM_ENTITY_REF:
dtd->hasParamEntityRefs = XML_TRUE;
- if (!paramEntityParsing)
+ if (! parser->m_paramEntityParsing)
dtd->keepProcessing = dtd->standalone;
else {
const XML_Char *name;
ENTITY *entity;
- name = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
+ name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (! name)
return XML_ERROR_NO_MEMORY;
entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
poolDiscard(&dtd->pool);
@@ -4547,20 +4837,40 @@ doProlog(XML_Parser parser,
if yes, check that the entity exists, and that it is internal,
otherwise call the skipped entity handler
*/
- if (prologState.documentEntity &&
- (dtd->standalone
- ? !openInternalEntities
- : !dtd->hasParamEntityRefs)) {
- if (!entity)
+ if (parser->m_prologState.documentEntity
+ && (dtd->standalone ? ! parser->m_openInternalEntities
+ : ! dtd->hasParamEntityRefs)) {
+ if (! entity)
return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
+ else if (! entity->is_internal) {
+ /* It's hard to exhaustively search the code to be sure,
+ * but there doesn't seem to be a way of executing the
+ * following line. There are two cases:
+ *
+ * If 'standalone' is false, the DTD must have no
+ * parameter entities or we wouldn't have passed the outer
+ * 'if' statement. That measn the only entity in the hash
+ * table is the external subset name "#" which cannot be
+ * given as a parameter entity name in XML syntax, so the
+ * lookup must have returned NULL and we don't even reach
+ * the test for an internal entity.
+ *
+ * If 'standalone' is true, it does not seem to be
+ * possible to create entities taking this code path that
+ * are not internal entities, so fail the test above.
+ *
+ * Because this analysis is very uncertain, the code is
+ * being left in place and merely removed from the
+ * coverage test statistics.
+ */
+ return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
+ }
+ } else if (! entity) {
dtd->keepProcessing = dtd->standalone;
/* cannot report skipped entities in declarations */
- if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
- skippedEntityHandler(handlerArg, name, 1);
+ if ((role == XML_ROLE_PARAM_ENTITY_REF)
+ && parser->m_skippedEntityHandler) {
+ parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
handleDefault = XML_FALSE;
}
break;
@@ -4569,50 +4879,46 @@ doProlog(XML_Parser parser,
return XML_ERROR_RECURSIVE_ENTITY_REF;
if (entity->textPtr) {
enum XML_Error result;
- XML_Bool betweenDecl =
- (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
+ XML_Bool betweenDecl
+ = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
result = processInternalEntity(parser, entity, betweenDecl);
if (result != XML_ERROR_NONE)
return result;
handleDefault = XML_FALSE;
break;
}
- if (externalEntityRefHandler) {
+ if (parser->m_externalEntityRefHandler) {
dtd->paramEntityRead = XML_FALSE;
entity->open = XML_TRUE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
+ if (! parser->m_externalEntityRefHandler(
+ parser->m_externalEntityRefHandlerArg, 0, entity->base,
+ entity->systemId, entity->publicId)) {
entity->open = XML_FALSE;
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
}
entity->open = XML_FALSE;
handleDefault = XML_FALSE;
- if (!dtd->paramEntityRead) {
+ if (! dtd->paramEntityRead) {
dtd->keepProcessing = dtd->standalone;
break;
}
- }
- else {
+ } else {
dtd->keepProcessing = dtd->standalone;
break;
}
}
#endif /* XML_DTD */
- if (!dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
+ if (! dtd->standalone && parser->m_notStandaloneHandler
+ && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
return XML_ERROR_NOT_STANDALONE;
break;
- /* Element declaration stuff */
+ /* Element declaration stuff */
case XML_ROLE_ELEMENT_NAME:
- if (elementDeclHandler) {
- declElementType = getElementType(parser, enc, s, next);
- if (!declElementType)
+ if (parser->m_elementDeclHandler) {
+ parser->m_declElementType = getElementType(parser, enc, s, next);
+ if (! parser->m_declElementType)
return XML_ERROR_NO_MEMORY;
dtd->scaffLevel = 0;
dtd->scaffCount = 0;
@@ -4624,19 +4930,20 @@ doProlog(XML_Parser parser,
case XML_ROLE_CONTENT_ANY:
case XML_ROLE_CONTENT_EMPTY:
if (dtd->in_eldecl) {
- if (elementDeclHandler) {
- XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
- if (!content)
+ if (parser->m_elementDeclHandler) {
+ XML_Content *content
+ = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
+ if (! content)
return XML_ERROR_NO_MEMORY;
content->quant = XML_CQUANT_NONE;
content->name = NULL;
content->numchildren = 0;
content->children = NULL;
- content->type = ((role == XML_ROLE_CONTENT_ANY) ?
- XML_CTYPE_ANY :
- XML_CTYPE_EMPTY);
+ content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
+ : XML_CTYPE_EMPTY);
*eventEndPP = s;
- elementDeclHandler(handlerArg, declElementType->name, content);
+ parser->m_elementDeclHandler(
+ parser->m_handlerArg, parser->m_declElementType->name, content);
handleDefault = XML_FALSE;
}
dtd->in_eldecl = XML_FALSE;
@@ -4647,7 +4954,7 @@ doProlog(XML_Parser parser,
if (dtd->in_eldecl) {
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
= XML_CTYPE_MIXED;
- if (elementDeclHandler)
+ if (parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
}
break;
@@ -4668,23 +4975,23 @@ doProlog(XML_Parser parser,
ELEMENT_TYPE *el;
const XML_Char *name;
int nameLen;
- const char *nxt = (quant == XML_CQUANT_NONE
- ? next
- : next - enc->minBytesPerChar);
+ const char *nxt
+ = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
int myindex = nextScaffoldPart(parser);
if (myindex < 0)
return XML_ERROR_NO_MEMORY;
dtd->scaffold[myindex].type = XML_CTYPE_NAME;
dtd->scaffold[myindex].quant = quant;
el = getElementType(parser, enc, s, nxt);
- if (!el)
+ if (! el)
return XML_ERROR_NO_MEMORY;
name = el->name;
dtd->scaffold[myindex].name = name;
nameLen = 0;
- for (; name[nameLen++]; );
- dtd->contentStringLen += nameLen;
- if (elementDeclHandler)
+ for (; name[nameLen++];)
+ ;
+ dtd->contentStringLen += nameLen;
+ if (parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
}
break;
@@ -4702,17 +5009,18 @@ doProlog(XML_Parser parser,
quant = XML_CQUANT_PLUS;
closeGroup:
if (dtd->in_eldecl) {
- if (elementDeclHandler)
+ if (parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
dtd->scaffLevel--;
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
if (dtd->scaffLevel == 0) {
- if (!handleDefault) {
+ if (! handleDefault) {
XML_Content *model = build_model(parser);
- if (!model)
+ if (! model)
return XML_ERROR_NO_MEMORY;
*eventEndPP = s;
- elementDeclHandler(handlerArg, declElementType->name, model);
+ parser->m_elementDeclHandler(
+ parser->m_handlerArg, parser->m_declElementType->name, model);
}
dtd->in_eldecl = XML_FALSE;
dtd->contentStringLen = 0;
@@ -4722,12 +5030,12 @@ doProlog(XML_Parser parser,
/* End element declaration stuff */
case XML_ROLE_PI:
- if (!reportProcessingInstruction(parser, enc, s, next))
+ if (! reportProcessingInstruction(parser, enc, s, next))
return XML_ERROR_NO_MEMORY;
handleDefault = XML_FALSE;
break;
case XML_ROLE_COMMENT:
- if (!reportComment(parser, enc, s, next))
+ if (! reportComment(parser, enc, s, next))
return XML_ERROR_NO_MEMORY;
handleDefault = XML_FALSE;
break;
@@ -4739,31 +5047,31 @@ doProlog(XML_Parser parser,
}
break;
case XML_ROLE_DOCTYPE_NONE:
- if (startDoctypeDeclHandler)
+ if (parser->m_startDoctypeDeclHandler)
handleDefault = XML_FALSE;
break;
case XML_ROLE_ENTITY_NONE:
- if (dtd->keepProcessing && entityDeclHandler)
+ if (dtd->keepProcessing && parser->m_entityDeclHandler)
handleDefault = XML_FALSE;
break;
case XML_ROLE_NOTATION_NONE:
- if (notationDeclHandler)
+ if (parser->m_notationDeclHandler)
handleDefault = XML_FALSE;
break;
case XML_ROLE_ATTLIST_NONE:
- if (dtd->keepProcessing && attlistDeclHandler)
+ if (dtd->keepProcessing && parser->m_attlistDeclHandler)
handleDefault = XML_FALSE;
break;
case XML_ROLE_ELEMENT_NONE:
- if (elementDeclHandler)
+ if (parser->m_elementDeclHandler)
handleDefault = XML_FALSE;
break;
} /* end of big switch */
- if (handleDefault && defaultHandler)
+ if (handleDefault && parser->m_defaultHandler)
reportDefault(parser, enc, s, next);
- switch (ps_parsing) {
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
@@ -4778,23 +5086,20 @@ doProlog(XML_Parser parser,
}
static enum XML_Error PTRCALL
-epilogProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- processor = epilogProcessor;
- eventPtr = s;
+epilogProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
+ parser->m_processor = epilogProcessor;
+ parser->m_eventPtr = s;
for (;;) {
const char *next = NULL;
- int tok = XmlPrologTok(encoding, s, end, &next);
- eventEndPtr = next;
+ int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
+ parser->m_eventEndPtr = next;
switch (tok) {
/* report partial linebreak - it might be the last token */
case -XML_TOK_PROLOG_S:
- if (defaultHandler) {
- reportDefault(parser, encoding, s, next);
- if (ps_parsing == XML_FINISHED)
+ if (parser->m_defaultHandler) {
+ reportDefault(parser, parser->m_encoding, s, next);
+ if (parser->m_parsingStatus.parsing == XML_FINISHED)
return XML_ERROR_ABORTED;
}
*nextPtr = next;
@@ -4803,28 +5108,28 @@ epilogProcessor(XML_Parser parser,
*nextPtr = s;
return XML_ERROR_NONE;
case XML_TOK_PROLOG_S:
- if (defaultHandler)
- reportDefault(parser, encoding, s, next);
+ if (parser->m_defaultHandler)
+ reportDefault(parser, parser->m_encoding, s, next);
break;
case XML_TOK_PI:
- if (!reportProcessingInstruction(parser, encoding, s, next))
+ if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_COMMENT:
- if (!reportComment(parser, encoding, s, next))
+ if (! reportComment(parser, parser->m_encoding, s, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_INVALID:
- eventPtr = next;
+ parser->m_eventPtr = next;
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_PARTIAL:
- if (!ps_finalBuffer) {
+ if (! parser->m_parsingStatus.finalBuffer) {
*nextPtr = s;
return XML_ERROR_NONE;
}
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
- if (!ps_finalBuffer) {
+ if (! parser->m_parsingStatus.finalBuffer) {
*nextPtr = s;
return XML_ERROR_NONE;
}
@@ -4832,167 +5137,162 @@ epilogProcessor(XML_Parser parser,
default:
return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
}
- eventPtr = s = next;
- switch (ps_parsing) {
+ parser->m_eventPtr = s = next;
+ switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
return XML_ERROR_ABORTED;
- default: ;
+ default:;
}
}
}
static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl)
-{
+processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
const char *textStart, *textEnd;
const char *next;
enum XML_Error result;
OPEN_INTERNAL_ENTITY *openEntity;
- if (freeInternalEntities) {
- openEntity = freeInternalEntities;
- freeInternalEntities = openEntity->next;
- }
- else {
- openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
- if (!openEntity)
+ if (parser->m_freeInternalEntities) {
+ openEntity = parser->m_freeInternalEntities;
+ parser->m_freeInternalEntities = openEntity->next;
+ } else {
+ openEntity
+ = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
+ if (! openEntity)
return XML_ERROR_NO_MEMORY;
}
entity->open = XML_TRUE;
entity->processed = 0;
- openEntity->next = openInternalEntities;
- openInternalEntities = openEntity;
+ openEntity->next = parser->m_openInternalEntities;
+ parser->m_openInternalEntities = openEntity;
openEntity->entity = entity;
- openEntity->startTagLevel = tagLevel;
+ openEntity->startTagLevel = parser->m_tagLevel;
openEntity->betweenDecl = betweenDecl;
openEntity->internalEventPtr = NULL;
openEntity->internalEventEndPtr = NULL;
textStart = (char *)entity->textPtr;
textEnd = (char *)(entity->textPtr + entity->textLen);
+ /* Set a safe default value in case 'next' does not get set */
+ next = textStart;
#ifdef XML_DTD
if (entity->is_param) {
- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
- result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
- next, &next, XML_FALSE);
- }
- else
+ int tok
+ = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
+ result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
+ tok, next, &next, XML_FALSE, XML_FALSE);
+ } else
#endif /* XML_DTD */
- result = doContent(parser, tagLevel, internalEncoding, textStart,
- textEnd, &next, XML_FALSE);
+ result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
+ textStart, textEnd, &next, XML_FALSE);
if (result == XML_ERROR_NONE) {
- if (textEnd != next && ps_parsing == XML_SUSPENDED) {
+ if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
entity->processed = (int)(next - textStart);
- processor = internalEntityProcessor;
- }
- else {
+ parser->m_processor = internalEntityProcessor;
+ } else {
entity->open = XML_FALSE;
- openInternalEntities = openEntity->next;
+ parser->m_openInternalEntities = openEntity->next;
/* put openEntity back in list of free instances */
- openEntity->next = freeInternalEntities;
- freeInternalEntities = openEntity;
+ openEntity->next = parser->m_freeInternalEntities;
+ parser->m_freeInternalEntities = openEntity;
}
}
return result;
}
static enum XML_Error PTRCALL
-internalEntityProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
+internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
ENTITY *entity;
const char *textStart, *textEnd;
const char *next;
enum XML_Error result;
- OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
- if (!openEntity)
+ OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
+ if (! openEntity)
return XML_ERROR_UNEXPECTED_STATE;
entity = openEntity->entity;
textStart = ((char *)entity->textPtr) + entity->processed;
textEnd = (char *)(entity->textPtr + entity->textLen);
+ /* Set a safe default value in case 'next' does not get set */
+ next = textStart;
#ifdef XML_DTD
if (entity->is_param) {
- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
- result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
- next, &next, XML_FALSE);
- }
- else
+ int tok
+ = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
+ result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
+ tok, next, &next, XML_FALSE, XML_TRUE);
+ } else
#endif /* XML_DTD */
- result = doContent(parser, openEntity->startTagLevel, internalEncoding,
- textStart, textEnd, &next, XML_FALSE);
+ result = doContent(parser, openEntity->startTagLevel,
+ parser->m_internalEncoding, textStart, textEnd, &next,
+ XML_FALSE);
if (result != XML_ERROR_NONE)
return result;
- else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
+ else if (textEnd != next
+ && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
entity->processed = (int)(next - (char *)entity->textPtr);
return result;
- }
- else {
+ } else {
entity->open = XML_FALSE;
- openInternalEntities = openEntity->next;
+ parser->m_openInternalEntities = openEntity->next;
/* put openEntity back in list of free instances */
- openEntity->next = freeInternalEntities;
- freeInternalEntities = openEntity;
+ openEntity->next = parser->m_freeInternalEntities;
+ parser->m_freeInternalEntities = openEntity;
}
#ifdef XML_DTD
if (entity->is_param) {
int tok;
- processor = prologProcessor;
- tok = XmlPrologTok(encoding, s, end, &next);
- return doProlog(parser, encoding, s, end, tok, next, nextPtr,
- (XML_Bool)!ps_finalBuffer);
- }
- else
+ parser->m_processor = prologProcessor;
+ tok = XmlPrologTok(parser->m_encoding, s, end, &next);
+ return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
+ } else
#endif /* XML_DTD */
{
- processor = contentProcessor;
+ parser->m_processor = contentProcessor;
/* see externalEntityContentProcessor vs contentProcessor */
- return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
- nextPtr, (XML_Bool)!ps_finalBuffer);
+ return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
+ s, end, nextPtr,
+ (XML_Bool)! parser->m_parsingStatus.finalBuffer);
}
}
static enum XML_Error PTRCALL
-errorProcessor(XML_Parser parser,
- const char *UNUSED_P(s),
- const char *UNUSED_P(end),
- const char **UNUSED_P(nextPtr))
-{
- return errorCode;
+errorProcessor(XML_Parser parser, const char *s, const char *end,
+ const char **nextPtr) {
+ UNUSED_P(s);
+ UNUSED_P(end);
+ UNUSED_P(nextPtr);
+ return parser->m_errorCode;
}
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end,
- STRING_POOL *pool)
-{
- enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
- end, pool);
+ const char *ptr, const char *end, STRING_POOL *pool) {
+ enum XML_Error result
+ = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
if (result)
return result;
- if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+ if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
poolChop(pool);
- if (!poolAppendChar(pool, XML_T('\0')))
+ if (! poolAppendChar(pool, XML_T('\0')))
return XML_ERROR_NO_MEMORY;
return XML_ERROR_NONE;
}
static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end,
- STRING_POOL *pool)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+ const char *ptr, const char *end, STRING_POOL *pool) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
for (;;) {
const char *next;
int tok = XmlAttributeValueTok(enc, ptr, end, &next);
@@ -5000,41 +5300,42 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
case XML_TOK_NONE:
return XML_ERROR_NONE;
case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = next;
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = ptr;
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = ptr;
return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_CHAR_REF:
- {
- XML_Char buf[XML_ENCODE_MAX];
- int i;
- int n = XmlCharRefNumber(enc, ptr);
- if (n < 0) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BAD_CHAR_REF;
- }
- if (!isCdata
- && n == 0x20 /* space */
- && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
- break;
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BAD_CHAR_REF;
- }
- for (i = 0; i < n; i++) {
- if (!poolAppendChar(pool, buf[i]))
- return XML_ERROR_NO_MEMORY;
- }
+ case XML_TOK_CHAR_REF: {
+ XML_Char buf[XML_ENCODE_MAX];
+ int i;
+ int n = XmlCharRefNumber(enc, ptr);
+ if (n < 0) {
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = ptr;
+ return XML_ERROR_BAD_CHAR_REF;
}
- break;
+ if (! isCdata && n == 0x20 /* space */
+ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+ break;
+ n = XmlEncode(n, (ICHAR *)buf);
+ /* The XmlEncode() functions can never return 0 here. That
+ * error return happens if the code point passed in is either
+ * negative or greater than or equal to 0x110000. The
+ * XmlCharRefNumber() functions will all return a number
+ * strictly less than 0x110000 or a negative value if an error
+ * occurred. The negative value is intercepted above, so
+ * XmlEncode() is never passed a value it might return an
+ * error for.
+ */
+ for (i = 0; i < n; i++) {
+ if (! poolAppendChar(pool, buf[i]))
+ return XML_ERROR_NO_MEMORY;
+ }
+ } break;
case XML_TOK_DATA_CHARS:
- if (!poolAppend(pool, enc, ptr, next))
+ if (! poolAppend(pool, enc, ptr, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_TRAILING_CR:
@@ -5042,95 +5343,119 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
/* fall through */
case XML_TOK_ATTRIBUTE_VALUE_S:
case XML_TOK_DATA_NEWLINE:
- if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+ if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
break;
- if (!poolAppendChar(pool, 0x20))
+ if (! poolAppendChar(pool, 0x20))
return XML_ERROR_NO_MEMORY;
break;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- ENTITY *entity;
- char checkEntityDecl;
- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
- ptr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (!poolAppendChar(pool, ch))
- return XML_ERROR_NO_MEMORY;
- break;
- }
- name = poolStoreString(&temp2Pool, enc,
- ptr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
+ case XML_TOK_ENTITY_REF: {
+ const XML_Char *name;
+ ENTITY *entity;
+ char checkEntityDecl;
+ XML_Char ch = (XML_Char)XmlPredefinedEntityName(
+ enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
+ if (ch) {
+ if (! poolAppendChar(pool, ch))
return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
- poolDiscard(&temp2Pool);
- /* First, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal.
- */
- if (pool == &dtd->pool) /* are we called from prolog? */
- checkEntityDecl =
+ break;
+ }
+ name = poolStoreString(&parser->m_temp2Pool, enc,
+ ptr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (! name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
+ poolDiscard(&parser->m_temp2Pool);
+ /* First, determine if a check for an existing declaration is needed;
+ if yes, check that the entity exists, and that it is internal.
+ */
+ if (pool == &dtd->pool) /* are we called from prolog? */
+ checkEntityDecl =
#ifdef XML_DTD
- prologState.documentEntity &&
+ parser->m_prologState.documentEntity &&
#endif /* XML_DTD */
- (dtd->standalone
- ? !openInternalEntities
- : !dtd->hasParamEntityRefs);
- else /* if (pool == &tempPool): we are called from content */
- checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
- if (checkEntityDecl) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- /* Cannot report skipped entity here - see comments on
- skippedEntityHandler.
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- */
- /* Cannot call the default handler because this would be
- out of sync with the call to the startElementHandler.
- if ((pool == &tempPool) && defaultHandler)
- reportDefault(parser, enc, ptr, next);
- */
- break;
- }
- if (entity->open) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- }
- if (entity->notation) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BINARY_ENTITY_REF;
- }
- if (!entity->textPtr) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
- }
- else {
- enum XML_Error result;
- const XML_Char *textEnd = entity->textPtr + entity->textLen;
- entity->open = XML_TRUE;
- result = appendAttributeValue(parser, internalEncoding, isCdata,
- (char *)entity->textPtr,
- (char *)textEnd, pool);
- entity->open = XML_FALSE;
- if (result)
- return result;
+ (dtd->standalone ? ! parser->m_openInternalEntities
+ : ! dtd->hasParamEntityRefs);
+ else /* if (pool == &parser->m_tempPool): we are called from content */
+ checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
+ if (checkEntityDecl) {
+ if (! entity)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ else if (! entity->is_internal)
+ return XML_ERROR_ENTITY_DECLARED_IN_PE;
+ } else if (! entity) {
+ /* Cannot report skipped entity here - see comments on
+ parser->m_skippedEntityHandler.
+ if (parser->m_skippedEntityHandler)
+ parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
+ */
+ /* Cannot call the default handler because this would be
+ out of sync with the call to the startElementHandler.
+ if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
+ reportDefault(parser, enc, ptr, next);
+ */
+ break;
+ }
+ if (entity->open) {
+ if (enc == parser->m_encoding) {
+ /* It does not appear that this line can be executed.
+ *
+ * The "if (entity->open)" check catches recursive entity
+ * definitions. In order to be called with an open
+ * entity, it must have gone through this code before and
+ * been through the recursive call to
+ * appendAttributeValue() some lines below. That call
+ * sets the local encoding ("enc") to the parser's
+ * internal encoding (internal_utf8 or internal_utf16),
+ * which can never be the same as the principle encoding.
+ * It doesn't appear there is another code path that gets
+ * here with entity->open being TRUE.
+ *
+ * Since it is not certain that this logic is watertight,
+ * we keep the line and merely exclude it from coverage
+ * tests.
+ */
+ parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
}
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
}
- break;
+ if (entity->notation) {
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = ptr;
+ return XML_ERROR_BINARY_ENTITY_REF;
+ }
+ if (! entity->textPtr) {
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = ptr;
+ return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+ } else {
+ enum XML_Error result;
+ const XML_Char *textEnd = entity->textPtr + entity->textLen;
+ entity->open = XML_TRUE;
+ result = appendAttributeValue(parser, parser->m_internalEncoding,
+ isCdata, (char *)entity->textPtr,
+ (char *)textEnd, pool);
+ entity->open = XML_FALSE;
+ if (result)
+ return result;
+ }
+ } break;
default:
- if (enc == encoding)
- eventPtr = ptr;
+ /* The only token returned by XmlAttributeValueTok() that does
+ * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
+ * Getting that would require an entity name to contain an
+ * incomplete XML character (e.g. \xE2\x82); however previous
+ * tokenisers will have already recognised and rejected such
+ * names before XmlAttributeValueTok() gets a look-in. This
+ * default case should be retained as a safety net, but the code
+ * excluded from coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = ptr;
return XML_ERROR_UNEXPECTED_STATE;
+ /* LCOV_EXCL_STOP */
}
ptr = next;
}
@@ -5138,23 +5463,20 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
}
static enum XML_Error
-storeEntityValue(XML_Parser parser,
- const ENCODING *enc,
- const char *entityTextPtr,
- const char *entityTextEnd)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+storeEntityValue(XML_Parser parser, const ENCODING *enc,
+ const char *entityTextPtr, const char *entityTextEnd) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
STRING_POOL *pool = &(dtd->entityValuePool);
enum XML_Error result = XML_ERROR_NONE;
#ifdef XML_DTD
- int oldInEntityValue = prologState.inEntityValue;
- prologState.inEntityValue = 1;
+ int oldInEntityValue = parser->m_prologState.inEntityValue;
+ parser->m_prologState.inEntityValue = 1;
#endif /* XML_DTD */
/* never return Null for the value argument in EntityDeclHandler,
since this would indicate an external entity; therefore we
have to make sure that entityValuePool.start is not null */
- if (!pool->blocks) {
- if (!poolGrow(pool))
+ if (! pool->blocks) {
+ if (! poolGrow(pool))
return XML_ERROR_NO_MEMORY;
}
@@ -5164,61 +5486,55 @@ storeEntityValue(XML_Parser parser,
switch (tok) {
case XML_TOK_PARAM_ENTITY_REF:
#ifdef XML_DTD
- if (isParamEntity || enc != encoding) {
+ if (parser->m_isParamEntity || enc != parser->m_encoding) {
const XML_Char *name;
ENTITY *entity;
- name = poolStoreString(&tempPool, enc,
+ name = poolStoreString(&parser->m_tempPool, enc,
entityTextPtr + enc->minBytesPerChar,
next - enc->minBytesPerChar);
- if (!name) {
+ if (! name) {
result = XML_ERROR_NO_MEMORY;
goto endEntityValue;
}
entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
- poolDiscard(&tempPool);
- if (!entity) {
+ poolDiscard(&parser->m_tempPool);
+ if (! entity) {
/* not a well-formedness error - see XML 1.0: WFC Entity Declared */
/* cannot report skipped entity here - see comments on
- skippedEntityHandler
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
+ parser->m_skippedEntityHandler
+ if (parser->m_skippedEntityHandler)
+ parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
*/
dtd->keepProcessing = dtd->standalone;
goto endEntityValue;
}
if (entity->open) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = entityTextPtr;
result = XML_ERROR_RECURSIVE_ENTITY_REF;
goto endEntityValue;
}
if (entity->systemId) {
- if (externalEntityRefHandler) {
+ if (parser->m_externalEntityRefHandler) {
dtd->paramEntityRead = XML_FALSE;
entity->open = XML_TRUE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
+ if (! parser->m_externalEntityRefHandler(
+ parser->m_externalEntityRefHandlerArg, 0, entity->base,
+ entity->systemId, entity->publicId)) {
entity->open = XML_FALSE;
result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
goto endEntityValue;
}
entity->open = XML_FALSE;
- if (!dtd->paramEntityRead)
+ if (! dtd->paramEntityRead)
dtd->keepProcessing = dtd->standalone;
- }
- else
+ } else
dtd->keepProcessing = dtd->standalone;
- }
- else {
+ } else {
entity->open = XML_TRUE;
- result = storeEntityValue(parser,
- internalEncoding,
- (char *)entity->textPtr,
- (char *)(entity->textPtr
- + entity->textLen));
+ result = storeEntityValue(
+ parser, parser->m_internalEncoding, (char *)entity->textPtr,
+ (char *)(entity->textPtr + entity->textLen));
entity->open = XML_FALSE;
if (result)
goto endEntityValue;
@@ -5228,7 +5544,7 @@ storeEntityValue(XML_Parser parser,
#endif /* XML_DTD */
/* In the internal subset, PE references are not legal
within markup declarations, e.g entity values in this case. */
- eventPtr = entityTextPtr;
+ parser->m_eventPtr = entityTextPtr;
result = XML_ERROR_PARAM_ENTITY_REF;
goto endEntityValue;
case XML_TOK_NONE:
@@ -5236,7 +5552,7 @@ storeEntityValue(XML_Parser parser,
goto endEntityValue;
case XML_TOK_ENTITY_REF:
case XML_TOK_DATA_CHARS:
- if (!poolAppend(pool, enc, entityTextPtr, next)) {
+ if (! poolAppend(pool, enc, entityTextPtr, next)) {
result = XML_ERROR_NO_MEMORY;
goto endEntityValue;
}
@@ -5245,67 +5561,75 @@ storeEntityValue(XML_Parser parser,
next = entityTextPtr + enc->minBytesPerChar;
/* fall through */
case XML_TOK_DATA_NEWLINE:
- if (pool->end == pool->ptr && !poolGrow(pool)) {
- result = XML_ERROR_NO_MEMORY;
+ if (pool->end == pool->ptr && ! poolGrow(pool)) {
+ result = XML_ERROR_NO_MEMORY;
goto endEntityValue;
}
*(pool->ptr)++ = 0xA;
break;
- case XML_TOK_CHAR_REF:
- {
- XML_Char buf[XML_ENCODE_MAX];
- int i;
- int n = XmlCharRefNumber(enc, entityTextPtr);
- if (n < 0) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
- goto endEntityValue;
- }
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
+ case XML_TOK_CHAR_REF: {
+ XML_Char buf[XML_ENCODE_MAX];
+ int i;
+ int n = XmlCharRefNumber(enc, entityTextPtr);
+ if (n < 0) {
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = entityTextPtr;
+ result = XML_ERROR_BAD_CHAR_REF;
+ goto endEntityValue;
+ }
+ n = XmlEncode(n, (ICHAR *)buf);
+ /* The XmlEncode() functions can never return 0 here. That
+ * error return happens if the code point passed in is either
+ * negative or greater than or equal to 0x110000. The
+ * XmlCharRefNumber() functions will all return a number
+ * strictly less than 0x110000 or a negative value if an error
+ * occurred. The negative value is intercepted above, so
+ * XmlEncode() is never passed a value it might return an
+ * error for.
+ */
+ for (i = 0; i < n; i++) {
+ if (pool->end == pool->ptr && ! poolGrow(pool)) {
+ result = XML_ERROR_NO_MEMORY;
goto endEntityValue;
}
- for (i = 0; i < n; i++) {
- if (pool->end == pool->ptr && !poolGrow(pool)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- *(pool->ptr)++ = buf[i];
- }
+ *(pool->ptr)++ = buf[i];
}
- break;
+ } break;
case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = entityTextPtr;
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = entityTextPtr;
result = XML_ERROR_INVALID_TOKEN;
goto endEntityValue;
case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = next;
result = XML_ERROR_INVALID_TOKEN;
goto endEntityValue;
default:
- if (enc == encoding)
- eventPtr = entityTextPtr;
+ /* This default case should be unnecessary -- all the tokens
+ * that XmlEntityValueTok() can return have their own explicit
+ * cases -- but should be retained for safety. We do however
+ * exclude it from the coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
+ if (enc == parser->m_encoding)
+ parser->m_eventPtr = entityTextPtr;
result = XML_ERROR_UNEXPECTED_STATE;
goto endEntityValue;
+ /* LCOV_EXCL_STOP */
}
entityTextPtr = next;
}
endEntityValue:
#ifdef XML_DTD
- prologState.inEntityValue = oldInEntityValue;
+ parser->m_prologState.inEntityValue = oldInEntityValue;
#endif /* XML_DTD */
return result;
}
static void FASTCALL
-normalizeLines(XML_Char *s)
-{
+normalizeLines(XML_Char *s) {
XML_Char *p;
for (;; s++) {
if (*s == XML_T('\0'))
@@ -5319,8 +5643,7 @@ normalizeLines(XML_Char *s)
*p++ = 0xA;
if (*++s == 0xA)
s++;
- }
- else
+ } else
*p++ = *s++;
} while (*s);
*p = XML_T('\0');
@@ -5328,88 +5651,100 @@ normalizeLines(XML_Char *s)
static int
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
+ const char *start, const char *end) {
const XML_Char *target;
XML_Char *data;
const char *tem;
- if (!processingInstructionHandler) {
- if (defaultHandler)
+ if (! parser->m_processingInstructionHandler) {
+ if (parser->m_defaultHandler)
reportDefault(parser, enc, start, end);
return 1;
}
start += enc->minBytesPerChar * 2;
tem = start + XmlNameLength(enc, start);
- target = poolStoreString(&tempPool, enc, start, tem);
- if (!target)
+ target = poolStoreString(&parser->m_tempPool, enc, start, tem);
+ if (! target)
return 0;
- poolFinish(&tempPool);
- data = poolStoreString(&tempPool, enc,
- XmlSkipS(enc, tem),
- end - enc->minBytesPerChar*2);
- if (!data)
+ poolFinish(&parser->m_tempPool);
+ data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
+ end - enc->minBytesPerChar * 2);
+ if (! data)
return 0;
normalizeLines(data);
- processingInstructionHandler(handlerArg, target, data);
- poolClear(&tempPool);
+ parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
+ poolClear(&parser->m_tempPool);
return 1;
}
static int
-reportComment(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end) {
XML_Char *data;
- if (!commentHandler) {
- if (defaultHandler)
+ if (! parser->m_commentHandler) {
+ if (parser->m_defaultHandler)
reportDefault(parser, enc, start, end);
return 1;
}
- data = poolStoreString(&tempPool,
- enc,
+ data = poolStoreString(&parser->m_tempPool, enc,
start + enc->minBytesPerChar * 4,
end - enc->minBytesPerChar * 3);
- if (!data)
+ if (! data)
return 0;
normalizeLines(data);
- commentHandler(handlerArg, data);
- poolClear(&tempPool);
+ parser->m_commentHandler(parser->m_handlerArg, data);
+ poolClear(&parser->m_tempPool);
return 1;
}
static void
-reportDefault(XML_Parser parser, const ENCODING *enc,
- const char *s, const char *end)
-{
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
+ const char *end) {
if (MUST_CONVERT(enc, s)) {
enum XML_Convert_Result convert_res;
const char **eventPP;
const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ if (enc == parser->m_encoding) {
+ eventPP = &parser->m_eventPtr;
+ eventEndPP = &parser->m_eventEndPtr;
+ } else {
+ /* To get here, two things must be true; the parser must be
+ * using a character encoding that is not the same as the
+ * encoding passed in, and the encoding passed in must need
+ * conversion to the internal format (UTF-8 unless XML_UNICODE
+ * is defined). The only occasions on which the encoding passed
+ * in is not the same as the parser's encoding are when it is
+ * the internal encoding (e.g. a previously defined parameter
+ * entity, already converted to internal format). This by
+ * definition doesn't need conversion, so the whole branch never
+ * gets executed.
+ *
+ * For safety's sake we don't delete these lines and merely
+ * exclude them from coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
+ eventPP = &(parser->m_openInternalEntities->internalEventPtr);
+ eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
+ /* LCOV_EXCL_STOP */
}
do {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
+ convert_res
+ = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
*eventEndPP = s;
- defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
+ parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
+ (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
*eventPP = s;
- } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
- }
- else
- defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
+ } while ((convert_res != XML_CONVERT_COMPLETED)
+ && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
+ } else
+ parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
+ (int)((XML_Char *)end - (XML_Char *)s));
}
-
static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
- XML_Bool isId, const XML_Char *value, XML_Parser parser)
-{
+ XML_Bool isId, const XML_Char *value, XML_Parser parser) {
DEFAULT_ATTRIBUTE *att;
if (value || isId) {
/* The handling of default attributes gets messed up if we have
@@ -5418,22 +5753,23 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
for (i = 0; i < type->nDefaultAtts; i++)
if (attId == type->defaultAtts[i].id)
return 1;
- if (isId && !type->idAtt && !attId->xmlns)
+ if (isId && ! type->idAtt && ! attId->xmlns)
type->idAtt = attId;
}
if (type->nDefaultAtts == type->allocDefaultAtts) {
if (type->allocDefaultAtts == 0) {
type->allocDefaultAtts = 8;
- type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
- * sizeof(DEFAULT_ATTRIBUTE));
- if (!type->defaultAtts)
+ type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
+ parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+ if (! type->defaultAtts) {
+ type->allocDefaultAtts = 0;
return 0;
- }
- else {
+ }
+ } else {
DEFAULT_ATTRIBUTE *temp;
int count = type->allocDefaultAtts * 2;
- temp = (DEFAULT_ATTRIBUTE *)
- REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
+ temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
+ (count * sizeof(DEFAULT_ATTRIBUTE)));
if (temp == NULL)
return 0;
type->allocDefaultAtts = count;
@@ -5444,92 +5780,89 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
att->id = attId;
att->value = value;
att->isCdata = isCdata;
- if (!isCdata)
+ if (! isCdata)
attId->maybeTokenized = XML_TRUE;
type->nDefaultAtts += 1;
return 1;
}
static int
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
const XML_Char *name;
for (name = elementType->name; *name; name++) {
if (*name == XML_T(ASCII_COLON)) {
PREFIX *prefix;
const XML_Char *s;
for (s = elementType->name; s != name; s++) {
- if (!poolAppendChar(&dtd->pool, *s))
+ if (! poolAppendChar(&dtd->pool, *s))
return 0;
}
- if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ if (! poolAppendChar(&dtd->pool, XML_T('\0')))
return 0;
prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
sizeof(PREFIX));
- if (!prefix)
+ if (! prefix)
return 0;
if (prefix->name == poolStart(&dtd->pool))
poolFinish(&dtd->pool);
else
poolDiscard(&dtd->pool);
elementType->prefix = prefix;
-
+ break;
}
}
return 1;
}
static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
+ const char *end) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
ATTRIBUTE_ID *id;
const XML_Char *name;
- if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ if (! poolAppendChar(&dtd->pool, XML_T('\0')))
return NULL;
name = poolStoreString(&dtd->pool, enc, start, end);
- if (!name)
+ if (! name)
return NULL;
/* skip quotation mark - its storage will be re-used (like in name[-1]) */
++name;
- id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
- if (!id)
+ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
+ sizeof(ATTRIBUTE_ID));
+ if (! id)
return NULL;
if (id->name != name)
poolDiscard(&dtd->pool);
else {
poolFinish(&dtd->pool);
- if (!ns)
+ if (! parser->m_ns)
;
- else if (name[0] == XML_T(ASCII_x)
- && name[1] == XML_T(ASCII_m)
- && name[2] == XML_T(ASCII_l)
- && name[3] == XML_T(ASCII_n)
- && name[4] == XML_T(ASCII_s)
- && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
+ else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
+ && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
+ && name[4] == XML_T(ASCII_s)
+ && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
if (name[5] == XML_T('\0'))
id->prefix = &dtd->defaultPrefix;
else
- id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
+ id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
+ sizeof(PREFIX));
id->xmlns = XML_TRUE;
- }
- else {
+ } else {
int i;
for (i = 0; name[i]; i++) {
/* attributes without prefix are *not* in the default namespace */
if (name[i] == XML_T(ASCII_COLON)) {
int j;
for (j = 0; j < i; j++) {
- if (!poolAppendChar(&dtd->pool, name[j]))
+ if (! poolAppendChar(&dtd->pool, name[j]))
return NULL;
}
- if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+ if (! poolAppendChar(&dtd->pool, XML_T('\0')))
return NULL;
- id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
- sizeof(PREFIX));
- if (!id->prefix)
+ id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
+ poolStart(&dtd->pool), sizeof(PREFIX));
+ if (! id->prefix)
return NULL;
if (id->prefix->name == poolStart(&dtd->pool))
poolFinish(&dtd->pool);
@@ -5546,23 +5879,44 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
#define CONTEXT_SEP XML_T(ASCII_FF)
static const XML_Char *
-getContext(XML_Parser parser)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+getContext(XML_Parser parser) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
HASH_TABLE_ITER iter;
XML_Bool needSep = XML_FALSE;
if (dtd->defaultPrefix.binding) {
int i;
int len;
- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
+ if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
return NULL;
len = dtd->defaultPrefix.binding->uriLen;
- if (namespaceSeparator)
+ if (parser->m_namespaceSeparator)
len--;
- for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
- return NULL;
+ for (i = 0; i < len; i++) {
+ if (! poolAppendChar(&parser->m_tempPool,
+ dtd->defaultPrefix.binding->uri[i])) {
+ /* Because of memory caching, I don't believe this line can be
+ * executed.
+ *
+ * This is part of a loop copying the default prefix binding
+ * URI into the parser's temporary string pool. Previously,
+ * that URI was copied into the same string pool, with a
+ * terminating NUL character, as part of setContext(). When
+ * the pool was cleared, that leaves a block definitely big
+ * enough to hold the URI on the free block list of the pool.
+ * The URI copy in getContext() therefore cannot run out of
+ * memory.
+ *
+ * If the pool is used between the setContext() and
+ * getContext() calls, the worst it can do is leave a bigger
+ * block on the front of the free list. Given that this is
+ * all somewhat inobvious and program logic can be changed, we
+ * don't delete the line but we do exclude it from the test
+ * coverage statistics.
+ */
+ return NULL; /* LCOV_EXCL_LINE */
+ }
+ }
needSep = XML_TRUE;
}
@@ -5572,102 +5926,107 @@ getContext(XML_Parser parser)
int len;
const XML_Char *s;
PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
- if (!prefix)
+ if (! prefix)
break;
- if (!prefix->binding)
- continue;
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+ if (! prefix->binding) {
+ /* This test appears to be (justifiable) paranoia. There does
+ * not seem to be a way of injecting a prefix without a binding
+ * that doesn't get errored long before this function is called.
+ * The test should remain for safety's sake, so we instead
+ * exclude the following line from the coverage statistics.
+ */
+ continue; /* LCOV_EXCL_LINE */
+ }
+ if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
return NULL;
for (s = prefix->name; *s; s++)
- if (!poolAppendChar(&tempPool, *s))
+ if (! poolAppendChar(&parser->m_tempPool, *s))
return NULL;
- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
+ if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
return NULL;
len = prefix->binding->uriLen;
- if (namespaceSeparator)
+ if (parser->m_namespaceSeparator)
len--;
for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
+ if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
return NULL;
needSep = XML_TRUE;
}
-
hashTableIterInit(&iter, &(dtd->generalEntities));
for (;;) {
const XML_Char *s;
ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
- if (!e)
+ if (! e)
break;
- if (!e->open)
+ if (! e->open)
continue;
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+ if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
return NULL;
for (s = e->name; *s; s++)
- if (!poolAppendChar(&tempPool, *s))
+ if (! poolAppendChar(&parser->m_tempPool, *s))
return 0;
needSep = XML_TRUE;
}
- if (!poolAppendChar(&tempPool, XML_T('\0')))
+ if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
return NULL;
- return tempPool.start;
+ return parser->m_tempPool.start;
}
static XML_Bool
-setContext(XML_Parser parser, const XML_Char *context)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+setContext(XML_Parser parser, const XML_Char *context) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
const XML_Char *s = context;
while (*context != XML_T('\0')) {
if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
ENTITY *e;
- if (!poolAppendChar(&tempPool, XML_T('\0')))
+ if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
return XML_FALSE;
- e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
+ e = (ENTITY *)lookup(parser, &dtd->generalEntities,
+ poolStart(&parser->m_tempPool), 0);
if (e)
e->open = XML_TRUE;
if (*s != XML_T('\0'))
s++;
context = s;
- poolDiscard(&tempPool);
- }
- else if (*s == XML_T(ASCII_EQUALS)) {
+ poolDiscard(&parser->m_tempPool);
+ } else if (*s == XML_T(ASCII_EQUALS)) {
PREFIX *prefix;
- if (poolLength(&tempPool) == 0)
+ if (poolLength(&parser->m_tempPool) == 0)
prefix = &dtd->defaultPrefix;
else {
- if (!poolAppendChar(&tempPool, XML_T('\0')))
+ if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
return XML_FALSE;
- prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
- sizeof(PREFIX));
- if (!prefix)
+ prefix
+ = (PREFIX *)lookup(parser, &dtd->prefixes,
+ poolStart(&parser->m_tempPool), sizeof(PREFIX));
+ if (! prefix)
return XML_FALSE;
- if (prefix->name == poolStart(&tempPool)) {
+ if (prefix->name == poolStart(&parser->m_tempPool)) {
prefix->name = poolCopyString(&dtd->pool, prefix->name);
- if (!prefix->name)
+ if (! prefix->name)
return XML_FALSE;
}
- poolDiscard(&tempPool);
+ poolDiscard(&parser->m_tempPool);
}
- for (context = s + 1;
- *context != CONTEXT_SEP && *context != XML_T('\0');
+ for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
context++)
- if (!poolAppendChar(&tempPool, *context))
+ if (! poolAppendChar(&parser->m_tempPool, *context))
return XML_FALSE;
- if (!poolAppendChar(&tempPool, XML_T('\0')))
+ if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
return XML_FALSE;
- if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
- &inheritedBindings) != XML_ERROR_NONE)
+ if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
+ &parser->m_inheritedBindings)
+ != XML_ERROR_NONE)
return XML_FALSE;
- poolDiscard(&tempPool);
+ poolDiscard(&parser->m_tempPool);
if (*context != XML_T('\0'))
++context;
s = context;
- }
- else {
- if (!poolAppendChar(&tempPool, *s))
+ } else {
+ if (! poolAppendChar(&parser->m_tempPool, *s))
return XML_FALSE;
s++;
}
@@ -5676,8 +6035,7 @@ setContext(XML_Parser parser, const XML_Char *context)
}
static void FASTCALL
-normalizePublicId(XML_Char *publicId)
-{
+normalizePublicId(XML_Char *publicId) {
XML_Char *p = publicId;
XML_Char *s;
for (s = publicId; *s; s++) {
@@ -5698,8 +6056,7 @@ normalizePublicId(XML_Char *publicId)
}
static DTD *
-dtdCreate(const XML_Memory_Handling_Suite *ms)
-{
+dtdCreate(const XML_Memory_Handling_Suite *ms) {
DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
if (p == NULL)
return p;
@@ -5731,13 +6088,12 @@ dtdCreate(const XML_Memory_Handling_Suite *ms)
}
static void
-dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
-{
+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
HASH_TABLE_ITER iter;
hashTableIterInit(&iter, &(p->elementTypes));
for (;;) {
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!e)
+ if (! e)
break;
if (e->allocDefaultAtts != 0)
ms->free_fcn(e->defaultAtts);
@@ -5773,13 +6129,12 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
}
static void
-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
-{
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
HASH_TABLE_ITER iter;
hashTableIterInit(&iter, &(p->elementTypes));
for (;;) {
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!e)
+ if (! e)
break;
if (e->allocDefaultAtts != 0)
ms->free_fcn(e->defaultAtts);
@@ -5804,8 +6159,8 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
The new DTD has already been initialized.
*/
static int
-dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
-{
+dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
+ const XML_Memory_Handling_Suite *ms) {
HASH_TABLE_ITER iter;
/* Copy the prefix table. */
@@ -5814,12 +6169,12 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
for (;;) {
const XML_Char *name;
const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
- if (!oldP)
+ if (! oldP)
break;
name = poolCopyString(&(newDtd->pool), oldP->name);
- if (!name)
+ if (! name)
return 0;
- if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
+ if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
return 0;
}
@@ -5832,18 +6187,18 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
const XML_Char *name;
const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
- if (!oldA)
+ if (! oldA)
break;
/* Remember to allocate the scratch byte before the name. */
- if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+ if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
return 0;
name = poolCopyString(&(newDtd->pool), oldA->name);
- if (!name)
+ if (! name)
return 0;
++name;
newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
sizeof(ATTRIBUTE_ID));
- if (!newA)
+ if (! newA)
return 0;
newA->maybeTokenized = oldA->maybeTokenized;
if (oldA->prefix) {
@@ -5865,58 +6220,52 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
ELEMENT_TYPE *newE;
const XML_Char *name;
const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!oldE)
+ if (! oldE)
break;
name = poolCopyString(&(newDtd->pool), oldE->name);
- if (!name)
+ if (! name)
return 0;
newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
sizeof(ELEMENT_TYPE));
- if (!newE)
+ if (! newE)
return 0;
if (oldE->nDefaultAtts) {
- newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
- ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
- if (!newE->defaultAtts) {
- ms->free_fcn(newE);
+ newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
+ oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+ if (! newE->defaultAtts) {
return 0;
}
}
if (oldE->idAtt)
- newE->idAtt = (ATTRIBUTE_ID *)
- lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
+ newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
+ oldE->idAtt->name, 0);
newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
if (oldE->prefix)
newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
oldE->prefix->name, 0);
for (i = 0; i < newE->nDefaultAtts; i++) {
- newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
- lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+ newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
+ oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
if (oldE->defaultAtts[i].value) {
newE->defaultAtts[i].value
= poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
- if (!newE->defaultAtts[i].value)
+ if (! newE->defaultAtts[i].value)
return 0;
- }
- else
+ } else
newE->defaultAtts[i].value = NULL;
}
}
/* Copy the entity tables. */
- if (!copyEntityTable(oldParser,
- &(newDtd->generalEntities),
- &(newDtd->pool),
- &(oldDtd->generalEntities)))
- return 0;
+ if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
+ &(oldDtd->generalEntities)))
+ return 0;
#ifdef XML_DTD
- if (!copyEntityTable(oldParser,
- &(newDtd->paramEntities),
- &(newDtd->pool),
- &(oldDtd->paramEntities)))
- return 0;
+ if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
+ &(oldDtd->paramEntities)))
+ return 0;
newDtd->paramEntityRead = oldDtd->paramEntityRead;
#endif /* XML_DTD */
@@ -5933,14 +6282,11 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
newDtd->scaffIndex = oldDtd->scaffIndex;
return 1;
-} /* End dtdCopy */
+} /* End dtdCopy */
static int
-copyEntityTable(XML_Parser oldParser,
- HASH_TABLE *newTable,
- STRING_POOL *newPool,
- const HASH_TABLE *oldTable)
-{
+copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
+ STRING_POOL *newPool, const HASH_TABLE *oldTable) {
HASH_TABLE_ITER iter;
const XML_Char *cachedOldBase = NULL;
const XML_Char *cachedNewBase = NULL;
@@ -5951,17 +6297,17 @@ copyEntityTable(XML_Parser oldParser,
ENTITY *newE;
const XML_Char *name;
const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
- if (!oldE)
+ if (! oldE)
break;
name = poolCopyString(newPool, oldE->name);
- if (!name)
+ if (! name)
return 0;
newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
- if (!newE)
+ if (! newE)
return 0;
if (oldE->systemId) {
const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
- if (!tem)
+ if (! tem)
return 0;
newE->systemId = tem;
if (oldE->base) {
@@ -5970,29 +6316,28 @@ copyEntityTable(XML_Parser oldParser,
else {
cachedOldBase = oldE->base;
tem = poolCopyString(newPool, cachedOldBase);
- if (!tem)
+ if (! tem)
return 0;
cachedNewBase = newE->base = tem;
}
}
if (oldE->publicId) {
tem = poolCopyString(newPool, oldE->publicId);
- if (!tem)
+ if (! tem)
return 0;
newE->publicId = tem;
}
- }
- else {
- const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
- oldE->textLen);
- if (!tem)
+ } else {
+ const XML_Char *tem
+ = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
+ if (! tem)
return 0;
newE->textPtr = tem;
newE->textLen = oldE->textLen;
}
if (oldE->notation) {
const XML_Char *tem = poolCopyString(newPool, oldE->notation);
- if (!tem)
+ if (! tem)
return 0;
newE->notation = tem;
}
@@ -6005,44 +6350,57 @@ copyEntityTable(XML_Parser oldParser,
#define INIT_POWER 6
static XML_Bool FASTCALL
-keyeq(KEY s1, KEY s2)
-{
+keyeq(KEY s1, KEY s2) {
for (; *s1 == *s2; s1++, s2++)
if (*s1 == 0)
return XML_TRUE;
return XML_FALSE;
}
+static size_t
+keylen(KEY s) {
+ size_t len = 0;
+ for (; *s; s++, len++)
+ ;
+ return len;
+}
+
+static void
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
+ key->k[0] = 0;
+ key->k[1] = get_hash_secret_salt(parser);
+}
+
static unsigned long FASTCALL
-hash(XML_Parser parser, KEY s)
-{
- unsigned long h = hash_secret_salt;
- while (*s)
- h = CHAR_HASH(h, *s++);
- return h;
+hash(XML_Parser parser, KEY s) {
+ struct siphash state;
+ struct sipkey key;
+ (void)sip24_valid;
+ copy_salt_to_sipkey(parser, &key);
+ sip24_init(&state, &key);
+ sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
+ return (unsigned long)sip24_final(&state);
}
static NAMED *
-lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
-{
+lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
size_t i;
if (table->size == 0) {
size_t tsize;
- if (!createSize)
+ if (! createSize)
return NULL;
table->power = INIT_POWER;
/* table->size is a power of 2 */
table->size = (size_t)1 << INIT_POWER;
tsize = table->size * sizeof(NAMED *);
table->v = (NAMED **)table->mem->malloc_fcn(tsize);
- if (!table->v) {
+ if (! table->v) {
table->size = 0;
return NULL;
}
memset(table->v, 0, tsize);
i = hash(parser, name) & ((unsigned long)table->size - 1);
- }
- else {
+ } else {
unsigned long h = hash(parser, name);
unsigned long mask = (unsigned long)table->size - 1;
unsigned char step = 0;
@@ -6050,11 +6408,11 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
while (table->v[i]) {
if (keyeq(name, table->v[i]->name))
return table->v[i];
- if (!step)
+ if (! step)
step = PROBE_STEP(h, mask, table->power);
i < step ? (i += table->size - step) : (i -= step);
}
- if (!createSize)
+ if (! createSize)
return NULL;
/* check for overflow (table is half full) */
@@ -6064,7 +6422,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
unsigned long newMask = (unsigned long)newSize - 1;
size_t tsize = newSize * sizeof(NAMED *);
NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
- if (!newV)
+ if (! newV)
return NULL;
memset(newV, 0, tsize);
for (i = 0; i < table->size; i++)
@@ -6073,7 +6431,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
size_t j = newHash & newMask;
step = 0;
while (newV[j]) {
- if (!step)
+ if (! step)
step = PROBE_STEP(newHash, newMask, newPower);
j < step ? (j += newSize - step) : (j -= step);
}
@@ -6086,14 +6444,14 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
i = h & newMask;
step = 0;
while (table->v[i]) {
- if (!step)
+ if (! step)
step = PROBE_STEP(h, newMask, newPower);
i < step ? (i += newSize - step) : (i -= step);
}
}
}
table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
- if (!table->v[i])
+ if (! table->v[i])
return NULL;
memset(table->v[i], 0, createSize);
table->v[i]->name = name;
@@ -6102,8 +6460,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
}
static void FASTCALL
-hashTableClear(HASH_TABLE *table)
-{
+hashTableClear(HASH_TABLE *table) {
size_t i;
for (i = 0; i < table->size; i++) {
table->mem->free_fcn(table->v[i]);
@@ -6113,8 +6470,7 @@ hashTableClear(HASH_TABLE *table)
}
static void FASTCALL
-hashTableDestroy(HASH_TABLE *table)
-{
+hashTableDestroy(HASH_TABLE *table) {
size_t i;
for (i = 0; i < table->size; i++)
table->mem->free_fcn(table->v[i]);
@@ -6122,8 +6478,7 @@ hashTableDestroy(HASH_TABLE *table)
}
static void FASTCALL
-hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
-{
+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
p->power = 0;
p->size = 0;
p->used = 0;
@@ -6132,15 +6487,13 @@ hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
}
static void FASTCALL
-hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
-{
+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
iter->p = table->v;
iter->end = iter->p + table->size;
}
-static NAMED * FASTCALL
-hashTableIterNext(HASH_TABLE_ITER *iter)
-{
+static NAMED *FASTCALL
+hashTableIterNext(HASH_TABLE_ITER *iter) {
while (iter->p != iter->end) {
NAMED *tem = *(iter->p)++;
if (tem)
@@ -6150,8 +6503,7 @@ hashTableIterNext(HASH_TABLE_ITER *iter)
}
static void FASTCALL
-poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
-{
+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
pool->blocks = NULL;
pool->freeBlocks = NULL;
pool->start = NULL;
@@ -6161,9 +6513,8 @@ poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
}
static void FASTCALL
-poolClear(STRING_POOL *pool)
-{
- if (!pool->freeBlocks)
+poolClear(STRING_POOL *pool) {
+ if (! pool->freeBlocks)
pool->freeBlocks = pool->blocks;
else {
BLOCK *p = pool->blocks;
@@ -6181,8 +6532,7 @@ poolClear(STRING_POOL *pool)
}
static void FASTCALL
-poolDestroy(STRING_POOL *pool)
-{
+poolDestroy(STRING_POOL *pool) {
BLOCK *p = pool->blocks;
while (p) {
BLOCK *tem = p->next;
@@ -6198,26 +6548,26 @@ poolDestroy(STRING_POOL *pool)
}
static XML_Char *
-poolAppend(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end)
-{
- if (!pool->ptr && !poolGrow(pool))
+poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
+ const char *end) {
+ if (! pool->ptr && ! poolGrow(pool))
return NULL;
for (;;) {
- const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
- if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
+ const enum XML_Convert_Result convert_res = XmlConvert(
+ enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+ if ((convert_res == XML_CONVERT_COMPLETED)
+ || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
- if (!poolGrow(pool))
+ if (! poolGrow(pool))
return NULL;
}
return pool->start;
}
-static const XML_Char * FASTCALL
-poolCopyString(STRING_POOL *pool, const XML_Char *s)
-{
+static const XML_Char *FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s) {
do {
- if (!poolAppendChar(pool, *s))
+ if (! poolAppendChar(pool, *s))
return NULL;
} while (*s++);
s = pool->start;
@@ -6226,12 +6576,23 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s)
}
static const XML_Char *
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
-{
- if (!pool->ptr && !poolGrow(pool))
- return NULL;
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
+ if (! pool->ptr && ! poolGrow(pool)) {
+ /* The following line is unreachable given the current usage of
+ * poolCopyStringN(). Currently it is called from exactly one
+ * place to copy the text of a simple general entity. By that
+ * point, the name of the entity is already stored in the pool, so
+ * pool->ptr cannot be NULL.
+ *
+ * If poolCopyStringN() is used elsewhere as it well might be,
+ * this line may well become executable again. Regardless, this
+ * sort of check shouldn't be removed lightly, so we just exclude
+ * it from the coverage statistics.
+ */
+ return NULL; /* LCOV_EXCL_LINE */
+ }
for (; n > 0; --n, s++) {
- if (!poolAppendChar(pool, *s))
+ if (! poolAppendChar(pool, *s))
return NULL;
}
s = pool->start;
@@ -6239,11 +6600,10 @@ poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
return s;
}
-static const XML_Char * FASTCALL
-poolAppendString(STRING_POOL *pool, const XML_Char *s)
-{
+static const XML_Char *FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s) {
while (*s) {
- if (!poolAppendChar(pool, *s))
+ if (! poolAppendChar(pool, *s))
return NULL;
s++;
}
@@ -6251,20 +6611,46 @@ poolAppendString(STRING_POOL *pool, const XML_Char *s)
}
static XML_Char *
-poolStoreString(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end)
-{
- if (!poolAppend(pool, enc, ptr, end))
+poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
+ const char *end) {
+ if (! poolAppend(pool, enc, ptr, end))
return NULL;
- if (pool->ptr == pool->end && !poolGrow(pool))
+ if (pool->ptr == pool->end && ! poolGrow(pool))
return NULL;
*(pool->ptr)++ = 0;
return pool->start;
}
+static size_t
+poolBytesToAllocateFor(int blockSize) {
+ /* Unprotected math would be:
+ ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
+ **
+ ** Detect overflow, avoiding _signed_ overflow undefined behavior
+ ** For a + b * c we check b * c in isolation first, so that addition of a
+ ** on top has no chance of making us accept a small non-negative number
+ */
+ const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
+
+ if (blockSize <= 0)
+ return 0;
+
+ if (blockSize > (int)(INT_MAX / stretch))
+ return 0;
+
+ {
+ const int stretchedBlockSize = blockSize * (int)stretch;
+ const int bytesToAllocate
+ = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
+ if (bytesToAllocate < 0)
+ return 0;
+
+ return (size_t)bytesToAllocate;
+ }
+}
+
static XML_Bool FASTCALL
-poolGrow(STRING_POOL *pool)
-{
+poolGrow(STRING_POOL *pool) {
if (pool->freeBlocks) {
if (pool->start == 0) {
pool->blocks = pool->freeBlocks;
@@ -6290,44 +6676,76 @@ poolGrow(STRING_POOL *pool)
}
if (pool->blocks && pool->start == pool->blocks->s) {
BLOCK *temp;
- int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
+ int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
+ size_t bytesToAllocate;
+
+ /* NOTE: Needs to be calculated prior to calling `realloc`
+ to avoid dangling pointers: */
+ const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
+
+ if (blockSize < 0) {
+ /* This condition traps a situation where either more than
+ * INT_MAX/2 bytes have already been allocated. This isn't
+ * readily testable, since it is unlikely that an average
+ * machine will have that much memory, so we exclude it from the
+ * coverage statistics.
+ */
+ return XML_FALSE; /* LCOV_EXCL_LINE */
+ }
- if (blockSize < 0)
+ bytesToAllocate = poolBytesToAllocateFor(blockSize);
+ if (bytesToAllocate == 0)
return XML_FALSE;
- temp = (BLOCK *)
- pool->mem->realloc_fcn(pool->blocks,
- (offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char)));
+ temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
+ (unsigned)bytesToAllocate);
if (temp == NULL)
return XML_FALSE;
pool->blocks = temp;
pool->blocks->size = blockSize;
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+ pool->ptr = pool->blocks->s + offsetInsideBlock;
pool->start = pool->blocks->s;
pool->end = pool->start + blockSize;
- }
- else {
+ } else {
BLOCK *tem;
int blockSize = (int)(pool->end - pool->start);
-
- if (blockSize < 0)
- return XML_FALSE;
+ size_t bytesToAllocate;
+
+ if (blockSize < 0) {
+ /* This condition traps a situation where either more than
+ * INT_MAX bytes have already been allocated (which is prevented
+ * by various pieces of program logic, not least this one, never
+ * mind the unlikelihood of actually having that much memory) or
+ * the pool control fields have been corrupted (which could
+ * conceivably happen in an extremely buggy user handler
+ * function). Either way it isn't readily testable, so we
+ * exclude it from the coverage statistics.
+ */
+ return XML_FALSE; /* LCOV_EXCL_LINE */
+ }
if (blockSize < INIT_BLOCK_SIZE)
blockSize = INIT_BLOCK_SIZE;
- else
+ else {
+ /* Detect overflow, avoiding _signed_ overflow undefined behavior */
+ if ((int)((unsigned)blockSize * 2U) < 0) {
+ return XML_FALSE;
+ }
blockSize *= 2;
- tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char));
- if (!tem)
+ }
+
+ bytesToAllocate = poolBytesToAllocateFor(blockSize);
+ if (bytesToAllocate == 0)
+ return XML_FALSE;
+
+ tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
+ if (! tem)
return XML_FALSE;
tem->size = blockSize;
tem->next = pool->blocks;
pool->blocks = tem;
if (pool->ptr != pool->start)
- memcpy(tem->s, pool->start,
- (pool->ptr - pool->start) * sizeof(XML_Char));
+ memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
pool->ptr = tem->s + (pool->ptr - pool->start);
pool->start = tem->s;
pool->end = tem->s + blockSize;
@@ -6336,15 +6754,14 @@ poolGrow(STRING_POOL *pool)
}
static int FASTCALL
-nextScaffoldPart(XML_Parser parser)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
- CONTENT_SCAFFOLD * me;
+nextScaffoldPart(XML_Parser parser) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
+ CONTENT_SCAFFOLD *me;
int next;
- if (!dtd->scaffIndex) {
- dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
- if (!dtd->scaffIndex)
+ if (! dtd->scaffIndex) {
+ dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
+ if (! dtd->scaffIndex)
return -1;
dtd->scaffIndex[0] = 0;
}
@@ -6352,15 +6769,14 @@ nextScaffoldPart(XML_Parser parser)
if (dtd->scaffCount >= dtd->scaffSize) {
CONTENT_SCAFFOLD *temp;
if (dtd->scaffold) {
- temp = (CONTENT_SCAFFOLD *)
- REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
+ temp = (CONTENT_SCAFFOLD *)REALLOC(
+ parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
if (temp == NULL)
return -1;
dtd->scaffSize *= 2;
- }
- else {
- temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
- * sizeof(CONTENT_SCAFFOLD));
+ } else {
+ temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
+ * sizeof(CONTENT_SCAFFOLD));
if (temp == NULL)
return -1;
dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
@@ -6370,11 +6786,12 @@ nextScaffoldPart(XML_Parser parser)
next = dtd->scaffCount++;
me = &dtd->scaffold[next];
if (dtd->scaffLevel) {
- CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
+ CONTENT_SCAFFOLD *parent
+ = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
if (parent->lastchild) {
dtd->scaffold[parent->lastchild].nextsib = next;
}
- if (!parent->childcnt)
+ if (! parent->childcnt)
parent->firstchild = next;
parent->lastchild = next;
parent->childcnt++;
@@ -6384,13 +6801,9 @@ nextScaffoldPart(XML_Parser parser)
}
static void
-build_node(XML_Parser parser,
- int src_node,
- XML_Content *dest,
- XML_Content **contpos,
- XML_Char **strpos)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+build_node(XML_Parser parser, int src_node, XML_Content *dest,
+ XML_Content **contpos, XML_Char **strpos) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
dest->type = dtd->scaffold[src_node].type;
dest->quant = dtd->scaffold[src_node].quant;
if (dest->type == XML_CTYPE_NAME) {
@@ -6399,21 +6812,19 @@ build_node(XML_Parser parser,
src = dtd->scaffold[src_node].name;
for (;;) {
*(*strpos)++ = *src;
- if (!*src)
+ if (! *src)
break;
src++;
}
dest->numchildren = 0;
dest->children = NULL;
- }
- else {
+ } else {
unsigned int i;
int cn;
dest->numchildren = dtd->scaffold[src_node].childcnt;
dest->children = *contpos;
*contpos += dest->numchildren;
- for (i = 0, cn = dtd->scaffold[src_node].firstchild;
- i < dest->numchildren;
+ for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren;
i++, cn = dtd->scaffold[cn].nextsib) {
build_node(parser, cn, &(dest->children[i]), contpos, strpos);
}
@@ -6422,20 +6833,19 @@ build_node(XML_Parser parser,
}
static XML_Content *
-build_model (XML_Parser parser)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+build_model(XML_Parser parser) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
XML_Content *ret;
XML_Content *cpos;
- XML_Char * str;
+ XML_Char *str;
int allocsize = (dtd->scaffCount * sizeof(XML_Content)
+ (dtd->contentStringLen * sizeof(XML_Char)));
- ret = (XML_Content *)MALLOC(allocsize);
- if (!ret)
+ ret = (XML_Content *)MALLOC(parser, allocsize);
+ if (! ret)
return NULL;
- str = (XML_Char *) (&ret[dtd->scaffCount]);
+ str = (XML_Char *)(&ret[dtd->scaffCount]);
cpos = &ret[1];
build_node(parser, 0, ret, &cpos, &str);
@@ -6443,26 +6853,45 @@ build_model (XML_Parser parser)
}
static ELEMENT_TYPE *
-getElementType(XML_Parser parser,
- const ENCODING *enc,
- const char *ptr,
- const char *end)
-{
- DTD * const dtd = _dtd; /* save one level of indirection */
+getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
+ const char *end) {
+ DTD *const dtd = parser->m_dtd; /* save one level of indirection */
const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
ELEMENT_TYPE *ret;
- if (!name)
+ if (! name)
return NULL;
- ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
- if (!ret)
+ ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
+ sizeof(ELEMENT_TYPE));
+ if (! ret)
return NULL;
if (ret->name != name)
poolDiscard(&dtd->pool);
else {
poolFinish(&dtd->pool);
- if (!setElementTypePrefix(parser, ret))
+ if (! setElementTypePrefix(parser, ret))
return NULL;
}
return ret;
}
+
+static XML_Char *
+copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
+ int charsRequired = 0;
+ XML_Char *result;
+
+ /* First determine how long the string is */
+ while (s[charsRequired] != 0) {
+ charsRequired++;
+ }
+ /* Include the terminator */
+ charsRequired++;
+
+ /* Now allocate space for the copy */
+ result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
+ if (result == NULL)
+ return NULL;
+ /* Copy the original into place */
+ memcpy(result, s, charsRequired * sizeof(XML_Char));
+ return result;
+}
diff --git a/freebsd/contrib/expat/lib/xmlrole.c b/freebsd/contrib/expat/lib/xmlrole.c
index 3accd40d..0832e1d0 100644
--- a/freebsd/contrib/expat/lib/xmlrole.c
+++ b/freebsd/contrib/expat/lib/xmlrole.c
@@ -1,24 +1,46 @@
#include <machine/rtems-bsd-user-space.h>
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stddef.h>
-#ifdef WIN32
-#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
+#ifdef _WIN32
+# include "winconfig.h"
#else
-#ifdef HAVE_EXPAT_CONFIG_H
-#include <expat_config.h>
-#endif
-#endif /* ndef WIN32 */
+# ifdef HAVE_EXPAT_CONFIG_H
+# include <expat_config.h>
+# endif
+#endif /* ndef _WIN32 */
#include "expat_external.h"
#include "internal.h"
@@ -32,107 +54,88 @@
*/
-static const char KW_ANY[] = {
- ASCII_A, ASCII_N, ASCII_Y, '\0' };
-static const char KW_ATTLIST[] = {
- ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
-static const char KW_CDATA[] = {
- ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_DOCTYPE[] = {
- ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
-static const char KW_ELEMENT[] = {
- ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
-static const char KW_EMPTY[] = {
- ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
-static const char KW_ENTITIES[] = {
- ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
- '\0' };
-static const char KW_ENTITY[] = {
- ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
-static const char KW_FIXED[] = {
- ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
-static const char KW_ID[] = {
- ASCII_I, ASCII_D, '\0' };
-static const char KW_IDREF[] = {
- ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
-static const char KW_IDREFS[] = {
- ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+static const char KW_ANY[] = {ASCII_A, ASCII_N, ASCII_Y, '\0'};
+static const char KW_ATTLIST[]
+ = {ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0'};
+static const char KW_CDATA[]
+ = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
+static const char KW_DOCTYPE[]
+ = {ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0'};
+static const char KW_ELEMENT[]
+ = {ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0'};
+static const char KW_EMPTY[]
+ = {ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0'};
+static const char KW_ENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
+ ASCII_I, ASCII_E, ASCII_S, '\0'};
+static const char KW_ENTITY[]
+ = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
+static const char KW_FIXED[]
+ = {ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0'};
+static const char KW_ID[] = {ASCII_I, ASCII_D, '\0'};
+static const char KW_IDREF[]
+ = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
+static const char KW_IDREFS[]
+ = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
#ifdef XML_DTD
-static const char KW_IGNORE[] = {
- ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+static const char KW_IGNORE[]
+ = {ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0'};
#endif
-static const char KW_IMPLIED[] = {
- ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_IMPLIED[]
+ = {ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0'};
#ifdef XML_DTD
-static const char KW_INCLUDE[] = {
- ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_INCLUDE[]
+ = {ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0'};
#endif
-static const char KW_NDATA[] = {
- ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_NMTOKEN[] = {
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
-static const char KW_NMTOKENS[] = {
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,
- '\0' };
-static const char KW_NOTATION[] =
- { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,
- '\0' };
-static const char KW_PCDATA[] = {
- ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_PUBLIC[] = {
- ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
-static const char KW_REQUIRED[] = {
- ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,
- '\0' };
-static const char KW_SYSTEM[] = {
- ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+static const char KW_NDATA[]
+ = {ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
+static const char KW_NMTOKEN[]
+ = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
+static const char KW_NMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
+ ASCII_E, ASCII_N, ASCII_S, '\0'};
+static const char KW_NOTATION[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
+ ASCII_I, ASCII_O, ASCII_N, '\0'};
+static const char KW_PCDATA[]
+ = {ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
+static const char KW_PUBLIC[]
+ = {ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0'};
+static const char KW_REQUIRED[] = {ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I,
+ ASCII_R, ASCII_E, ASCII_D, '\0'};
+static const char KW_SYSTEM[]
+ = {ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0'};
#ifndef MIN_BYTES_PER_CHAR
-#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+# define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
#endif
#ifdef XML_DTD
-#define setTopLevel(state) \
- ((state)->handler = ((state)->documentEntity \
- ? internalSubset \
- : externalSubset1))
+# define setTopLevel(state) \
+ ((state)->handler \
+ = ((state)->documentEntity ? internalSubset : externalSubset1))
#else /* not XML_DTD */
-#define setTopLevel(state) ((state)->handler = internalSubset)
+# define setTopLevel(state) ((state)->handler = internalSubset)
#endif /* not XML_DTD */
-typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
+typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok,
+ const char *ptr, const char *end,
const ENCODING *enc);
-static PROLOG_HANDLER
- prolog0, prolog1, prolog2,
- doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
- internalSubset,
- entity0, entity1, entity2, entity3, entity4, entity5, entity6,
- entity7, entity8, entity9, entity10,
- notation0, notation1, notation2, notation3, notation4,
- attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
- attlist7, attlist8, attlist9,
- element0, element1, element2, element3, element4, element5, element6,
- element7,
+static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2,
+ doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2,
+ entity3, entity4, entity5, entity6, entity7, entity8, entity9, entity10,
+ notation0, notation1, notation2, notation3, notation4, attlist0, attlist1,
+ attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8,
+ attlist9, element0, element1, element2, element3, element4, element5,
+ element6, element7,
#ifdef XML_DTD
- externalSubset0, externalSubset1,
- condSect0, condSect1, condSect2,
+ externalSubset0, externalSubset1, condSect0, condSect1, condSect2,
#endif /* XML_DTD */
- declClose,
- error;
+ declClose, error;
static int FASTCALL common(PROLOG_STATE *state, int tok);
static int PTRCALL
-prolog0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
state->handler = prolog1;
@@ -149,10 +152,8 @@ prolog0(PROLOG_STATE *state,
case XML_TOK_BOM:
return XML_ROLE_NONE;
case XML_TOK_DECL_OPEN:
- if (!XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_DOCTYPE))
+ if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
+ KW_DOCTYPE))
break;
state->handler = doctype0;
return XML_ROLE_DOCTYPE_NONE;
@@ -164,12 +165,8 @@ prolog0(PROLOG_STATE *state,
}
static int PTRCALL
-prolog1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
@@ -178,12 +175,17 @@ prolog1(PROLOG_STATE *state,
case XML_TOK_COMMENT:
return XML_ROLE_COMMENT;
case XML_TOK_BOM:
- return XML_ROLE_NONE;
+ /* This case can never arise. To reach this role function, the
+ * parse must have passed through prolog0 and therefore have had
+ * some form of input, even if only a space. At that point, a
+ * byte order mark is no longer a valid character (though
+ * technically it should be interpreted as a non-breaking space),
+ * so will be rejected by the tokenizing stages.
+ */
+ return XML_ROLE_NONE; /* LCOV_EXCL_LINE */
case XML_TOK_DECL_OPEN:
- if (!XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_DOCTYPE))
+ if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
+ KW_DOCTYPE))
break;
state->handler = doctype0;
return XML_ROLE_DOCTYPE_NONE;
@@ -195,12 +197,11 @@ prolog1(PROLOG_STATE *state,
}
static int PTRCALL
-prolog2(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
@@ -216,12 +217,11 @@ prolog2(PROLOG_STATE *state,
}
static int PTRCALL
-doctype0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
@@ -234,12 +234,8 @@ doctype0(PROLOG_STATE *state,
}
static int PTRCALL
-doctype1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
@@ -264,12 +260,11 @@ doctype1(PROLOG_STATE *state,
}
static int PTRCALL
-doctype2(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
@@ -281,12 +276,11 @@ doctype2(PROLOG_STATE *state,
}
static int PTRCALL
-doctype3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
@@ -298,12 +292,11 @@ doctype3(PROLOG_STATE *state,
}
static int PTRCALL
-doctype4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
@@ -318,12 +311,11 @@ doctype4(PROLOG_STATE *state,
}
static int PTRCALL
-doctype5(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
@@ -335,40 +327,28 @@ doctype5(PROLOG_STATE *state,
}
static int PTRCALL
-internalSubset(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
case XML_TOK_DECL_OPEN:
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
+ if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
KW_ENTITY)) {
state->handler = entity0;
return XML_ROLE_ENTITY_NONE;
}
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
+ if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
KW_ATTLIST)) {
state->handler = attlist0;
return XML_ROLE_ATTLIST_NONE;
}
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
+ if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
KW_ELEMENT)) {
state->handler = element0;
return XML_ROLE_ELEMENT_NONE;
}
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
+ if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
KW_NOTATION)) {
state->handler = notation0;
return XML_ROLE_NOTATION_NONE;
@@ -392,12 +372,8 @@ internalSubset(PROLOG_STATE *state,
#ifdef XML_DTD
static int PTRCALL
-externalSubset0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
state->handler = externalSubset1;
if (tok == XML_TOK_XML_DECL)
return XML_ROLE_TEXT_DECL;
@@ -405,12 +381,8 @@ externalSubset0(PROLOG_STATE *state,
}
static int PTRCALL
-externalSubset1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_COND_SECT_OPEN:
state->handler = condSect0;
@@ -437,12 +409,11 @@ externalSubset1(PROLOG_STATE *state,
#endif /* XML_DTD */
static int PTRCALL
-entity0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -457,12 +428,11 @@ entity0(PROLOG_STATE *state,
}
static int PTRCALL
-entity1(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -474,12 +444,8 @@ entity1(PROLOG_STATE *state,
}
static int PTRCALL
-entity2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -502,12 +468,11 @@ entity2(PROLOG_STATE *state,
}
static int PTRCALL
-entity3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -519,12 +484,11 @@ entity3(PROLOG_STATE *state,
}
static int PTRCALL
-entity4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -536,12 +500,8 @@ entity4(PROLOG_STATE *state,
}
static int PTRCALL
-entity5(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -559,12 +519,11 @@ entity5(PROLOG_STATE *state,
}
static int PTRCALL
-entity6(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -577,12 +536,8 @@ entity6(PROLOG_STATE *state,
}
static int PTRCALL
-entity7(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -605,12 +560,11 @@ entity7(PROLOG_STATE *state,
}
static int PTRCALL
-entity8(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -622,12 +576,11 @@ entity8(PROLOG_STATE *state,
}
static int PTRCALL
-entity9(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -639,12 +592,11 @@ entity9(PROLOG_STATE *state,
}
static int PTRCALL
-entity10(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
@@ -656,12 +608,11 @@ entity10(PROLOG_STATE *state,
}
static int PTRCALL
-notation0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
@@ -673,12 +624,8 @@ notation0(PROLOG_STATE *state,
}
static int PTRCALL
-notation1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
@@ -697,12 +644,11 @@ notation1(PROLOG_STATE *state,
}
static int PTRCALL
-notation2(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
@@ -714,12 +660,11 @@ notation2(PROLOG_STATE *state,
}
static int PTRCALL
-notation3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
@@ -732,12 +677,11 @@ notation3(PROLOG_STATE *state,
}
static int PTRCALL
-notation4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
@@ -753,12 +697,11 @@ notation4(PROLOG_STATE *state,
}
static int PTRCALL
-attlist0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
@@ -771,12 +714,11 @@ attlist0(PROLOG_STATE *state,
}
static int PTRCALL
-attlist1(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
@@ -792,34 +734,23 @@ attlist1(PROLOG_STATE *state,
}
static int PTRCALL
-attlist2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- {
- static const char * const types[] = {
- KW_CDATA,
- KW_ID,
- KW_IDREF,
- KW_IDREFS,
- KW_ENTITY,
- KW_ENTITIES,
- KW_NMTOKEN,
- KW_NMTOKENS,
- };
- int i;
- for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
- if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
- state->handler = attlist8;
- return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
- }
- }
+ case XML_TOK_NAME: {
+ static const char *const types[] = {
+ KW_CDATA, KW_ID, KW_IDREF, KW_IDREFS,
+ KW_ENTITY, KW_ENTITIES, KW_NMTOKEN, KW_NMTOKENS,
+ };
+ int i;
+ for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++)
+ if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+ state->handler = attlist8;
+ return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+ }
+ }
if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
state->handler = attlist5;
return XML_ROLE_ATTLIST_NONE;
@@ -833,12 +764,11 @@ attlist2(PROLOG_STATE *state,
}
static int PTRCALL
-attlist3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
@@ -852,12 +782,11 @@ attlist3(PROLOG_STATE *state,
}
static int PTRCALL
-attlist4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
@@ -872,12 +801,11 @@ attlist4(PROLOG_STATE *state,
}
static int PTRCALL
-attlist5(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
@@ -889,12 +817,11 @@ attlist5(PROLOG_STATE *state,
}
static int PTRCALL
-attlist6(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
@@ -906,12 +833,11 @@ attlist6(PROLOG_STATE *state,
}
static int PTRCALL
-attlist7(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
@@ -927,33 +853,23 @@ attlist7(PROLOG_STATE *state,
/* default value */
static int PTRCALL
-attlist8(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_POUND_NAME:
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
+ if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
KW_IMPLIED)) {
state->handler = attlist1;
return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
}
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
+ if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
KW_REQUIRED)) {
state->handler = attlist1;
return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
}
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
+ if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
KW_FIXED)) {
state->handler = attlist9;
return XML_ROLE_ATTLIST_NONE;
@@ -967,12 +883,11 @@ attlist8(PROLOG_STATE *state,
}
static int PTRCALL
-attlist9(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
@@ -984,12 +899,11 @@ attlist9(PROLOG_STATE *state,
}
static int PTRCALL
-element0(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
@@ -1002,12 +916,8 @@ element0(PROLOG_STATE *state,
}
static int PTRCALL
-element1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
@@ -1032,19 +942,13 @@ element1(PROLOG_STATE *state,
}
static int PTRCALL
-element2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
case XML_TOK_POUND_NAME:
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
+ if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
KW_PCDATA)) {
state->handler = element3;
return XML_ROLE_CONTENT_PCDATA;
@@ -1072,12 +976,11 @@ element2(PROLOG_STATE *state,
}
static int PTRCALL
-element3(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
@@ -1097,12 +1000,11 @@ element3(PROLOG_STATE *state,
}
static int PTRCALL
-element4(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
@@ -1115,12 +1017,11 @@ element4(PROLOG_STATE *state,
}
static int PTRCALL
-element5(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
@@ -1136,12 +1037,11 @@ element5(PROLOG_STATE *state,
}
static int PTRCALL
-element6(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
@@ -1166,12 +1066,11 @@ element6(PROLOG_STATE *state,
}
static int PTRCALL
-element7(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
@@ -1216,12 +1115,8 @@ element7(PROLOG_STATE *state,
#ifdef XML_DTD
static int PTRCALL
-condSect0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
+condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
@@ -1240,12 +1135,11 @@ condSect0(PROLOG_STATE *state,
}
static int PTRCALL
-condSect1(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
@@ -1258,12 +1152,11 @@ condSect1(PROLOG_STATE *state,
}
static int PTRCALL
-condSect2(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
@@ -1277,12 +1170,11 @@ condSect2(PROLOG_STATE *state,
#endif /* XML_DTD */
static int PTRCALL
-declClose(PROLOG_STATE *state,
- int tok,
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
switch (tok) {
case XML_TOK_PROLOG_S:
return state->role_none;
@@ -1293,21 +1185,42 @@ declClose(PROLOG_STATE *state,
return common(state, tok);
}
+/* This function will only be invoked if the internal logic of the
+ * parser has broken down. It is used in two cases:
+ *
+ * 1: When the XML prolog has been finished. At this point the
+ * processor (the parser level above these role handlers) should
+ * switch from prologProcessor to contentProcessor and reinitialise
+ * the handler function.
+ *
+ * 2: When an error has been detected (via common() below). At this
+ * point again the processor should be switched to errorProcessor,
+ * which will never call a handler.
+ *
+ * The result of this is that error() can only be called if the
+ * processor switch failed to happen, which is an internal error and
+ * therefore we shouldn't be able to provoke it simply by using the
+ * library. It is a necessary backstop, however, so we merely exclude
+ * it from the coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
static int PTRCALL
-error(PROLOG_STATE *UNUSED_P(state),
- int UNUSED_P(tok),
- const char *UNUSED_P(ptr),
- const char *UNUSED_P(end),
- const ENCODING *UNUSED_P(enc))
-{
+error(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
+ const ENCODING *enc) {
+ UNUSED_P(state);
+ UNUSED_P(tok);
+ UNUSED_P(ptr);
+ UNUSED_P(end);
+ UNUSED_P(enc);
return XML_ROLE_NONE;
}
+/* LCOV_EXCL_STOP */
static int FASTCALL
-common(PROLOG_STATE *state, int tok)
-{
+common(PROLOG_STATE *state, int tok) {
#ifdef XML_DTD
- if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+ if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
return XML_ROLE_INNER_PARAM_ENTITY_REF;
#endif
state->handler = error;
@@ -1315,8 +1228,7 @@ common(PROLOG_STATE *state, int tok)
}
void
-XmlPrologStateInit(PROLOG_STATE *state)
-{
+XmlPrologStateInit(PROLOG_STATE *state) {
state->handler = prolog0;
#ifdef XML_DTD
state->documentEntity = 1;
@@ -1328,8 +1240,7 @@ XmlPrologStateInit(PROLOG_STATE *state)
#ifdef XML_DTD
void
-XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
-{
+XmlPrologStateInitExternalEntity(PROLOG_STATE *state) {
state->handler = externalSubset0;
state->documentEntity = 0;
state->includeLevel = 0;
diff --git a/freebsd/contrib/expat/lib/xmlrole.h b/freebsd/contrib/expat/lib/xmlrole.h
index 4dd9f06f..036aba64 100644
--- a/freebsd/contrib/expat/lib/xmlrole.h
+++ b/freebsd/contrib/expat/lib/xmlrole.h
@@ -1,5 +1,33 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef XmlRole_INCLUDED
@@ -8,7 +36,7 @@
#ifdef __VMS
/* 0 1 2 3 0 1 2 3
1234567890123456789012345678901 1234567890123456789012345678901 */
-#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
+# define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
#endif
#include "xmltok.h"
@@ -85,11 +113,8 @@ enum {
};
typedef struct prolog_state {
- int (PTRCALL *handler) (struct prolog_state *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc);
+ int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr,
+ const char *end, const ENCODING *enc);
unsigned level;
int role_none;
#ifdef XML_DTD
@@ -104,8 +129,8 @@ void XmlPrologStateInit(PROLOG_STATE *);
void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
#endif /* XML_DTD */
-#define XmlTokenRole(state, tok, ptr, end, enc) \
- (((state)->handler)(state, tok, ptr, end, enc))
+#define XmlTokenRole(state, tok, ptr, end, enc) \
+ (((state)->handler)(state, tok, ptr, end, enc))
#ifdef __cplusplus
}
diff --git a/freebsd/contrib/expat/lib/xmltok.c b/freebsd/contrib/expat/lib/xmltok.c
index fe9d3450..7e6a2c2f 100644
--- a/freebsd/contrib/expat/lib/xmltok.c
+++ b/freebsd/contrib/expat/lib/xmltok.c
@@ -1,24 +1,56 @@
#include <machine/rtems-bsd-user-space.h>
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stddef.h>
+#include <string.h> /* memcpy */
-#ifdef WIN32
-#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
+#if defined(_MSC_VER) && (_MSC_VER <= 1700)
+/* for vs2012/11.0/1700 and earlier Visual Studio compilers */
+# define bool int
+# define false 0
+# define true 1
#else
-#ifdef HAVE_EXPAT_CONFIG_H
-#include <expat_config.h>
+# include <stdbool.h>
#endif
-#endif /* ndef WIN32 */
+
+#ifdef _WIN32
+# include "winconfig.h"
+#else
+# ifdef HAVE_EXPAT_CONFIG_H
+# include <expat_config.h>
+# endif
+#endif /* ndef _WIN32 */
#include "expat_external.h"
#include "internal.h"
@@ -26,59 +58,49 @@
#include "nametab.h"
#ifdef XML_DTD
-#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+# define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
#else
-#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+# define IGNORE_SECTION_TOK_VTABLE /* as nothing */
#endif
-#define VTABLE1 \
- { PREFIX(prologTok), PREFIX(contentTok), \
- PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
- { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
- PREFIX(sameName), \
- PREFIX(nameMatchesAscii), \
- PREFIX(nameLength), \
- PREFIX(skipS), \
- PREFIX(getAtts), \
- PREFIX(charRefNumber), \
- PREFIX(predefinedEntityName), \
- PREFIX(updatePosition), \
- PREFIX(isPublicId)
+#define VTABLE1 \
+ {PREFIX(prologTok), PREFIX(contentTok), \
+ PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE}, \
+ {PREFIX(attributeValueTok), PREFIX(entityValueTok)}, \
+ PREFIX(nameMatchesAscii), PREFIX(nameLength), PREFIX(skipS), \
+ PREFIX(getAtts), PREFIX(charRefNumber), PREFIX(predefinedEntityName), \
+ PREFIX(updatePosition), PREFIX(isPublicId)
#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
-#define UCS2_GET_NAMING(pages, hi, lo) \
- (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
+#define UCS2_GET_NAMING(pages, hi, lo) \
+ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo)&0x1F)))
/* A 2 byte UTF-8 representation splits the characters 11 bits between
the bottom 5 and 6 bits of the bytes. We need 8 bits to index into
pages, 3 bits to add to that index and 5 bits to generate the mask.
*/
-#define UTF8_GET_NAMING2(pages, byte) \
- (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
- + ((((byte)[0]) & 3) << 1) \
- + ((((byte)[1]) >> 5) & 1)] \
- & (1u << (((byte)[1]) & 0x1F)))
+#define UTF8_GET_NAMING2(pages, byte) \
+ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+ + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)] \
+ & (1u << (((byte)[1]) & 0x1F)))
/* A 3 byte UTF-8 representation splits the characters 16 bits between
the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index
into pages, 3 bits to add to that index and 5 bits to generate the
mask.
*/
-#define UTF8_GET_NAMING3(pages, byte) \
- (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
- + ((((byte)[1]) >> 2) & 0xF)] \
- << 3) \
- + ((((byte)[1]) & 3) << 1) \
- + ((((byte)[2]) >> 5) & 1)] \
- & (1u << (((byte)[2]) & 0x1F)))
-
-#define UTF8_GET_NAMING(pages, p, n) \
- ((n) == 2 \
- ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
- : ((n) == 3 \
- ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
- : 0))
+#define UTF8_GET_NAMING3(pages, byte) \
+ (namingBitmap \
+ [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)] \
+ << 3) \
+ + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \
+ & (1u << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n) \
+ ((n) == 2 \
+ ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+ : ((n) == 3 ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) : 0))
/* Detection of invalid UTF-8 sequences is based on Table 3.1B
of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
@@ -90,88 +112,76 @@
(A & 0xC0) == 0xC0 means A > 0xBF
*/
-#define UTF8_INVALID2(p) \
+#define UTF8_INVALID2(p) \
((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
-#define UTF8_INVALID3(p) \
- (((p)[2] & 0x80) == 0 \
- || \
- ((*p) == 0xEF && (p)[1] == 0xBF \
- ? \
- (p)[2] > 0xBD \
- : \
- ((p)[2] & 0xC0) == 0xC0) \
- || \
- ((*p) == 0xE0 \
- ? \
- (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
- : \
- ((p)[1] & 0x80) == 0 \
- || \
- ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
-
-#define UTF8_INVALID4(p) \
- (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
- || \
- ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
- || \
- ((*p) == 0xF0 \
- ? \
- (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
- : \
- ((p)[1] & 0x80) == 0 \
- || \
- ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
+#define UTF8_INVALID3(p) \
+ (((p)[2] & 0x80) == 0 \
+ || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \
+ : ((p)[2] & 0xC0) == 0xC0) \
+ || ((*p) == 0xE0 \
+ ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
+ : ((p)[1] & 0x80) == 0 \
+ || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
+
+#define UTF8_INVALID4(p) \
+ (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0 \
+ || ((p)[2] & 0xC0) == 0xC0 \
+ || ((*p) == 0xF0 \
+ ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
+ : ((p)[1] & 0x80) == 0 \
+ || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
static int PTRFASTCALL
-isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p))
-{
+isNever(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
+ UNUSED_P(p);
return 0;
}
static int PTRFASTCALL
-utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isName2(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isName3(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
}
#define utf8_isName4 isNever
static int PTRFASTCALL
-utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isNmstrt2(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isNmstrt3(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
}
#define utf8_isNmstrt4 isNever
static int PTRFASTCALL
-utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isInvalid2(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
return UTF8_INVALID2((const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isInvalid3(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
return UTF8_INVALID3((const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p)
-{
+utf8_isInvalid4(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
return UTF8_INVALID4((const unsigned char *)p);
}
@@ -179,61 +189,44 @@ struct normal_encoding {
ENCODING enc;
unsigned char type[256];
#ifdef XML_MIN_SIZE
- int (PTRFASTCALL *byteType)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
- int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
- int (PTRCALL *charMatches)(const ENCODING *, const char *, int);
+ int(PTRFASTCALL *byteType)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
+ int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
+ int(PTRCALL *charMatches)(const ENCODING *, const char *, int);
#endif /* XML_MIN_SIZE */
- int (PTRFASTCALL *isName2)(const ENCODING *, const char *);
- int (PTRFASTCALL *isName3)(const ENCODING *, const char *);
- int (PTRFASTCALL *isName4)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
- int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
- int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
- int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
- int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isName2)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isName3)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isName4)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
+ int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
};
-#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc))
+#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc))
#ifdef XML_MIN_SIZE
-#define STANDARD_VTABLE(E) \
- E ## byteType, \
- E ## isNameMin, \
- E ## isNmstrtMin, \
- E ## byteToAscii, \
- E ## charMatches,
+# define STANDARD_VTABLE(E) \
+ E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches,
#else
-#define STANDARD_VTABLE(E) /* as nothing */
+# define STANDARD_VTABLE(E) /* as nothing */
#endif
-#define NORMAL_VTABLE(E) \
- E ## isName2, \
- E ## isName3, \
- E ## isName4, \
- E ## isNmstrt2, \
- E ## isNmstrt3, \
- E ## isNmstrt4, \
- E ## isInvalid2, \
- E ## isInvalid3, \
- E ## isInvalid4
-
-#define NULL_VTABLE \
- /* isName2 */ NULL, \
- /* isName3 */ NULL, \
- /* isName4 */ NULL, \
- /* isNmstrt2 */ NULL, \
- /* isNmstrt3 */ NULL, \
- /* isNmstrt4 */ NULL, \
- /* isInvalid2 */ NULL, \
- /* isInvalid3 */ NULL, \
- /* isInvalid4 */ NULL
+#define NORMAL_VTABLE(E) \
+ E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \
+ E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4
+
+#define NULL_VTABLE \
+ /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \
+ /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \
+ /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL
static int FASTCALL checkCharRefNumber(int);
@@ -241,75 +234,70 @@ static int FASTCALL checkCharRefNumber(int);
#include "ascii.h"
#ifdef XML_MIN_SIZE
-#define sb_isNameMin isNever
-#define sb_isNmstrtMin isNever
+# define sb_isNameMin isNever
+# define sb_isNmstrtMin isNever
#endif
#ifdef XML_MIN_SIZE
-#define MINBPC(enc) ((enc)->minBytesPerChar)
+# define MINBPC(enc) ((enc)->minBytesPerChar)
#else
/* minimum bytes per character */
-#define MINBPC(enc) 1
+# define MINBPC(enc) 1
#endif
-#define SB_BYTE_TYPE(enc, p) \
+#define SB_BYTE_TYPE(enc, p) \
(((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
-sb_byteType(const ENCODING *enc, const char *p)
-{
+sb_byteType(const ENCODING *enc, const char *p) {
return SB_BYTE_TYPE(enc, p);
}
-#define BYTE_TYPE(enc, p) \
- (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
+# define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
#else
-#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+# define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
#endif
#ifdef XML_MIN_SIZE
-#define BYTE_TO_ASCII(enc, p) \
- (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
+# define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
static int PTRFASTCALL
-sb_byteToAscii(const ENCODING *enc, const char *p)
-{
+sb_byteToAscii(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
return *p;
}
#else
-#define BYTE_TO_ASCII(enc, p) (*(p))
+# define BYTE_TO_ASCII(enc, p) (*(p))
#endif
-#define IS_NAME_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))
-#define IS_NMSTRT_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))
-#define IS_INVALID_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))
+#define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n) \
+ (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
#ifdef XML_MIN_SIZE
-#define IS_NAME_CHAR_MINBPC(enc, p) \
- (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
- (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
+# define IS_NAME_CHAR_MINBPC(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
+# define IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
#else
-#define IS_NAME_CHAR_MINBPC(enc, p) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+# define IS_NAME_CHAR_MINBPC(enc, p) (0)
+# define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
#endif
#ifdef XML_MIN_SIZE
-#define CHAR_MATCHES(enc, p, c) \
- (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
+# define CHAR_MATCHES(enc, p, c) \
+ (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
static int PTRCALL
-sb_charMatches(const ENCODING *enc, const char *p, int c)
-{
+sb_charMatches(const ENCODING *enc, const char *p, int c) {
+ UNUSED_P(enc);
return *p == c;
}
#else
/* c is an ASCII character */
-#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+# define CHAR_MATCHES(enc, p, c) (*(p) == c)
#endif
-#define PREFIX(ident) normal_ ## ident
+#define PREFIX(ident) normal_##ident
#define XML_TOK_IMPL_C
#include "xmltok_impl.c"
#undef XML_TOK_IMPL_C
@@ -324,42 +312,46 @@ sb_charMatches(const ENCODING *enc, const char *p, int c)
#undef IS_NMSTRT_CHAR_MINBPC
#undef IS_INVALID_CHAR
-enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
- UTF8_cval1 = 0x00,
- UTF8_cval2 = 0xc0,
- UTF8_cval3 = 0xe0,
- UTF8_cval4 = 0xf0
+enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
+ UTF8_cval1 = 0x00,
+ UTF8_cval2 = 0xc0,
+ UTF8_cval3 = 0xe0,
+ UTF8_cval4 = 0xf0
};
void
-align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef)
-{
- const char * fromLim = *fromLimRef;
+_INTERNAL_trim_to_complete_utf8_characters(const char *from,
+ const char **fromLimRef) {
+ const char *fromLim = *fromLimRef;
size_t walked = 0;
for (; fromLim > from; fromLim--, walked++) {
const unsigned char prev = (unsigned char)fromLim[-1];
- if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
+ if ((prev & 0xf8u)
+ == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
if (walked + 1 >= 4) {
fromLim += 4 - 1;
break;
} else {
walked = 0;
}
- } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
+ } else if ((prev & 0xf0u)
+ == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
if (walked + 1 >= 3) {
fromLim += 3 - 1;
break;
} else {
walked = 0;
}
- } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
+ } else if ((prev & 0xe0u)
+ == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
if (walked + 1 >= 2) {
fromLim += 2 - 1;
break;
} else {
walked = 0;
}
- } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
+ } else if ((prev & 0x80u)
+ == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
break;
}
}
@@ -367,35 +359,47 @@ align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef)
}
static enum XML_Convert_Result PTRCALL
-utf8_toUtf8(const ENCODING *UNUSED_P(enc),
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
- char *to;
- const char *from;
- if (fromLim - *fromP > toLim - *toP) {
- /* Avoid copying partial characters. */
- res = XML_CONVERT_OUTPUT_EXHAUSTED;
- fromLim = *fromP + (toLim - *toP);
- align_limit_to_full_utf8_characters(*fromP, &fromLim);
+utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
+ char **toP, const char *toLim) {
+ bool input_incomplete = false;
+ bool output_exhausted = false;
+
+ /* Avoid copying partial characters (due to limited space). */
+ const ptrdiff_t bytesAvailable = fromLim - *fromP;
+ const ptrdiff_t bytesStorable = toLim - *toP;
+ UNUSED_P(enc);
+ if (bytesAvailable > bytesStorable) {
+ fromLim = *fromP + bytesStorable;
+ output_exhausted = true;
+ }
+
+ /* Avoid copying partial characters (from incomplete input). */
+ {
+ const char *const fromLimBefore = fromLim;
+ _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim);
+ if (fromLim < fromLimBefore) {
+ input_incomplete = true;
+ }
}
- for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)
- *to = *from;
- *fromP = from;
- *toP = to;
- if ((to == toLim) && (from < fromLim))
+ {
+ const ptrdiff_t bytesToCopy = fromLim - *fromP;
+ memcpy(*toP, *fromP, bytesToCopy);
+ *fromP += bytesToCopy;
+ *toP += bytesToCopy;
+ }
+
+ if (output_exhausted) /* needs to go first */
return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else if (input_incomplete)
+ return XML_CONVERT_INPUT_INCOMPLETE;
else
- return res;
+ return XML_CONVERT_COMPLETED;
}
static enum XML_Convert_Result PTRCALL
-utf8_toUtf16(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
+utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim) {
enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
unsigned short *to = *toP;
const char *from = *fromP;
@@ -404,7 +408,7 @@ utf8_toUtf16(const ENCODING *enc,
case BT_LEAD2:
if (fromLim - from < 2) {
res = XML_CONVERT_INPUT_INCOMPLETE;
- break;
+ goto after;
}
*to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
from += 2;
@@ -412,37 +416,37 @@ utf8_toUtf16(const ENCODING *enc,
case BT_LEAD3:
if (fromLim - from < 3) {
res = XML_CONVERT_INPUT_INCOMPLETE;
- break;
+ goto after;
}
- *to++ = (unsigned short)(((from[0] & 0xf) << 12)
- | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
+ *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6)
+ | (from[2] & 0x3f));
from += 3;
break;
- case BT_LEAD4:
- {
- unsigned long n;
- if (toLim - to < 2) {
- res = XML_CONVERT_OUTPUT_EXHAUSTED;
- goto after;
- }
- if (fromLim - from < 4) {
- res = XML_CONVERT_INPUT_INCOMPLETE;
- goto after;
- }
- n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
- | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
- n -= 0x10000;
- to[0] = (unsigned short)((n >> 10) | 0xD800);
- to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
- to += 2;
- from += 4;
+ case BT_LEAD4: {
+ unsigned long n;
+ if (toLim - to < 2) {
+ res = XML_CONVERT_OUTPUT_EXHAUSTED;
+ goto after;
}
- break;
+ if (fromLim - from < 4) {
+ res = XML_CONVERT_INPUT_INCOMPLETE;
+ goto after;
+ }
+ n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
+ | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+ n -= 0x10000;
+ to[0] = (unsigned short)((n >> 10) | 0xD800);
+ to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+ to += 2;
+ from += 4;
+ } break;
default:
*to++ = *from++;
break;
}
}
+ if (from < fromLim)
+ res = XML_CONVERT_OUTPUT_EXHAUSTED;
after:
*fromP = from;
*toP = to;
@@ -450,56 +454,51 @@ after:
}
#ifdef XML_NS
-static const struct normal_encoding utf8_encoding_ns = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#include "asciitab.h"
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
+static const struct normal_encoding utf8_encoding_ns
+ = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
+ {
+# include "asciitab.h"
+# include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
#endif
-static const struct normal_encoding utf8_encoding = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
+static const struct normal_encoding utf8_encoding
+ = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
+ {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
#ifdef XML_NS
-static const struct normal_encoding internal_utf8_encoding_ns = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#include "iasciitab.h"
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
+static const struct normal_encoding internal_utf8_encoding_ns
+ = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
+ {
+# include "iasciitab.h"
+# include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
#endif
-static const struct normal_encoding internal_utf8_encoding = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
+static const struct normal_encoding internal_utf8_encoding
+ = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
+ {
#define BT_COLON BT_NMSTRT
#include "iasciitab.h"
#undef BT_COLON
#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
static enum XML_Convert_Result PTRCALL
-latin1_toUtf8(const ENCODING *UNUSED_P(enc),
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
+latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
+ char **toP, const char *toLim) {
+ UNUSED_P(enc);
for (;;) {
unsigned char c;
if (*fromP == fromLim)
@@ -511,8 +510,7 @@ latin1_toUtf8(const ENCODING *UNUSED_P(enc),
*(*toP)++ = (char)((c >> 6) | UTF8_cval2);
*(*toP)++ = (char)((c & 0x3f) | 0x80);
(*fromP)++;
- }
- else {
+ } else {
if (*toP == toLim)
return XML_CONVERT_OUTPUT_EXHAUSTED;
*(*toP)++ = *(*fromP)++;
@@ -521,10 +519,9 @@ latin1_toUtf8(const ENCODING *UNUSED_P(enc),
}
static enum XML_Convert_Result PTRCALL
-latin1_toUtf16(const ENCODING *UNUSED_P(enc),
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
+latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim) {
+ UNUSED_P(enc);
while (*fromP < fromLim && *toP < toLim)
*(*toP)++ = (unsigned char)*(*fromP)++;
@@ -536,33 +533,30 @@ latin1_toUtf16(const ENCODING *UNUSED_P(enc),
#ifdef XML_NS
-static const struct normal_encoding latin1_encoding_ns = {
- { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(sb_) NULL_VTABLE
-};
+static const struct normal_encoding latin1_encoding_ns
+ = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0},
+ {
+# include "asciitab.h"
+# include "latin1tab.h"
+ },
+ STANDARD_VTABLE(sb_) NULL_VTABLE};
#endif
-static const struct normal_encoding latin1_encoding = {
- { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
- {
+static const struct normal_encoding latin1_encoding
+ = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0},
+ {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
- },
- STANDARD_VTABLE(sb_) NULL_VTABLE
-};
+ },
+ STANDARD_VTABLE(sb_) NULL_VTABLE};
static enum XML_Convert_Result PTRCALL
-ascii_toUtf8(const ENCODING *UNUSED_P(enc),
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
+ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
+ char **toP, const char *toLim) {
+ UNUSED_P(enc);
while (*fromP < fromLim && *toP < toLim)
*(*toP)++ = *(*fromP)++;
@@ -574,40 +568,45 @@ ascii_toUtf8(const ENCODING *UNUSED_P(enc),
#ifdef XML_NS
-static const struct normal_encoding ascii_encoding_ns = {
- { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
- {
-#include "asciitab.h"
-/* BT_NONXML == 0 */
- },
- STANDARD_VTABLE(sb_) NULL_VTABLE
-};
+static const struct normal_encoding ascii_encoding_ns
+ = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0},
+ {
+# include "asciitab.h"
+ /* BT_NONXML == 0 */
+ },
+ STANDARD_VTABLE(sb_) NULL_VTABLE};
#endif
-static const struct normal_encoding ascii_encoding = {
- { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
- {
+static const struct normal_encoding ascii_encoding
+ = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0},
+ {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
-/* BT_NONXML == 0 */
- },
- STANDARD_VTABLE(sb_) NULL_VTABLE
-};
+ /* BT_NONXML == 0 */
+ },
+ STANDARD_VTABLE(sb_) NULL_VTABLE};
static int PTRFASTCALL
-unicode_byte_type(char hi, char lo)
-{
+unicode_byte_type(char hi, char lo) {
switch ((unsigned char)hi) {
- case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+ /* 0xD800–0xDBFF first 16-bit code unit or high surrogate (W1) */
+ case 0xD8:
+ case 0xD9:
+ case 0xDA:
+ case 0xDB:
return BT_LEAD4;
- case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ /* 0xDC00–0xDFFF second 16-bit code unit or low surrogate (W2) */
+ case 0xDC:
+ case 0xDD:
+ case 0xDE:
+ case 0xDF:
return BT_TRAIL;
case 0xFF:
switch ((unsigned char)lo) {
- case 0xFF:
- case 0xFE:
+ case 0xFF: /* noncharacter-FFFF */
+ case 0xFE: /* noncharacter-FFFE */
return BT_NONXML;
}
break;
@@ -615,102 +614,105 @@ unicode_byte_type(char hi, char lo)
return BT_NONASCII;
}
-#define DEFINE_UTF16_TO_UTF8(E) \
-static enum XML_Convert_Result PTRCALL \
-E ## toUtf8(const ENCODING *UNUSED_P(enc), \
- const char **fromP, const char *fromLim, \
- char **toP, const char *toLim) \
-{ \
- const char *from = *fromP; \
- fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \
- for (; from < fromLim; from += 2) { \
- int plane; \
- unsigned char lo2; \
- unsigned char lo = GET_LO(from); \
- unsigned char hi = GET_HI(from); \
- switch (hi) { \
- case 0: \
- if (lo < 0x80) { \
- if (*toP == toLim) { \
- *fromP = from; \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- } \
- *(*toP)++ = lo; \
- break; \
- } \
- /* fall through */ \
- case 0x1: case 0x2: case 0x3: \
- case 0x4: case 0x5: case 0x6: case 0x7: \
- if (toLim - *toP < 2) { \
- *fromP = from; \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- } \
- *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
- *(*toP)++ = ((lo & 0x3f) | 0x80); \
- break; \
- default: \
- if (toLim - *toP < 3) { \
- *fromP = from; \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- } \
- /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
- *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
- *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
- *(*toP)++ = ((lo & 0x3f) | 0x80); \
- break; \
- case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
- if (toLim - *toP < 4) { \
- *fromP = from; \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- } \
- if (fromLim - from < 4) { \
- *fromP = from; \
- return XML_CONVERT_INPUT_INCOMPLETE; \
- } \
- plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
- *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
- *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
- from += 2; \
- lo2 = GET_LO(from); \
- *(*toP)++ = (((lo & 0x3) << 4) \
- | ((GET_HI(from) & 0x3) << 2) \
- | (lo2 >> 6) \
- | 0x80); \
- *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
- break; \
- } \
- } \
- *fromP = from; \
- if (from < fromLim) \
- return XML_CONVERT_INPUT_INCOMPLETE; \
- else \
- return XML_CONVERT_COMPLETED; \
-}
+#define DEFINE_UTF16_TO_UTF8(E) \
+ static enum XML_Convert_Result PTRCALL E##toUtf8( \
+ const ENCODING *enc, const char **fromP, const char *fromLim, \
+ char **toP, const char *toLim) { \
+ const char *from = *fromP; \
+ UNUSED_P(enc); \
+ fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \
+ for (; from < fromLim; from += 2) { \
+ int plane; \
+ unsigned char lo2; \
+ unsigned char lo = GET_LO(from); \
+ unsigned char hi = GET_HI(from); \
+ switch (hi) { \
+ case 0: \
+ if (lo < 0x80) { \
+ if (*toP == toLim) { \
+ *fromP = from; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ } \
+ *(*toP)++ = lo; \
+ break; \
+ } \
+ /* fall through */ \
+ case 0x1: \
+ case 0x2: \
+ case 0x3: \
+ case 0x4: \
+ case 0x5: \
+ case 0x6: \
+ case 0x7: \
+ if (toLim - *toP < 2) { \
+ *fromP = from; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ } \
+ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
+ *(*toP)++ = ((lo & 0x3f) | 0x80); \
+ break; \
+ default: \
+ if (toLim - *toP < 3) { \
+ *fromP = from; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ } \
+ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
+ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
+ *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
+ *(*toP)++ = ((lo & 0x3f) | 0x80); \
+ break; \
+ case 0xD8: \
+ case 0xD9: \
+ case 0xDA: \
+ case 0xDB: \
+ if (toLim - *toP < 4) { \
+ *fromP = from; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ } \
+ if (fromLim - from < 4) { \
+ *fromP = from; \
+ return XML_CONVERT_INPUT_INCOMPLETE; \
+ } \
+ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
+ *(*toP)++ = (char)((plane >> 2) | UTF8_cval4); \
+ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
+ from += 2; \
+ lo2 = GET_LO(from); \
+ *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2) \
+ | (lo2 >> 6) | 0x80); \
+ *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
+ break; \
+ } \
+ } \
+ *fromP = from; \
+ if (from < fromLim) \
+ return XML_CONVERT_INPUT_INCOMPLETE; \
+ else \
+ return XML_CONVERT_COMPLETED; \
+ }
-#define DEFINE_UTF16_TO_UTF16(E) \
-static enum XML_Convert_Result PTRCALL \
-E ## toUtf16(const ENCODING *UNUSED_P(enc), \
- const char **fromP, const char *fromLim, \
- unsigned short **toP, const unsigned short *toLim) \
-{ \
- enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
- fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
- /* Avoid copying first half only of surrogate */ \
- if (fromLim - *fromP > ((toLim - *toP) << 1) \
- && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
- fromLim -= 2; \
- res = XML_CONVERT_INPUT_INCOMPLETE; \
- } \
- for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
- *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
- if ((*toP == toLim) && (*fromP < fromLim)) \
- return XML_CONVERT_OUTPUT_EXHAUSTED; \
- else \
- return res; \
-}
+#define DEFINE_UTF16_TO_UTF16(E) \
+ static enum XML_Convert_Result PTRCALL E##toUtf16( \
+ const ENCODING *enc, const char **fromP, const char *fromLim, \
+ unsigned short **toP, const unsigned short *toLim) { \
+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
+ UNUSED_P(enc); \
+ fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
+ /* Avoid copying first half only of surrogate */ \
+ if (fromLim - *fromP > ((toLim - *toP) << 1) \
+ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
+ fromLim -= 2; \
+ res = XML_CONVERT_INPUT_INCOMPLETE; \
+ } \
+ for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
+ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+ if ((*toP == toLim) && (*fromP < fromLim)) \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ else \
+ return res; \
+ }
-#define SET2(ptr, ch) \
- (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define SET2(ptr, ch) (((ptr)[0] = ((ch)&0xff)), ((ptr)[1] = ((ch) >> 8)))
#define GET_LO(ptr) ((unsigned char)(ptr)[0])
#define GET_HI(ptr) ((unsigned char)(ptr)[1])
@@ -721,8 +723,7 @@ DEFINE_UTF16_TO_UTF16(little2_)
#undef GET_LO
#undef GET_HI
-#define SET2(ptr, ch) \
- (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define SET2(ptr, ch) (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch)&0xFF)))
#define GET_LO(ptr) ((unsigned char)(ptr)[1])
#define GET_HI(ptr) ((unsigned char)(ptr)[0])
@@ -733,317 +734,307 @@ DEFINE_UTF16_TO_UTF16(big2_)
#undef GET_LO
#undef GET_HI
-#define LITTLE2_BYTE_TYPE(enc, p) \
- ((p)[1] == 0 \
- ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
- : unicode_byte_type((p)[1], (p)[0]))
-#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
-#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
-#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+#define LITTLE2_BYTE_TYPE(enc, p) \
+ ((p)[1] == 0 ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
+ : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(p) \
UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
-#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \
UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
-little2_byteType(const ENCODING *enc, const char *p)
-{
+little2_byteType(const ENCODING *enc, const char *p) {
return LITTLE2_BYTE_TYPE(enc, p);
}
static int PTRFASTCALL
-little2_byteToAscii(const ENCODING *enc, const char *p)
-{
- return LITTLE2_BYTE_TO_ASCII(enc, p);
+little2_byteToAscii(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
+ return LITTLE2_BYTE_TO_ASCII(p);
}
static int PTRCALL
-little2_charMatches(const ENCODING *enc, const char *p, int c)
-{
- return LITTLE2_CHAR_MATCHES(enc, p, c);
+little2_charMatches(const ENCODING *enc, const char *p, int c) {
+ UNUSED_P(enc);
+ return LITTLE2_CHAR_MATCHES(p, c);
}
static int PTRFASTCALL
-little2_isNameMin(const ENCODING *enc, const char *p)
-{
- return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+little2_isNameMin(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
+ return LITTLE2_IS_NAME_CHAR_MINBPC(p);
}
static int PTRFASTCALL
-little2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
- return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+little2_isNmstrtMin(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
+ return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p);
}
-#undef VTABLE
-#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+# undef VTABLE
+# define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
#else /* not XML_MIN_SIZE */
-#undef PREFIX
-#define PREFIX(ident) little2_ ## ident
-#define MINBPC(enc) 2
+# undef PREFIX
+# define PREFIX(ident) little2_##ident
+# define MINBPC(enc) 2
/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#define XML_TOK_IMPL_C
-#include "xmltok_impl.c"
-#undef XML_TOK_IMPL_C
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
+# define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+# define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p)
+# define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c)
+# define IS_NAME_CHAR(enc, p, n) 0
+# define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
+# define IS_NMSTRT_CHAR(enc, p, n) (0)
+# define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
+
+# define XML_TOK_IMPL_C
+# include "xmltok_impl.c"
+# undef XML_TOK_IMPL_C
+
+# undef MINBPC
+# undef BYTE_TYPE
+# undef BYTE_TO_ASCII
+# undef CHAR_MATCHES
+# undef IS_NAME_CHAR
+# undef IS_NAME_CHAR_MINBPC
+# undef IS_NMSTRT_CHAR
+# undef IS_NMSTRT_CHAR_MINBPC
+# undef IS_INVALID_CHAR
#endif /* not XML_MIN_SIZE */
#ifdef XML_NS
-static const struct normal_encoding little2_encoding_ns = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 1234
- 1
-#else
- 0
-#endif
- },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_) NULL_VTABLE
-};
+static const struct normal_encoding little2_encoding_ns
+ = {{VTABLE, 2, 0,
+# if BYTEORDER == 1234
+ 1
+# else
+ 0
+# endif
+ },
+ {
+# include "asciitab.h"
+# include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_) NULL_VTABLE};
#endif
-static const struct normal_encoding little2_encoding = {
- { VTABLE, 2, 0,
+static const struct normal_encoding little2_encoding
+ = {{VTABLE, 2, 0,
#if BYTEORDER == 1234
- 1
+ 1
#else
- 0
+ 0
#endif
- },
- {
+ },
+ {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_) NULL_VTABLE
-};
+ },
+ STANDARD_VTABLE(little2_) NULL_VTABLE};
#if BYTEORDER != 4321
-#ifdef XML_NS
+# ifdef XML_NS
-static const struct normal_encoding internal_little2_encoding_ns = {
- { VTABLE, 2, 0, 1 },
- {
-#include "iasciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_) NULL_VTABLE
-};
+static const struct normal_encoding internal_little2_encoding_ns
+ = {{VTABLE, 2, 0, 1},
+ {
+# include "iasciitab.h"
+# include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_) NULL_VTABLE};
-#endif
+# endif
-static const struct normal_encoding internal_little2_encoding = {
- { VTABLE, 2, 0, 1 },
- {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_) NULL_VTABLE
-};
+static const struct normal_encoding internal_little2_encoding
+ = {{VTABLE, 2, 0, 1},
+ {
+# define BT_COLON BT_NMSTRT
+# include "iasciitab.h"
+# undef BT_COLON
+# include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_) NULL_VTABLE};
#endif
-
-#define BIG2_BYTE_TYPE(enc, p) \
- ((p)[0] == 0 \
- ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
- : unicode_byte_type((p)[0], (p)[1]))
-#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
-#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
-#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+#define BIG2_BYTE_TYPE(enc, p) \
+ ((p)[0] == 0 \
+ ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
+ : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(p) \
UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
-#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \
UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
-big2_byteType(const ENCODING *enc, const char *p)
-{
+big2_byteType(const ENCODING *enc, const char *p) {
return BIG2_BYTE_TYPE(enc, p);
}
static int PTRFASTCALL
-big2_byteToAscii(const ENCODING *enc, const char *p)
-{
- return BIG2_BYTE_TO_ASCII(enc, p);
+big2_byteToAscii(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
+ return BIG2_BYTE_TO_ASCII(p);
}
static int PTRCALL
-big2_charMatches(const ENCODING *enc, const char *p, int c)
-{
- return BIG2_CHAR_MATCHES(enc, p, c);
+big2_charMatches(const ENCODING *enc, const char *p, int c) {
+ UNUSED_P(enc);
+ return BIG2_CHAR_MATCHES(p, c);
}
static int PTRFASTCALL
-big2_isNameMin(const ENCODING *enc, const char *p)
-{
- return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+big2_isNameMin(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
+ return BIG2_IS_NAME_CHAR_MINBPC(p);
}
static int PTRFASTCALL
-big2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
- return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+big2_isNmstrtMin(const ENCODING *enc, const char *p) {
+ UNUSED_P(enc);
+ return BIG2_IS_NMSTRT_CHAR_MINBPC(p);
}
-#undef VTABLE
-#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+# undef VTABLE
+# define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
#else /* not XML_MIN_SIZE */
-#undef PREFIX
-#define PREFIX(ident) big2_ ## ident
-#define MINBPC(enc) 2
+# undef PREFIX
+# define PREFIX(ident) big2_##ident
+# define MINBPC(enc) 2
/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#define XML_TOK_IMPL_C
-#include "xmltok_impl.c"
-#undef XML_TOK_IMPL_C
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
+# define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+# define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p)
+# define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c)
+# define IS_NAME_CHAR(enc, p, n) 0
+# define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
+# define IS_NMSTRT_CHAR(enc, p, n) (0)
+# define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
+
+# define XML_TOK_IMPL_C
+# include "xmltok_impl.c"
+# undef XML_TOK_IMPL_C
+
+# undef MINBPC
+# undef BYTE_TYPE
+# undef BYTE_TO_ASCII
+# undef CHAR_MATCHES
+# undef IS_NAME_CHAR
+# undef IS_NAME_CHAR_MINBPC
+# undef IS_NMSTRT_CHAR
+# undef IS_NMSTRT_CHAR_MINBPC
+# undef IS_INVALID_CHAR
#endif /* not XML_MIN_SIZE */
#ifdef XML_NS
-static const struct normal_encoding big2_encoding_ns = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 4321
- 1
-#else
- 0
-#endif
- },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_) NULL_VTABLE
-};
+static const struct normal_encoding big2_encoding_ns
+ = {{VTABLE, 2, 0,
+# if BYTEORDER == 4321
+ 1
+# else
+ 0
+# endif
+ },
+ {
+# include "asciitab.h"
+# include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_) NULL_VTABLE};
#endif
-static const struct normal_encoding big2_encoding = {
- { VTABLE, 2, 0,
+static const struct normal_encoding big2_encoding
+ = {{VTABLE, 2, 0,
#if BYTEORDER == 4321
- 1
+ 1
#else
- 0
+ 0
#endif
- },
- {
+ },
+ {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_) NULL_VTABLE
-};
+ },
+ STANDARD_VTABLE(big2_) NULL_VTABLE};
#if BYTEORDER != 1234
-#ifdef XML_NS
+# ifdef XML_NS
-static const struct normal_encoding internal_big2_encoding_ns = {
- { VTABLE, 2, 0, 1 },
- {
-#include "iasciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_) NULL_VTABLE
-};
+static const struct normal_encoding internal_big2_encoding_ns
+ = {{VTABLE, 2, 0, 1},
+ {
+# include "iasciitab.h"
+# include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_) NULL_VTABLE};
-#endif
+# endif
-static const struct normal_encoding internal_big2_encoding = {
- { VTABLE, 2, 0, 1 },
- {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_) NULL_VTABLE
-};
+static const struct normal_encoding internal_big2_encoding
+ = {{VTABLE, 2, 0, 1},
+ {
+# define BT_COLON BT_NMSTRT
+# include "iasciitab.h"
+# undef BT_COLON
+# include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_) NULL_VTABLE};
#endif
#undef PREFIX
static int FASTCALL
-streqci(const char *s1, const char *s2)
-{
+streqci(const char *s1, const char *s2) {
for (;;) {
char c1 = *s1++;
char c2 = *s2++;
if (ASCII_a <= c1 && c1 <= ASCII_z)
c1 += ASCII_A - ASCII_a;
if (ASCII_a <= c2 && c2 <= ASCII_z)
- c2 += ASCII_A - ASCII_a;
+ /* The following line will never get executed. streqci() is
+ * only called from two places, both of which guarantee to put
+ * upper-case strings into s2.
+ */
+ c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
if (c1 != c2)
return 0;
- if (!c1)
+ if (! c1)
break;
}
return 1;
}
static void PTRCALL
-initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr,
- const char *end, POSITION *pos)
-{
+initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end,
+ POSITION *pos) {
+ UNUSED_P(enc);
normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
}
static int
-toAscii(const ENCODING *enc, const char *ptr, const char *end)
-{
+toAscii(const ENCODING *enc, const char *ptr, const char *end) {
char buf[1];
char *p = buf;
XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
@@ -1054,8 +1045,7 @@ toAscii(const ENCODING *enc, const char *ptr, const char *end)
}
static int FASTCALL
-isSpace(int c)
-{
+isSpace(int c) {
switch (c) {
case 0x20:
case 0xD:
@@ -1070,21 +1060,16 @@ isSpace(int c)
followed by name=val.
*/
static int
-parsePseudoAttribute(const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **namePtr,
- const char **nameEndPtr,
- const char **valPtr,
- const char **nextTokPtr)
-{
+parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end,
+ const char **namePtr, const char **nameEndPtr,
+ const char **valPtr, const char **nextTokPtr) {
int c;
char open;
if (ptr == end) {
*namePtr = NULL;
return 1;
}
- if (!isSpace(toAscii(enc, ptr, end))) {
+ if (! isSpace(toAscii(enc, ptr, end))) {
*nextTokPtr = ptr;
return 0;
}
@@ -1140,12 +1125,9 @@ parsePseudoAttribute(const ENCODING *enc,
c = toAscii(enc, ptr, end);
if (c == open)
break;
- if (!(ASCII_a <= c && c <= ASCII_z)
- && !(ASCII_A <= c && c <= ASCII_Z)
- && !(ASCII_0 <= c && c <= ASCII_9)
- && c != ASCII_PERIOD
- && c != ASCII_MINUS
- && c != ASCII_UNDERSCORE) {
+ if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)
+ && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD
+ && c != ASCII_MINUS && c != ASCII_UNDERSCORE) {
*nextTokPtr = ptr;
return 0;
}
@@ -1154,68 +1136,52 @@ parsePseudoAttribute(const ENCODING *enc,
return 1;
}
-static const char KW_version[] = {
- ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
-};
+static const char KW_version[]
+ = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'};
-static const char KW_encoding[] = {
- ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
-};
+static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d,
+ ASCII_i, ASCII_n, ASCII_g, '\0'};
-static const char KW_standalone[] = {
- ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,
- ASCII_n, ASCII_e, '\0'
-};
+static const char KW_standalone[]
+ = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a,
+ ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'};
-static const char KW_yes[] = {
- ASCII_y, ASCII_e, ASCII_s, '\0'
-};
+static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'};
-static const char KW_no[] = {
- ASCII_n, ASCII_o, '\0'
-};
+static const char KW_no[] = {ASCII_n, ASCII_o, '\0'};
static int
-doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
- const char *,
+doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *,
const char *),
- int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingName,
- const ENCODING **encoding,
- int *standalone)
-{
+ int isGeneralTextEntity, const ENCODING *enc, const char *ptr,
+ const char *end, const char **badPtr, const char **versionPtr,
+ const char **versionEndPtr, const char **encodingName,
+ const ENCODING **encoding, int *standalone) {
const char *val = NULL;
const char *name = NULL;
const char *nameEnd = NULL;
ptr += 5 * enc->minBytesPerChar;
end -= 2 * enc->minBytesPerChar;
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
- || !name) {
+ if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
+ || ! name) {
*badPtr = ptr;
return 0;
}
- if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
- if (!isGeneralTextEntity) {
+ if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+ if (! isGeneralTextEntity) {
*badPtr = name;
return 0;
}
- }
- else {
+ } else {
if (versionPtr)
*versionPtr = val;
if (versionEndPtr)
*versionEndPtr = ptr;
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+ if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
*badPtr = ptr;
return 0;
}
- if (!name) {
+ if (! name) {
if (isGeneralTextEntity) {
/* a TextDecl must have an EncodingDecl */
*badPtr = ptr;
@@ -1226,7 +1192,7 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
}
if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
int c = toAscii(enc, val, end);
- if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+ if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) {
*badPtr = val;
return 0;
}
@@ -1234,14 +1200,14 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
*encodingName = val;
if (encoding)
*encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+ if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
*badPtr = ptr;
return 0;
}
- if (!name)
+ if (! name)
return 1;
}
- if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
+ if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
|| isGeneralTextEntity) {
*badPtr = name;
return 0;
@@ -1249,12 +1215,10 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
if (standalone)
*standalone = 1;
- }
- else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+ } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
if (standalone)
*standalone = 0;
- }
- else {
+ } else {
*badPtr = val;
return 0;
}
@@ -1268,11 +1232,16 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
}
static int FASTCALL
-checkCharRefNumber(int result)
-{
+checkCharRefNumber(int result) {
switch (result >> 8) {
- case 0xD8: case 0xD9: case 0xDA: case 0xDB:
- case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ case 0xD8:
+ case 0xD9:
+ case 0xDA:
+ case 0xDB:
+ case 0xDC:
+ case 0xDD:
+ case 0xDE:
+ case 0xDF:
return -1;
case 0:
if (latin1_encoding.type[result] == BT_NONXML)
@@ -1287,8 +1256,7 @@ checkCharRefNumber(int result)
}
int FASTCALL
-XmlUtf8Encode(int c, char *buf)
-{
+XmlUtf8Encode(int c, char *buf) {
enum {
/* minN is minimum legal resulting value for N byte sequence */
min2 = 0x80,
@@ -1297,7 +1265,7 @@ XmlUtf8Encode(int c, char *buf)
};
if (c < 0)
- return 0;
+ return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */
if (c < min2) {
buf[0] = (char)(c | UTF8_cval1);
return 1;
@@ -1320,12 +1288,11 @@ XmlUtf8Encode(int c, char *buf)
buf[3] = (char)((c & 0x3f) | 0x80);
return 4;
}
- return 0;
+ return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
}
int FASTCALL
-XmlUtf16Encode(int charNum, unsigned short *buf)
-{
+XmlUtf16Encode(int charNum, unsigned short *buf) {
if (charNum < 0)
return 0;
if (charNum < 0x10000) {
@@ -1349,17 +1316,15 @@ struct unknown_encoding {
char utf8[256][4];
};
-#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc))
+#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc))
int
-XmlSizeOfUnknownEncoding(void)
-{
+XmlSizeOfUnknownEncoding(void) {
return sizeof(struct unknown_encoding);
}
static int PTRFASTCALL
-unknown_isName(const ENCODING *enc, const char *p)
-{
+unknown_isName(const ENCODING *enc, const char *p) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
if (c & ~0xFFFF)
@@ -1368,8 +1333,7 @@ unknown_isName(const ENCODING *enc, const char *p)
}
static int PTRFASTCALL
-unknown_isNmstrt(const ENCODING *enc, const char *p)
-{
+unknown_isNmstrt(const ENCODING *enc, const char *p) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
if (c & ~0xFFFF)
@@ -1378,18 +1342,15 @@ unknown_isNmstrt(const ENCODING *enc, const char *p)
}
static int PTRFASTCALL
-unknown_isInvalid(const ENCODING *enc, const char *p)
-{
+unknown_isInvalid(const ENCODING *enc, const char *p) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
}
static enum XML_Convert_Result PTRCALL
-unknown_toUtf8(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
+unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
+ char **toP, const char *toLim) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
char buf[XML_UTF8_ENCODE_MAX];
for (;;) {
@@ -1407,33 +1368,27 @@ unknown_toUtf8(const ENCODING *enc,
utf8 = buf;
*fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- (BT_LEAD2 - 2));
- }
- else {
+ } else {
if (n > toLim - *toP)
return XML_CONVERT_OUTPUT_EXHAUSTED;
(*fromP)++;
}
- do {
- *(*toP)++ = *utf8++;
- } while (--n != 0);
+ memcpy(*toP, utf8, n);
+ *toP += n;
}
}
static enum XML_Convert_Result PTRCALL
-unknown_toUtf16(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
+unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
while (*fromP < fromLim && *toP < toLim) {
unsigned short c = uenc->utf16[(unsigned char)**fromP];
if (c == 0) {
- c = (unsigned short)
- uenc->convert(uenc->userData, *fromP);
+ c = (unsigned short)uenc->convert(uenc->userData, *fromP);
*fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- (BT_LEAD2 - 2));
- }
- else
+ } else
(*fromP)++;
*(*toP)++ = c;
}
@@ -1445,19 +1400,14 @@ unknown_toUtf16(const ENCODING *enc,
}
ENCODING *
-XmlInitUnknownEncoding(void *mem,
- int *table,
- CONVERTER convert,
- void *userData)
-{
+XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
+ void *userData) {
int i;
struct unknown_encoding *e = (struct unknown_encoding *)mem;
- for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
- ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+ memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding));
for (i = 0; i < 128; i++)
if (latin1_encoding.type[i] != BT_OTHER
- && latin1_encoding.type[i] != BT_NONXML
- && table[i] != i)
+ && latin1_encoding.type[i] != BT_NONXML && table[i] != i)
return 0;
for (i = 0; i < 256; i++) {
int c = table[i];
@@ -1467,32 +1417,30 @@ XmlInitUnknownEncoding(void *mem,
e->utf16[i] = 0xFFFF;
e->utf8[i][0] = 1;
e->utf8[i][1] = 0;
- }
- else if (c < 0) {
+ } else if (c < 0) {
if (c < -4)
return 0;
+ /* Multi-byte sequences need a converter function */
+ if (! convert)
+ return 0;
e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
e->utf8[i][0] = 0;
e->utf16[i] = 0;
- }
- else if (c < 0x80) {
+ } else if (c < 0x80) {
if (latin1_encoding.type[c] != BT_OTHER
- && latin1_encoding.type[c] != BT_NONXML
- && c != i)
+ && latin1_encoding.type[c] != BT_NONXML && c != i)
return 0;
e->normal.type[i] = latin1_encoding.type[c];
e->utf8[i][0] = 1;
e->utf8[i][1] = (char)c;
e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
- }
- else if (checkCharRefNumber(c) < 0) {
+ } else if (checkCharRefNumber(c) < 0) {
e->normal.type[i] = BT_NONXML;
/* This shouldn't really get used. */
e->utf16[i] = 0xFFFF;
e->utf8[i][0] = 1;
e->utf8[i][1] = 0;
- }
- else {
+ } else {
if (c > 0xFFFF)
return 0;
if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
@@ -1537,44 +1485,32 @@ enum {
NO_ENC
};
-static const char KW_ISO_8859_1[] = {
- ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,
- ASCII_MINUS, ASCII_1, '\0'
-};
-static const char KW_US_ASCII[] = {
- ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,
- '\0'
-};
-static const char KW_UTF_8[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
-};
-static const char KW_UTF_16[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
-};
-static const char KW_UTF_16BE[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,
- '\0'
-};
-static const char KW_UTF_16LE[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,
- '\0'
-};
+static const char KW_ISO_8859_1[]
+ = {ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8,
+ ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'};
+static const char KW_US_ASCII[]
+ = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S,
+ ASCII_C, ASCII_I, ASCII_I, '\0'};
+static const char KW_UTF_8[]
+ = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'};
+static const char KW_UTF_16[]
+ = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'};
+static const char KW_UTF_16BE[]
+ = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
+ ASCII_6, ASCII_B, ASCII_E, '\0'};
+static const char KW_UTF_16LE[]
+ = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
+ ASCII_6, ASCII_L, ASCII_E, '\0'};
static int FASTCALL
-getEncodingIndex(const char *name)
-{
- static const char * const encodingNames[] = {
- KW_ISO_8859_1,
- KW_US_ASCII,
- KW_UTF_8,
- KW_UTF_16,
- KW_UTF_16BE,
- KW_UTF_16LE,
+getEncodingIndex(const char *name) {
+ static const char *const encodingNames[] = {
+ KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE,
};
int i;
if (name == NULL)
return NO_ENC;
- for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+ for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++)
if (streqci(name, encodingNames[i]))
return i;
return UNKNOWN_ENC;
@@ -1594,15 +1530,9 @@ getEncodingIndex(const char *name)
XML_PROLOG_STATE otherwise.
*/
-
static int
-initScan(const ENCODING * const *encodingTable,
- const INIT_ENCODING *enc,
- int state,
- const char *ptr,
- const char *end,
- const char **nextTokPtr)
-{
+initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc,
+ int state, const char *ptr, const char *end, const char **nextTokPtr) {
const ENCODING **encPtr;
if (ptr >= end)
@@ -1627,20 +1557,17 @@ initScan(const ENCODING * const *encodingTable,
case 0xFE:
case 0xFF:
case 0xEF: /* possibly first byte of UTF-8 BOM */
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
break;
/* fall through */
case 0x00:
case 0x3C:
return XML_TOK_PARTIAL;
}
- }
- else {
+ } else {
switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
case 0xFEFF:
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
break;
*nextTokPtr = ptr + 2;
*encPtr = encodingTable[UTF_16BE_ENC];
@@ -1654,8 +1581,7 @@ initScan(const ENCODING * const *encodingTable,
*encPtr = encodingTable[UTF_16LE_ENC];
return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
case 0xFFFE:
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
break;
*nextTokPtr = ptr + 2;
*encPtr = encodingTable[UTF_16LE_ENC];
@@ -1670,8 +1596,8 @@ initScan(const ENCODING * const *encodingTable,
*/
if (state == XML_CONTENT_STATE) {
int e = INIT_ENC_INDEX(enc);
- if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC
- || e == UTF_16LE_ENC || e == UTF_16_ENC)
+ if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC
+ || e == UTF_16_ENC)
break;
}
if (ptr + 2 == end)
@@ -1694,8 +1620,7 @@ initScan(const ENCODING * const *encodingTable,
break;
*encPtr = encodingTable[UTF_16BE_ENC];
return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
- }
- else if (ptr[1] == '\0') {
+ } else if (ptr[1] == '\0') {
/* We could recover here in the case:
- parsing an external entity
- second byte is 0
@@ -1717,7 +1642,6 @@ initScan(const ENCODING * const *encodingTable,
return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
}
-
#define NS(x) x
#define ns(x) x
#define XML_TOK_NS_C
@@ -1728,22 +1652,19 @@ initScan(const ENCODING * const *encodingTable,
#ifdef XML_NS
-#define NS(x) x ## NS
-#define ns(x) x ## _ns
+# define NS(x) x##NS
+# define ns(x) x##_ns
-#define XML_TOK_NS_C
-#include "xmltok_ns.c"
-#undef XML_TOK_NS_C
+# define XML_TOK_NS_C
+# include "xmltok_ns.c"
+# undef XML_TOK_NS_C
-#undef NS
-#undef ns
+# undef NS
+# undef ns
ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
- int *table,
- CONVERTER convert,
- void *userData)
-{
+XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
+ void *userData) {
ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
if (enc)
((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
diff --git a/freebsd/contrib/expat/lib/xmltok.h b/freebsd/contrib/expat/lib/xmltok.h
index 752007e8..2adbf530 100644
--- a/freebsd/contrib/expat/lib/xmltok.h
+++ b/freebsd/contrib/expat/lib/xmltok.h
@@ -1,5 +1,33 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef XmlTok_INCLUDED
@@ -10,16 +38,18 @@ extern "C" {
#endif
/* The following token may be returned by XmlContentTok */
-#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
- start of illegal ]]> sequence */
+#define XML_TOK_TRAILING_RSQB \
+ -5 /* ] or ]] at the end of the scan; might be \
+ start of illegal ]]> sequence */
/* The following tokens may be returned by both XmlPrologTok and
XmlContentTok.
*/
-#define XML_TOK_NONE -4 /* The string to be scanned is empty */
-#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
- might be part of CRLF sequence */
-#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
-#define XML_TOK_PARTIAL -1 /* only part of a token */
+#define XML_TOK_NONE -4 /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR \
+ -3 /* A CR at the end of the scan; \
+ might be part of CRLF sequence */
+#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1 /* only part of a token */
#define XML_TOK_INVALID 0
/* The following tokens are returned by XmlContentTok; some are also
@@ -34,24 +64,24 @@ extern "C" {
#define XML_TOK_DATA_NEWLINE 7
#define XML_TOK_CDATA_SECT_OPEN 8
#define XML_TOK_ENTITY_REF 9
-#define XML_TOK_CHAR_REF 10 /* numeric character reference */
+#define XML_TOK_CHAR_REF 10 /* numeric character reference */
/* The following tokens may be returned by both XmlPrologTok and
XmlContentTok.
*/
-#define XML_TOK_PI 11 /* processing instruction */
-#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+#define XML_TOK_PI 11 /* processing instruction */
+#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
#define XML_TOK_COMMENT 13
-#define XML_TOK_BOM 14 /* Byte order mark */
+#define XML_TOK_BOM 14 /* Byte order mark */
/* The following tokens are returned only by XmlPrologTok */
#define XML_TOK_PROLOG_S 15
-#define XML_TOK_DECL_OPEN 16 /* <!foo */
-#define XML_TOK_DECL_CLOSE 17 /* > */
+#define XML_TOK_DECL_OPEN 16 /* <!foo */
+#define XML_TOK_DECL_CLOSE 17 /* > */
#define XML_TOK_NAME 18
#define XML_TOK_NMTOKEN 19
-#define XML_TOK_POUND_NAME 20 /* #name */
-#define XML_TOK_OR 21 /* | */
+#define XML_TOK_POUND_NAME 20 /* #name */
+#define XML_TOK_OR 21 /* | */
#define XML_TOK_PERCENT 22
#define XML_TOK_OPEN_PAREN 23
#define XML_TOK_CLOSE_PAREN 24
@@ -62,14 +92,14 @@ extern "C" {
#define XML_TOK_INSTANCE_START 29
/* The following occur only in element type declarations */
-#define XML_TOK_NAME_QUESTION 30 /* name? */
-#define XML_TOK_NAME_ASTERISK 31 /* name* */
-#define XML_TOK_NAME_PLUS 32 /* name+ */
-#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
-#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
-#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
-#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
-#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
+#define XML_TOK_NAME_QUESTION 30 /* name? */
+#define XML_TOK_NAME_ASTERISK 31 /* name* */
+#define XML_TOK_NAME_PLUS 32 /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
#define XML_TOK_COMMA 38
/* The following token is returned only by XmlAttributeValueTok */
@@ -84,20 +114,20 @@ extern "C" {
#define XML_TOK_PREFIXED_NAME 41
#ifdef XML_DTD
-#define XML_TOK_IGNORE_SECT 42
+# define XML_TOK_IGNORE_SECT 42
#endif /* XML_DTD */
#ifdef XML_DTD
-#define XML_N_STATES 4
+# define XML_N_STATES 4
#else /* not XML_DTD */
-#define XML_N_STATES 3
+# define XML_N_STATES 3
#endif /* not XML_DTD */
#define XML_PROLOG_STATE 0
#define XML_CONTENT_STATE 1
#define XML_CDATA_SECTION_STATE 2
#ifdef XML_DTD
-#define XML_IGNORE_SECTION_STATE 3
+# define XML_IGNORE_SECTION_STATE 3
#endif /* XML_DTD */
#define XML_N_LITERAL_TYPES 2
@@ -125,55 +155,41 @@ typedef struct {
struct encoding;
typedef struct encoding ENCODING;
-typedef int (PTRCALL *SCANNER)(const ENCODING *,
- const char *,
- const char *,
- const char **);
+typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *,
+ const char **);
enum XML_Convert_Result {
XML_CONVERT_COMPLETED = 0,
XML_CONVERT_INPUT_INCOMPLETE = 1,
- XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */
+ XML_CONVERT_OUTPUT_EXHAUSTED
+ = 2 /* and therefore potentially input remaining as well */
};
struct encoding {
SCANNER scanners[XML_N_STATES];
SCANNER literalScanners[XML_N_LITERAL_TYPES];
- int (PTRCALL *sameName)(const ENCODING *,
- const char *,
- const char *);
- int (PTRCALL *nameMatchesAscii)(const ENCODING *,
- const char *,
- const char *,
- const char *);
- int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
+ int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *,
+ const char *);
+ int(PTRFASTCALL *nameLength)(const ENCODING *, const char *);
const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
- int (PTRCALL *getAtts)(const ENCODING *enc,
- const char *ptr,
- int attsMax,
- ATTRIBUTE *atts);
- int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
- int (PTRCALL *predefinedEntityName)(const ENCODING *,
- const char *,
- const char *);
- void (PTRCALL *updatePosition)(const ENCODING *,
- const char *ptr,
- const char *end,
- POSITION *);
- int (PTRCALL *isPublicId)(const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr);
- enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
- const char **fromP,
- const char *fromLim,
- char **toP,
- const char *toLim);
- enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
- const char **fromP,
- const char *fromLim,
- unsigned short **toP,
- const unsigned short *toLim);
+ int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
+ ATTRIBUTE *atts);
+ int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
+ int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *,
+ const char *);
+ void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr,
+ const char *end, POSITION *);
+ int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr,
+ const char *end, const char **badPtr);
+ enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc,
+ const char **fromP,
+ const char *fromLim, char **toP,
+ const char *toLim);
+ enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc,
+ const char **fromP,
+ const char *fromLim,
+ unsigned short **toP,
+ const unsigned short *toLim);
int minBytesPerChar;
char isUtf8;
char isUtf16;
@@ -200,68 +216,62 @@ struct encoding {
the prolog outside literals, comments and processing instructions.
*/
-
-#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+#define XmlTok(enc, state, ptr, end, nextTokPtr) \
(((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
-#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
-#define XmlContentTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+#define XmlContentTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
-#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
#ifdef XML_DTD
-#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+# define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
#endif /* XML_DTD */
/* This is used for performing a 2nd-level tokenization on the content
of a literal that has already been returned by XmlTok.
*/
-#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
(((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
-#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
- XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
- XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
+ XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
-#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
+ XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
-#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
(((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
-#define XmlNameLength(enc, ptr) \
- (((enc)->nameLength)(enc, ptr))
+#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr))
-#define XmlSkipS(enc, ptr) \
- (((enc)->skipS)(enc, ptr))
+#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr))
-#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+#define XmlGetAttributes(enc, ptr, attsMax, atts) \
(((enc)->getAtts)(enc, ptr, attsMax, atts))
-#define XmlCharRefNumber(enc, ptr) \
- (((enc)->charRefNumber)(enc, ptr))
+#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr))
-#define XmlPredefinedEntityName(enc, ptr, end) \
+#define XmlPredefinedEntityName(enc, ptr, end) \
(((enc)->predefinedEntityName)(enc, ptr, end))
-#define XmlUpdatePosition(enc, ptr, end, pos) \
+#define XmlUpdatePosition(enc, ptr, end, pos) \
(((enc)->updatePosition)(enc, ptr, end, pos))
-#define XmlIsPublicId(enc, ptr, end, badPtr) \
+#define XmlIsPublicId(enc, ptr, end, badPtr) \
(((enc)->isPublicId)(enc, ptr, end, badPtr))
-#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
-#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
typedef struct {
@@ -269,16 +279,11 @@ typedef struct {
const ENCODING **encPtr;
} INIT_ENCODING;
-int XmlParseXmlDecl(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
+int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc,
+ const char *ptr, const char *end, const char **badPtr,
+ const char **versionPtr, const char **versionEndPtr,
const char **encodingNamePtr,
- const ENCODING **namedEncodingPtr,
- int *standalonePtr);
+ const ENCODING **namedEncodingPtr, int *standalonePtr);
int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
const ENCODING *XmlGetUtf8InternalEncoding(void);
@@ -287,34 +292,22 @@ int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
int XmlSizeOfUnknownEncoding(void);
+typedef int(XMLCALL *CONVERTER)(void *userData, const char *p);
-typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
-
-ENCODING *
-XmlInitUnknownEncoding(void *mem,
- int *table,
- CONVERTER convert,
- void *userData);
+ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
+ void *userData);
-int XmlParseXmlDeclNS(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
+int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc,
+ const char *ptr, const char *end, const char **badPtr,
+ const char **versionPtr, const char **versionEndPtr,
const char **encodingNamePtr,
- const ENCODING **namedEncodingPtr,
- int *standalonePtr);
+ const ENCODING **namedEncodingPtr, int *standalonePtr);
int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
const ENCODING *XmlGetUtf8InternalEncodingNS(void);
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
-ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
- int *table,
- CONVERTER convert,
- void *userData);
+ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
+ void *userData);
#ifdef __cplusplus
}
#endif
diff --git a/freebsd/contrib/expat/lib/xmltok_impl.c b/freebsd/contrib/expat/lib/xmltok_impl.c
index 2deec94f..639a4bd0 100644
--- a/freebsd/contrib/expat/lib/xmltok_impl.c
+++ b/freebsd/contrib/expat/lib/xmltok_impl.c
@@ -1,134 +1,157 @@
#include <machine/rtems-bsd-user-space.h>
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/* This file is included!
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/* This file is included! */
#ifdef XML_TOK_IMPL_C
-#ifndef IS_INVALID_CHAR
-#define IS_INVALID_CHAR(enc, ptr, n) (0)
-#endif
+# ifndef IS_INVALID_CHAR
+# define IS_INVALID_CHAR(enc, ptr, n) (0)
+# endif
-#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (IS_INVALID_CHAR(enc, ptr, n)) { \
- *(nextTokPtr) = (ptr); \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
+# define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+ case BT_LEAD##n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (IS_INVALID_CHAR(enc, ptr, n)) { \
+ *(nextTokPtr) = (ptr); \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
-#define INVALID_CASES(ptr, nextTokPtr) \
- INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
- INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
- INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
- case BT_NONXML: \
- case BT_MALFORM: \
- case BT_TRAIL: \
- *(nextTokPtr) = (ptr); \
+# define INVALID_CASES(ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
+ case BT_NONXML: \
+ case BT_MALFORM: \
+ case BT_TRAIL: \
+ *(nextTokPtr) = (ptr); \
return XML_TOK_INVALID;
-#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NAME_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
-
-#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
- case BT_NONASCII: \
- if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- case BT_NMSTRT: \
- case BT_HEX: \
- case BT_DIGIT: \
- case BT_NAME: \
- case BT_MINUS: \
- ptr += MINBPC(enc); \
- break; \
- CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
- CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
- CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+# define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
+ case BT_LEAD##n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (! IS_NAME_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
-#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
+# define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
+ case BT_NONASCII: \
+ if (! IS_NAME_CHAR_MINBPC(enc, ptr)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ /* fall through */ \
+ case BT_NMSTRT: \
+ case BT_HEX: \
+ case BT_DIGIT: \
+ case BT_NAME: \
+ case BT_MINUS: \
+ ptr += MINBPC(enc); \
+ break; \
+ CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
+ CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
+ CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
-#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
- case BT_NONASCII: \
- if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- case BT_NMSTRT: \
- case BT_HEX: \
- ptr += MINBPC(enc); \
- break; \
- CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
- CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
- CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+# define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
+ case BT_LEAD##n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (! IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
-#ifndef PREFIX
-#define PREFIX(ident) ident
-#endif
+# define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
+ case BT_NONASCII: \
+ if (! IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ /* fall through */ \
+ case BT_NMSTRT: \
+ case BT_HEX: \
+ ptr += MINBPC(enc); \
+ break; \
+ CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
+ CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
+ CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+# ifndef PREFIX
+# define PREFIX(ident) ident
+# endif
-#define HAS_CHARS(enc, ptr, end, count) \
- (end - ptr >= count * MINBPC(enc))
+# define HAS_CHARS(enc, ptr, end, count) (end - ptr >= count * MINBPC(enc))
-#define HAS_CHAR(enc, ptr, end) \
- HAS_CHARS(enc, ptr, end, 1)
+# define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1)
-#define REQUIRE_CHARS(enc, ptr, end, count) \
- { \
- if (! HAS_CHARS(enc, ptr, end, count)) { \
- return XML_TOK_PARTIAL; \
- } \
+# define REQUIRE_CHARS(enc, ptr, end, count) \
+ { \
+ if (! HAS_CHARS(enc, ptr, end, count)) { \
+ return XML_TOK_PARTIAL; \
+ } \
}
-#define REQUIRE_CHAR(enc, ptr, end) \
- REQUIRE_CHARS(enc, ptr, end, 1)
-
+# define REQUIRE_CHAR(enc, ptr, end) REQUIRE_CHARS(enc, ptr, end, 1)
/* ptr points to character following "<!-" */
static int PTRCALL
-PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
if (HAS_CHAR(enc, ptr, end)) {
- if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+ if (! CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- INVALID_CASES(ptr, nextTokPtr)
+ INVALID_CASES(ptr, nextTokPtr)
case BT_MINUS:
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
@@ -148,9 +171,8 @@ PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
/* ptr points to character following "<!" */
static int PTRCALL
-PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_MINUS:
@@ -172,12 +194,17 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
REQUIRE_CHARS(enc, ptr, end, 2);
/* don't allow <!ENTITY% foo "whatever"> */
switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
- case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
+ case BT_PERCNT:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
/* fall through */
- case BT_S: case BT_CR: case BT_LF:
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
*nextTokPtr = ptr;
return XML_TOK_DECL_OPEN;
case BT_NMSTRT:
@@ -193,12 +220,12 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
}
static int PTRCALL
-PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
- const char *end, int *tokPtr)
-{
+PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end,
+ int *tokPtr) {
int upper = 0;
+ UNUSED_P(enc);
*tokPtr = XML_TOK_PI;
- if (end - ptr != MINBPC(enc)*3)
+ if (end - ptr != MINBPC(enc) * 3)
return 1;
switch (BYTE_TO_ASCII(enc, ptr)) {
case ASCII_x:
@@ -238,30 +265,31 @@ PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
/* ptr points to character following "<?" */
static int PTRCALL
-PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
int tok;
const char *target = ptr;
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
- if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
+ if (! PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- INVALID_CASES(ptr, nextTokPtr)
+ INVALID_CASES(ptr, nextTokPtr)
case BT_QUEST:
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
@@ -277,7 +305,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
}
return XML_TOK_PARTIAL;
case BT_QUEST:
- if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+ if (! PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
@@ -297,16 +325,16 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
}
static int PTRCALL
-PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
- ASCII_T, ASCII_A, ASCII_LSQB };
+PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
+ static const char CDATA_LSQB[]
+ = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB};
int i;
+ UNUSED_P(enc);
/* CDATA[ */
REQUIRE_CHARS(enc, ptr, end, 6);
for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
- if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+ if (! CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
@@ -316,9 +344,8 @@ PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
}
static int PTRCALL
-PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
if (ptr >= end)
return XML_TOK_NONE;
if (MINBPC(enc) > 1) {
@@ -334,11 +361,11 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
case BT_RSQB:
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+ if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB))
break;
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
ptr -= MINBPC(enc);
break;
}
@@ -354,23 +381,25 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
case BT_LF:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_DATA_NEWLINE;
- INVALID_CASES(ptr, nextTokPtr)
+ INVALID_CASES(ptr, nextTokPtr)
default:
ptr += MINBPC(enc);
break;
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_DATA_CHARS; \
- } \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+# define LEAD_CASE(n) \
+ case BT_LEAD##n: \
+ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_DATA_CHARS; \
+ } \
+ ptr += n; \
+ break;
+ LEAD_CASE(2)
+ LEAD_CASE(3)
+ LEAD_CASE(4)
+# undef LEAD_CASE
case BT_NONXML:
case BT_MALFORM:
case BT_TRAIL:
@@ -391,23 +420,26 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
/* ptr points to character following "</" */
static int PTRCALL
-PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_CR: case BT_LF:
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
break;
case BT_GT:
*nextTokPtr = ptr + MINBPC(enc);
@@ -418,13 +450,13 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
}
}
return XML_TOK_PARTIAL;
-#ifdef XML_NS
+# ifdef XML_NS
case BT_COLON:
/* no need to check qname syntax here,
since end-tag must match exactly */
ptr += MINBPC(enc);
break;
-#endif
+# endif
case BT_GT:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_END_TAG;
@@ -439,9 +471,8 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
/* ptr points to character following "&#X" */
static int PTRCALL
-PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
if (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
@@ -471,9 +502,8 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
/* ptr points to character following "&#" */
static int PTRCALL
-PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
if (HAS_CHAR(enc, ptr, end)) {
if (CHAR_MATCHES(enc, ptr, ASCII_x))
return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -504,11 +534,10 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
static int PTRCALL
PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
+ const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_NUM:
return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
default:
@@ -517,7 +546,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_SEMI:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_ENTITY_REF;
@@ -533,15 +562,14 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
static int PTRCALL
PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
-#ifdef XML_NS
+ const char **nextTokPtr) {
+# ifdef XML_NS
int hadColon = 0;
-#endif
+# endif
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+# ifdef XML_NS
case BT_COLON:
if (hadColon) {
*nextTokPtr = ptr;
@@ -551,14 +579,16 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
break;
-#endif
- case BT_S: case BT_CR: case BT_LF:
+# endif
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
for (;;) {
int t;
@@ -577,102 +607,102 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_INVALID;
}
}
- /* fall through */
- case BT_EQUALS:
- {
- int open;
-#ifdef XML_NS
- hadColon = 0;
-#endif
- for (;;) {
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- open = BYTE_TYPE(enc, ptr);
- if (open == BT_QUOT || open == BT_APOS)
- break;
- switch (open) {
- case BT_S:
- case BT_LF:
- case BT_CR:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
+ /* fall through */
+ case BT_EQUALS: {
+ int open;
+# ifdef XML_NS
+ hadColon = 0;
+# endif
+ for (;;) {
ptr += MINBPC(enc);
- /* in attribute value */
- for (;;) {
- int t;
- REQUIRE_CHAR(enc, ptr, end);
- t = BYTE_TYPE(enc, ptr);
- if (t == open)
- break;
- switch (t) {
+ REQUIRE_CHAR(enc, ptr, end);
+ open = BYTE_TYPE(enc, ptr);
+ if (open == BT_QUOT || open == BT_APOS)
+ break;
+ switch (open) {
+ case BT_S:
+ case BT_LF:
+ case BT_CR:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ ptr += MINBPC(enc);
+ /* in attribute value */
+ for (;;) {
+ int t;
+ REQUIRE_CHAR(enc, ptr, end);
+ t = BYTE_TYPE(enc, ptr);
+ if (t == open)
+ break;
+ switch (t) {
INVALID_CASES(ptr, nextTokPtr)
- case BT_AMP:
- {
- int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
- if (tok <= 0) {
- if (tok == XML_TOK_INVALID)
- *nextTokPtr = ptr;
- return tok;
- }
- break;
- }
- case BT_LT:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- default:
- ptr += MINBPC(enc);
- break;
+ case BT_AMP: {
+ int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+ if (tok <= 0) {
+ if (tok == XML_TOK_INVALID)
+ *nextTokPtr = ptr;
+ return tok;
}
+ break;
+ }
+ case BT_LT:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ default:
+ ptr += MINBPC(enc);
+ break;
}
+ }
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
+ break;
+ case BT_SOL:
+ goto sol;
+ case BT_GT:
+ goto gt;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ /* ptr points to closing quote */
+ for (;;) {
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_S:
case BT_CR:
case BT_LF:
- break;
- case BT_SOL:
- goto sol;
+ continue;
case BT_GT:
- goto gt;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- /* ptr points to closing quote */
- for (;;) {
+ gt:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_START_TAG_WITH_ATTS;
+ case BT_SOL:
+ sol:
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
- continue;
- case BT_GT:
- gt:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_START_TAG_WITH_ATTS;
- case BT_SOL:
- sol:
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
- default:
+ if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- break;
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
}
break;
}
+ break;
+ }
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
@@ -685,14 +715,13 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
static int PTRCALL
PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
-#ifdef XML_NS
+ const char **nextTokPtr) {
+# ifdef XML_NS
int hadColon;
-#endif
+# endif
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_EXCL:
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
@@ -700,8 +729,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
case BT_MINUS:
return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_LSQB:
- return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
- end, nextTokPtr);
+ return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
}
*nextTokPtr = ptr;
return XML_TOK_INVALID;
@@ -713,14 +741,14 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
-#ifdef XML_NS
+# ifdef XML_NS
hadColon = 0;
-#endif
+# endif
/* we have a start-tag */
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+# ifdef XML_NS
case BT_COLON:
if (hadColon) {
*nextTokPtr = ptr;
@@ -730,34 +758,37 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
break;
-#endif
- case BT_S: case BT_CR: case BT_LF:
- {
- ptr += MINBPC(enc);
- while (HAS_CHAR(enc, ptr, end)) {
- switch (BYTE_TYPE(enc, ptr)) {
+# endif
+ case BT_S:
+ case BT_CR:
+ case BT_LF: {
+ ptr += MINBPC(enc);
+ while (HAS_CHAR(enc, ptr, end)) {
+ switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_GT:
- goto gt;
- case BT_SOL:
- goto sol;
- case BT_S: case BT_CR: case BT_LF:
- ptr += MINBPC(enc);
- continue;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+ case BT_GT:
+ goto gt;
+ case BT_SOL:
+ goto sol;
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
+ ptr += MINBPC(enc);
+ continue;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
}
- return XML_TOK_PARTIAL;
+ return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
}
+ return XML_TOK_PARTIAL;
+ }
case BT_GT:
gt:
*nextTokPtr = ptr + MINBPC(enc);
@@ -766,7 +797,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
sol:
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
@@ -782,8 +813,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
static int PTRCALL
PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
+ const char **nextTokPtr) {
if (ptr >= end)
return XML_TOK_NONE;
if (MINBPC(enc) > 1) {
@@ -815,48 +845,50 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
ptr += MINBPC(enc);
if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_RSQB;
- if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+ if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB))
break;
ptr += MINBPC(enc);
if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_RSQB;
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) {
ptr -= MINBPC(enc);
break;
}
*nextTokPtr = ptr;
return XML_TOK_INVALID;
- INVALID_CASES(ptr, nextTokPtr)
+ INVALID_CASES(ptr, nextTokPtr)
default:
ptr += MINBPC(enc);
break;
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_DATA_CHARS; \
- } \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+# define LEAD_CASE(n) \
+ case BT_LEAD##n: \
+ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_DATA_CHARS; \
+ } \
+ ptr += n; \
+ break;
+ LEAD_CASE(2)
+ LEAD_CASE(3)
+ LEAD_CASE(4)
+# undef LEAD_CASE
case BT_RSQB:
if (HAS_CHARS(enc, ptr, end, 2)) {
- if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
- ptr += MINBPC(enc);
- break;
- }
- if (HAS_CHARS(enc, ptr, end, 3)) {
- if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
- ptr += MINBPC(enc);
- break;
- }
- *nextTokPtr = ptr + 2*MINBPC(enc);
- return XML_TOK_INVALID;
- }
+ if (! CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+ ptr += MINBPC(enc);
+ break;
+ }
+ if (HAS_CHARS(enc, ptr, end, 3)) {
+ if (! CHAR_MATCHES(enc, ptr + 2 * MINBPC(enc), ASCII_GT)) {
+ ptr += MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr + 2 * MINBPC(enc);
+ return XML_TOK_INVALID;
+ }
}
/* fall through */
case BT_AMP:
@@ -881,12 +913,14 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
static int PTRCALL
PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
+ const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S:
+ case BT_LF:
+ case BT_CR:
+ case BT_PERCNT:
*nextTokPtr = ptr;
return XML_TOK_PERCENT;
default:
@@ -895,7 +929,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_SEMI:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_PARAM_ENTITY_REF;
@@ -909,20 +943,24 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
static int PTRCALL
PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
+ const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_CR: case BT_LF: case BT_S:
- case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_CR:
+ case BT_LF:
+ case BT_S:
+ case BT_RPAR:
+ case BT_GT:
+ case BT_PERCNT:
+ case BT_VERBAR:
*nextTokPtr = ptr;
return XML_TOK_POUND_NAME;
default:
@@ -934,14 +972,12 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
}
static int PTRCALL
-PREFIX(scanLit)(int open, const ENCODING *enc,
- const char *ptr, const char *end,
- const char **nextTokPtr)
-{
+PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
while (HAS_CHAR(enc, ptr, end)) {
int t = BYTE_TYPE(enc, ptr);
switch (t) {
- INVALID_CASES(ptr, nextTokPtr)
+ INVALID_CASES(ptr, nextTokPtr)
case BT_QUOT:
case BT_APOS:
ptr += MINBPC(enc);
@@ -951,8 +987,12 @@ PREFIX(scanLit)(int open, const ENCODING *enc,
return -XML_TOK_LITERAL;
*nextTokPtr = ptr;
switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_CR: case BT_LF:
- case BT_GT: case BT_PERCNT: case BT_LSQB:
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
+ case BT_GT:
+ case BT_PERCNT:
+ case BT_LSQB:
return XML_TOK_LITERAL;
default:
return XML_TOK_INVALID;
@@ -967,8 +1007,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc,
static int PTRCALL
PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
+ const char **nextTokPtr) {
int tok;
if (ptr >= end)
return XML_TOK_NONE;
@@ -986,27 +1025,26 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_APOS:
return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_LT:
- {
- ptr += MINBPC(enc);
- REQUIRE_CHAR(enc, ptr, end);
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_EXCL:
- return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_QUEST:
- return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_NMSTRT:
- case BT_HEX:
- case BT_NONASCII:
- case BT_LEAD2:
- case BT_LEAD3:
- case BT_LEAD4:
- *nextTokPtr = ptr - MINBPC(enc);
- return XML_TOK_INSTANCE_START;
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
+ case BT_LT: {
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_EXCL:
+ return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_QUEST:
+ return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_NMSTRT:
+ case BT_HEX:
+ case BT_NONASCII:
+ case BT_LEAD2:
+ case BT_LEAD3:
+ case BT_LEAD4:
+ *nextTokPtr = ptr - MINBPC(enc);
+ return XML_TOK_INSTANCE_START;
}
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
case BT_CR:
if (ptr + MINBPC(enc) == end) {
*nextTokPtr = end;
@@ -1014,13 +1052,15 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
return -XML_TOK_PROLOG_S;
}
/* fall through */
- case BT_S: case BT_LF:
+ case BT_S:
+ case BT_LF:
for (;;) {
ptr += MINBPC(enc);
if (! HAS_CHAR(enc, ptr, end))
break;
switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_LF:
+ case BT_S:
+ case BT_LF:
break;
case BT_CR:
/* don't split CR/LF pair */
@@ -1049,7 +1089,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
REQUIRE_CHARS(enc, ptr, end, 2);
if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
- *nextTokPtr = ptr + 2*MINBPC(enc);
+ *nextTokPtr = ptr + 2 * MINBPC(enc);
return XML_TOK_COND_SECT_CLOSE;
}
}
@@ -1072,8 +1112,12 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
case BT_PLUS:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_CLOSE_PAREN_PLUS;
- case BT_CR: case BT_LF: case BT_S:
- case BT_GT: case BT_COMMA: case BT_VERBAR:
+ case BT_CR:
+ case BT_LF:
+ case BT_S:
+ case BT_GT:
+ case BT_COMMA:
+ case BT_VERBAR:
case BT_RPAR:
*nextTokPtr = ptr;
return XML_TOK_CLOSE_PAREN;
@@ -1088,24 +1132,26 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_DECL_CLOSE;
case BT_NUM:
return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
- ptr += n; \
- tok = XML_TOK_NAME; \
- break; \
- } \
- if (IS_NAME_CHAR(enc, ptr, n)) { \
- ptr += n; \
- tok = XML_TOK_NMTOKEN; \
- break; \
- } \
- *nextTokPtr = ptr; \
+# define LEAD_CASE(n) \
+ case BT_LEAD##n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ ptr += n; \
+ tok = XML_TOK_NAME; \
+ break; \
+ } \
+ if (IS_NAME_CHAR(enc, ptr, n)) { \
+ ptr += n; \
+ tok = XML_TOK_NMTOKEN; \
+ break; \
+ } \
+ *nextTokPtr = ptr; \
return XML_TOK_INVALID;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+ LEAD_CASE(2)
+ LEAD_CASE(3)
+ LEAD_CASE(4)
+# undef LEAD_CASE
case BT_NMSTRT:
case BT_HEX:
tok = XML_TOK_NAME;
@@ -1114,9 +1160,9 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
case BT_DIGIT:
case BT_NAME:
case BT_MINUS:
-#ifdef XML_NS
+# ifdef XML_NS
case BT_COLON:
-#endif
+# endif
tok = XML_TOK_NMTOKEN;
ptr += MINBPC(enc);
break;
@@ -1138,13 +1184,19 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_GT: case BT_RPAR: case BT_COMMA:
- case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
- case BT_S: case BT_CR: case BT_LF:
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_GT:
+ case BT_RPAR:
+ case BT_COMMA:
+ case BT_VERBAR:
+ case BT_LSQB:
+ case BT_PERCNT:
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
*nextTokPtr = ptr;
return tok;
-#ifdef XML_NS
+# ifdef XML_NS
case BT_COLON:
ptr += MINBPC(enc);
switch (tok) {
@@ -1152,7 +1204,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
REQUIRE_CHAR(enc, ptr, end);
tok = XML_TOK_PREFIXED_NAME;
switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
default:
tok = XML_TOK_NMTOKEN;
break;
@@ -1163,23 +1215,23 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
break;
}
break;
-#endif
+# endif
case BT_PLUS:
- if (tok == XML_TOK_NMTOKEN) {
+ if (tok == XML_TOK_NMTOKEN) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_NAME_PLUS;
case BT_AST:
- if (tok == XML_TOK_NMTOKEN) {
+ if (tok == XML_TOK_NMTOKEN) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_NAME_ASTERISK;
case BT_QUEST:
- if (tok == XML_TOK_NMTOKEN) {
+ if (tok == XML_TOK_NMTOKEN) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
@@ -1194,21 +1246,30 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
}
static int PTRCALL
-PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
const char *start;
if (ptr >= end)
return XML_TOK_NONE;
- else if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_PARTIAL;
+ else if (! HAS_CHAR(enc, ptr, end)) {
+ /* This line cannot be executed. The incoming data has already
+ * been tokenized once, so incomplete characters like this have
+ * already been eliminated from the input. Retaining the paranoia
+ * check is still valuable, however.
+ */
+ return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
+ }
start = ptr;
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+# define LEAD_CASE(n) \
+ case BT_LEAD##n: \
+ ptr += n; \
+ break;
+ LEAD_CASE(2)
+ LEAD_CASE(3)
+ LEAD_CASE(4)
+# undef LEAD_CASE
case BT_AMP:
if (ptr == start)
return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -1254,21 +1315,30 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
}
static int PTRCALL
-PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
const char *start;
if (ptr >= end)
return XML_TOK_NONE;
- else if (! HAS_CHAR(enc, ptr, end))
- return XML_TOK_PARTIAL;
+ else if (! HAS_CHAR(enc, ptr, end)) {
+ /* This line cannot be executed. The incoming data has already
+ * been tokenized once, so incomplete characters like this have
+ * already been eliminated from the input. Retaining the paranoia
+ * check is still valuable, however.
+ */
+ return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
+ }
start = ptr;
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+# define LEAD_CASE(n) \
+ case BT_LEAD##n: \
+ ptr += n; \
+ break;
+ LEAD_CASE(2)
+ LEAD_CASE(3)
+ LEAD_CASE(4)
+# undef LEAD_CASE
case BT_AMP:
if (ptr == start)
return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
@@ -1276,8 +1346,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
return XML_TOK_DATA_CHARS;
case BT_PERCNT:
if (ptr == start) {
- int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
- end, nextTokPtr);
+ int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
}
*nextTokPtr = ptr;
@@ -1310,12 +1379,11 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
return XML_TOK_DATA_CHARS;
}
-#ifdef XML_DTD
+# ifdef XML_DTD
static int PTRCALL
-PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
+PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr) {
int level = 0;
if (MINBPC(enc) > 1) {
size_t n = end - ptr;
@@ -1326,7 +1394,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
}
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
- INVALID_CASES(ptr, nextTokPtr)
+ INVALID_CASES(ptr, nextTokPtr)
case BT_LT:
ptr += MINBPC(enc);
REQUIRE_CHAR(enc, ptr, end);
@@ -1363,12 +1431,11 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
return XML_TOK_PARTIAL;
}
-#endif /* XML_DTD */
+# endif /* XML_DTD */
static int PTRCALL
PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
- const char **badPtr)
-{
+ const char **badPtr) {
ptr += MINBPC(enc);
end -= MINBPC(enc);
for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
@@ -1391,9 +1458,9 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
case BT_AST:
case BT_PERCNT:
case BT_NUM:
-#ifdef XML_NS
+# ifdef XML_NS
case BT_COLON:
-#endif
+# endif
break;
case BT_S:
if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
@@ -1403,8 +1470,9 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
break;
case BT_NAME:
case BT_NMSTRT:
- if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+ if (! (BYTE_TO_ASCII(enc, ptr) & ~0x7f))
break;
+ /* fall through */
default:
switch (BYTE_TO_ASCII(enc, ptr)) {
case 0x24: /* $ */
@@ -1426,9 +1494,8 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
*/
static int PTRCALL
-PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
- int attsMax, ATTRIBUTE *atts)
-{
+PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
+ ATTRIBUTE *atts) {
enum { other, inName, inValue } state = inName;
int nAtts = 0;
int open = 0; /* defined when state == inValue;
@@ -1436,32 +1503,35 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
-#define START_NAME \
- if (state == other) { \
- if (nAtts < attsMax) { \
- atts[nAtts].name = ptr; \
- atts[nAtts].normalized = 1; \
- } \
- state = inName; \
- }
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+# define START_NAME \
+ if (state == other) { \
+ if (nAtts < attsMax) { \
+ atts[nAtts].name = ptr; \
+ atts[nAtts].normalized = 1; \
+ } \
+ state = inName; \
+ }
+# define LEAD_CASE(n) \
+ case BT_LEAD##n: \
+ START_NAME ptr += (n - MINBPC(enc)); \
+ break;
+ LEAD_CASE(2)
+ LEAD_CASE(3)
+ LEAD_CASE(4)
+# undef LEAD_CASE
case BT_NONASCII:
case BT_NMSTRT:
case BT_HEX:
START_NAME
break;
-#undef START_NAME
+# undef START_NAME
case BT_QUOT:
if (state != inValue) {
if (nAtts < attsMax)
atts[nAtts].valuePtr = ptr + MINBPC(enc);
state = inValue;
open = BT_QUOT;
- }
- else if (open == BT_QUOT) {
+ } else if (open == BT_QUOT) {
state = other;
if (nAtts < attsMax)
atts[nAtts].valueEnd = ptr;
@@ -1474,8 +1544,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
atts[nAtts].valuePtr = ptr + MINBPC(enc);
state = inValue;
open = BT_APOS;
- }
- else if (open == BT_APOS) {
+ } else if (open == BT_APOS) {
state = other;
if (nAtts < attsMax)
atts[nAtts].valueEnd = ptr;
@@ -1489,16 +1558,15 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
case BT_S:
if (state == inName)
state = other;
- else if (state == inValue
- && nAtts < attsMax
- && atts[nAtts].normalized
+ else if (state == inValue && nAtts < attsMax && atts[nAtts].normalized
&& (ptr == atts[nAtts].valuePtr
|| BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
|| BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
|| BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
atts[nAtts].normalized = 0;
break;
- case BT_CR: case BT_LF:
+ case BT_CR:
+ case BT_LF:
/* This case ensures that the first attribute name is counted
Apart from that we could just change state on the quote. */
if (state == inName)
@@ -1519,29 +1587,44 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
}
static int PTRFASTCALL
-PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
-{
+PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) {
int result = 0;
/* skip &# */
- ptr += 2*MINBPC(enc);
+ UNUSED_P(enc);
+ ptr += 2 * MINBPC(enc);
if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
- for (ptr += MINBPC(enc);
- !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
+ for (ptr += MINBPC(enc); ! CHAR_MATCHES(enc, ptr, ASCII_SEMI);
ptr += MINBPC(enc)) {
int c = BYTE_TO_ASCII(enc, ptr);
switch (c) {
- case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
- case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+ case ASCII_0:
+ case ASCII_1:
+ case ASCII_2:
+ case ASCII_3:
+ case ASCII_4:
+ case ASCII_5:
+ case ASCII_6:
+ case ASCII_7:
+ case ASCII_8:
+ case ASCII_9:
result <<= 4;
result |= (c - ASCII_0);
break;
- case ASCII_A: case ASCII_B: case ASCII_C:
- case ASCII_D: case ASCII_E: case ASCII_F:
+ case ASCII_A:
+ case ASCII_B:
+ case ASCII_C:
+ case ASCII_D:
+ case ASCII_E:
+ case ASCII_F:
result <<= 4;
result += 10 + (c - ASCII_A);
break;
- case ASCII_a: case ASCII_b: case ASCII_c:
- case ASCII_d: case ASCII_e: case ASCII_f:
+ case ASCII_a:
+ case ASCII_b:
+ case ASCII_c:
+ case ASCII_d:
+ case ASCII_e:
+ case ASCII_f:
result <<= 4;
result += 10 + (c - ASCII_a);
break;
@@ -1549,9 +1632,8 @@ PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
if (result >= 0x110000)
return -1;
}
- }
- else {
- for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+ } else {
+ for (; ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
int c = BYTE_TO_ASCII(enc, ptr);
result *= 10;
result += (c - ASCII_0);
@@ -1563,10 +1645,10 @@ PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
}
static int PTRCALL
-PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
- const char *end)
-{
- switch ((end - ptr)/MINBPC(enc)) {
+PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+ const char *end) {
+ UNUSED_P(enc);
+ switch ((end - ptr) / MINBPC(enc)) {
case 2:
if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
switch (BYTE_TO_ASCII(enc, ptr)) {
@@ -1617,97 +1699,42 @@ PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
}
static int PTRCALL
-PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
-{
- for (;;) {
- switch (BYTE_TYPE(enc, ptr1)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (*ptr1++ != *ptr2++) \
- return 0;
- LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
-#undef LEAD_CASE
- /* fall through */
- if (*ptr1++ != *ptr2++)
- return 0;
- break;
- case BT_NONASCII:
- case BT_NMSTRT:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- case BT_HEX:
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 1) {
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 2) {
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 3) {
- if (*ptr2++ != *ptr1++)
- return 0;
- }
- }
- }
- break;
- default:
- if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
- return 1;
- switch (BYTE_TYPE(enc, ptr2)) {
- case BT_LEAD2:
- case BT_LEAD3:
- case BT_LEAD4:
- case BT_NONASCII:
- case BT_NMSTRT:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- case BT_HEX:
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
- return 0;
- default:
- return 1;
- }
- }
- }
- /* not reached */
-}
-
-static int PTRCALL
-PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
- const char *end1, const char *ptr2)
-{
+PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+ const char *end1, const char *ptr2) {
+ UNUSED_P(enc);
for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
- if (end1 - ptr1 < MINBPC(enc))
- return 0;
- if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+ if (end1 - ptr1 < MINBPC(enc)) {
+ /* This line cannot be executed. The incoming data has already
+ * been tokenized once, so incomplete characters like this have
+ * already been eliminated from the input. Retaining the
+ * paranoia check is still valuable, however.
+ */
+ return 0; /* LCOV_EXCL_LINE */
+ }
+ if (! CHAR_MATCHES(enc, ptr1, *ptr2))
return 0;
}
return ptr1 == end1;
}
static int PTRFASTCALL
-PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
-{
+PREFIX(nameLength)(const ENCODING *enc, const char *ptr) {
const char *start = ptr;
for (;;) {
switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+# define LEAD_CASE(n) \
+ case BT_LEAD##n: \
+ ptr += n; \
+ break;
+ LEAD_CASE(2)
+ LEAD_CASE(3)
+ LEAD_CASE(4)
+# undef LEAD_CASE
case BT_NONASCII:
case BT_NMSTRT:
-#ifdef XML_NS
+# ifdef XML_NS
case BT_COLON:
-#endif
+# endif
case BT_HEX:
case BT_DIGIT:
case BT_NAME:
@@ -1720,9 +1747,8 @@ PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
}
}
-static const char * PTRFASTCALL
-PREFIX(skipS)(const ENCODING *enc, const char *ptr)
-{
+static const char *PTRFASTCALL
+PREFIX(skipS)(const ENCODING *enc, const char *ptr) {
for (;;) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_LF:
@@ -1737,19 +1763,18 @@ PREFIX(skipS)(const ENCODING *enc, const char *ptr)
}
static void PTRCALL
-PREFIX(updatePosition)(const ENCODING *enc,
- const char *ptr,
- const char *end,
- POSITION *pos)
-{
+PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end,
+ POSITION *pos) {
while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
+# define LEAD_CASE(n) \
+ case BT_LEAD##n: \
+ ptr += n; \
+ break;
+ LEAD_CASE(2)
+ LEAD_CASE(3)
+ LEAD_CASE(4)
+# undef LEAD_CASE
case BT_LF:
pos->columnNumber = (XML_Size)-1;
pos->lineNumber++;
@@ -1770,12 +1795,12 @@ PREFIX(updatePosition)(const ENCODING *enc,
}
}
-#undef DO_LEAD_CASE
-#undef MULTIBYTE_CASES
-#undef INVALID_CASES
-#undef CHECK_NAME_CASE
-#undef CHECK_NAME_CASES
-#undef CHECK_NMSTRT_CASE
-#undef CHECK_NMSTRT_CASES
+# undef DO_LEAD_CASE
+# undef MULTIBYTE_CASES
+# undef INVALID_CASES
+# undef CHECK_NAME_CASE
+# undef CHECK_NAME_CASES
+# undef CHECK_NMSTRT_CASE
+# undef CHECK_NMSTRT_CASES
#endif /* XML_TOK_IMPL_C */
diff --git a/freebsd/contrib/expat/lib/xmltok_impl.h b/freebsd/contrib/expat/lib/xmltok_impl.h
index da0ea60a..e925dbc7 100644
--- a/freebsd/contrib/expat/lib/xmltok_impl.h
+++ b/freebsd/contrib/expat/lib/xmltok_impl.h
@@ -1,46 +1,73 @@
/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
enum {
- BT_NONXML,
- BT_MALFORM,
- BT_LT,
- BT_AMP,
- BT_RSQB,
- BT_LEAD2,
- BT_LEAD3,
- BT_LEAD4,
- BT_TRAIL,
- BT_CR,
- BT_LF,
- BT_GT,
- BT_QUOT,
- BT_APOS,
- BT_EQUALS,
- BT_QUEST,
- BT_EXCL,
- BT_SOL,
- BT_SEMI,
- BT_NUM,
- BT_LSQB,
- BT_S,
- BT_NMSTRT,
- BT_COLON,
- BT_HEX,
- BT_DIGIT,
- BT_NAME,
- BT_MINUS,
- BT_OTHER, /* known not to be a name or name start character */
+ BT_NONXML, /* e.g. noncharacter-FFFF */
+ BT_MALFORM, /* illegal, with regard to encoding */
+ BT_LT, /* less than = "<" */
+ BT_AMP, /* ampersand = "&" */
+ BT_RSQB, /* right square bracket = "[" */
+ BT_LEAD2, /* lead byte of a 2-byte UTF-8 character */
+ BT_LEAD3, /* lead byte of a 3-byte UTF-8 character */
+ BT_LEAD4, /* lead byte of a 4-byte UTF-8 character */
+ BT_TRAIL, /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */
+ BT_CR, /* carriage return = "\r" */
+ BT_LF, /* line feed = "\n" */
+ BT_GT, /* greater than = ">" */
+ BT_QUOT, /* quotation character = "\"" */
+ BT_APOS, /* aposthrophe = "'" */
+ BT_EQUALS, /* equal sign = "=" */
+ BT_QUEST, /* question mark = "?" */
+ BT_EXCL, /* exclamation mark = "!" */
+ BT_SOL, /* solidus, slash = "/" */
+ BT_SEMI, /* semicolon = ";" */
+ BT_NUM, /* number sign = "#" */
+ BT_LSQB, /* left square bracket = "[" */
+ BT_S, /* white space, e.g. "\t", " "[, "\r"] */
+ BT_NMSTRT, /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */
+ BT_COLON, /* colon = ":" */
+ BT_HEX, /* hex letter = "A".."F" + "a".."f" */
+ BT_DIGIT, /* digit = "0".."9" */
+ BT_NAME, /* dot and middle dot = "." + chr(0xb7) */
+ BT_MINUS, /* minus = "-" */
+ BT_OTHER, /* known not to be a name or name start character */
BT_NONASCII, /* might be a name or name start character */
- BT_PERCNT,
- BT_LPAR,
- BT_RPAR,
- BT_AST,
- BT_PLUS,
- BT_COMMA,
- BT_VERBAR
+ BT_PERCNT, /* percent sign = "%" */
+ BT_LPAR, /* left parenthesis = "(" */
+ BT_RPAR, /* right parenthesis = "(" */
+ BT_AST, /* asterisk = "*" */
+ BT_PLUS, /* plus sign = "+" */
+ BT_COMMA, /* comma = "," */
+ BT_VERBAR /* vertical bar = "|" */
};
#include <stddef.h>
diff --git a/freebsd/contrib/expat/lib/xmltok_ns.c b/freebsd/contrib/expat/lib/xmltok_ns.c
index f6a7281f..e73b0c2b 100644
--- a/freebsd/contrib/expat/lib/xmltok_ns.c
+++ b/freebsd/contrib/expat/lib/xmltok_ns.c
@@ -1,63 +1,81 @@
#include <machine/rtems-bsd-user-space.h>
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
+/* This file is included!
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/* This file is included! */
#ifdef XML_TOK_NS_C
const ENCODING *
-NS(XmlGetUtf8InternalEncoding)(void)
-{
+NS(XmlGetUtf8InternalEncoding)(void) {
return &ns(internal_utf8_encoding).enc;
}
const ENCODING *
-NS(XmlGetUtf16InternalEncoding)(void)
-{
-#if BYTEORDER == 1234
+NS(XmlGetUtf16InternalEncoding)(void) {
+# if BYTEORDER == 1234
return &ns(internal_little2_encoding).enc;
-#elif BYTEORDER == 4321
+# elif BYTEORDER == 4321
return &ns(internal_big2_encoding).enc;
-#else
+# else
const short n = 1;
- return (*(const char *)&n
- ? &ns(internal_little2_encoding).enc
- : &ns(internal_big2_encoding).enc);
-#endif
+ return (*(const char *)&n ? &ns(internal_little2_encoding).enc
+ : &ns(internal_big2_encoding).enc);
+# endif
}
-static const ENCODING * const NS(encodings)[] = {
- &ns(latin1_encoding).enc,
- &ns(ascii_encoding).enc,
- &ns(utf8_encoding).enc,
- &ns(big2_encoding).enc,
- &ns(big2_encoding).enc,
- &ns(little2_encoding).enc,
- &ns(utf8_encoding).enc /* NO_ENC */
+static const ENCODING *const NS(encodings)[] = {
+ &ns(latin1_encoding).enc, &ns(ascii_encoding).enc,
+ &ns(utf8_encoding).enc, &ns(big2_encoding).enc,
+ &ns(big2_encoding).enc, &ns(little2_encoding).enc,
+ &ns(utf8_encoding).enc /* NO_ENC */
};
static int PTRCALL
NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- return initScan(NS(encodings), (const INIT_ENCODING *)enc,
- XML_PROLOG_STATE, ptr, end, nextTokPtr);
+ const char **nextTokPtr) {
+ return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE,
+ ptr, end, nextTokPtr);
}
static int PTRCALL
NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- return initScan(NS(encodings), (const INIT_ENCODING *)enc,
- XML_CONTENT_STATE, ptr, end, nextTokPtr);
+ const char **nextTokPtr) {
+ return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE,
+ ptr, end, nextTokPtr);
}
int
NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
- const char *name)
-{
+ const char *name) {
int i = getEncodingIndex(name);
if (i == UNKNOWN_ENC)
return 0;
@@ -71,9 +89,8 @@ NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
}
static const ENCODING *
-NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
-{
-#define ENCODING_MAX 128
+NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) {
+# define ENCODING_MAX 128
char buf[ENCODING_MAX];
char *p = buf;
int i;
@@ -90,28 +107,14 @@ NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
}
int
-NS(XmlParseXmlDecl)(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingName,
- const ENCODING **encoding,
- int *standalone)
-{
- return doParseXmlDecl(NS(findEncoding),
- isGeneralTextEntity,
- enc,
- ptr,
- end,
- badPtr,
- versionPtr,
- versionEndPtr,
- encodingName,
- encoding,
- standalone);
+NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc,
+ const char *ptr, const char *end, const char **badPtr,
+ const char **versionPtr, const char **versionEndPtr,
+ const char **encodingName, const ENCODING **encoding,
+ int *standalone) {
+ return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end,
+ badPtr, versionPtr, versionEndPtr, encodingName,
+ encoding, standalone);
}
#endif /* XML_TOK_NS_C */
diff --git a/freebsd/contrib/libpcap/diag-control.h b/freebsd/contrib/libpcap/diag-control.h
index 12770361..cfc581b3 100644
--- a/freebsd/contrib/libpcap/diag-control.h
+++ b/freebsd/contrib/libpcap/diag-control.h
@@ -120,13 +120,14 @@
* shadowing the global declaration.
*
* So, if the compiler warns about that, we turn off -Wshadow warnings.
+ *
+ * In addition, the generated code may have functions with unreachable
+ * code, so suppress warnings about those.
*/
#if defined(_MSC_VER)
/*
* This is Microsoft Visual Studio; we can use
* __pragma(warning(disable:XXXX)) and __pragma(warning(push/pop)).
- *
- * Suppress unreachable code warnings.
*/
#define DIAG_OFF_BISON_BYACC \
__pragma(warning(push)) \
@@ -166,6 +167,9 @@
#else
/*
* Bison.
+ *
+ * The generated code may have functions with unreachable code, so
+ * suppress warnings about those.
*/
#if defined(_MSC_VER)
/*
diff --git a/freebsd/contrib/libpcap/fmtutils.c b/freebsd/contrib/libpcap/fmtutils.c
index ae550e24..2363811e 100644
--- a/freebsd/contrib/libpcap/fmtutils.c
+++ b/freebsd/contrib/libpcap/fmtutils.c
@@ -67,11 +67,6 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
size_t msglen;
char *p;
size_t errbuflen_remaining;
-#if defined(HAVE_STRERROR_S)
- errno_t err;
-#elif defined(HAVE_STRERROR_R)
- int err;
-#endif
va_start(ap, fmt);
pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
@@ -98,7 +93,10 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
* Now append the string for the error code.
*/
#if defined(HAVE_STRERROR_S)
- err = strerror_s(p, errbuflen_remaining, errnum);
+ /*
+ * We have a Windows-style strerror_s().
+ */
+ errno_t err = strerror_s(p, errbuflen_remaining, errnum);
if (err != 0) {
/*
* It doesn't appear to be documented anywhere obvious
@@ -106,8 +104,24 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
*/
pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
}
-#elif defined(HAVE_STRERROR_R)
- err = strerror_r(errnum, p, errbuflen_remaining);
+#elif defined(HAVE_GNU_STRERROR_R)
+ /*
+ * We have a GNU-style strerror_r(), which is *not* guaranteed to
+ * do anything to the buffer handed to it, and which returns a
+ * pointer to the error string, which may or may not be in
+ * the buffer.
+ *
+ * It is, however, guaranteed to succeed.
+ */
+ char strerror_buf[PCAP_ERRBUF_SIZE];
+ char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
+ pcap_snprintf(p, errbuflen_remaining, "%s", errstring);
+#elif defined(HAVE_POSIX_STRERROR_R)
+ /*
+ * We have a POSIX-style strerror_r(), which is guaranteed to fill
+ * in the buffer, but is not guaranteed to succeed.
+ */
+ int err = strerror_r(errnum, p, errbuflen_remaining);
if (err == EINVAL) {
/*
* UNIX 03 says this isn't guaranteed to produce a
@@ -131,3 +145,72 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
#endif
}
+
+#ifdef _WIN32
+/*
+ * Generate an error message based on a format, arguments, and a
+ * Win32 error, with a message for the Win32 error after the formatted output.
+ */
+void
+pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
+ const char *fmt, ...)
+{
+ va_list ap;
+ size_t msglen;
+ char *p;
+ size_t errbuflen_remaining;
+ DWORD retval;
+ char win32_errbuf[PCAP_ERRBUF_SIZE+1];
+
+ va_start(ap, fmt);
+ pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
+ va_end(ap);
+ msglen = strlen(errbuf);
+
+ /*
+ * Do we have enough space to append ": "?
+ * Including the terminating '\0', that's 3 bytes.
+ */
+ if (msglen + 3 > errbuflen) {
+ /* No - just give them what we've produced. */
+ return;
+ }
+ p = errbuf + msglen;
+ errbuflen_remaining = errbuflen - msglen;
+ *p++ = ':';
+ *p++ = ' ';
+ *p = '\0';
+ msglen += 2;
+ errbuflen_remaining -= 2;
+
+ /*
+ * Now append the string for the error code.
+ *
+ * XXX - what language ID to use?
+ *
+ * For UN*Xes, pcap_strerror() may or may not return localized
+ * strings.
+ *
+ * We currently don't have localized messages for libpcap, but
+ * we might want to do so. On the other hand, if most of these
+ * messages are going to be read by libpcap developers and
+ * perhaps by developers of libpcap-based applications, English
+ * might be a better choice, so the developer doesn't have to
+ * get the message translated if it's in a language they don't
+ * happen to understand.
+ */
+ retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ win32_errbuf, PCAP_ERRBUF_SIZE, NULL);
+ if (retval == 0) {
+ /*
+ * Failed.
+ */
+ pcap_snprintf(p, errbuflen_remaining,
+ "Couldn't get error message for error (%lu)", errnum);
+ return;
+ }
+
+ pcap_snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum);
+}
+#endif
diff --git a/freebsd/contrib/libpcap/fmtutils.h b/freebsd/contrib/libpcap/fmtutils.h
index 62c78fdb..838948bc 100644
--- a/freebsd/contrib/libpcap/fmtutils.h
+++ b/freebsd/contrib/libpcap/fmtutils.h
@@ -43,6 +43,11 @@ extern "C" {
void pcap_fmt_errmsg_for_errno(char *, size_t, int,
PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
+#ifdef _WIN32
+void pcap_fmt_errmsg_for_win32_err(char *, size_t, DWORD,
+ PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(4, 5);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/freebsd/contrib/libpcap/ftmacros.h b/freebsd/contrib/libpcap/ftmacros.h
index de8da98e..cd3daebd 100644
--- a/freebsd/contrib/libpcap/ftmacros.h
+++ b/freebsd/contrib/libpcap/ftmacros.h
@@ -85,20 +85,14 @@
*/
#elif defined(__linux__) || defined(linux) || defined(__linux)
/*
- * We can't turn _GNU_SOURCE on because some versions of GNU Libc
- * will give the GNU version of strerror_r(), which returns a
- * string pointer and doesn't necessarily fill in the buffer,
- * rather than the standard version of strerror_r(), which
- * returns 0 or an errno and always fills in the buffer. We
- * require both of the latter behaviors.
+ * Turn on _GNU_SOURCE to get everything GNU libc has to offer,
+ * including asprintf().
*
- * So we try turning everything else on that we can. This includes
- * defining _XOPEN_SOURCE as 600, because we want to force crypt()
- * to be declared on systems that use GNU libc, such as most Linux
- * distributions.
+ * Unfortunately, one thing it has to offer is a strerror_r()
+ * that's not POSIX-compliant, but we deal with that in
+ * pcap_fmt_errmsg_for_errno().
*/
- #define _POSIX_C_SOURCE 200809L
- #define _XOPEN_SOURCE 600
+ #define _GNU_SOURCE
/*
* We turn on both _DEFAULT_SOURCE and _BSD_SOURCE to try to get
diff --git a/freebsd/contrib/libpcap/gencode.c b/freebsd/contrib/libpcap/gencode.c
index df75cacd..7ae486fa 100644
--- a/freebsd/contrib/libpcap/gencode.c
+++ b/freebsd/contrib/libpcap/gencode.c
@@ -52,6 +52,8 @@
#include "pcap-int.h"
+#include "extract.h"
+
#include "ethertype.h"
#include "nlpid.h"
#include "llc.h"
@@ -279,6 +281,13 @@ struct _compiler_state {
struct addrinfo *ai;
/*
+ * Another thing that's allocated is the result of pcap_ether_aton();
+ * it must be freed with free(). This variable points to any
+ * address that would need to be freed.
+ */
+ u_char *e;
+
+ /*
* Various code constructs need to know the layout of the packet.
* These values give the necessary offsets from the beginning
* of the packet data.
@@ -419,35 +428,49 @@ struct _compiler_state {
int cur_chunk;
};
-void PCAP_NORETURN
-bpf_syntax_error(compiler_state_t *cstate, const char *msg)
+/*
+ * For use by routines outside this file.
+ */
+/* VARARGS */
+void
+bpf_set_error(compiler_state_t *cstate, const char *fmt, ...)
{
- bpf_error(cstate, "syntax error in filter expression: %s", msg);
- /* NOTREACHED */
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)pcap_vsnprintf(cstate->bpf_pcap->errbuf, PCAP_ERRBUF_SIZE,
+ fmt, ap);
+ va_end(ap);
}
+/*
+ * For use *ONLY* in routines in this file.
+ */
+static void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
+ PCAP_PRINTFLIKE(2, 3);
+
/* VARARGS */
-void PCAP_NORETURN
+static void PCAP_NORETURN
bpf_error(compiler_state_t *cstate, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- if (cstate->bpf_pcap != NULL)
- (void)pcap_vsnprintf(pcap_geterr(cstate->bpf_pcap),
- PCAP_ERRBUF_SIZE, fmt, ap);
+ (void)pcap_vsnprintf(cstate->bpf_pcap->errbuf, PCAP_ERRBUF_SIZE,
+ fmt, ap);
va_end(ap);
longjmp(cstate->top_ctx, 1);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
-static void init_linktype(compiler_state_t *, pcap_t *);
+static int init_linktype(compiler_state_t *, pcap_t *);
static void init_regs(compiler_state_t *);
static int alloc_reg(compiler_state_t *);
static void free_reg(compiler_state_t *, int);
static void initchunks(compiler_state_t *cstate);
+static void *newchunk_nolongjmp(compiler_state_t *cstate, size_t);
static void *newchunk(compiler_state_t *cstate, size_t);
static void freechunks(compiler_state_t *cstate);
static inline struct block *new_block(compiler_state_t *cstate, int);
@@ -545,6 +568,9 @@ static struct block *gen_check_802_11_data_frame(compiler_state_t *);
static struct block *gen_geneve_ll_check(compiler_state_t *cstate);
static struct block *gen_ppi_dlt_check(compiler_state_t *);
+static struct block *gen_atmfield_code_internal(compiler_state_t *, int,
+ bpf_int32, bpf_u_int32, int);
+static struct block *gen_atmtype_llc(compiler_state_t *);
static struct block *gen_msg_abbrev(compiler_state_t *, int type);
static void
@@ -560,7 +586,7 @@ initchunks(compiler_state_t *cstate)
}
static void *
-newchunk(compiler_state_t *cstate, size_t n)
+newchunk_nolongjmp(compiler_state_t *cstate, size_t n)
{
struct chunk *cp;
int k;
@@ -578,21 +604,40 @@ newchunk(compiler_state_t *cstate, size_t n)
if (n > cp->n_left) {
++cp;
k = ++cstate->cur_chunk;
- if (k >= NCHUNKS)
- bpf_error(cstate, "out of memory");
+ if (k >= NCHUNKS) {
+ bpf_set_error(cstate, "out of memory");
+ return (NULL);
+ }
size = CHUNK0SIZE << k;
cp->m = (void *)malloc(size);
- if (cp->m == NULL)
- bpf_error(cstate, "out of memory");
+ if (cp->m == NULL) {
+ bpf_set_error(cstate, "out of memory");
+ return (NULL);
+ }
memset((char *)cp->m, 0, size);
cp->n_left = size;
- if (n > size)
- bpf_error(cstate, "out of memory");
+ if (n > size) {
+ bpf_set_error(cstate, "out of memory");
+ return (NULL);
+ }
}
cp->n_left -= n;
return (void *)((char *)cp->m + cp->n_left);
}
+static void *
+newchunk(compiler_state_t *cstate, size_t n)
+{
+ void *p;
+
+ p = newchunk_nolongjmp(cstate, n);
+ if (p == NULL) {
+ longjmp(cstate->top_ctx, 1);
+ /*NOTREACHED*/
+ }
+ return (p);
+}
+
static void
freechunks(compiler_state_t *cstate)
{
@@ -605,14 +650,19 @@ freechunks(compiler_state_t *cstate)
/*
* A strdup whose allocations are freed after code generation is over.
+ * This is used by the lexical analyzer, so it can't longjmp; it just
+ * returns NULL on an allocation error, and the callers must check
+ * for it.
*/
char *
sdup(compiler_state_t *cstate, const char *s)
{
size_t n = strlen(s) + 1;
- char *cp = newchunk(cstate, n);
+ char *cp = newchunk_nolongjmp(cstate, n);
- strlcpy(cp, s, n);
+ if (cp == NULL)
+ return (NULL);
+ pcap_strlcpy(cp, s, n);
return (cp);
}
@@ -664,7 +714,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
compiler_state_t cstate;
const char * volatile xbuf = buf;
yyscan_t scanner = NULL;
- YY_BUFFER_STATE in_buffer = NULL;
+ volatile YY_BUFFER_STATE in_buffer = NULL;
u_int len;
int rc;
@@ -699,7 +749,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
* filter for this pcap_t; we might be running it from userland
* on captured packets to do packet classification. We really
* need a better way of handling this, but this is all that
- * the WinPcap code did.
+ * the WinPcap remote capture code did.
*/
if (p->save_current_filter_op != NULL)
(p->save_current_filter_op)(p, buf);
@@ -710,20 +760,12 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
#ifdef INET6
cstate.ai = NULL;
#endif
+ cstate.e = NULL;
cstate.ic.root = NULL;
cstate.ic.cur_mark = 0;
cstate.bpf_pcap = p;
init_regs(&cstate);
- if (setjmp(cstate.top_ctx)) {
-#ifdef INET6
- if (cstate.ai != NULL)
- freeaddrinfo(cstate.ai);
-#endif
- rc = -1;
- goto quit;
- }
-
cstate.netmask = mask;
cstate.snaplen = pcap_snapshot(p);
@@ -745,19 +787,53 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
*/
pcap_set_extra(&cstate, scanner);
- init_linktype(&cstate, p);
- (void)pcap_parse(scanner, &cstate);
+ if (init_linktype(&cstate, p) == -1) {
+ rc = -1;
+ goto quit;
+ }
+ if (pcap_parse(scanner, &cstate) != 0) {
+#ifdef INET6
+ if (cstate.ai != NULL)
+ freeaddrinfo(cstate.ai);
+#endif
+ if (cstate.e != NULL)
+ free(cstate.e);
+ rc = -1;
+ goto quit;
+ }
- if (cstate.ic.root == NULL)
+ if (cstate.ic.root == NULL) {
+ /*
+ * Catch errors reported by gen_retblk().
+ */
+ if (setjmp(cstate.top_ctx)) {
+ rc = -1;
+ goto quit;
+ }
cstate.ic.root = gen_retblk(&cstate, cstate.snaplen);
+ }
if (optimize && !cstate.no_optimize) {
- bpf_optimize(&cstate, &cstate.ic);
+ if (bpf_optimize(&cstate.ic, p->errbuf) == -1) {
+ /* Failure */
+ rc = -1;
+ goto quit;
+ }
if (cstate.ic.root == NULL ||
- (cstate.ic.root->s.code == (BPF_RET|BPF_K) && cstate.ic.root->s.k == 0))
- bpf_error(&cstate, "expression rejects all packets");
+ (cstate.ic.root->s.code == (BPF_RET|BPF_K) && cstate.ic.root->s.k == 0)) {
+ (void)pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "expression rejects all packets");
+ rc = -1;
+ goto quit;
+ }
+ }
+ program->bf_insns = icode_to_fcode(&cstate.ic,
+ cstate.ic.root, &len, p->errbuf);
+ if (program->bf_insns == NULL) {
+ /* Failure */
+ rc = -1;
+ goto quit;
}
- program->bf_insns = icode_to_fcode(&cstate, &cstate.ic, cstate.ic.root, &len);
program->bf_len = len;
rc = 0; /* We're all okay */
@@ -853,12 +929,19 @@ merge(struct block *b0, struct block *b1)
*p = b1;
}
-void
+int
finish_parse(compiler_state_t *cstate, struct block *p)
{
struct block *ppi_dlt_check;
/*
+ * Catch errors reported by us and routines below us, and return -1
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (-1);
+
+ /*
* Insert before the statements of the first (root) block any
* statements needed to load the lengths of any variable-length
* headers into registers.
@@ -900,6 +983,7 @@ finish_parse(compiler_state_t *cstate, struct block *p)
p->sense = !p->sense;
backpatch(p, gen_retblk(cstate, 0));
cstate->ic.root = p->head;
+ return (0);
}
void
@@ -977,13 +1061,22 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
{
register struct block *b, *tmp;
+ /*
+ * XXX - the actual *instructions* do unsigned comparisons on
+ * most platforms, and the load instructions don't do sign
+ * extension, so gen_cmp() should really take an unsigned
+ * value argument.
+ *
+ * As the load instructons also don't do sign-extension, we
+ * fetch the values from the byte array as unsigned. We don't
+ * want to use the signed versions of the extract calls.
+ */
b = NULL;
while (size >= 4) {
register const u_char *p = &v[size - 4];
- bpf_int32 w = ((bpf_int32)p[0] << 24) |
- ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3];
- tmp = gen_cmp(cstate, offrel, offset + size - 4, BPF_W, w);
+ tmp = gen_cmp(cstate, offrel, offset + size - 4, BPF_W,
+ (bpf_int32)EXTRACT_32BITS(p));
if (b != NULL)
gen_and(b, tmp);
b = tmp;
@@ -991,9 +1084,9 @@ gen_bcmp(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
}
while (size >= 2) {
register const u_char *p = &v[size - 2];
- bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1];
- tmp = gen_cmp(cstate, offrel, offset + size - 2, BPF_H, w);
+ tmp = gen_cmp(cstate, offrel, offset + size - 2, BPF_H,
+ (bpf_int32)EXTRACT_16BITS(p));
if (b != NULL)
gen_and(b, tmp);
b = tmp;
@@ -1038,7 +1131,7 @@ gen_ncmp(compiler_state_t *cstate, enum e_offrel offrel, bpf_u_int32 offset,
return b;
}
-static void
+static int
init_linktype(compiler_state_t *cstate, pcap_t *p)
{
cstate->pcap_fddipad = p->fddipad;
@@ -1243,6 +1336,7 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_linkhdr.is_variable = 1;
/* Fall through, 802.11 doesn't have a variable link
* prefix but is otherwise the same. */
+ /* FALLTHROUGH */
case DLT_IEEE802_11:
/*
@@ -1332,13 +1426,20 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_nl_nosnap = 0; /* no 802.2 LLC */
break;
- case DLT_LINUX_SLL: /* fake header for Linux cooked socket */
+ case DLT_LINUX_SLL: /* fake header for Linux cooked socket v1 */
cstate->off_linktype.constant_part = 14;
cstate->off_linkpl.constant_part = 16;
cstate->off_nl = 0;
cstate->off_nl_nosnap = 0; /* no 802.2 LLC */
break;
+ case DLT_LINUX_SLL2: /* fake header for Linux cooked socket v2 */
+ cstate->off_linktype.constant_part = 0;
+ cstate->off_linkpl.constant_part = 20;
+ cstate->off_nl = 0;
+ cstate->off_nl_nosnap = 0; /* no 802.2 LLC */
+ break;
+
case DLT_LTALK:
/*
* LocalTalk does have a 1-byte type field in the LLAP header,
@@ -1614,12 +1715,14 @@ init_linktype(compiler_state_t *cstate, pcap_t *p)
cstate->off_nl = OFFSET_NOT_SET;
cstate->off_nl_nosnap = OFFSET_NOT_SET;
} else {
- bpf_error(cstate, "unknown data link type %d", cstate->linktype);
+ bpf_set_error(cstate, "unknown data link type %d", cstate->linktype);
+ return (-1);
}
break;
}
cstate->off_outermostlinkhdr = cstate->off_prevlinkhdr = cstate->off_linkhdr;
+ return (0);
}
/*
@@ -1671,6 +1774,19 @@ gen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
{
struct slist *s, *s2;
+ /*
+ * Squelch warnings from compilers that *don't* assume that
+ * offrel always has a valid enum value and therefore don't
+ * assume that we'll always go through one of the case arms.
+ *
+ * If we have a default case, compilers that *do* assume that
+ * will then complain about the default case code being
+ * unreachable.
+ *
+ * Damned if you do, damned if you don't.
+ */
+ s = NULL;
+
switch (offrel) {
case OR_PACKET:
@@ -1734,10 +1850,6 @@ gen_load_a(compiler_state_t *cstate, enum e_offrel offrel, u_int offset,
case OR_TRAN_IPV6:
s = gen_load_absoffsetrel(cstate, &cstate->off_linkpl, cstate->off_nl + 40 + offset, size);
break;
-
- default:
- abort();
- /* NOTREACHED */
}
return s;
}
@@ -2061,12 +2173,12 @@ gen_ipnet_linktype(compiler_state_t *cstate, int proto)
case ETHERTYPE_IP:
return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B, (bpf_int32)IPH_AF_INET);
- /* NOTREACHED */
+ /*NOTREACHED*/
case ETHERTYPE_IPV6:
return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_B,
(bpf_int32)IPH_AF_INET6);
- /* NOTREACHED */
+ /*NOTREACHED*/
default:
break;
@@ -3043,7 +3155,7 @@ gen_linktype(compiler_state_t *cstate, int proto)
default:
bpf_error(cstate, "unsupported protocol over mpls");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
}
@@ -3064,7 +3176,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
gen_and(b0, b1);
return b1;
/*NOTREACHED*/
- break;
case DLT_C_HDLC:
switch (proto) {
@@ -3076,9 +3187,7 @@ gen_linktype(compiler_state_t *cstate, int proto)
default:
return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
/*NOTREACHED*/
- break;
}
- break;
case DLT_IEEE802_11:
case DLT_PRISM_HEADER:
@@ -3097,7 +3206,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
gen_and(b0, b1);
return b1;
/*NOTREACHED*/
- break;
case DLT_FDDI:
/*
@@ -3105,7 +3213,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
*/
return gen_llc_linktype(cstate, proto);
/*NOTREACHED*/
- break;
case DLT_IEEE802:
/*
@@ -3113,14 +3220,12 @@ gen_linktype(compiler_state_t *cstate, int proto)
*/
return gen_llc_linktype(cstate, proto);
/*NOTREACHED*/
- break;
case DLT_ATM_RFC1483:
case DLT_ATM_CLIP:
case DLT_IP_OVER_FC:
return gen_llc_linktype(cstate, proto);
/*NOTREACHED*/
- break;
case DLT_SUNATM:
/*
@@ -3130,17 +3235,15 @@ gen_linktype(compiler_state_t *cstate, int proto)
*
* Check for LLC encapsulation and then check the protocol.
*/
- b0 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+ b0 = gen_atmfield_code_internal(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
b1 = gen_llc_linktype(cstate, proto);
gen_and(b0, b1);
return b1;
/*NOTREACHED*/
- break;
case DLT_LINUX_SLL:
return gen_linux_sll_linktype(cstate, proto);
/*NOTREACHED*/
- break;
case DLT_SLIP:
case DLT_SLIP_BSDOS:
@@ -3166,7 +3269,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
return gen_false(cstate); /* always false */
}
/*NOTREACHED*/
- break;
case DLT_IPV4:
/*
@@ -3178,7 +3280,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
/* Checking for something other than IPv4; always false */
return gen_false(cstate);
/*NOTREACHED*/
- break;
case DLT_IPV6:
/*
@@ -3190,7 +3291,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
/* Checking for something other than IPv6; always false */
return gen_false(cstate);
/*NOTREACHED*/
- break;
case DLT_PPP:
case DLT_PPP_PPPD:
@@ -3203,7 +3303,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
proto = ethertype_to_ppptype(proto);
return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
/*NOTREACHED*/
- break;
case DLT_PPP_BSDOS:
/*
@@ -3230,7 +3329,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
(bpf_int32)proto);
}
/*NOTREACHED*/
- break;
case DLT_NULL:
case DLT_LOOP:
@@ -3325,7 +3423,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
else
return gen_false(cstate);
/*NOTREACHED*/
- break;
#endif /* HAVE_NET_PFVAR_H */
case DLT_ARCNET:
@@ -3368,7 +3465,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
(bpf_int32)ARCTYPE_ATALK));
}
/*NOTREACHED*/
- break;
case DLT_LTALK:
switch (proto) {
@@ -3378,7 +3474,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
return gen_false(cstate);
}
/*NOTREACHED*/
- break;
case DLT_FRELAY:
/*
@@ -3422,7 +3517,6 @@ gen_linktype(compiler_state_t *cstate, int proto)
return gen_false(cstate);
}
/*NOTREACHED*/
- break;
case DLT_MFR:
bpf_error(cstate, "Multi-link Frame Relay link-layer type filtering not implemented");
@@ -3513,7 +3607,8 @@ gen_linktype(compiler_state_t *cstate, int proto)
case DLT_RAIF1:
bpf_error(cstate, "RAIF1 link-layer type filtering not implemented");
- case DLT_IPMB:
+ case DLT_IPMB_KONTRON:
+ case DLT_IPMB_LINUX:
bpf_error(cstate, "IPMB link-layer type filtering not implemented");
case DLT_AX25_KISS:
@@ -3540,20 +3635,16 @@ gen_linktype(compiler_state_t *cstate, int proto)
* above.)
*/
return gen_cmp(cstate, OR_LINKTYPE, 0, BPF_H, (bpf_int32)proto);
+ /*NOTREACHED */
} else {
/*
* No; report an error.
*/
- description = pcap_datalink_val_to_description(cstate->linktype);
- if (description != NULL) {
- bpf_error(cstate, "%s link-layer type filtering not implemented",
- description);
- } else {
- bpf_error(cstate, "DLT %u link-layer type filtering not implemented",
- cstate->linktype);
- }
+ description = pcap_datalink_val_to_description_or_dlt(cstate->linktype);
+ bpf_error(cstate, "%s link-layer type filtering not implemented",
+ description);
+ /*NOTREACHED */
}
- break;
}
}
@@ -3583,8 +3674,8 @@ gen_snap(compiler_state_t *cstate, bpf_u_int32 orgcode, bpf_u_int32 ptype)
/*
* Generate code to match frames with an LLC header.
*/
-struct block *
-gen_llc(compiler_state_t *cstate)
+static struct block *
+gen_llc_internal(compiler_state_t *cstate)
{
struct block *b0, *b1;
@@ -3611,7 +3702,7 @@ gen_llc(compiler_state_t *cstate)
/*
* We check for LLC traffic.
*/
- b0 = gen_atmtype_abbrev(cstate, A_LLC);
+ b0 = gen_atmtype_llc(cstate);
return b0;
case DLT_IEEE802: /* Token Ring */
@@ -3649,21 +3740,42 @@ gen_llc(compiler_state_t *cstate)
return b0;
default:
- bpf_error(cstate, "'llc' not supported for linktype %d", cstate->linktype);
- /* NOTREACHED */
+ bpf_error(cstate, "'llc' not supported for %s",
+ pcap_datalink_val_to_description_or_dlt(cstate->linktype));
+ /*NOTREACHED*/
}
}
struct block *
+gen_llc(compiler_state_t *cstate)
+{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ return gen_llc_internal(cstate);
+}
+
+struct block *
gen_llc_i(compiler_state_t *cstate)
{
struct block *b0, *b1;
struct slist *s;
/*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ /*
* Check whether this is an LLC frame.
*/
- b0 = gen_llc(cstate);
+ b0 = gen_llc_internal(cstate);
/*
* Load the control byte and test the low-order bit; it must
@@ -3684,9 +3796,16 @@ gen_llc_s(compiler_state_t *cstate)
struct block *b0, *b1;
/*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ /*
* Check whether this is an LLC frame.
*/
- b0 = gen_llc(cstate);
+ b0 = gen_llc_internal(cstate);
/*
* Now compare the low-order 2 bit of the control byte against
@@ -3703,9 +3822,16 @@ gen_llc_u(compiler_state_t *cstate)
struct block *b0, *b1;
/*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ /*
* Check whether this is an LLC frame.
*/
- b0 = gen_llc(cstate);
+ b0 = gen_llc_internal(cstate);
/*
* Now compare the low-order 2 bit of the control byte against
@@ -3722,9 +3848,16 @@ gen_llc_s_subtype(compiler_state_t *cstate, bpf_u_int32 subtype)
struct block *b0, *b1;
/*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ /*
* Check whether this is an LLC frame.
*/
- b0 = gen_llc(cstate);
+ b0 = gen_llc_internal(cstate);
/*
* Now check for an S frame with the appropriate type.
@@ -3740,9 +3873,16 @@ gen_llc_u_subtype(compiler_state_t *cstate, bpf_u_int32 subtype)
struct block *b0, *b1;
/*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ /*
* Check whether this is an LLC frame.
*/
- b0 = gen_llc(cstate);
+ b0 = gen_llc_internal(cstate);
/*
* Now check for a U frame with the appropriate type.
@@ -3862,8 +4002,8 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
gen_and(b0, b1);
return b1;
- case Q_OR:
case Q_DEFAULT:
+ case Q_OR:
b0 = gen_hostop(cstate, addr, mask, Q_SRC, proto, src_off, dst_off);
b1 = gen_hostop(cstate, addr, mask, Q_DST, proto, src_off, dst_off);
gen_or(b0, b1);
@@ -3871,30 +4011,31 @@ gen_hostop(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
case Q_ADDR1:
bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_ADDR2:
bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_ADDR3:
bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_ADDR4:
bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_RA:
bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_TA:
bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
default:
abort();
+ /*NOTREACHED*/
}
b0 = gen_linktype(cstate, proto);
b1 = gen_mcmp(cstate, OR_LINKPL, offset, BPF_W, (bpf_int32)addr, mask);
@@ -3927,8 +4068,8 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
gen_and(b0, b1);
return b1;
- case Q_OR:
case Q_DEFAULT:
+ case Q_OR:
b0 = gen_hostop6(cstate, addr, mask, Q_SRC, proto, src_off, dst_off);
b1 = gen_hostop6(cstate, addr, mask, Q_DST, proto, src_off, dst_off);
gen_or(b0, b1);
@@ -3936,30 +4077,31 @@ gen_hostop6(compiler_state_t *cstate, struct in6_addr *addr,
case Q_ADDR1:
bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_ADDR2:
bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_ADDR3:
bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_ADDR4:
bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_RA:
bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
case Q_TA:
bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
- break;
+ /*NOTREACHED*/
default:
abort();
+ /*NOTREACHED*/
}
/* this order is important */
a = (uint32_t *)addr;
@@ -4004,30 +4146,30 @@ gen_ehostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
case Q_ADDR1:
bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11 with 802.11 headers");
- break;
+ /*NOTREACHED*/
case Q_ADDR2:
bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11 with 802.11 headers");
- break;
+ /*NOTREACHED*/
case Q_ADDR3:
bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11 with 802.11 headers");
- break;
+ /*NOTREACHED*/
case Q_ADDR4:
bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11 with 802.11 headers");
- break;
+ /*NOTREACHED*/
case Q_RA:
bpf_error(cstate, "'ra' is only supported on 802.11 with 802.11 headers");
- break;
+ /*NOTREACHED*/
case Q_TA:
bpf_error(cstate, "'ta' is only supported on 802.11 with 802.11 headers");
- break;
+ /*NOTREACHED*/
}
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
@@ -4060,30 +4202,30 @@ gen_fhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
case Q_ADDR1:
bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR2:
bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR3:
bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR4:
bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_RA:
bpf_error(cstate, "'ra' is only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_TA:
bpf_error(cstate, "'ta' is only supported on 802.11");
- break;
+ /*NOTREACHED*/
}
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
@@ -4116,30 +4258,30 @@ gen_thostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
case Q_ADDR1:
bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR2:
bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR3:
bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR4:
bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_RA:
bpf_error(cstate, "'ra' is only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_TA:
bpf_error(cstate, "'ta' is only supported on 802.11");
- break;
+ /*NOTREACHED*/
}
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
@@ -4428,6 +4570,68 @@ gen_wlanhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
gen_and(b1, b0);
return b0;
+ case Q_AND:
+ b0 = gen_wlanhostop(cstate, eaddr, Q_SRC);
+ b1 = gen_wlanhostop(cstate, eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_wlanhostop(cstate, eaddr, Q_SRC);
+ b1 = gen_wlanhostop(cstate, eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ /*
+ * XXX - add BSSID keyword?
+ */
+ case Q_ADDR1:
+ return (gen_bcmp(cstate, OR_LINKHDR, 4, 6, eaddr));
+
+ case Q_ADDR2:
+ /*
+ * Not present in CTS or ACK control frames.
+ */
+ b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b1);
+ b2 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b2);
+ gen_and(b1, b2);
+ gen_or(b0, b2);
+ b1 = gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr);
+ gen_and(b2, b1);
+ return b1;
+
+ case Q_ADDR3:
+ /*
+ * Not present in control frames.
+ */
+ b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_bcmp(cstate, OR_LINKHDR, 16, 6, eaddr);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ADDR4:
+ /*
+ * Present only if the direction mask has both "From DS"
+ * and "To DS" set. Neither control frames nor management
+ * frames should have both of those set, so we don't
+ * check the frame type.
+ */
+ b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B,
+ IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
+ b1 = gen_bcmp(cstate, OR_LINKHDR, 24, 6, eaddr);
+ gen_and(b0, b1);
+ return b1;
+
case Q_RA:
/*
* Not present in management frames; addr1 in other
@@ -4498,71 +4702,9 @@ gen_wlanhostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
b1 = gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr);
gen_and(b2, b1);
return b1;
-
- /*
- * XXX - add BSSID keyword?
- */
- case Q_ADDR1:
- return (gen_bcmp(cstate, OR_LINKHDR, 4, 6, eaddr));
-
- case Q_ADDR2:
- /*
- * Not present in CTS or ACK control frames.
- */
- b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
- IEEE80211_FC0_TYPE_MASK);
- gen_not(b0);
- b1 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
- IEEE80211_FC0_SUBTYPE_MASK);
- gen_not(b1);
- b2 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
- IEEE80211_FC0_SUBTYPE_MASK);
- gen_not(b2);
- gen_and(b1, b2);
- gen_or(b0, b2);
- b1 = gen_bcmp(cstate, OR_LINKHDR, 10, 6, eaddr);
- gen_and(b2, b1);
- return b1;
-
- case Q_ADDR3:
- /*
- * Not present in control frames.
- */
- b0 = gen_mcmp(cstate, OR_LINKHDR, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
- IEEE80211_FC0_TYPE_MASK);
- gen_not(b0);
- b1 = gen_bcmp(cstate, OR_LINKHDR, 16, 6, eaddr);
- gen_and(b0, b1);
- return b1;
-
- case Q_ADDR4:
- /*
- * Present only if the direction mask has both "From DS"
- * and "To DS" set. Neither control frames nor management
- * frames should have both of those set, so we don't
- * check the frame type.
- */
- b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B,
- IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
- b1 = gen_bcmp(cstate, OR_LINKHDR, 24, 6, eaddr);
- gen_and(b0, b1);
- return b1;
-
- case Q_AND:
- b0 = gen_wlanhostop(cstate, eaddr, Q_SRC);
- b1 = gen_wlanhostop(cstate, eaddr, Q_DST);
- gen_and(b0, b1);
- return b1;
-
- case Q_DEFAULT:
- case Q_OR:
- b0 = gen_wlanhostop(cstate, eaddr, Q_SRC);
- b1 = gen_wlanhostop(cstate, eaddr, Q_DST);
- gen_or(b0, b1);
- return b1;
}
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
@@ -4597,30 +4739,30 @@ gen_ipfchostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
case Q_ADDR1:
bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR2:
bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR3:
bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR4:
bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_RA:
bpf_error(cstate, "'ra' is only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_TA:
bpf_error(cstate, "'ta' is only supported on 802.11");
- break;
+ /*NOTREACHED*/
}
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
@@ -4667,19 +4809,41 @@ gen_dnhostop(compiler_state_t *cstate, bpf_u_int32 addr, int dir)
gen_and(b0, b1);
return b1;
- case Q_OR:
case Q_DEFAULT:
+ case Q_OR:
/* Inefficient because we do our Calvinball dance twice */
b0 = gen_dnhostop(cstate, addr, Q_SRC);
b1 = gen_dnhostop(cstate, addr, Q_DST);
gen_or(b0, b1);
return b1;
- case Q_ISO:
- bpf_error(cstate, "ISO host filtering not implemented");
+ case Q_ADDR1:
+ bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ /*NOTREACHED*/
+
+ case Q_ADDR2:
+ bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ /*NOTREACHED*/
+
+ case Q_ADDR3:
+ bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ /*NOTREACHED*/
+
+ case Q_ADDR4:
+ bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for addresses other than 802.11 MAC addresses");
+ /*NOTREACHED*/
+
+ case Q_RA:
+ bpf_error(cstate, "'ra' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+ /*NOTREACHED*/
+
+ case Q_TA:
+ bpf_error(cstate, "'ta' is not a valid qualifier for addresses other than 802.11 MAC addresses");
+ /*NOTREACHED*/
default:
abort();
+ /*NOTREACHED*/
}
b0 = gen_linktype(cstate, ETHERTYPE_DN);
/* Check for pad = 1, long header case */
@@ -4771,6 +4935,9 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
}
return b0;
+ case Q_LINK:
+ bpf_error(cstate, "link-layer modifier applied to %s", typestr);
+
case Q_IP:
return gen_hostop(cstate, addr, mask, dir, ETHERTYPE_IP, 12, 16);
@@ -4780,12 +4947,12 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
case Q_ARP:
return gen_hostop(cstate, addr, mask, dir, ETHERTYPE_ARP, 14, 24);
- case Q_TCP:
- bpf_error(cstate, "'tcp' modifier applied to %s", typestr);
-
case Q_SCTP:
bpf_error(cstate, "'sctp' modifier applied to %s", typestr);
+ case Q_TCP:
+ bpf_error(cstate, "'tcp' modifier applied to %s", typestr);
+
case Q_UDP:
bpf_error(cstate, "'udp' modifier applied to %s", typestr);
@@ -4798,36 +4965,24 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
case Q_IGRP:
bpf_error(cstate, "'igrp' modifier applied to %s", typestr);
- case Q_PIM:
- bpf_error(cstate, "'pim' modifier applied to %s", typestr);
-
- case Q_VRRP:
- bpf_error(cstate, "'vrrp' modifier applied to %s", typestr);
-
- case Q_CARP:
- bpf_error(cstate, "'carp' modifier applied to %s", typestr);
-
case Q_ATALK:
- bpf_error(cstate, "ATALK host filtering not implemented");
-
- case Q_AARP:
- bpf_error(cstate, "AARP host filtering not implemented");
+ bpf_error(cstate, "AppleTalk host filtering not implemented");
case Q_DECNET:
return gen_dnhostop(cstate, addr, dir);
- case Q_SCA:
- bpf_error(cstate, "SCA host filtering not implemented");
-
case Q_LAT:
bpf_error(cstate, "LAT host filtering not implemented");
- case Q_MOPDL:
- bpf_error(cstate, "MOPDL host filtering not implemented");
+ case Q_SCA:
+ bpf_error(cstate, "SCA host filtering not implemented");
case Q_MOPRC:
bpf_error(cstate, "MOPRC host filtering not implemented");
+ case Q_MOPDL:
+ bpf_error(cstate, "MOPDL host filtering not implemented");
+
case Q_IPV6:
bpf_error(cstate, "'ip6' modifier applied to ip host");
@@ -4840,6 +4995,15 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
case Q_ESP:
bpf_error(cstate, "'esp' modifier applied to %s", typestr);
+ case Q_PIM:
+ bpf_error(cstate, "'pim' modifier applied to %s", typestr);
+
+ case Q_VRRP:
+ bpf_error(cstate, "'vrrp' modifier applied to %s", typestr);
+
+ case Q_AARP:
+ bpf_error(cstate, "AARP host filtering not implemented");
+
case Q_ISO:
bpf_error(cstate, "ISO host filtering not implemented");
@@ -4861,13 +5025,37 @@ gen_host(compiler_state_t *cstate, bpf_u_int32 addr, bpf_u_int32 mask,
case Q_NETBEUI:
bpf_error(cstate, "'netbeui' modifier applied to %s", typestr);
+ case Q_ISIS_L1:
+ bpf_error(cstate, "'l1' modifier applied to %s", typestr);
+
+ case Q_ISIS_L2:
+ bpf_error(cstate, "'l2' modifier applied to %s", typestr);
+
+ case Q_ISIS_IIH:
+ bpf_error(cstate, "'iih' modifier applied to %s", typestr);
+
+ case Q_ISIS_SNP:
+ bpf_error(cstate, "'snp' modifier applied to %s", typestr);
+
+ case Q_ISIS_CSNP:
+ bpf_error(cstate, "'csnp' modifier applied to %s", typestr);
+
+ case Q_ISIS_PSNP:
+ bpf_error(cstate, "'psnp' modifier applied to %s", typestr);
+
+ case Q_ISIS_LSP:
+ bpf_error(cstate, "'lsp' modifier applied to %s", typestr);
+
case Q_RADIO:
bpf_error(cstate, "'radio' modifier applied to %s", typestr);
+ case Q_CARP:
+ bpf_error(cstate, "'carp' modifier applied to %s", typestr);
+
default:
abort();
}
- /* NOTREACHED */
+ /*NOTREACHED*/
}
#ifdef INET6
@@ -4900,93 +5088,114 @@ gen_host6(compiler_state_t *cstate, struct in6_addr *addr,
bpf_error(cstate, "'arp' modifier applied to ip6 %s", typestr);
case Q_SCTP:
- bpf_error(cstate, "'sctp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'sctp' modifier applied to ip6 %s", typestr);
case Q_TCP:
- bpf_error(cstate, "'tcp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'tcp' modifier applied to ip6 %s", typestr);
case Q_UDP:
- bpf_error(cstate, "'udp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'udp' modifier applied to ip6 %s", typestr);
case Q_ICMP:
- bpf_error(cstate, "'icmp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'icmp' modifier applied to ip6 %s", typestr);
case Q_IGMP:
- bpf_error(cstate, "'igmp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'igmp' modifier applied to ip6 %s", typestr);
case Q_IGRP:
- bpf_error(cstate, "'igrp' modifier applied to %s", typestr);
-
- case Q_PIM:
- bpf_error(cstate, "'pim' modifier applied to %s", typestr);
-
- case Q_VRRP:
- bpf_error(cstate, "'vrrp' modifier applied to %s", typestr);
-
- case Q_CARP:
- bpf_error(cstate, "'carp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'igrp' modifier applied to ip6 %s", typestr);
case Q_ATALK:
- bpf_error(cstate, "ATALK host filtering not implemented");
-
- case Q_AARP:
- bpf_error(cstate, "AARP host filtering not implemented");
+ bpf_error(cstate, "AppleTalk modifier applied to ip6 %s", typestr);
case Q_DECNET:
bpf_error(cstate, "'decnet' modifier applied to ip6 %s", typestr);
- case Q_SCA:
- bpf_error(cstate, "SCA host filtering not implemented");
-
case Q_LAT:
- bpf_error(cstate, "LAT host filtering not implemented");
+ bpf_error(cstate, "'lat' modifier applied to ip6 %s", typestr);
- case Q_MOPDL:
- bpf_error(cstate, "MOPDL host filtering not implemented");
+ case Q_SCA:
+ bpf_error(cstate, "'sca' modifier applied to ip6 %s", typestr);
case Q_MOPRC:
- bpf_error(cstate, "MOPRC host filtering not implemented");
+ bpf_error(cstate, "'moprc' modifier applied to ip6 %s", typestr);
+
+ case Q_MOPDL:
+ bpf_error(cstate, "'mopdl' modifier applied to ip6 %s", typestr);
case Q_IPV6:
return gen_hostop6(cstate, addr, mask, dir, ETHERTYPE_IPV6, 8, 24);
case Q_ICMPV6:
- bpf_error(cstate, "'icmp6' modifier applied to %s", typestr);
+ bpf_error(cstate, "'icmp6' modifier applied to ip6 %s", typestr);
case Q_AH:
- bpf_error(cstate, "'ah' modifier applied to %s", typestr);
+ bpf_error(cstate, "'ah' modifier applied to ip6 %s", typestr);
case Q_ESP:
- bpf_error(cstate, "'esp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'esp' modifier applied to ip6 %s", typestr);
+
+ case Q_PIM:
+ bpf_error(cstate, "'pim' modifier applied to ip6 %s", typestr);
+
+ case Q_VRRP:
+ bpf_error(cstate, "'vrrp' modifier applied to ip6 %s", typestr);
+
+ case Q_AARP:
+ bpf_error(cstate, "'aarp' modifier applied to ip6 %s", typestr);
case Q_ISO:
- bpf_error(cstate, "ISO host filtering not implemented");
+ bpf_error(cstate, "'iso' modifier applied to ip6 %s", typestr);
case Q_ESIS:
- bpf_error(cstate, "'esis' modifier applied to %s", typestr);
+ bpf_error(cstate, "'esis' modifier applied to ip6 %s", typestr);
case Q_ISIS:
- bpf_error(cstate, "'isis' modifier applied to %s", typestr);
+ bpf_error(cstate, "'isis' modifier applied to ip6 %s", typestr);
case Q_CLNP:
- bpf_error(cstate, "'clnp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'clnp' modifier applied to ip6 %s", typestr);
case Q_STP:
- bpf_error(cstate, "'stp' modifier applied to %s", typestr);
+ bpf_error(cstate, "'stp' modifier applied to ip6 %s", typestr);
case Q_IPX:
- bpf_error(cstate, "IPX host filtering not implemented");
+ bpf_error(cstate, "'ipx' modifier applied to ip6 %s", typestr);
case Q_NETBEUI:
- bpf_error(cstate, "'netbeui' modifier applied to %s", typestr);
+ bpf_error(cstate, "'netbeui' modifier applied to ip6 %s", typestr);
+
+ case Q_ISIS_L1:
+ bpf_error(cstate, "'l1' modifier applied to ip6 %s", typestr);
+
+ case Q_ISIS_L2:
+ bpf_error(cstate, "'l2' modifier applied to ip6 %s", typestr);
+
+ case Q_ISIS_IIH:
+ bpf_error(cstate, "'iih' modifier applied to ip6 %s", typestr);
+
+ case Q_ISIS_SNP:
+ bpf_error(cstate, "'snp' modifier applied to ip6 %s", typestr);
+
+ case Q_ISIS_CSNP:
+ bpf_error(cstate, "'csnp' modifier applied to ip6 %s", typestr);
+
+ case Q_ISIS_PSNP:
+ bpf_error(cstate, "'psnp' modifier applied to ip6 %s", typestr);
+
+ case Q_ISIS_LSP:
+ bpf_error(cstate, "'lsp' modifier applied to ip6 %s", typestr);
case Q_RADIO:
- bpf_error(cstate, "'radio' modifier applied to %s", typestr);
+ bpf_error(cstate, "'radio' modifier applied to ip6 %s", typestr);
+
+ case Q_CARP:
+ bpf_error(cstate, "'carp' modifier applied to ip6 %s", typestr);
default:
abort();
}
- /* NOTREACHED */
+ /*NOTREACHED*/
}
#endif
@@ -5093,12 +5302,12 @@ gen_gateway(compiler_state_t *cstate, const u_char *eaddr,
return b1;
}
bpf_error(cstate, "illegal modifier of 'gateway'");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
#endif
-struct block *
-gen_proto_abbrev(compiler_state_t *cstate, int proto)
+static struct block *
+gen_proto_abbrev_internal(compiler_state_t *cstate, int proto)
{
struct block *b0;
struct block *b1;
@@ -5337,6 +5546,19 @@ gen_proto_abbrev(compiler_state_t *cstate, int proto)
return b1;
}
+struct block *
+gen_proto_abbrev(compiler_state_t *cstate, int proto)
+{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ return gen_proto_abbrev_internal(cstate, proto);
+}
+
static struct block *
gen_ipfrag(compiler_state_t *cstate)
{
@@ -5393,21 +5615,46 @@ gen_portop(compiler_state_t *cstate, int port, int proto, int dir)
b1 = gen_portatom(cstate, 2, (bpf_int32)port);
break;
- case Q_OR:
- case Q_DEFAULT:
+ case Q_AND:
tmp = gen_portatom(cstate, 0, (bpf_int32)port);
b1 = gen_portatom(cstate, 2, (bpf_int32)port);
- gen_or(tmp, b1);
+ gen_and(tmp, b1);
break;
- case Q_AND:
+ case Q_DEFAULT:
+ case Q_OR:
tmp = gen_portatom(cstate, 0, (bpf_int32)port);
b1 = gen_portatom(cstate, 2, (bpf_int32)port);
- gen_and(tmp, b1);
+ gen_or(tmp, b1);
break;
+ case Q_ADDR1:
+ bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for ports");
+ /*NOTREACHED*/
+
+ case Q_ADDR2:
+ bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for ports");
+ /*NOTREACHED*/
+
+ case Q_ADDR3:
+ bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for ports");
+ /*NOTREACHED*/
+
+ case Q_ADDR4:
+ bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for ports");
+ /*NOTREACHED*/
+
+ case Q_RA:
+ bpf_error(cstate, "'ra' is not a valid qualifier for ports");
+ /*NOTREACHED*/
+
+ case Q_TA:
+ bpf_error(cstate, "'ta' is not a valid qualifier for ports");
+ /*NOTREACHED*/
+
default:
abort();
+ /*NOTREACHED*/
}
gen_and(b0, b1);
@@ -5478,17 +5725,17 @@ gen_portop6(compiler_state_t *cstate, int port, int proto, int dir)
b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
break;
- case Q_OR:
- case Q_DEFAULT:
+ case Q_AND:
tmp = gen_portatom6(cstate, 0, (bpf_int32)port);
b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
- gen_or(tmp, b1);
+ gen_and(tmp, b1);
break;
- case Q_AND:
+ case Q_DEFAULT:
+ case Q_OR:
tmp = gen_portatom6(cstate, 0, (bpf_int32)port);
b1 = gen_portatom6(cstate, 2, (bpf_int32)port);
- gen_and(tmp, b1);
+ gen_or(tmp, b1);
break;
default:
@@ -5575,21 +5822,46 @@ gen_portrangeop(compiler_state_t *cstate, int port1, int port2, int proto,
b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
break;
- case Q_OR:
- case Q_DEFAULT:
+ case Q_AND:
tmp = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
- gen_or(tmp, b1);
+ gen_and(tmp, b1);
break;
- case Q_AND:
+ case Q_DEFAULT:
+ case Q_OR:
tmp = gen_portrangeatom(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
b1 = gen_portrangeatom(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
- gen_and(tmp, b1);
+ gen_or(tmp, b1);
break;
+ case Q_ADDR1:
+ bpf_error(cstate, "'addr1' and 'address1' are not valid qualifiers for port ranges");
+ /*NOTREACHED*/
+
+ case Q_ADDR2:
+ bpf_error(cstate, "'addr2' and 'address2' are not valid qualifiers for port ranges");
+ /*NOTREACHED*/
+
+ case Q_ADDR3:
+ bpf_error(cstate, "'addr3' and 'address3' are not valid qualifiers for port ranges");
+ /*NOTREACHED*/
+
+ case Q_ADDR4:
+ bpf_error(cstate, "'addr4' and 'address4' are not valid qualifiers for port ranges");
+ /*NOTREACHED*/
+
+ case Q_RA:
+ bpf_error(cstate, "'ra' is not a valid qualifier for port ranges");
+ /*NOTREACHED*/
+
+ case Q_TA:
+ bpf_error(cstate, "'ta' is not a valid qualifier for port ranges");
+ /*NOTREACHED*/
+
default:
abort();
+ /*NOTREACHED*/
}
gen_and(b0, b1);
@@ -5671,17 +5943,17 @@ gen_portrangeop6(compiler_state_t *cstate, int port1, int port2, int proto,
b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
break;
- case Q_OR:
- case Q_DEFAULT:
+ case Q_AND:
tmp = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
- gen_or(tmp, b1);
+ gen_and(tmp, b1);
break;
- case Q_AND:
+ case Q_DEFAULT:
+ case Q_OR:
tmp = gen_portrangeatom6(cstate, 0, (bpf_int32)port1, (bpf_int32)port2);
b1 = gen_portrangeatom6(cstate, 2, (bpf_int32)port1, (bpf_int32)port2);
- gen_and(tmp, b1);
+ gen_or(tmp, b1);
break;
default:
@@ -6118,6 +6390,9 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
gen_or(b0, b1);
return b1;
+ case Q_LINK:
+ return gen_linktype(cstate, v);
+
case Q_IP:
/*
* For FDDI, RFC 1188 says that SNAP encapsulation is used,
@@ -6143,6 +6418,104 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
gen_and(b0, b1);
return b1;
+ case Q_ARP:
+ bpf_error(cstate, "arp does not encapsulate another protocol");
+ /*NOTREACHED*/
+
+ case Q_RARP:
+ bpf_error(cstate, "rarp does not encapsulate another protocol");
+ /*NOTREACHED*/
+
+ case Q_SCTP:
+ bpf_error(cstate, "'sctp proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_TCP:
+ bpf_error(cstate, "'tcp proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_UDP:
+ bpf_error(cstate, "'udp proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_ICMP:
+ bpf_error(cstate, "'icmp proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_IGMP:
+ bpf_error(cstate, "'igmp proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_IGRP:
+ bpf_error(cstate, "'igrp proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_ATALK:
+ bpf_error(cstate, "AppleTalk encapsulation is not specifiable");
+ /*NOTREACHED*/
+
+ case Q_DECNET:
+ bpf_error(cstate, "DECNET encapsulation is not specifiable");
+ /*NOTREACHED*/
+
+ case Q_LAT:
+ bpf_error(cstate, "LAT does not encapsulate another protocol");
+ /*NOTREACHED*/
+
+ case Q_SCA:
+ bpf_error(cstate, "SCA does not encapsulate another protocol");
+ /*NOTREACHED*/
+
+ case Q_MOPRC:
+ bpf_error(cstate, "MOPRC does not encapsulate another protocol");
+ /*NOTREACHED*/
+
+ case Q_MOPDL:
+ bpf_error(cstate, "MOPDL does not encapsulate another protocol");
+ /*NOTREACHED*/
+
+ case Q_IPV6:
+ b0 = gen_linktype(cstate, ETHERTYPE_IPV6);
+#ifndef CHASE_CHAIN
+ /*
+ * Also check for a fragment header before the final
+ * header.
+ */
+ b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, IPPROTO_FRAGMENT);
+ b1 = gen_cmp(cstate, OR_LINKPL, 40, BPF_B, (bpf_int32)v);
+ gen_and(b2, b1);
+ b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)v);
+ gen_or(b2, b1);
+#else
+ b1 = gen_protochain(cstate, v, Q_IPV6);
+#endif
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ICMPV6:
+ bpf_error(cstate, "'icmp6 proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_AH:
+ bpf_error(cstate, "'ah proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_ESP:
+ bpf_error(cstate, "'ah proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_PIM:
+ bpf_error(cstate, "'pim proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_VRRP:
+ bpf_error(cstate, "'vrrp proto' is bogus");
+ /*NOTREACHED*/
+
+ case Q_AARP:
+ bpf_error(cstate, "'aarp proto' is bogus");
+ /*NOTREACHED*/
+
case Q_ISO:
switch (cstate->linktype) {
@@ -6167,7 +6540,6 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
*/
return gen_cmp(cstate, OR_LINKHDR, 2, BPF_H, (0x03<<8) | v);
/*NOTREACHED*/
- break;
case DLT_C_HDLC:
/*
@@ -6187,6 +6559,10 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
return b1;
}
+ case Q_ESIS:
+ bpf_error(cstate, "'esis proto' is bogus");
+ /*NOTREACHED*/
+
case Q_ISIS:
b0 = gen_proto(cstate, ISO10589_ISIS, Q_ISO, Q_DEFAULT);
/*
@@ -6197,121 +6573,63 @@ gen_proto(compiler_state_t *cstate, int v, int proto, int dir)
gen_and(b0, b1);
return b1;
- case Q_ARP:
- bpf_error(cstate, "arp does not encapsulate another protocol");
- /* NOTREACHED */
-
- case Q_RARP:
- bpf_error(cstate, "rarp does not encapsulate another protocol");
- /* NOTREACHED */
-
- case Q_ATALK:
- bpf_error(cstate, "atalk encapsulation is not specifiable");
- /* NOTREACHED */
-
- case Q_DECNET:
- bpf_error(cstate, "decnet encapsulation is not specifiable");
- /* NOTREACHED */
-
- case Q_SCA:
- bpf_error(cstate, "sca does not encapsulate another protocol");
- /* NOTREACHED */
-
- case Q_LAT:
- bpf_error(cstate, "lat does not encapsulate another protocol");
- /* NOTREACHED */
+ case Q_CLNP:
+ bpf_error(cstate, "'clnp proto' is not supported");
+ /*NOTREACHED*/
- case Q_MOPRC:
- bpf_error(cstate, "moprc does not encapsulate another protocol");
- /* NOTREACHED */
+ case Q_STP:
+ bpf_error(cstate, "'stp proto' is bogus");
+ /*NOTREACHED*/
- case Q_MOPDL:
- bpf_error(cstate, "mopdl does not encapsulate another protocol");
- /* NOTREACHED */
+ case Q_IPX:
+ bpf_error(cstate, "'ipx proto' is bogus");
+ /*NOTREACHED*/
- case Q_LINK:
- return gen_linktype(cstate, v);
+ case Q_NETBEUI:
+ bpf_error(cstate, "'netbeui proto' is bogus");
+ /*NOTREACHED*/
- case Q_UDP:
- bpf_error(cstate, "'udp proto' is bogus");
- /* NOTREACHED */
+ case Q_ISIS_L1:
+ bpf_error(cstate, "'l1 proto' is bogus");
+ /*NOTREACHED*/
- case Q_TCP:
- bpf_error(cstate, "'tcp proto' is bogus");
- /* NOTREACHED */
+ case Q_ISIS_L2:
+ bpf_error(cstate, "'l2 proto' is bogus");
+ /*NOTREACHED*/
- case Q_SCTP:
- bpf_error(cstate, "'sctp proto' is bogus");
- /* NOTREACHED */
+ case Q_ISIS_IIH:
+ bpf_error(cstate, "'iih proto' is bogus");
+ /*NOTREACHED*/
- case Q_ICMP:
- bpf_error(cstate, "'icmp proto' is bogus");
- /* NOTREACHED */
+ case Q_ISIS_SNP:
+ bpf_error(cstate, "'snp proto' is bogus");
+ /*NOTREACHED*/
- case Q_IGMP:
- bpf_error(cstate, "'igmp proto' is bogus");
- /* NOTREACHED */
+ case Q_ISIS_CSNP:
+ bpf_error(cstate, "'csnp proto' is bogus");
+ /*NOTREACHED*/
- case Q_IGRP:
- bpf_error(cstate, "'igrp proto' is bogus");
- /* NOTREACHED */
+ case Q_ISIS_PSNP:
+ bpf_error(cstate, "'psnp proto' is bogus");
+ /*NOTREACHED*/
- case Q_PIM:
- bpf_error(cstate, "'pim proto' is bogus");
- /* NOTREACHED */
+ case Q_ISIS_LSP:
+ bpf_error(cstate, "'lsp proto' is bogus");
+ /*NOTREACHED*/
- case Q_VRRP:
- bpf_error(cstate, "'vrrp proto' is bogus");
- /* NOTREACHED */
+ case Q_RADIO:
+ bpf_error(cstate, "'radio proto' is bogus");
+ /*NOTREACHED*/
case Q_CARP:
bpf_error(cstate, "'carp proto' is bogus");
- /* NOTREACHED */
-
- case Q_IPV6:
- b0 = gen_linktype(cstate, ETHERTYPE_IPV6);
-#ifndef CHASE_CHAIN
- /*
- * Also check for a fragment header before the final
- * header.
- */
- b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, IPPROTO_FRAGMENT);
- b1 = gen_cmp(cstate, OR_LINKPL, 40, BPF_B, (bpf_int32)v);
- gen_and(b2, b1);
- b2 = gen_cmp(cstate, OR_LINKPL, 6, BPF_B, (bpf_int32)v);
- gen_or(b2, b1);
-#else
- b1 = gen_protochain(cstate, v, Q_IPV6);
-#endif
- gen_and(b0, b1);
- return b1;
-
- case Q_ICMPV6:
- bpf_error(cstate, "'icmp6 proto' is bogus");
-
- case Q_AH:
- bpf_error(cstate, "'ah proto' is bogus");
-
- case Q_ESP:
- bpf_error(cstate, "'ah proto' is bogus");
-
- case Q_STP:
- bpf_error(cstate, "'stp proto' is bogus");
-
- case Q_IPX:
- bpf_error(cstate, "'ipx proto' is bogus");
-
- case Q_NETBEUI:
- bpf_error(cstate, "'netbeui proto' is bogus");
-
- case Q_RADIO:
- bpf_error(cstate, "'radio proto' is bogus");
+ /*NOTREACHED*/
default:
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
- /* NOTREACHED */
+ /*NOTREACHED*/
}
struct block *
@@ -6333,6 +6651,13 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
int port, real_proto;
int port1, port2;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (q.addr) {
case Q_NET:
@@ -6611,10 +6936,10 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q)
case Q_UNDEF:
syntax(cstate);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
struct block *
@@ -6624,12 +6949,23 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
register int nlen, mlen;
bpf_u_int32 n, m;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
nlen = __pcap_atoin(s1, &n);
+ if (nlen < 0)
+ bpf_error(cstate, "invalid IPv4 address '%s'", s1);
/* Promote short ipaddr */
n <<= 32 - nlen;
if (s2 != NULL) {
mlen = __pcap_atoin(s2, &m);
+ if (mlen < 0)
+ bpf_error(cstate, "invalid IPv4 address '%s'", s2);
/* Promote short ipaddr */
m <<= 32 - mlen;
if ((n & ~m) != 0)
@@ -6659,27 +6995,39 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
default:
bpf_error(cstate, "Mask syntax for networks only");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
- /* NOTREACHED */
+ /*NOTREACHED*/
}
struct block *
gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q)
{
bpf_u_int32 mask;
- int proto = q.proto;
- int dir = q.dir;
+ int proto;
+ int dir;
register int vlen;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ proto = q.proto;
+ dir = q.dir;
if (s == NULL)
vlen = 32;
else if (q.proto == Q_DECNET) {
vlen = __pcap_atodn(s, &v);
if (vlen == 0)
bpf_error(cstate, "malformed decnet address '%s'", s);
- } else
+ } else {
vlen = __pcap_atoin(s, &v);
+ if (vlen < 0)
+ bpf_error(cstate, "invalid IPv4 address '%s'", s);
+ }
switch (q.addr) {
@@ -6752,7 +7100,7 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q)
case Q_GATEWAY:
bpf_error(cstate, "'gateway' requires a name");
- /* NOTREACHED */
+ /*NOTREACHED*/
case Q_PROTO:
return gen_proto(cstate, (int)v, proto, dir);
@@ -6762,13 +7110,13 @@ gen_ncode(compiler_state_t *cstate, const char *s, bpf_u_int32 v, struct qual q)
case Q_UNDEF:
syntax(cstate);
- /* NOTREACHED */
+ /*NOTREACHED*/
default:
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
- /* NOTREACHED */
+ /*NOTREACHED*/
}
#ifdef INET6
@@ -6782,6 +7130,13 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
struct block *b;
uint32_t *a, *m;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if (s2)
bpf_error(cstate, "no mask %s supported", s2);
@@ -6825,45 +7180,64 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
default:
bpf_error(cstate, "invalid qualifier against IPv6 address");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
}
#endif /*INET6*/
struct block *
-gen_ecode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
+gen_ecode(compiler_state_t *cstate, const char *s, struct qual q)
{
struct block *b, *tmp;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
+ cstate->e = pcap_ether_aton(s);
+ if (cstate->e == NULL)
+ bpf_error(cstate, "malloc");
switch (cstate->linktype) {
case DLT_EN10MB:
case DLT_NETANALYZER:
case DLT_NETANALYZER_TRANSPARENT:
tmp = gen_prevlinkhdr_check(cstate);
- b = gen_ehostop(cstate, eaddr, (int)q.dir);
+ b = gen_ehostop(cstate, cstate->e, (int)q.dir);
if (tmp != NULL)
gen_and(tmp, b);
- return b;
+ break;
case DLT_FDDI:
- return gen_fhostop(cstate, eaddr, (int)q.dir);
+ b = gen_fhostop(cstate, cstate->e, (int)q.dir);
+ break;
case DLT_IEEE802:
- return gen_thostop(cstate, eaddr, (int)q.dir);
+ b = gen_thostop(cstate, cstate->e, (int)q.dir);
+ break;
case DLT_IEEE802_11:
case DLT_PRISM_HEADER:
case DLT_IEEE802_11_RADIO_AVS:
case DLT_IEEE802_11_RADIO:
case DLT_PPI:
- return gen_wlanhostop(cstate, eaddr, (int)q.dir);
+ b = gen_wlanhostop(cstate, cstate->e, (int)q.dir);
+ break;
case DLT_IP_OVER_FC:
- return gen_ipfchostop(cstate, eaddr, (int)q.dir);
+ b = gen_ipfchostop(cstate, cstate->e, (int)q.dir);
+ break;
default:
+ free(cstate->e);
+ cstate->e = NULL;
bpf_error(cstate, "ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
- break;
+ /*NOTREACHED*/
}
+ free(cstate->e);
+ cstate->e = NULL;
+ return (b);
}
bpf_error(cstate, "ethernet address used in non-ether expression");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
void
@@ -6905,8 +7279,8 @@ xfer_to_a(compiler_state_t *cstate, struct arth *a)
* (1, 2, or 4) at that offset into that register, making it the register
* for "index".
*/
-struct arth *
-gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
+static struct arth *
+gen_load_internal(compiler_state_t *cstate, int proto, struct arth *inst, int size)
{
struct slist *s, *tmp;
struct block *b;
@@ -7052,7 +7426,7 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
* Do the computation only if the packet contains
* the protocol in question.
*/
- b = gen_proto_abbrev(cstate, proto);
+ b = gen_proto_abbrev_internal(cstate, proto);
if (inst->b)
gen_and(inst->b, b);
inst->b = b;
@@ -7110,10 +7484,10 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
* if this is an IP datagram and is the first or
* only fragment of that datagram.
*/
- gen_and(gen_proto_abbrev(cstate, proto), b = gen_ipfrag(cstate));
+ gen_and(gen_proto_abbrev_internal(cstate, proto), b = gen_ipfrag(cstate));
if (inst->b)
gen_and(inst->b, b);
- gen_and(gen_proto_abbrev(cstate, Q_IP), b);
+ gen_and(gen_proto_abbrev_internal(cstate, Q_IP), b);
inst->b = b;
break;
case Q_ICMPV6:
@@ -7121,7 +7495,7 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
* Do the computation only if the packet contains
* the protocol in question.
*/
- b = gen_proto_abbrev(cstate, Q_IPV6);
+ b = gen_proto_abbrev_internal(cstate, Q_IPV6);
if (inst->b) {
gen_and(inst->b, b);
}
@@ -7178,8 +7552,21 @@ gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
return inst;
}
-struct block *
-gen_relation(compiler_state_t *cstate, int code, struct arth *a0,
+struct arth *
+gen_load(compiler_state_t *cstate, int proto, struct arth *inst, int size)
+{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ return gen_load_internal(cstate, proto, inst, size);
+}
+
+static struct block *
+gen_relation_internal(compiler_state_t *cstate, int code, struct arth *a0,
struct arth *a1, int reversed)
{
struct slist *s0, *s1, *s2;
@@ -7222,13 +7609,36 @@ gen_relation(compiler_state_t *cstate, int code, struct arth *a0,
return b;
}
+struct block *
+gen_relation(compiler_state_t *cstate, int code, struct arth *a0,
+ struct arth *a1, int reversed)
+{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ return gen_relation_internal(cstate, code, a0, a1, reversed);
+}
+
struct arth *
gen_loadlen(compiler_state_t *cstate)
{
- int regno = alloc_reg(cstate);
- struct arth *a = (struct arth *)newchunk(cstate, sizeof(*a));
+ int regno;
+ struct arth *a;
struct slist *s;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ regno = alloc_reg(cstate);
+ a = (struct arth *)newchunk(cstate, sizeof(*a));
s = new_stmt(cstate, BPF_LD|BPF_LEN);
s->next = new_stmt(cstate, BPF_ST);
s->next->s.k = regno;
@@ -7238,8 +7648,8 @@ gen_loadlen(compiler_state_t *cstate)
return a;
}
-struct arth *
-gen_loadi(compiler_state_t *cstate, int val)
+static struct arth *
+gen_loadi_internal(compiler_state_t *cstate, int val)
{
struct arth *a;
struct slist *s;
@@ -7260,10 +7670,36 @@ gen_loadi(compiler_state_t *cstate, int val)
}
struct arth *
-gen_neg(compiler_state_t *cstate, struct arth *a)
+gen_loadi(compiler_state_t *cstate, int val)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ return gen_loadi_internal(cstate, val);
+}
+
+/*
+ * The a_arg dance is to avoid annoying whining by compilers that
+ * a might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
+ * It's not *used* after setjmp returns.
+ */
+struct arth *
+gen_neg(compiler_state_t *cstate, struct arth *a_arg)
+{
+ struct arth *a = a_arg;
struct slist *s;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
s = xfer_to_a(cstate, a);
sappend(a->s, s);
s = new_stmt(cstate, BPF_ALU|BPF_NEG);
@@ -7276,15 +7712,31 @@ gen_neg(compiler_state_t *cstate, struct arth *a)
return a;
}
+/*
+ * The a0_arg dance is to avoid annoying whining by compilers that
+ * a0 might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
+ * It's not *used* after setjmp returns.
+ */
struct arth *
-gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
+gen_arth(compiler_state_t *cstate, int code, struct arth *a0_arg,
struct arth *a1)
{
+ struct arth *a0 = a0_arg;
struct slist *s0, *s1, *s2;
/*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ /*
* Disallow division by, or modulus by, zero; we do this here
* so that it gets done even if the optimizer is disabled.
+ *
+ * Also disallow shifts by a value greater than 31; we do this
+ * here, for the same reason.
*/
if (code == BPF_DIV) {
if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0)
@@ -7292,6 +7744,15 @@ gen_arth(compiler_state_t *cstate, int code, struct arth *a0,
} else if (code == BPF_MOD) {
if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0)
bpf_error(cstate, "modulus by zero");
+ } else if (code == BPF_LSH || code == BPF_RSH) {
+ /*
+ * XXX - we need to make up our minds as to what integers
+ * are signed and what integers are unsigned in BPF programs
+ * and in our IR.
+ */
+ if (a1->s->s.code == (BPF_LD|BPF_IMM) &&
+ (a1->s->s.k < 0 || a1->s->s.k > 31))
+ bpf_error(cstate, "shift by more than 31 bits");
}
s0 = xfer_to_x(cstate, a1);
s1 = xfer_to_a(cstate, a0);
@@ -7339,7 +7800,7 @@ alloc_reg(compiler_state_t *cstate)
}
}
bpf_error(cstate, "too many registers needed to evaluate expression");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
@@ -7369,6 +7830,13 @@ gen_len(compiler_state_t *cstate, int jmp, int n)
struct block *
gen_greater(compiler_state_t *cstate, int n)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
return gen_len(cstate, BPF_JGE, n);
}
@@ -7380,6 +7848,13 @@ gen_less(compiler_state_t *cstate, int n)
{
struct block *b;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
b = gen_len(cstate, BPF_JGT, n);
gen_not(b);
@@ -7402,6 +7877,13 @@ gen_byteop(compiler_state_t *cstate, int op, int idx, int val)
struct block *b;
struct slist *s;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (op) {
default:
abort();
@@ -7442,6 +7924,13 @@ gen_broadcast(compiler_state_t *cstate, int proto)
struct block *b0, *b1, *b2;
static const u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (proto) {
case Q_DEFAULT:
@@ -7473,7 +7962,7 @@ gen_broadcast(compiler_state_t *cstate, int proto)
default:
bpf_error(cstate, "not a broadcast link");
}
- break;
+ /*NOTREACHED*/
case Q_IP:
/*
@@ -7493,7 +7982,7 @@ gen_broadcast(compiler_state_t *cstate, int proto)
return b2;
}
bpf_error(cstate, "only link-layer/IP broadcast filters supported");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
@@ -7520,6 +8009,13 @@ gen_multicast(compiler_state_t *cstate, int proto)
register struct block *b0, *b1, *b2;
register struct slist *s;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (proto) {
case Q_DEFAULT:
@@ -7688,7 +8184,7 @@ gen_multicast(compiler_state_t *cstate, int proto)
return b1;
}
bpf_error(cstate, "link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
@@ -7706,13 +8202,20 @@ gen_inbound(compiler_state_t *cstate, int dir)
register struct block *b0;
/*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ /*
* Only some data link types support inbound/outbound qualifiers.
*/
switch (cstate->linktype) {
case DLT_SLIP:
- b0 = gen_relation(cstate, BPF_JEQ,
- gen_load(cstate, Q_LINK, gen_loadi(cstate, 0), 1),
- gen_loadi(cstate, 0),
+ b0 = gen_relation_internal(cstate, BPF_JEQ,
+ gen_load_internal(cstate, Q_LINK, gen_loadi_internal(cstate, 0), 1),
+ gen_loadi_internal(cstate, 0),
dir);
break;
@@ -7735,6 +8238,15 @@ gen_inbound(compiler_state_t *cstate, int dir)
}
break;
+ case DLT_LINUX_SLL2:
+ /* match outgoing packets */
+ b0 = gen_cmp(cstate, OR_LINKHDR, 10, BPF_B, LINUX_SLL_OUTGOING);
+ if (!dir) {
+ /* to filter on inbound traffic, invert the match */
+ gen_not(b0);
+ }
+ break;
+
#ifdef HAVE_NET_PFVAR_H
case DLT_PFLOG:
b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, dir), BPF_B,
@@ -7811,10 +8323,10 @@ gen_inbound(compiler_state_t *cstate, int dir)
*/
if (cstate->bpf_pcap->rfile != NULL) {
/* We have a FILE *, so this is a savefile */
- bpf_error(cstate, "inbound/outbound not supported on linktype %d when reading savefiles",
- cstate->linktype);
+ bpf_error(cstate, "inbound/outbound not supported on %s when reading savefiles",
+ pcap_datalink_val_to_description_or_dlt(cstate->linktype));
b0 = NULL;
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/* match outgoing packets */
b0 = gen_cmp(cstate, OR_LINKHDR, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H,
@@ -7824,9 +8336,9 @@ gen_inbound(compiler_state_t *cstate, int dir)
gen_not(b0);
}
#else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
- bpf_error(cstate, "inbound/outbound not supported on linktype %d",
- cstate->linktype);
- /* NOTREACHED */
+ bpf_error(cstate, "inbound/outbound not supported on %s",
+ pcap_datalink_val_to_description_or_dlt(cstate->linktype));
+ /*NOTREACHED*/
#endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
}
return (b0);
@@ -7840,18 +8352,26 @@ gen_pf_ifname(compiler_state_t *cstate, const char *ifname)
struct block *b0;
u_int len, off;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if (cstate->linktype != DLT_PFLOG) {
bpf_error(cstate, "ifname supported only on PF linktype");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
len = sizeof(((struct pfloghdr *)0)->ifname);
off = offsetof(struct pfloghdr, ifname);
if (strlen(ifname) >= len) {
bpf_error(cstate, "ifname interface names can only be %d characters",
len-1);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
- b0 = gen_bcmp(cstate, OR_LINKHDR, off, strlen(ifname), (const u_char *)ifname);
+ b0 = gen_bcmp(cstate, OR_LINKHDR, off, (u_int)strlen(ifname),
+ (const u_char *)ifname);
return (b0);
}
@@ -7861,19 +8381,26 @@ gen_pf_ruleset(compiler_state_t *cstate, char *ruleset)
{
struct block *b0;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if (cstate->linktype != DLT_PFLOG) {
bpf_error(cstate, "ruleset supported only on PF linktype");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) {
bpf_error(cstate, "ruleset names can only be %ld characters",
(long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1));
- /* NOTREACHED */
+ /*NOTREACHED*/
}
b0 = gen_bcmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, ruleset),
- strlen(ruleset), (const u_char *)ruleset);
+ (u_int)strlen(ruleset), (const u_char *)ruleset);
return (b0);
}
@@ -7883,9 +8410,16 @@ gen_pf_rnr(compiler_state_t *cstate, int rnr)
{
struct block *b0;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if (cstate->linktype != DLT_PFLOG) {
bpf_error(cstate, "rnr supported only on PF linktype");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, rulenr), BPF_W,
@@ -7899,9 +8433,16 @@ gen_pf_srnr(compiler_state_t *cstate, int srnr)
{
struct block *b0;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if (cstate->linktype != DLT_PFLOG) {
bpf_error(cstate, "srnr supported only on PF linktype");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, subrulenr), BPF_W,
@@ -7915,9 +8456,16 @@ gen_pf_reason(compiler_state_t *cstate, int reason)
{
struct block *b0;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if (cstate->linktype != DLT_PFLOG) {
bpf_error(cstate, "reason supported only on PF linktype");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, reason), BPF_B,
@@ -7931,9 +8479,16 @@ gen_pf_action(compiler_state_t *cstate, int action)
{
struct block *b0;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if (cstate->linktype != DLT_PFLOG) {
bpf_error(cstate, "action supported only on PF linktype");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
b0 = gen_cmp(cstate, OR_LINKHDR, offsetof(struct pfloghdr, action), BPF_B,
@@ -7944,43 +8499,85 @@ gen_pf_action(compiler_state_t *cstate, int action)
struct block *
gen_pf_ifname(compiler_state_t *cstate, const char *ifname _U_)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
bpf_error(cstate, "libpcap was compiled without pf support");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
struct block *
gen_pf_ruleset(compiler_state_t *cstate, char *ruleset _U_)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
struct block *
gen_pf_rnr(compiler_state_t *cstate, int rnr _U_)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
struct block *
gen_pf_srnr(compiler_state_t *cstate, int srnr _U_)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
struct block *
gen_pf_reason(compiler_state_t *cstate, int reason _U_)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
struct block *
gen_pf_action(compiler_state_t *cstate, int action _U_)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
#endif /* HAVE_NET_PFVAR_H */
@@ -7990,6 +8587,13 @@ gen_p80211_type(compiler_state_t *cstate, int type, int mask)
{
struct block *b0;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (cstate->linktype) {
case DLT_IEEE802_11:
@@ -8002,7 +8606,7 @@ gen_p80211_type(compiler_state_t *cstate, int type, int mask)
default:
bpf_error(cstate, "802.11 link-layer types supported only on 802.11");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
return (b0);
@@ -8013,6 +8617,13 @@ gen_p80211_fcdir(compiler_state_t *cstate, int fcdir)
{
struct block *b0;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (cstate->linktype) {
case DLT_IEEE802_11:
@@ -8023,7 +8634,7 @@ gen_p80211_fcdir(compiler_state_t *cstate, int fcdir)
default:
bpf_error(cstate, "frame direction supported only with 802.11 headers");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
b0 = gen_mcmp(cstate, OR_LINKHDR, 1, BPF_B, (bpf_int32)fcdir,
@@ -8033,24 +8644,37 @@ gen_p80211_fcdir(compiler_state_t *cstate, int fcdir)
}
struct block *
-gen_acode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
+gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
{
+ struct block *b;
+
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (cstate->linktype) {
case DLT_ARCNET:
case DLT_ARCNET_LINUX:
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
- q.proto == Q_LINK)
- return (gen_ahostop(cstate, eaddr, (int)q.dir));
- else {
+ q.proto == Q_LINK) {
+ cstate->e = pcap_ether_aton(s);
+ if (cstate->e == NULL)
+ bpf_error(cstate, "malloc");
+ b = gen_ahostop(cstate, cstate->e, (int)q.dir);
+ free(cstate->e);
+ cstate->e = NULL;
+ return (b);
+ } else
bpf_error(cstate, "ARCnet address used in non-arc expression");
- /* NOTREACHED */
- }
- break;
+ /*NOTREACHED*/
default:
bpf_error(cstate, "aid supported only on ARCnet");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
}
@@ -8082,30 +8706,30 @@ gen_ahostop(compiler_state_t *cstate, const u_char *eaddr, int dir)
case Q_ADDR1:
bpf_error(cstate, "'addr1' and 'address1' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR2:
bpf_error(cstate, "'addr2' and 'address2' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR3:
bpf_error(cstate, "'addr3' and 'address3' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_ADDR4:
bpf_error(cstate, "'addr4' and 'address4' are only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_RA:
bpf_error(cstate, "'ra' is only supported on 802.11");
- break;
+ /*NOTREACHED*/
case Q_TA:
bpf_error(cstate, "'ta' is only supported on 802.11");
- break;
+ /*NOTREACHED*/
}
abort();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
static struct block *
@@ -8125,19 +8749,24 @@ gen_vlan_tpid_test(compiler_state_t *cstate)
}
static struct block *
-gen_vlan_vid_test(compiler_state_t *cstate, int vlan_num)
+gen_vlan_vid_test(compiler_state_t *cstate, bpf_u_int32 vlan_num)
{
+ if (vlan_num > 0x0fff) {
+ bpf_error(cstate, "VLAN tag %u greater than maximum %u",
+ vlan_num, 0x0fff);
+ }
return gen_mcmp(cstate, OR_LINKPL, 0, BPF_H, (bpf_int32)vlan_num, 0x0fff);
}
static struct block *
-gen_vlan_no_bpf_extensions(compiler_state_t *cstate, int vlan_num)
+gen_vlan_no_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num,
+ int has_vlan_tag)
{
struct block *b0, *b1;
b0 = gen_vlan_tpid_test(cstate);
- if (vlan_num >= 0) {
+ if (has_vlan_tag) {
b1 = gen_vlan_vid_test(cstate, vlan_num);
gen_and(b0, b1);
b0 = b1;
@@ -8220,12 +8849,15 @@ gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
sappend(s, s2);
sjeq->s.jt = s2;
- /* jump to the test in b_vid (bypass loading VID from packet data) */
+ /* Jump to the test in b_vid. We need to jump one instruction before
+ * the end of the b_vid block so that we only skip loading the TCI
+ * from packet data and not the 'and' instruction extractging VID.
+ */
cnt = 0;
for (s2 = b_vid->stmts; s2; s2 = s2->next)
cnt++;
s2 = new_stmt(cstate, JMP(BPF_JA));
- s2->s.k = cnt;
+ s2->s.k = cnt - 1;
sappend(s, s2);
/* insert our statements at the beginning of b_vid */
@@ -8242,7 +8874,8 @@ gen_vlan_patch_vid_test(compiler_state_t *cstate, struct block *b_vid)
* update variable part of the offsets
*/
static struct block *
-gen_vlan_bpf_extensions(compiler_state_t *cstate, int vlan_num)
+gen_vlan_bpf_extensions(compiler_state_t *cstate, bpf_u_int32 vlan_num,
+ int has_vlan_tag)
{
struct block *b0, *b_tpid, *b_vid = NULL;
struct slist *s;
@@ -8267,14 +8900,14 @@ gen_vlan_bpf_extensions(compiler_state_t *cstate, int vlan_num)
* function but gen_vlan_bpf_extensions() isn't called in that case.
*/
b_tpid = gen_vlan_tpid_test(cstate);
- if (vlan_num >= 0)
+ if (has_vlan_tag)
b_vid = gen_vlan_vid_test(cstate, vlan_num);
gen_vlan_patch_tpid_test(cstate, b_tpid);
gen_or(b0, b_tpid);
b0 = b_tpid;
- if (vlan_num >= 0) {
+ if (has_vlan_tag) {
gen_vlan_patch_vid_test(cstate, b_vid);
gen_and(b0, b_vid);
b0 = b_vid;
@@ -8288,10 +8921,17 @@ gen_vlan_bpf_extensions(compiler_state_t *cstate, int vlan_num)
* support IEEE 802.1Q VLAN trunk over ethernet
*/
struct block *
-gen_vlan(compiler_state_t *cstate, int vlan_num)
+gen_vlan(compiler_state_t *cstate, bpf_u_int32 vlan_num, int has_vlan_tag)
{
struct block *b0;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
/* can't check for VLAN-encapsulated packets inside MPLS */
if (cstate->label_stack_depth > 0)
bpf_error(cstate, "no VLAN match after MPLS");
@@ -8342,24 +8982,27 @@ gen_vlan(compiler_state_t *cstate, int vlan_num)
* Do we need special VLAN handling?
*/
if (cstate->bpf_pcap->bpf_codegen_flags & BPF_SPECIAL_VLAN_HANDLING)
- b0 = gen_vlan_bpf_extensions(cstate, vlan_num);
+ b0 = gen_vlan_bpf_extensions(cstate, vlan_num,
+ has_vlan_tag);
else
- b0 = gen_vlan_no_bpf_extensions(cstate, vlan_num);
+ b0 = gen_vlan_no_bpf_extensions(cstate,
+ vlan_num, has_vlan_tag);
} else
#endif
- b0 = gen_vlan_no_bpf_extensions(cstate, vlan_num);
+ b0 = gen_vlan_no_bpf_extensions(cstate, vlan_num,
+ has_vlan_tag);
break;
case DLT_IEEE802_11:
case DLT_PRISM_HEADER:
case DLT_IEEE802_11_RADIO_AVS:
case DLT_IEEE802_11_RADIO:
- b0 = gen_vlan_no_bpf_extensions(cstate, vlan_num);
+ b0 = gen_vlan_no_bpf_extensions(cstate, vlan_num, has_vlan_tag);
break;
default:
- bpf_error(cstate, "no VLAN support for data link type %d",
- cstate->linktype);
+ bpf_error(cstate, "no VLAN support for %s",
+ pcap_datalink_val_to_description_or_dlt(cstate->linktype));
/*NOTREACHED*/
}
@@ -8370,12 +9013,25 @@ gen_vlan(compiler_state_t *cstate, int vlan_num)
/*
* support for MPLS
+ *
+ * The label_num_arg dance is to avoid annoying whining by compilers that
+ * label_num might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
+ * It's not *used* after setjmp returns.
*/
struct block *
-gen_mpls(compiler_state_t *cstate, int label_num)
+gen_mpls(compiler_state_t *cstate, bpf_u_int32 label_num_arg,
+ int has_label_num)
{
+ volatile bpf_u_int32 label_num = label_num_arg;
struct block *b0, *b1;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
if (cstate->label_stack_depth > 0) {
/* just match the bottom-of-stack bit clear */
b0 = gen_mcmp(cstate, OR_PREVMPLSHDR, 2, BPF_B, 0, 0x01);
@@ -8402,15 +9058,18 @@ gen_mpls(compiler_state_t *cstate, int label_num)
* leave it for now */
default:
- bpf_error(cstate, "no MPLS support for data link type %d",
- cstate->linktype);
+ bpf_error(cstate, "no MPLS support for %s",
+ pcap_datalink_val_to_description_or_dlt(cstate->linktype));
/*NOTREACHED*/
- break;
}
}
/* If a specific MPLS label is requested, check it */
- if (label_num >= 0) {
+ if (has_label_num) {
+ if (label_num > 0xFFFFF) {
+ bpf_error(cstate, "MPLS label %u greater than maximum %u",
+ label_num, 0xFFFFF);
+ }
label_num = label_num << 12; /* label is shifted 12 bits on the wire */
b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W, (bpf_int32)label_num,
0xfffff000); /* only compare the first 20 bits */
@@ -8444,22 +9103,40 @@ gen_mpls(compiler_state_t *cstate, int label_num)
struct block *
gen_pppoed(compiler_state_t *cstate)
{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
/* check for PPPoE discovery */
return gen_linktype(cstate, (bpf_int32)ETHERTYPE_PPPOED);
}
struct block *
-gen_pppoes(compiler_state_t *cstate, int sess_num)
+gen_pppoes(compiler_state_t *cstate, bpf_u_int32 sess_num, int has_sess_num)
{
struct block *b0, *b1;
/*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ /*
* Test against the PPPoE session link-layer type.
*/
b0 = gen_linktype(cstate, (bpf_int32)ETHERTYPE_PPPOES);
/* If a specific session is requested, check PPPoE session id */
- if (sess_num >= 0) {
+ if (has_sess_num) {
+ if (sess_num > 0x0000ffff) {
+ bpf_error(cstate, "PPPoE session number %u greater than maximum %u",
+ sess_num, 0x0000ffff);
+ }
b1 = gen_mcmp(cstate, OR_LINKPL, 0, BPF_W,
(bpf_int32)sess_num, 0x0000ffff);
gen_and(b0, b1);
@@ -8471,29 +9148,8 @@ gen_pppoes(compiler_state_t *cstate, int sess_num)
* the PPP packet, and note that this is PPPoE rather than
* raw PPP.
*
- * XXX - this is a bit of a kludge. If we were to split the
- * compiler into a parser that parses an expression and
- * generates an expression tree, and a code generator that
- * takes an expression tree (which could come from our
- * parser or from some other parser) and generates BPF code,
- * we could perhaps make the offsets parameters of routines
- * and, in the handler for an "AND" node, pass to subnodes
- * other than the PPPoE node the adjusted offsets.
- *
- * This would mean that "pppoes" would, instead of changing the
- * behavior of *all* tests after it, change only the behavior
- * of tests ANDed with it. That would change the documented
- * semantics of "pppoes", which might break some expressions.
- * However, it would mean that "(pppoes and ip) or ip" would check
- * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than
- * checking only for VLAN-encapsulated IP, so that could still
- * be considered worth doing; it wouldn't break expressions
- * that are of the form "pppoes and ..." which I suspect are the
- * most common expressions involving "pppoes". "pppoes or ..."
- * doesn't necessarily do what the user would really want, now,
- * as all the "or ..." tests would be done assuming PPPoE, even
- * though the "or" could be viewed as meaning "or, if this isn't
- * a PPPoE packet...".
+ * XXX - this is a bit of a kludge. See the comments in
+ * gen_vlan().
*
* The "network-layer" protocol is PPPoE, which has a 6-byte
* PPPoE header, followed by a PPP packet.
@@ -8523,7 +9179,7 @@ gen_pppoes(compiler_state_t *cstate, int sess_num)
static struct block *
gen_geneve_check(compiler_state_t *cstate,
struct block *(*gen_portfn)(compiler_state_t *, int, int, int),
- enum e_offrel offrel, int vni)
+ enum e_offrel offrel, bpf_u_int32 vni, int has_vni)
{
struct block *b0, *b1;
@@ -8536,7 +9192,11 @@ gen_geneve_check(compiler_state_t *cstate,
gen_and(b0, b1);
b0 = b1;
- if (vni >= 0) {
+ if (has_vni) {
+ if (vni > 0xffffff) {
+ bpf_error(cstate, "Geneve VNI %u greater than maximum %u",
+ vni, 0xffffff);
+ }
vni <<= 8; /* VNI is in the upper 3 bytes */
b1 = gen_mcmp(cstate, offrel, 12, BPF_W, (bpf_int32)vni,
0xffffff00);
@@ -8553,12 +9213,12 @@ gen_geneve_check(compiler_state_t *cstate,
* needed) into register A to be used later to compute
* the inner packet offsets. */
static struct block *
-gen_geneve4(compiler_state_t *cstate, int vni)
+gen_geneve4(compiler_state_t *cstate, bpf_u_int32 vni, int has_vni)
{
struct block *b0, *b1;
struct slist *s, *s1;
- b0 = gen_geneve_check(cstate, gen_port, OR_TRAN_IPV4, vni);
+ b0 = gen_geneve_check(cstate, gen_port, OR_TRAN_IPV4, vni, has_vni);
/* Load the IP header length into A. */
s = gen_loadx_iphdrlen(cstate);
@@ -8579,12 +9239,12 @@ gen_geneve4(compiler_state_t *cstate, int vni)
}
static struct block *
-gen_geneve6(compiler_state_t *cstate, int vni)
+gen_geneve6(compiler_state_t *cstate, bpf_u_int32 vni, int has_vni)
{
struct block *b0, *b1;
struct slist *s, *s1;
- b0 = gen_geneve_check(cstate, gen_port6, OR_TRAN_IPV6, vni);
+ b0 = gen_geneve_check(cstate, gen_port6, OR_TRAN_IPV6, vni, has_vni);
/* Load the IP header length. We need to account for a
* variable length link prefix if there is one. */
@@ -8757,13 +9417,20 @@ gen_geneve_offsets(compiler_state_t *cstate)
/* Check to see if this is a Geneve packet. */
struct block *
-gen_geneve(compiler_state_t *cstate, int vni)
+gen_geneve(compiler_state_t *cstate, bpf_u_int32 vni, int has_vni)
{
struct block *b0, *b1;
struct slist *s;
- b0 = gen_geneve4(cstate, vni);
- b1 = gen_geneve6(cstate, vni);
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ b0 = gen_geneve4(cstate, vni, has_vni);
+ b1 = gen_geneve6(cstate, vni, has_vni);
gen_or(b0, b1);
b0 = b1;
@@ -8813,9 +9480,9 @@ gen_geneve_ll_check(compiler_state_t *cstate)
return b0;
}
-struct block *
-gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
- bpf_u_int32 jtype, int reverse)
+static struct block *
+gen_atmfield_code_internal(compiler_state_t *cstate, int atmfield,
+ bpf_int32 jvalue, bpf_u_int32 jtype, int reverse)
{
struct block *b0;
@@ -8868,28 +9535,80 @@ gen_atmfield_code(compiler_state_t *cstate, int atmfield, bpf_int32 jvalue,
return b0;
}
+static struct block *
+gen_atmtype_metac(compiler_state_t *cstate)
+{
+ struct block *b0, *b1;
+
+ b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_VCI, 1, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ return b1;
+}
+
+static struct block *
+gen_atmtype_sc(compiler_state_t *cstate)
+{
+ struct block *b0, *b1;
+
+ b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_VCI, 5, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ return b1;
+}
+
+static struct block *
+gen_atmtype_llc(compiler_state_t *cstate)
+{
+ struct block *b0;
+
+ b0 = gen_atmfield_code_internal(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+ cstate->linktype = cstate->prevlinktype;
+ return b0;
+}
+
+struct block *
+gen_atmfield_code(compiler_state_t *cstate, int atmfield,
+ bpf_int32 jvalue, bpf_u_int32 jtype, int reverse)
+{
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ return gen_atmfield_code_internal(cstate, atmfield, jvalue, jtype,
+ reverse);
+}
+
struct block *
gen_atmtype_abbrev(compiler_state_t *cstate, int type)
{
struct block *b0, *b1;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (type) {
case A_METAC:
/* Get all packets in Meta signalling Circuit */
if (!cstate->is_atm)
bpf_error(cstate, "'metac' supported only on raw ATM");
- b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
- b1 = gen_atmfield_code(cstate, A_VCI, 1, BPF_JEQ, 0);
- gen_and(b0, b1);
+ b1 = gen_atmtype_metac(cstate);
break;
case A_BCC:
/* Get all packets in Broadcast Circuit*/
if (!cstate->is_atm)
bpf_error(cstate, "'bcc' supported only on raw ATM");
- b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
- b1 = gen_atmfield_code(cstate, A_VCI, 2, BPF_JEQ, 0);
+ b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_VCI, 2, BPF_JEQ, 0);
gen_and(b0, b1);
break;
@@ -8897,8 +9616,8 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
/* Get all cells in Segment OAM F4 circuit*/
if (!cstate->is_atm)
bpf_error(cstate, "'oam4sc' supported only on raw ATM");
- b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
- b1 = gen_atmfield_code(cstate, A_VCI, 3, BPF_JEQ, 0);
+ b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
gen_and(b0, b1);
break;
@@ -8906,8 +9625,8 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
/* Get all cells in End-to-End OAM F4 Circuit*/
if (!cstate->is_atm)
bpf_error(cstate, "'oam4ec' supported only on raw ATM");
- b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
- b1 = gen_atmfield_code(cstate, A_VCI, 4, BPF_JEQ, 0);
+ b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
gen_and(b0, b1);
break;
@@ -8915,17 +9634,15 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
/* Get all packets in connection Signalling Circuit */
if (!cstate->is_atm)
bpf_error(cstate, "'sc' supported only on raw ATM");
- b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
- b1 = gen_atmfield_code(cstate, A_VCI, 5, BPF_JEQ, 0);
- gen_and(b0, b1);
+ b1 = gen_atmtype_sc(cstate);
break;
case A_ILMIC:
/* Get all packets in ILMI Circuit */
if (!cstate->is_atm)
bpf_error(cstate, "'ilmic' supported only on raw ATM");
- b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
- b1 = gen_atmfield_code(cstate, A_VCI, 16, BPF_JEQ, 0);
+ b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_VCI, 16, BPF_JEQ, 0);
gen_and(b0, b1);
break;
@@ -8933,7 +9650,7 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
/* Get all LANE packets */
if (!cstate->is_atm)
bpf_error(cstate, "'lane' supported only on raw ATM");
- b1 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
/*
* Arrange that all subsequent tests assume LANE
@@ -8956,8 +9673,7 @@ gen_atmtype_abbrev(compiler_state_t *cstate, int type)
/* Get all LLC-encapsulated packets */
if (!cstate->is_atm)
bpf_error(cstate, "'llc' supported only on raw ATM");
- b1 = gen_atmfield_code(cstate, A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
- cstate->linktype = cstate->prevlinktype;
+ b1 = gen_atmtype_llc(cstate);
break;
default:
@@ -8978,6 +9694,13 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type)
{
struct block *b0, *b1;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (type) {
case M_FISU:
@@ -9040,17 +9763,34 @@ gen_mtp2type_abbrev(compiler_state_t *cstate, int type)
return b0;
}
+/*
+ * The jvalue_arg dance is to avoid annoying whining by compilers that
+ * jvalue might be clobbered by longjmp - yeah, it might, but *WHO CARES*?
+ * It's not *used* after setjmp returns.
+ */
struct block *
-gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
- bpf_u_int32 jtype, int reverse)
+gen_mtp3field_code(compiler_state_t *cstate, int mtp3field,
+ bpf_u_int32 jvalue_arg, bpf_u_int32 jtype, int reverse)
{
+ volatile bpf_u_int32 jvalue = jvalue_arg;
struct block *b0;
bpf_u_int32 val1 , val2 , val3;
- u_int newoff_sio = cstate->off_sio;
- u_int newoff_opc = cstate->off_opc;
- u_int newoff_dpc = cstate->off_dpc;
- u_int newoff_sls = cstate->off_sls;
+ u_int newoff_sio;
+ u_int newoff_opc;
+ u_int newoff_dpc;
+ u_int newoff_sls;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
+ newoff_sio = cstate->off_sio;
+ newoff_opc = cstate->off_opc;
+ newoff_dpc = cstate->off_dpc;
+ newoff_sls = cstate->off_sls;
switch (mtp3field) {
case MH_SIO:
@@ -9069,7 +9809,9 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
break;
case MH_OPC:
- newoff_opc+=3;
+ newoff_opc += 3;
+
+ /* FALLTHROUGH */
case M_OPC:
if (cstate->off_opc == OFFSET_NOT_SET)
bpf_error(cstate, "'opc' supported only on SS7");
@@ -9113,7 +9855,9 @@ gen_mtp3field_code(compiler_state_t *cstate, int mtp3field, bpf_u_int32 jvalue,
break;
case MH_SLS:
- newoff_sls+=3;
+ newoff_sls += 3;
+ /* FALLTHROUGH */
+
case M_SLS:
if (cstate->off_sls == OFFSET_NOT_SET)
bpf_error(cstate, "'sls' supported only on SS7");
@@ -9146,27 +9890,27 @@ gen_msg_abbrev(compiler_state_t *cstate, int type)
switch (type) {
case A_SETUP:
- b1 = gen_atmfield_code(cstate, A_MSGTYPE, SETUP, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, SETUP, BPF_JEQ, 0);
break;
case A_CALLPROCEED:
- b1 = gen_atmfield_code(cstate, A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
break;
case A_CONNECT:
- b1 = gen_atmfield_code(cstate, A_MSGTYPE, CONNECT, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, CONNECT, BPF_JEQ, 0);
break;
case A_CONNECTACK:
- b1 = gen_atmfield_code(cstate, A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
break;
case A_RELEASE:
- b1 = gen_atmfield_code(cstate, A_MSGTYPE, RELEASE, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, RELEASE, BPF_JEQ, 0);
break;
case A_RELEASE_DONE:
- b1 = gen_atmfield_code(cstate, A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
break;
default:
@@ -9180,22 +9924,34 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
{
struct block *b0, *b1;
+ /*
+ * Catch errors reported by us and routines below us, and return NULL
+ * on an error.
+ */
+ if (setjmp(cstate->top_ctx))
+ return (NULL);
+
switch (type) {
case A_OAM:
if (!cstate->is_atm)
bpf_error(cstate, "'oam' supported only on raw ATM");
- b1 = gen_atmmulti_abbrev(cstate, A_OAMF4);
+ /* OAM F4 type */
+ b0 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
+ gen_or(b0, b1);
+ b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
+ gen_and(b0, b1);
break;
case A_OAMF4:
if (!cstate->is_atm)
bpf_error(cstate, "'oamf4' supported only on raw ATM");
/* OAM F4 type */
- b0 = gen_atmfield_code(cstate, A_VCI, 3, BPF_JEQ, 0);
- b1 = gen_atmfield_code(cstate, A_VCI, 4, BPF_JEQ, 0);
+ b0 = gen_atmfield_code_internal(cstate, A_VCI, 3, BPF_JEQ, 0);
+ b1 = gen_atmfield_code_internal(cstate, A_VCI, 4, BPF_JEQ, 0);
gen_or(b0, b1);
- b0 = gen_atmfield_code(cstate, A_VPI, 0, BPF_JEQ, 0);
+ b0 = gen_atmfield_code_internal(cstate, A_VPI, 0, BPF_JEQ, 0);
gen_and(b0, b1);
break;
@@ -9217,7 +9973,7 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, A_RELEASE_DONE);
gen_or(b0, b1);
- b0 = gen_atmtype_abbrev(cstate, A_SC);
+ b0 = gen_atmtype_sc(cstate);
gen_and(b0, b1);
break;
@@ -9233,7 +9989,7 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
gen_or(b0, b1);
b0 = gen_msg_abbrev(cstate, A_RELEASE_DONE);
gen_or(b0, b1);
- b0 = gen_atmtype_abbrev(cstate, A_METAC);
+ b0 = gen_atmtype_metac(cstate);
gen_and(b0, b1);
break;
diff --git a/freebsd/contrib/libpcap/gencode.h b/freebsd/contrib/libpcap/gencode.h
index 88def5a8..cc21e043 100644
--- a/freebsd/contrib/libpcap/gencode.h
+++ b/freebsd/contrib/libpcap/gencode.h
@@ -113,16 +113,14 @@
#define Q_ISIS_L2 32
/* PDU types */
#define Q_ISIS_IIH 33
-#define Q_ISIS_LAN_IIH 34
-#define Q_ISIS_PTP_IIH 35
-#define Q_ISIS_SNP 36
-#define Q_ISIS_CSNP 37
-#define Q_ISIS_PSNP 38
-#define Q_ISIS_LSP 39
+#define Q_ISIS_SNP 34
+#define Q_ISIS_CSNP 35
+#define Q_ISIS_PSNP 36
+#define Q_ISIS_LSP 37
-#define Q_RADIO 40
+#define Q_RADIO 38
-#define Q_CARP 41
+#define Q_CARP 39
/* Directional qualifiers. */
@@ -299,8 +297,8 @@ void gen_or(struct block *, struct block *);
void gen_not(struct block *);
struct block *gen_scode(compiler_state_t *, const char *, struct qual);
-struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual);
-struct block *gen_acode(compiler_state_t *, const u_char *, struct qual);
+struct block *gen_ecode(compiler_state_t *, const char *, struct qual);
+struct block *gen_acode(compiler_state_t *, const char *, struct qual);
struct block *gen_mcode(compiler_state_t *, const char *, const char *,
unsigned int, struct qual);
#ifdef INET6
@@ -326,13 +324,13 @@ struct block *gen_llc_u(compiler_state_t *);
struct block *gen_llc_s_subtype(compiler_state_t *, bpf_u_int32);
struct block *gen_llc_u_subtype(compiler_state_t *, bpf_u_int32);
-struct block *gen_vlan(compiler_state_t *, int);
-struct block *gen_mpls(compiler_state_t *, int);
+struct block *gen_vlan(compiler_state_t *, bpf_u_int32, int);
+struct block *gen_mpls(compiler_state_t *, bpf_u_int32, int);
struct block *gen_pppoed(compiler_state_t *);
-struct block *gen_pppoes(compiler_state_t *, int);
+struct block *gen_pppoes(compiler_state_t *, bpf_u_int32, int);
-struct block *gen_geneve(compiler_state_t *, int);
+struct block *gen_geneve(compiler_state_t *, bpf_u_int32, int);
struct block *gen_atmfield_code(compiler_state_t *, int, bpf_int32,
bpf_u_int32, int);
@@ -343,29 +341,11 @@ struct block *gen_mtp2type_abbrev(compiler_state_t *, int type);
struct block *gen_mtp3field_code(compiler_state_t *, int, bpf_u_int32,
bpf_u_int32, int);
-#ifndef HAVE_NET_PFVAR_H
-PCAP_NORETURN
-#endif
struct block *gen_pf_ifname(compiler_state_t *, const char *);
-#ifndef HAVE_NET_PFVAR_H
-PCAP_NORETURN
-#endif
struct block *gen_pf_rnr(compiler_state_t *, int);
-#ifndef HAVE_NET_PFVAR_H
-PCAP_NORETURN
-#endif
struct block *gen_pf_srnr(compiler_state_t *, int);
-#ifndef HAVE_NET_PFVAR_H
-PCAP_NORETURN
-#endif
struct block *gen_pf_ruleset(compiler_state_t *, char *);
-#ifndef HAVE_NET_PFVAR_H
-PCAP_NORETURN
-#endif
struct block *gen_pf_reason(compiler_state_t *, int);
-#ifndef HAVE_NET_PFVAR_H
-PCAP_NORETURN
-#endif
struct block *gen_pf_action(compiler_state_t *, int);
struct block *gen_p80211_type(compiler_state_t *, int, int);
@@ -386,16 +366,15 @@ struct icode {
int cur_mark;
};
-void bpf_optimize(compiler_state_t *, struct icode *ic);
-void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *);
-void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
+int bpf_optimize(struct icode *, char *);
+void bpf_set_error(compiler_state_t *, const char *, ...)
PCAP_PRINTFLIKE(2, 3);
-void finish_parse(compiler_state_t *, struct block *);
+int finish_parse(compiler_state_t *, struct block *);
char *sdup(compiler_state_t *, const char *);
-struct bpf_insn *icode_to_fcode(compiler_state_t *, struct icode *,
- struct block *, u_int *);
+struct bpf_insn *icode_to_fcode(struct icode *, struct block *, u_int *,
+ char *);
void sappend(struct slist *, struct slist *);
/*
diff --git a/freebsd/contrib/libpcap/grammar.c b/freebsd/contrib/libpcap/grammar.c
index 4672c0b6..f4871223 100644
--- a/freebsd/contrib/libpcap/grammar.c
+++ b/freebsd/contrib/libpcap/grammar.c
@@ -5,7 +5,7 @@
#define YYBYACC 1
#define YYMAJOR 1
#define YYMINOR 9
-#define YYPATCH 20170201
+#define YYPATCH 20170430
#define YYEMPTY (-1)
#define yyclearin (yychar = YYEMPTY)
@@ -290,13 +290,12 @@ str2tok(const char *str, const struct tok *toks)
return (-1);
}
-static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
+static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
-static PCAP_NORETURN_DEF void
+static void
yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
{
- bpf_syntax_error(cstate, msg);
- /* NOTREACHED */
+ bpf_set_error(cstate, "can't parse filter expression: %s", msg);
}
#ifdef HAVE_NET_PFVAR_H
@@ -310,8 +309,8 @@ pfreason_to_num(compiler_state_t *cstate, const char *reason)
if (pcap_strcasecmp(reason, reasons[i]) == 0)
return (i);
}
- bpf_error(cstate, "unknown PF reason");
- /*NOTREACHED*/
+ bpf_set_error(cstate, "unknown PF reason");
+ return (-1);
}
static int
@@ -334,26 +333,32 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
return (PF_NORDR);
#endif
else {
- bpf_error(cstate, "unknown PF action");
- /*NOTREACHED*/
+ bpf_set_error(cstate, "unknown PF action");
+ return (-1);
}
}
#else /* !HAVE_NET_PFVAR_H */
-static PCAP_NORETURN_DEF int
+static int
pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
{
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
+ bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
+ return (-1);
}
-static PCAP_NORETURN_DEF int
+static int
pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
{
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
+ bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
+ return (-1);
}
#endif /* HAVE_NET_PFVAR_H */
+/*
+ * For calls that might return an "an error occurred" value.
+ */
+#define CHECK_INT_VAL(val) if (val == -1) YYABORT
+#define CHECK_PTR_VAL(val) if (val == NULL) YYABORT
+
DIAG_OFF_BISON_BYACC
#ifdef YYSTYPE
#undef YYSTYPE_IS_DECLARED
@@ -361,11 +366,10 @@ DIAG_OFF_BISON_BYACC
#endif
#ifndef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
-#line 286 "grammar.y"
+#line 291 "grammar.y"
typedef union {
int i;
bpf_u_int32 h;
- u_char *e;
char *s;
struct stmt *stmt;
struct arth *a;
@@ -378,7 +382,7 @@ typedef union {
struct block *rblk;
} YYSTYPE;
#endif /* !YYSTYPE_IS_DECLARED */
-#line 382 "grammar.c"
+#line 386 "grammar.c"
/* compatibility with bison */
#ifdef YYPARSE_PARAM
@@ -531,9 +535,10 @@ extern int YYPARSE_DECL();
#define HOPC 370
#define HDPC 371
#define HSLS 372
-#define OR 373
-#define AND 374
-#define UMINUS 375
+#define LEX_ERROR 373
+#define OR 374
+#define AND 375
+#define UMINUS 376
#define YYERRCODE 256
typedef int YYINT;
static const YYINT pcap_lhs[] = { -1,
@@ -624,347 +629,349 @@ static const YYINT pcap_dgoto[] = { 1,
119, 234, 288, 236, 239,
};
static const YYINT pcap_sindex[] = { 0,
- 0, 431, -281, -278, -273, 0, 0, 0, 0, 0,
+ 0, 432, -273, -265, -254, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, -279, -259, -221,
- -186, -286, -216, 0, 0, 0, 0, 0, 0, -24,
+ 0, 0, 0, 0, 0, 0, 0, -262, -229, -183,
+ -169, -284, -209, 0, 0, 0, 0, 0, 0, -24,
-24, 0, -24, -24, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -274,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, -286,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 653, 0,
- -336, 0, 0, -21, 936, 855, 0, 16, 0, 431,
- 431, 0, 0, 0, 0, 0, 237, 0, 782, 0,
- 0, 114, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -24, 0, 0, 0, 0, 0, -14, 16,
- 653, 0, 0, 320, 320, 0, 0, -30, 64, 0,
- 0, 0, 0, -21, -21, -245, -194, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, -280, -191, -270, 0,
- 0, 0, 0, 0, 0, -118, 0, 0, 0, 0,
- 0, 0, 653, 653, 653, 653, 653, 653, 653, 653,
- 0, 0, 0, 653, 653, 653, 653, 653, -37, 85,
- 90, 0, 0, -153, -141, -135, 0, 0, 0, -128,
- -125, -122, 0, 0, 0, 0, 0, 0, 0, -114,
- 90, 159, 0, 0, 0, 320, 320, 0, 0, -142,
- -110, -100, 0, 152, -336, 90, 0, -63, -58, -52,
- -49, 0, 0, -76, 0, 0, 0, 0, 0, 0,
- 443, 443, 184, 529, 336, 336, -14, -14, 159, 159,
- 159, 159, 972, 0, 0, 0, 0, 0, 0, -41,
- 0, 0, 0, -34, 0, 90, 0, 0, 0, 0,
- -21, -21, 0, 0, 0, 0, -262, 0, -61, 0,
- -135, 0, -122, 0, 0, 0, 0, 0, 135, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 654, 0,
+ -249, 0, 0, -21, 896, 856, 0, 14, 0, 432,
+ 432, 0, 0, 0, 0, 0, 140, 0, 237, 0,
+ 0, -27, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -24, 0, 0, 0, 0, 0, -14, 14,
+ 654, 0, 0, 320, 320, 0, 0, -47, 81, 0,
+ 0, 0, 0, -21, -21, -186, -170, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -274, -182, -270, 0,
+ 0, 0, 0, 0, 0, -86, 0, 0, 0, 0,
+ 0, 0, 654, 654, 654, 654, 654, 654, 654, 654,
+ 0, 0, 0, 654, 654, 654, 654, 654, -39, 97,
+ 100, 0, 0, -148, -146, -141, 0, 0, 0, -125,
+ -122, -117, 0, 0, 0, 0, 0, 0, 0, -115,
+ 100, 990, 0, 0, 0, 320, 320, 0, 0, -159,
+ -112, -110, 0, 150, -249, 100, 0, -65, -63, -51,
+ -49, 0, 0, -87, 0, 0, 0, 0, 0, 0,
+ 484, 484, 184, 530, 191, 191, -14, -14, 990, 990,
+ 990, 990, 973, 0, 0, 0, 0, 0, 0, -37,
+ 0, 0, 0, -36, 0, 100, 0, 0, 0, 0,
+ -21, -21, 0, 0, 0, 0, -184, 0, -66, 0,
+ -141, 0, -117, 0, 0, 0, 0, 0, 137, 0,
0, 0,
};
static const YYINT pcap_rindex[] = { 0,
- 0, 573, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 574, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
- 8, 0, 25, 28, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,
+ 8, 0, 13, 25, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 233, 0, 0, 0, 0, 0, 0, 1, 0, 992,
- 992, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 232, 0, 0, 0, 0, 0, 0, 1, 0, 993,
+ 993, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
- 0, 0, 0, 992, 992, 0, 0, 67, 72, 0,
- 0, 0, 0, 0, 0, 248, 591, 0, 0, 0,
+ 0, 0, 0, 993, 993, 0, 0, 32, 38, 0,
+ 0, 0, 0, 0, 0, 248, 592, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 53, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 905,
- 960, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 906,
+ 961, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 15, 992, 992, 0, 0, 0,
- 0, 0, 0, -185, 0, -159, 0, 0, 0, 0,
- 0, 0, 0, 79, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 15, 993, 993, 0, 0, 0,
+ 0, 0, 0, -138, 0, -135, 0, 0, 0, 0,
+ 0, 0, 0, 70, 0, 0, 0, 0, 0, 0,
30, 124, 158, 149, 99, 110, 40, 74, 183, 194,
- 84, 89, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 767, 0, 0, 0, 0,
+ 72, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 768, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
};
static const YYINT pcap_gindex[] = { 0,
- 234, 229, -113, 0, -99, 0, 0, 0, 0, 0,
- 71, 0, 944, 47, 0, 112, 1012, -83, -3, 14,
- -205, 1004, 811, 0, 0, 0, 0, 0, 0, 0,
+ 247, 12, -113, 0, 62, 0, 0, 0, 0, 0,
+ 84, 0, 1003, -64, 0, 112, 1004, -85, 11, 41,
+ -205, 1017, 354, 0, 0, 0, 0, 0, 0, 0,
0, -187, 0, 0, 0, 0, -188, 0, 0, 0,
0, 0, 0, 0, 0,
};
-#define YYTABLESIZE 1300
-static const YYINT pcap_table[] = { 280,
- 40, 192, 169, 254, 117, 115, 282, 117, 259, 110,
- 232, 88, 111, 263, 12, 90, 221, 112, 90, 272,
- 237, 127, 184, 194, 120, 200, 118, 122, 286, 167,
- 223, 141, 233, 113, 214, 219, 132, 133, 128, 161,
+#define YYTABLESIZE 1309
+static const YYINT pcap_table[] = { 221,
+ 40, 254, 169, 280, 282, 115, 117, 117, 259, 127,
+ 206, 88, 120, 263, 12, 90, 232, 110, 90, 272,
+ 237, 194, 184, 200, 122, 111, 128, 141, 118, 167,
+ 223, 17, 209, 208, 207, 190, 112, 19, 233, 161,
169, 40, 238, 169, 169, 169, 115, 169, 117, 169,
- 287, 155, 155, 114, 281, 12, 155, 155, 283, 155,
- 169, 155, 169, 169, 169, 120, 17, 167, 122, 115,
- 167, 19, 141, 162, 155, 155, 155, 161, 133, 185,
- 161, 161, 161, 41, 161, 33, 161, 167, 42, 167,
- 167, 167, 33, 290, 291, 169, 120, 161, 159, 161,
- 161, 161, 223, 195, 116, 201, 188, 17, 155, 160,
- 222, 162, 19, 98, 162, 162, 162, 192, 162, 133,
- 162, 235, 167, 168, 41, 255, 169, 228, 229, 42,
- 256, 162, 161, 162, 162, 162, 159, 257, 155, 159,
- 148, 159, 150, 159, 151, 152, 190, 160, 164, 258,
- 160, 206, 160, 167, 160, 193, 159, 165, 159, 159,
- 159, 168, 261, 161, 168, 262, 162, 160, 199, 160,
- 160, 160, 267, 209, 208, 207, 265, 190, 230, 231,
- 268, 168, 163, 168, 168, 168, 164, 29, 29, 164,
- 269, 159, 270, 166, 273, 184, 176, 162, 165, 274,
- 179, 177, 160, 178, 275, 180, 164, 276, 164, 164,
- 164, 98, 98, 28, 28, 165, 168, 165, 165, 165,
- 184, 176, 159, 163, 277, 179, 177, 292, 178, 289,
- 180, 220, 1, 160, 166, 91, 240, 205, 271, 0,
- 163, 164, 163, 163, 163, 98, 98, 168, 0, 0,
- 165, 166, 185, 166, 166, 166, 0, 49, 49, 49,
- 49, 49, 190, 49, 49, 0, 25, 49, 49, 25,
- 0, 0, 164, 0, 0, 163, 90, 185, 0, 0,
- 52, 165, 175, 0, 0, 0, 166, 52, 0, 49,
+ 113, 155, 155, 120, 281, 12, 155, 155, 283, 155,
+ 169, 155, 169, 169, 169, 122, 190, 167, 141, 133,
+ 167, 41, 17, 162, 155, 155, 155, 161, 19, 185,
+ 161, 161, 161, 114, 161, 33, 161, 167, 42, 167,
+ 167, 167, 33, 290, 291, 169, 205, 161, 159, 161,
+ 161, 161, 223, 120, 188, 141, 286, 115, 155, 160,
+ 133, 162, 41, 98, 162, 162, 162, 195, 162, 201,
+ 162, 116, 167, 168, 132, 133, 169, 222, 287, 42,
+ 235, 162, 161, 162, 162, 162, 159, 255, 155, 159,
+ 256, 159, 257, 159, 258, 213, 218, 160, 164, 193,
+ 160, 190, 160, 167, 160, 267, 159, 165, 159, 159,
+ 159, 168, 192, 161, 168, 261, 162, 160, 262, 160,
+ 160, 160, 148, 199, 150, 265, 151, 152, 268, 90,
+ 269, 168, 163, 168, 168, 168, 164, 228, 229, 164,
+ 270, 159, 273, 166, 274, 214, 219, 162, 165, 183,
+ 182, 181, 160, 230, 231, 275, 164, 276, 164, 164,
+ 164, 98, 98, 277, 220, 165, 168, 165, 165, 165,
+ 184, 176, 159, 163, 289, 179, 177, 184, 178, 292,
+ 180, 1, 179, 160, 166, 29, 29, 180, 28, 28,
+ 163, 164, 163, 163, 163, 98, 98, 168, 91, 240,
+ 165, 166, 0, 166, 166, 166, 0, 49, 49, 49,
+ 49, 49, 0, 49, 49, 271, 25, 49, 49, 25,
+ 0, 0, 164, 0, 0, 163, 90, 185, 192, 0,
+ 52, 165, 284, 285, 185, 0, 166, 52, 0, 49,
49, 136, 137, 138, 139, 140, 183, 182, 181, 0,
49, 49, 49, 49, 49, 49, 49, 49, 49, 0,
0, 0, 169, 169, 169, 0, 0, 0, 0, 0,
- 169, 169, 141, 0, 155, 155, 155, 98, 98, 0,
- 0, 132, 155, 155, 0, 132, 133, 0, 132, 167,
+ 169, 169, 0, 0, 155, 155, 155, 98, 98, 0,
+ 0, 0, 155, 155, 132, 133, 132, 132, 0, 167,
167, 167, 0, 33, 0, 0, 0, 167, 167, 161,
- 161, 161, 88, 0, 0, 0, 0, 161, 161, 90,
- 0, 0, 213, 218, 89, 33, 33, 33, 33, 33,
- 0, 0, 184, 40, 40, 169, 169, 179, 115, 115,
- 117, 117, 180, 162, 162, 162, 0, 12, 12, 0,
- 0, 162, 162, 0, 0, 0, 0, 120, 120, 0,
- 122, 122, 167, 167, 141, 141, 0, 0, 159, 159,
- 159, 0, 161, 161, 0, 0, 159, 159, 0, 160,
- 160, 160, 0, 0, 0, 0, 0, 160, 160, 185,
- 0, 0, 0, 168, 168, 168, 0, 0, 0, 17,
- 17, 168, 168, 0, 19, 19, 162, 162, 0, 0,
- 0, 133, 133, 0, 0, 0, 41, 41, 164, 164,
- 164, 42, 42, 88, 0, 0, 0, 165, 165, 165,
- 90, 159, 159, 0, 0, 89, 173, 174, 0, 184,
- 0, 0, 160, 160, 179, 177, 0, 178, 0, 180,
- 0, 0, 163, 163, 163, 0, 168, 168, 0, 284,
- 285, 173, 174, 166, 166, 166, 52, 0, 52, 0,
+ 161, 161, 88, 0, 0, 101, 0, 161, 161, 90,
+ 0, 0, 0, 0, 89, 33, 33, 33, 33, 33,
+ 0, 0, 0, 0, 40, 40, 169, 169, 0, 115,
+ 115, 117, 117, 162, 162, 162, 120, 120, 12, 12,
+ 0, 162, 162, 0, 0, 0, 0, 0, 122, 122,
+ 0, 141, 141, 167, 167, 17, 17, 0, 159, 159,
+ 159, 19, 19, 161, 161, 0, 159, 159, 0, 160,
+ 160, 160, 0, 0, 0, 0, 0, 160, 160, 0,
+ 193, 0, 0, 168, 168, 168, 0, 0, 0, 0,
+ 0, 168, 168, 133, 133, 41, 41, 162, 162, 170,
+ 171, 172, 0, 101, 101, 0, 0, 0, 164, 164,
+ 164, 0, 42, 42, 88, 0, 0, 165, 165, 165,
+ 0, 90, 159, 159, 0, 0, 89, 0, 0, 0,
+ 0, 0, 0, 160, 160, 0, 0, 217, 217, 0,
+ 0, 0, 163, 163, 163, 0, 0, 168, 168, 0,
+ 0, 173, 174, 166, 166, 166, 52, 0, 52, 0,
52, 52, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 164, 164, 0, 0, 0, 0, 193, 0, 0,
- 165, 165, 0, 0, 0, 0, 185, 0, 52, 0,
+ 184, 0, 164, 164, 0, 179, 177, 199, 178, 0,
+ 180, 165, 165, 0, 0, 0, 0, 0, 52, 0,
0, 0, 0, 0, 0, 0, 170, 171, 172, 0,
- 0, 0, 0, 0, 0, 163, 163, 0, 0, 0,
- 52, 52, 52, 52, 52, 184, 166, 166, 0, 0,
- 179, 177, 2, 178, 0, 180, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 163, 163, 0, 0,
+ 52, 52, 52, 52, 52, 0, 184, 166, 166, 217,
+ 217, 179, 177, 2, 178, 0, 180, 185, 0, 0,
0, 0, 0, 0, 3, 4, 0, 0, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 0, 0,
25, 26, 27, 28, 29, 30, 31, 32, 33, 0,
- 0, 0, 185, 51, 0, 0, 0, 0, 34, 0,
- 51, 0, 136, 137, 138, 139, 140, 0, 0, 35,
+ 0, 0, 0, 185, 51, 0, 0, 0, 34, 0,
+ 0, 51, 136, 137, 138, 139, 140, 0, 0, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
- 86, 87, 90, 0, 0, 3, 4, 89, 0, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 0,
- 0, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- 85, 86, 87, 155, 155, 0, 0, 0, 155, 155,
- 0, 155, 101, 155, 0, 0, 0, 0, 0, 0,
- 0, 90, 0, 0, 0, 0, 155, 155, 155, 50,
+ 86, 87, 0, 90, 0, 0, 3, 4, 89, 0,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 0, 0, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 34, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, 155, 155, 0, 0, 0, 155,
+ 155, 0, 155, 0, 155, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 155, 155, 155,
+ 50, 50, 50, 50, 50, 0, 50, 50, 0, 0,
+ 50, 50, 0, 0, 0, 0, 0, 173, 174, 0,
+ 51, 0, 51, 0, 51, 51, 0, 0, 0, 0,
+ 0, 155, 50, 50, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 51, 0, 0, 0, 0, 0, 0, 0,
+ 0, 155, 184, 176, 0, 0, 0, 179, 177, 0,
+ 178, 0, 180, 0, 51, 51, 51, 51, 51, 0,
+ 0, 0, 0, 0, 0, 183, 182, 181, 0, 0,
+ 0, 0, 0, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 156, 156, 25, 0, 0, 156, 156, 185,
+ 156, 0, 156, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 34, 0, 0, 156, 156, 156, 0, 0,
+ 0, 0, 0, 35, 36, 37, 38, 39, 0, 175,
+ 0, 0, 0, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 155, 155, 156,
+ 0, 0, 155, 155, 0, 155, 0, 155, 0, 184,
+ 176, 73, 0, 0, 179, 177, 0, 178, 100, 180,
+ 155, 155, 155, 0, 0, 0, 184, 176, 0, 156,
+ 279, 179, 177, 0, 178, 0, 180, 0, 0, 0,
+ 0, 0, 0, 122, 124, 0, 125, 126, 0, 0,
+ 0, 0, 0, 0, 155, 0, 123, 123, 0, 123,
+ 123, 0, 0, 0, 0, 278, 185, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 155, 155, 155,
+ 0, 0, 0, 185, 155, 155, 155, 0, 0, 0,
+ 0, 129, 0, 0, 0, 0, 175, 143, 0, 0,
+ 0, 0, 0, 191, 0, 0, 0, 0, 0, 0,
+ 144, 0, 0, 175, 0, 0, 100, 100, 0, 0,
+ 0, 0, 0, 196, 0, 202, 211, 0, 0, 0,
+ 0, 0, 0, 212, 191, 0, 0, 215, 215, 123,
+ 0, 28, 28, 0, 0, 0, 0, 226, 143, 0,
+ 216, 216, 146, 147, 148, 149, 150, 0, 151, 152,
+ 123, 144, 153, 154, 0, 170, 171, 172, 0, 0,
+ 0, 0, 0, 173, 174, 241, 242, 243, 244, 245,
+ 246, 247, 248, 0, 155, 156, 249, 250, 251, 252,
+ 253, 0, 0, 0, 0, 157, 158, 159, 160, 161,
+ 162, 163, 164, 165, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 156, 156, 156, 0, 266,
+ 215, 0, 0, 156, 156, 0, 0, 0, 0, 0,
+ 0, 0, 100, 216, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,
50, 50, 50, 50, 0, 50, 50, 0, 0, 50,
- 50, 183, 182, 181, 0, 0, 173, 174, 0, 51,
- 0, 51, 0, 51, 51, 0, 0, 0, 0, 0,
- 155, 50, 50, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 51, 0, 0, 0, 0, 0, 0, 0, 0,
- 155, 184, 176, 0, 0, 0, 179, 177, 0, 178,
- 0, 180, 0, 51, 51, 51, 51, 51, 0, 0,
- 101, 101, 0, 0, 183, 182, 181, 0, 0, 0,
- 0, 0, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 156, 156, 25, 217, 217, 156, 156, 185, 156,
- 0, 156, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 34, 0, 0, 156, 156, 156, 0, 0, 0,
- 0, 0, 35, 36, 37, 38, 39, 0, 175, 0,
- 0, 0, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 155, 155, 156, 0,
- 0, 155, 155, 0, 155, 100, 155, 0, 184, 176,
- 73, 0, 0, 179, 177, 0, 178, 0, 180, 155,
- 155, 155, 0, 0, 0, 0, 217, 217, 156, 279,
- 0, 0, 129, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 123, 123, 0, 123, 123, 0, 0,
- 0, 122, 124, 155, 125, 126, 0, 0, 0, 0,
- 0, 0, 0, 0, 278, 185, 0, 0, 0, 0,
- 0, 0, 199, 0, 212, 0, 155, 155, 155, 0,
- 0, 0, 0, 155, 155, 155, 0, 0, 0, 0,
- 0, 170, 171, 172, 0, 175, 0, 144, 0, 0,
- 0, 0, 0, 100, 100, 143, 0, 0, 0, 0,
- 196, 191, 202, 0, 0, 0, 241, 242, 243, 244,
- 245, 246, 247, 248, 0, 0, 123, 249, 250, 251,
- 252, 253, 0, 0, 211, 0, 0, 216, 216, 28,
- 28, 0, 191, 0, 0, 215, 215, 123, 144, 0,
- 0, 0, 0, 0, 0, 226, 143, 0, 0, 0,
- 0, 0, 0, 0, 170, 171, 172, 0, 0, 0,
- 0, 0, 173, 174, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 146, 147, 148, 149, 150, 0, 151, 152,
- 0, 0, 153, 154, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 156, 156, 156, 0, 0, 100,
- 216, 0, 156, 156, 155, 156, 0, 266, 215, 0,
- 0, 0, 0, 0, 0, 157, 158, 159, 160, 161,
- 162, 163, 164, 165, 0, 0, 0, 0, 50, 50,
- 50, 50, 50, 0, 50, 50, 0, 0, 50, 50,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 155,
- 155, 155, 0, 0, 144, 144, 0, 155, 155, 0,
- 50, 50, 143, 143, 0, 0, 0, 0, 0, 173,
- 174, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 155, 155, 155, 0, 143, 143, 0, 0, 155, 155,
+ 0, 50, 50, 0, 0, 0, 0, 144, 144, 0,
+ 173, 174, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 0, 0, 0, 0, 0, 0, 173, 174,
};
-static const YYINT pcap_check[] = { 41,
- 0, 101, 0, 41, 291, 0, 41, 0, 196, 291,
- 291, 33, 291, 202, 0, 40, 47, 291, 40, 225,
- 291, 296, 37, 107, 0, 109, 313, 0, 291, 0,
- 144, 0, 313, 313, 134, 135, 373, 374, 313, 0,
+static const YYINT pcap_check[] = { 47,
+ 0, 41, 0, 41, 41, 0, 291, 0, 196, 296,
+ 38, 33, 0, 202, 0, 40, 291, 291, 40, 225,
+ 291, 107, 37, 109, 0, 291, 313, 0, 313, 0,
+ 144, 0, 60, 61, 62, 100, 291, 0, 313, 0,
38, 41, 313, 41, 42, 43, 41, 45, 41, 47,
- 313, 37, 38, 313, 260, 41, 42, 43, 264, 45,
- 58, 47, 60, 61, 62, 41, 0, 38, 41, 291,
- 41, 0, 41, 0, 60, 61, 62, 38, 0, 94,
- 41, 42, 43, 0, 45, 33, 47, 58, 0, 60,
- 61, 62, 40, 281, 283, 93, 313, 58, 0, 60,
- 61, 62, 216, 107, 291, 109, 91, 41, 94, 0,
- 47, 38, 41, 2, 41, 42, 43, 217, 45, 41,
- 47, 313, 93, 0, 41, 41, 124, 373, 374, 41,
- 41, 58, 93, 60, 61, 62, 38, 291, 124, 41,
- 259, 43, 261, 45, 263, 264, 100, 38, 0, 291,
- 41, 38, 43, 124, 45, 291, 58, 0, 60, 61,
- 62, 38, 291, 124, 41, 291, 93, 58, 291, 60,
- 61, 62, 315, 60, 61, 62, 291, 131, 373, 374,
- 291, 58, 0, 60, 61, 62, 38, 373, 374, 41,
- 291, 93, 41, 0, 258, 37, 38, 124, 41, 258,
- 42, 43, 93, 45, 257, 47, 58, 257, 60, 61,
- 62, 100, 101, 373, 374, 58, 93, 60, 61, 62,
- 37, 38, 124, 41, 301, 42, 43, 93, 45, 291,
- 47, 262, 0, 124, 41, 2, 166, 124, 225, -1,
- 58, 93, 60, 61, 62, 134, 135, 124, -1, -1,
- 93, 58, 94, 60, 61, 62, -1, 257, 258, 259,
- 260, 261, 216, 263, 264, -1, 291, 267, 268, 291,
- -1, -1, 124, -1, -1, 93, 40, 94, -1, -1,
- 33, 124, 124, -1, -1, -1, 93, 40, -1, 289,
+ 313, 37, 38, 41, 260, 41, 42, 43, 264, 45,
+ 58, 47, 60, 61, 62, 41, 131, 38, 41, 0,
+ 41, 0, 41, 0, 60, 61, 62, 38, 41, 94,
+ 41, 42, 43, 313, 45, 33, 47, 58, 0, 60,
+ 61, 62, 40, 281, 283, 93, 124, 58, 0, 60,
+ 61, 62, 216, 313, 91, 94, 291, 291, 94, 0,
+ 41, 38, 41, 2, 41, 42, 43, 107, 45, 109,
+ 47, 291, 93, 0, 374, 375, 124, 47, 313, 41,
+ 313, 58, 93, 60, 61, 62, 38, 41, 124, 41,
+ 41, 43, 291, 45, 291, 134, 135, 38, 0, 291,
+ 41, 216, 43, 124, 45, 315, 58, 0, 60, 61,
+ 62, 38, 101, 124, 41, 291, 93, 58, 291, 60,
+ 61, 62, 259, 291, 261, 291, 263, 264, 291, 40,
+ 291, 58, 0, 60, 61, 62, 38, 374, 375, 41,
+ 41, 93, 258, 0, 258, 134, 135, 124, 41, 60,
+ 61, 62, 93, 374, 375, 257, 58, 257, 60, 61,
+ 62, 100, 101, 301, 262, 58, 93, 60, 61, 62,
+ 37, 38, 124, 41, 291, 42, 43, 37, 45, 93,
+ 47, 0, 42, 124, 41, 374, 375, 47, 374, 375,
+ 58, 93, 60, 61, 62, 134, 135, 124, 2, 166,
+ 93, 58, -1, 60, 61, 62, -1, 257, 258, 259,
+ 260, 261, -1, 263, 264, 225, 291, 267, 268, 291,
+ -1, -1, 124, -1, -1, 93, 40, 94, 217, -1,
+ 33, 124, 271, 272, 94, -1, 93, 40, -1, 289,
290, 313, 314, 315, 316, 317, 60, 61, 62, -1,
300, 301, 302, 303, 304, 305, 306, 307, 308, -1,
-1, -1, 310, 311, 312, -1, -1, -1, -1, -1,
- 318, 319, 94, -1, 310, 311, 312, 216, 217, -1,
- -1, 373, 318, 319, -1, 373, 374, -1, 373, 310,
+ 318, 319, -1, -1, 310, 311, 312, 216, 217, -1,
+ -1, -1, 318, 319, 374, 375, 374, 374, -1, 310,
311, 312, -1, 291, -1, -1, -1, 318, 319, 310,
- 311, 312, 33, -1, -1, -1, -1, 318, 319, 40,
- -1, -1, 134, 135, 45, 313, 314, 315, 316, 317,
- -1, -1, 37, 373, 374, 373, 374, 42, 373, 374,
- 373, 374, 47, 310, 311, 312, -1, 373, 374, -1,
- -1, 318, 319, -1, -1, -1, -1, 373, 374, -1,
- 373, 374, 373, 374, 373, 374, -1, -1, 310, 311,
- 312, -1, 373, 374, -1, -1, 318, 319, -1, 310,
- 311, 312, -1, -1, -1, -1, -1, 318, 319, 94,
- -1, -1, -1, 310, 311, 312, -1, -1, -1, 373,
- 374, 318, 319, -1, 373, 374, 373, 374, -1, -1,
- -1, 373, 374, -1, -1, -1, 373, 374, 310, 311,
- 312, 373, 374, 33, -1, -1, -1, 310, 311, 312,
- 40, 373, 374, -1, -1, 45, 318, 319, -1, 37,
- -1, -1, 373, 374, 42, 43, -1, 45, -1, 47,
- -1, -1, 310, 311, 312, -1, 373, 374, -1, 271,
- 272, 318, 319, 310, 311, 312, 259, -1, 261, -1,
+ 311, 312, 33, -1, -1, 2, -1, 318, 319, 40,
+ -1, -1, -1, -1, 45, 313, 314, 315, 316, 317,
+ -1, -1, -1, -1, 374, 375, 374, 375, -1, 374,
+ 375, 374, 375, 310, 311, 312, 374, 375, 374, 375,
+ -1, 318, 319, -1, -1, -1, -1, -1, 374, 375,
+ -1, 374, 375, 374, 375, 374, 375, -1, 310, 311,
+ 312, 374, 375, 374, 375, -1, 318, 319, -1, 310,
+ 311, 312, -1, -1, -1, -1, -1, 318, 319, -1,
+ 291, -1, -1, 310, 311, 312, -1, -1, -1, -1,
+ -1, 318, 319, 374, 375, 374, 375, 374, 375, 310,
+ 311, 312, -1, 100, 101, -1, -1, -1, 310, 311,
+ 312, -1, 374, 375, 33, -1, -1, 310, 311, 312,
+ -1, 40, 374, 375, -1, -1, 45, -1, -1, -1,
+ -1, -1, -1, 374, 375, -1, -1, 134, 135, -1,
+ -1, -1, 310, 311, 312, -1, -1, 374, 375, -1,
+ -1, 318, 319, 310, 311, 312, 259, -1, 261, -1,
263, 264, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 373, 374, -1, -1, -1, -1, 291, -1, -1,
- 373, 374, -1, -1, -1, -1, 94, -1, 291, -1,
+ 37, -1, 374, 375, -1, 42, 43, 291, 45, -1,
+ 47, 374, 375, -1, -1, -1, -1, -1, 291, -1,
-1, -1, -1, -1, -1, -1, 310, 311, 312, -1,
- -1, -1, -1, -1, -1, 373, 374, -1, -1, -1,
- 313, 314, 315, 316, 317, 37, 373, 374, -1, -1,
- 42, 43, 0, 45, -1, 47, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 374, 375, -1, -1,
+ 313, 314, 315, 316, 317, -1, 37, 374, 375, 216,
+ 217, 42, 43, 0, 45, -1, 47, 94, -1, -1,
-1, -1, -1, -1, 265, 266, -1, -1, 269, 270,
271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
281, 282, 283, 284, 285, 286, 287, 288, -1, -1,
291, 292, 293, 294, 295, 296, 297, 298, 299, -1,
- -1, -1, 94, 33, -1, -1, -1, -1, 309, -1,
- 40, -1, 313, 314, 315, 316, 317, -1, -1, 320,
+ -1, -1, -1, 94, 33, -1, -1, -1, 309, -1,
+ -1, 40, 313, 314, 315, 316, 317, -1, -1, 320,
321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
331, 332, 333, 334, 335, 336, 337, 338, 339, 340,
341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
351, 352, 353, 354, 355, 356, 357, 358, 359, 360,
361, 362, 363, 364, 365, 366, 367, 368, 369, 370,
- 371, 372, 40, -1, -1, 265, 266, 45, -1, 269,
- 270, 271, 272, 273, 274, 275, 276, 277, 278, 279,
- 280, 281, 282, 283, 284, 285, 286, 287, 288, -1,
- -1, 291, 292, 293, 294, 295, 296, 297, 298, 299,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 309,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 320, 321, 322, 323, 324, 325, 326, 327, 328, 329,
- 330, 331, 332, 333, 334, 335, 336, 337, 338, 339,
- 340, 341, 342, 343, 344, 345, 346, 347, 348, 349,
- 350, 351, 352, 353, 354, 355, 356, 357, 358, 359,
- 360, 361, 362, 363, 364, 365, 366, 367, 368, 369,
- 370, 371, 372, 37, 38, -1, -1, -1, 42, 43,
- -1, 45, 2, 47, -1, -1, -1, -1, -1, -1,
- -1, 40, -1, -1, -1, -1, 60, 61, 62, 257,
- 258, 259, 260, 261, -1, 263, 264, -1, -1, 267,
- 268, 60, 61, 62, -1, -1, 318, 319, -1, 259,
- -1, 261, -1, 263, 264, -1, -1, -1, -1, -1,
- 94, 289, 290, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 300, 301, 302, 303, 304, 305, 306, 307,
- 308, 291, -1, -1, -1, -1, -1, -1, -1, -1,
- 124, 37, 38, -1, -1, -1, 42, 43, -1, 45,
- -1, 47, -1, 313, 314, 315, 316, 317, -1, -1,
- 100, 101, -1, -1, 60, 61, 62, -1, -1, -1,
- -1, -1, 270, 271, 272, 273, 274, 275, 276, 277,
- 278, 279, 280, 281, 282, 283, 284, 285, 286, 287,
- 288, 37, 38, 291, 134, 135, 42, 43, 94, 45,
- -1, 47, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 309, -1, -1, 60, 61, 62, -1, -1, -1,
- -1, -1, 320, 321, 322, 323, 324, -1, 124, -1,
- -1, -1, 330, 331, 332, 333, 334, 335, 336, 337,
- 338, 339, 340, 341, 342, 343, 37, 38, 94, -1,
- -1, 42, 43, -1, 45, 2, 47, -1, 37, 38,
- 358, -1, -1, 42, 43, -1, 45, -1, 47, 60,
- 61, 62, -1, -1, -1, -1, 216, 217, 124, 58,
- -1, -1, 89, -1, -1, -1, -1, -1, -1, -1,
+ 371, 372, -1, 40, -1, -1, 265, 266, 45, -1,
+ 269, 270, 271, 272, 273, 274, 275, 276, 277, 278,
+ 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
+ -1, -1, 291, 292, 293, 294, 295, 296, 297, 298,
+ 299, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 309, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 320, 321, 322, 323, 324, 325, 326, 327, 328,
+ 329, 330, 331, 332, 333, 334, 335, 336, 337, 338,
+ 339, 340, 341, 342, 343, 344, 345, 346, 347, 348,
+ 349, 350, 351, 352, 353, 354, 355, 356, 357, 358,
+ 359, 360, 361, 362, 363, 364, 365, 366, 367, 368,
+ 369, 370, 371, 372, 37, 38, -1, -1, -1, 42,
+ 43, -1, 45, -1, 47, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 60, 61, 62,
+ 257, 258, 259, 260, 261, -1, 263, 264, -1, -1,
+ 267, 268, -1, -1, -1, -1, -1, 318, 319, -1,
+ 259, -1, 261, -1, 263, 264, -1, -1, -1, -1,
+ -1, 94, 289, 290, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 300, 301, 302, 303, 304, 305, 306,
+ 307, 308, 291, -1, -1, -1, -1, -1, -1, -1,
+ -1, 124, 37, 38, -1, -1, -1, 42, 43, -1,
+ 45, -1, 47, -1, 313, 314, 315, 316, 317, -1,
+ -1, -1, -1, -1, -1, 60, 61, 62, -1, -1,
+ -1, -1, -1, 270, 271, 272, 273, 274, 275, 276,
+ 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
+ 287, 288, 37, 38, 291, -1, -1, 42, 43, 94,
+ 45, -1, 47, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 309, -1, -1, 60, 61, 62, -1, -1,
+ -1, -1, -1, 320, 321, 322, 323, 324, -1, 124,
+ -1, -1, -1, 330, 331, 332, 333, 334, 335, 336,
+ 337, 338, 339, 340, 341, 342, 343, 37, 38, 94,
+ -1, -1, 42, 43, -1, 45, -1, 47, -1, 37,
+ 38, 358, -1, -1, 42, 43, -1, 45, 2, 47,
+ 60, 61, 62, -1, -1, -1, 37, 38, -1, 124,
+ 58, 42, 43, -1, 45, -1, 47, -1, -1, -1,
-1, -1, -1, 40, 41, -1, 43, 44, -1, -1,
- -1, 40, 41, 94, 43, 44, -1, -1, -1, -1,
- -1, -1, -1, -1, 93, 94, -1, -1, -1, -1,
- -1, -1, 291, -1, 131, -1, 310, 311, 312, -1,
- -1, -1, -1, 124, 318, 319, -1, -1, -1, -1,
- -1, 310, 311, 312, -1, 124, -1, 94, -1, -1,
- -1, -1, -1, 100, 101, 94, -1, -1, -1, -1,
- 107, 100, 109, -1, -1, -1, 173, 174, 175, 176,
- 177, 178, 179, 180, -1, -1, 123, 184, 185, 186,
- 187, 188, -1, -1, 123, -1, -1, 134, 135, 373,
- 374, -1, 131, -1, -1, 134, 135, 144, 145, -1,
- -1, -1, -1, -1, -1, 144, 145, -1, -1, -1,
- -1, -1, -1, -1, 310, 311, 312, -1, -1, -1,
- -1, -1, 318, 319, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 257, 258, 259, 260, 261, -1, 263, 264,
- -1, -1, 267, 268, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 310, 311, 312, -1, -1, 216,
- 217, -1, 318, 319, 289, 290, -1, 216, 217, -1,
- -1, -1, -1, -1, -1, 300, 301, 302, 303, 304,
- 305, 306, 307, 308, -1, -1, -1, -1, 257, 258,
- 259, 260, 261, -1, 263, 264, -1, -1, 267, 268,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 310,
- 311, 312, -1, -1, 271, 272, -1, 318, 319, -1,
- 289, 290, 271, 272, -1, -1, -1, -1, -1, 318,
- 319, 300, 301, 302, 303, 304, 305, 306, 307, 308,
+ -1, -1, -1, -1, 94, -1, 40, 41, -1, 43,
+ 44, -1, -1, -1, -1, 93, 94, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 310, 311, 312,
+ -1, -1, -1, 94, 124, 318, 319, -1, -1, -1,
+ -1, 89, -1, -1, -1, -1, 124, 94, -1, -1,
+ -1, -1, -1, 100, -1, -1, -1, -1, -1, -1,
+ 94, -1, -1, 124, -1, -1, 100, 101, -1, -1,
+ -1, -1, -1, 107, -1, 109, 123, -1, -1, -1,
+ -1, -1, -1, 131, 131, -1, -1, 134, 135, 123,
+ -1, 374, 375, -1, -1, -1, -1, 144, 145, -1,
+ 134, 135, 257, 258, 259, 260, 261, -1, 263, 264,
+ 144, 145, 267, 268, -1, 310, 311, 312, -1, -1,
+ -1, -1, -1, 318, 319, 173, 174, 175, 176, 177,
+ 178, 179, 180, -1, 289, 290, 184, 185, 186, 187,
+ 188, -1, -1, -1, -1, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 310, 311, 312, -1, 216,
+ 217, -1, -1, 318, 319, -1, -1, -1, -1, -1,
+ -1, -1, 216, 217, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 257,
+ 258, 259, 260, 261, -1, 263, 264, -1, -1, 267,
+ 268, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 310, 311, 312, -1, 271, 272, -1, -1, 318, 319,
+ -1, 289, 290, -1, -1, -1, -1, 271, 272, -1,
+ 318, 319, 300, 301, 302, 303, 304, 305, 306, 307,
+ 308, -1, -1, -1, -1, -1, -1, 318, 319,
};
#define YYFINAL 1
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
-#define YYMAXTOKEN 375
-#define YYUNDFTOKEN 423
+#define YYMAXTOKEN 376
+#define YYUNDFTOKEN 424
#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a))
#if YYDEBUG
static const char *const pcap_name[] = {
@@ -988,8 +995,8 @@ static const char *const pcap_name[] = {
"PSNP","STP","IPX","NETBEUI","LANE","LLC","METAC","BCC","SC","ILMIC","OAMF4EC",
"OAMF4SC","OAM","OAMF4","CONNECTMSG","METACONNECT","VPI","VCI","RADIO","FISU",
"LSSU","MSU","HFISU","HLSSU","HMSU","SIO","OPC","DPC","SLS","HSIO","HOPC",
-"HDPC","HSLS","OR","AND","UMINUS",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"illegal-symbol",
+"HDPC","HSLS","LEX_ERROR","OR","AND","UMINUS",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"illegal-symbol",
};
static const char *const pcap_rule[] = {
"$accept : prog",
@@ -1323,6 +1330,9 @@ YYPARSE_DECL()
}
#endif
+ memset(&yyval, 0, sizeof(yyval));
+ memset(&yylval, 0, sizeof(yylval));
+
yym = 0;
yyn = 0;
yynerrs = 0;
@@ -1448,593 +1458,598 @@ yyreduce:
switch (yyn)
{
case 1:
-#line 361 "grammar.y"
+#line 363 "grammar.y"
{
- finish_parse(cstate, yystack.l_mark[0].blk.b);
+ CHECK_INT_VAL(finish_parse(cstate, yystack.l_mark[0].blk.b));
}
break;
case 3:
-#line 366 "grammar.y"
+#line 368 "grammar.y"
{ yyval.blk.q = qerr; }
break;
case 5:
-#line 369 "grammar.y"
+#line 371 "grammar.y"
{ gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 6:
-#line 370 "grammar.y"
+#line 372 "grammar.y"
{ gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 7:
-#line 371 "grammar.y"
+#line 373 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 8:
-#line 372 "grammar.y"
+#line 374 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 9:
-#line 374 "grammar.y"
+#line 376 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
break;
case 10:
-#line 376 "grammar.y"
+#line 378 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
break;
case 12:
-#line 379 "grammar.y"
- { yyval.blk.b = gen_ncode(cstate, NULL, (bpf_u_int32)yystack.l_mark[0].i,
- yyval.blk.q = yystack.l_mark[-1].blk.q); }
+#line 381 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_ncode(cstate, NULL, (bpf_u_int32)yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-1].blk.q))); }
break;
case 13:
-#line 381 "grammar.y"
+#line 383 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
break;
case 14:
-#line 383 "grammar.y"
- { yyval.blk.b = gen_scode(cstate, yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q); }
+#line 385 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.blk.b = gen_scode(cstate, yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q))); }
break;
case 15:
-#line 384 "grammar.y"
- { yyval.blk.b = gen_mcode(cstate, yystack.l_mark[-2].s, NULL, yystack.l_mark[0].i,
- yyval.blk.q = yystack.l_mark[-3].blk.q); }
+#line 386 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[-2].s); CHECK_PTR_VAL((yyval.blk.b = gen_mcode(cstate, yystack.l_mark[-2].s, NULL, yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-3].blk.q))); }
break;
case 16:
-#line 386 "grammar.y"
- { yyval.blk.b = gen_mcode(cstate, yystack.l_mark[-2].s, yystack.l_mark[0].s, 0,
- yyval.blk.q = yystack.l_mark[-3].blk.q); }
+#line 388 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[-2].s); CHECK_PTR_VAL((yyval.blk.b = gen_mcode(cstate, yystack.l_mark[-2].s, yystack.l_mark[0].s, 0,
+ yyval.blk.q = yystack.l_mark[-3].blk.q))); }
break;
case 17:
-#line 388 "grammar.y"
+#line 390 "grammar.y"
{
+ CHECK_PTR_VAL(yystack.l_mark[0].s);
/* Decide how to parse HID based on proto */
yyval.blk.q = yystack.l_mark[-1].blk.q;
- if (yyval.blk.q.addr == Q_PORT)
- bpf_error(cstate, "'port' modifier applied to ip host");
- else if (yyval.blk.q.addr == Q_PORTRANGE)
- bpf_error(cstate, "'portrange' modifier applied to ip host");
- else if (yyval.blk.q.addr == Q_PROTO)
- bpf_error(cstate, "'proto' modifier applied to ip host");
- else if (yyval.blk.q.addr == Q_PROTOCHAIN)
- bpf_error(cstate, "'protochain' modifier applied to ip host");
- yyval.blk.b = gen_ncode(cstate, yystack.l_mark[0].s, 0, yyval.blk.q);
+ if (yyval.blk.q.addr == Q_PORT) {
+ bpf_set_error(cstate, "'port' modifier applied to ip host");
+ YYABORT;
+ } else if (yyval.blk.q.addr == Q_PORTRANGE) {
+ bpf_set_error(cstate, "'portrange' modifier applied to ip host");
+ YYABORT;
+ } else if (yyval.blk.q.addr == Q_PROTO) {
+ bpf_set_error(cstate, "'proto' modifier applied to ip host");
+ YYABORT;
+ } else if (yyval.blk.q.addr == Q_PROTOCHAIN) {
+ bpf_set_error(cstate, "'protochain' modifier applied to ip host");
+ YYABORT;
+ }
+ CHECK_PTR_VAL((yyval.blk.b = gen_ncode(cstate, yystack.l_mark[0].s, 0, yyval.blk.q)));
}
break;
case 18:
-#line 401 "grammar.y"
+#line 409 "grammar.y"
{
+ CHECK_PTR_VAL(yystack.l_mark[-2].s);
#ifdef INET6
- yyval.blk.b = gen_mcode6(cstate, yystack.l_mark[-2].s, NULL, yystack.l_mark[0].i,
- yyval.blk.q = yystack.l_mark[-3].blk.q);
+ CHECK_PTR_VAL((yyval.blk.b = gen_mcode6(cstate, yystack.l_mark[-2].s, NULL, yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-3].blk.q)));
#else
- bpf_error(cstate, "'ip6addr/prefixlen' not supported "
+ bpf_set_error(cstate, "'ip6addr/prefixlen' not supported "
"in this configuration");
+ YYABORT;
#endif /*INET6*/
}
break;
case 19:
-#line 410 "grammar.y"
+#line 420 "grammar.y"
{
+ CHECK_PTR_VAL(yystack.l_mark[0].s);
#ifdef INET6
- yyval.blk.b = gen_mcode6(cstate, yystack.l_mark[0].s, 0, 128,
- yyval.blk.q = yystack.l_mark[-1].blk.q);
+ CHECK_PTR_VAL((yyval.blk.b = gen_mcode6(cstate, yystack.l_mark[0].s, 0, 128,
+ yyval.blk.q = yystack.l_mark[-1].blk.q)));
#else
- bpf_error(cstate, "'ip6addr' not supported "
+ bpf_set_error(cstate, "'ip6addr' not supported "
"in this configuration");
+ YYABORT;
#endif /*INET6*/
}
break;
case 20:
-#line 419 "grammar.y"
- {
- yyval.blk.b = gen_ecode(cstate, yystack.l_mark[0].e, yyval.blk.q = yystack.l_mark[-1].blk.q);
- /*
- * $1 was allocated by "pcap_ether_aton()",
- * so we must free it now that we're done
- * with it.
- */
- free(yystack.l_mark[0].e);
- }
+#line 431 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.blk.b = gen_ecode(cstate, yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q))); }
break;
case 21:
-#line 428 "grammar.y"
- {
- yyval.blk.b = gen_acode(cstate, yystack.l_mark[0].e, yyval.blk.q = yystack.l_mark[-1].blk.q);
- /*
- * $1 was allocated by "pcap_ether_aton()",
- * so we must free it now that we're done
- * with it.
- */
- free(yystack.l_mark[0].e);
- }
+#line 432 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.blk.b = gen_acode(cstate, yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q))); }
break;
case 22:
-#line 437 "grammar.y"
+#line 433 "grammar.y"
{ gen_not(yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 23:
-#line 439 "grammar.y"
+#line 435 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
break;
case 24:
-#line 441 "grammar.y"
+#line 437 "grammar.y"
{ yyval.blk = yystack.l_mark[-1].blk; }
break;
case 26:
-#line 444 "grammar.y"
+#line 440 "grammar.y"
{ gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 27:
-#line 445 "grammar.y"
+#line 441 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 28:
-#line 447 "grammar.y"
- { yyval.blk.b = gen_ncode(cstate, NULL, (bpf_u_int32)yystack.l_mark[0].i,
- yyval.blk.q = yystack.l_mark[-1].blk.q); }
+#line 443 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_ncode(cstate, NULL, (bpf_u_int32)yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-1].blk.q))); }
break;
case 31:
-#line 452 "grammar.y"
+#line 448 "grammar.y"
{ gen_not(yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 32:
-#line 454 "grammar.y"
+#line 450 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-2].i, yystack.l_mark[-1].i, yystack.l_mark[0].i); }
break;
case 33:
-#line 455 "grammar.y"
+#line 451 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-1].i, yystack.l_mark[0].i, Q_DEFAULT); }
break;
case 34:
-#line 456 "grammar.y"
+#line 452 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, yystack.l_mark[0].i); }
break;
case 35:
-#line 457 "grammar.y"
+#line 453 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTO); }
break;
case 36:
-#line 458 "grammar.y"
- { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTOCHAIN); }
+#line 454 "grammar.y"
+ {
+#ifdef NO_PROTOCHAIN
+ bpf_set_error(cstate, "protochain not supported");
+ YYABORT;
+#else
+ QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTOCHAIN);
+#endif
+ }
break;
case 37:
-#line 459 "grammar.y"
+#line 462 "grammar.y"
{ QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, yystack.l_mark[0].i); }
break;
case 38:
-#line 461 "grammar.y"
+#line 464 "grammar.y"
{ yyval.blk = yystack.l_mark[0].blk; }
break;
case 39:
-#line 462 "grammar.y"
+#line 465 "grammar.y"
{ yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = yystack.l_mark[-2].blk.q; }
break;
case 40:
-#line 463 "grammar.y"
- { yyval.blk.b = gen_proto_abbrev(cstate, yystack.l_mark[0].i); yyval.blk.q = qerr; }
+#line 466 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_proto_abbrev(cstate, yystack.l_mark[0].i))); yyval.blk.q = qerr; }
break;
case 41:
-#line 464 "grammar.y"
- { yyval.blk.b = gen_relation(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 0);
+#line 467 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_relation(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 0)));
yyval.blk.q = qerr; }
break;
case 42:
-#line 466 "grammar.y"
- { yyval.blk.b = gen_relation(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 1);
+#line 469 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_relation(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 1)));
yyval.blk.q = qerr; }
break;
case 43:
-#line 468 "grammar.y"
+#line 471 "grammar.y"
{ yyval.blk.b = yystack.l_mark[0].rblk; yyval.blk.q = qerr; }
break;
case 44:
-#line 469 "grammar.y"
- { yyval.blk.b = gen_atmtype_abbrev(cstate, yystack.l_mark[0].i); yyval.blk.q = qerr; }
+#line 472 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_atmtype_abbrev(cstate, yystack.l_mark[0].i))); yyval.blk.q = qerr; }
break;
case 45:
-#line 470 "grammar.y"
- { yyval.blk.b = gen_atmmulti_abbrev(cstate, yystack.l_mark[0].i); yyval.blk.q = qerr; }
+#line 473 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_atmmulti_abbrev(cstate, yystack.l_mark[0].i))); yyval.blk.q = qerr; }
break;
case 46:
-#line 471 "grammar.y"
+#line 474 "grammar.y"
{ yyval.blk.b = yystack.l_mark[0].blk.b; yyval.blk.q = qerr; }
break;
case 47:
-#line 472 "grammar.y"
- { yyval.blk.b = gen_mtp2type_abbrev(cstate, yystack.l_mark[0].i); yyval.blk.q = qerr; }
+#line 475 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_mtp2type_abbrev(cstate, yystack.l_mark[0].i))); yyval.blk.q = qerr; }
break;
case 48:
-#line 473 "grammar.y"
+#line 476 "grammar.y"
{ yyval.blk.b = yystack.l_mark[0].blk.b; yyval.blk.q = qerr; }
break;
case 50:
-#line 477 "grammar.y"
+#line 480 "grammar.y"
{ yyval.i = Q_DEFAULT; }
break;
case 51:
-#line 480 "grammar.y"
+#line 483 "grammar.y"
{ yyval.i = Q_SRC; }
break;
case 52:
-#line 481 "grammar.y"
+#line 484 "grammar.y"
{ yyval.i = Q_DST; }
break;
case 53:
-#line 482 "grammar.y"
+#line 485 "grammar.y"
{ yyval.i = Q_OR; }
break;
case 54:
-#line 483 "grammar.y"
+#line 486 "grammar.y"
{ yyval.i = Q_OR; }
break;
case 55:
-#line 484 "grammar.y"
+#line 487 "grammar.y"
{ yyval.i = Q_AND; }
break;
case 56:
-#line 485 "grammar.y"
+#line 488 "grammar.y"
{ yyval.i = Q_AND; }
break;
case 57:
-#line 486 "grammar.y"
+#line 489 "grammar.y"
{ yyval.i = Q_ADDR1; }
break;
case 58:
-#line 487 "grammar.y"
+#line 490 "grammar.y"
{ yyval.i = Q_ADDR2; }
break;
case 59:
-#line 488 "grammar.y"
+#line 491 "grammar.y"
{ yyval.i = Q_ADDR3; }
break;
case 60:
-#line 489 "grammar.y"
+#line 492 "grammar.y"
{ yyval.i = Q_ADDR4; }
break;
case 61:
-#line 490 "grammar.y"
+#line 493 "grammar.y"
{ yyval.i = Q_RA; }
break;
case 62:
-#line 491 "grammar.y"
+#line 494 "grammar.y"
{ yyval.i = Q_TA; }
break;
case 63:
-#line 494 "grammar.y"
+#line 497 "grammar.y"
{ yyval.i = Q_HOST; }
break;
case 64:
-#line 495 "grammar.y"
+#line 498 "grammar.y"
{ yyval.i = Q_NET; }
break;
case 65:
-#line 496 "grammar.y"
+#line 499 "grammar.y"
{ yyval.i = Q_PORT; }
break;
case 66:
-#line 497 "grammar.y"
+#line 500 "grammar.y"
{ yyval.i = Q_PORTRANGE; }
break;
case 67:
-#line 500 "grammar.y"
+#line 503 "grammar.y"
{ yyval.i = Q_GATEWAY; }
break;
case 68:
-#line 502 "grammar.y"
+#line 505 "grammar.y"
{ yyval.i = Q_LINK; }
break;
case 69:
-#line 503 "grammar.y"
+#line 506 "grammar.y"
{ yyval.i = Q_IP; }
break;
case 70:
-#line 504 "grammar.y"
+#line 507 "grammar.y"
{ yyval.i = Q_ARP; }
break;
case 71:
-#line 505 "grammar.y"
+#line 508 "grammar.y"
{ yyval.i = Q_RARP; }
break;
case 72:
-#line 506 "grammar.y"
+#line 509 "grammar.y"
{ yyval.i = Q_SCTP; }
break;
case 73:
-#line 507 "grammar.y"
+#line 510 "grammar.y"
{ yyval.i = Q_TCP; }
break;
case 74:
-#line 508 "grammar.y"
+#line 511 "grammar.y"
{ yyval.i = Q_UDP; }
break;
case 75:
-#line 509 "grammar.y"
+#line 512 "grammar.y"
{ yyval.i = Q_ICMP; }
break;
case 76:
-#line 510 "grammar.y"
+#line 513 "grammar.y"
{ yyval.i = Q_IGMP; }
break;
case 77:
-#line 511 "grammar.y"
+#line 514 "grammar.y"
{ yyval.i = Q_IGRP; }
break;
case 78:
-#line 512 "grammar.y"
+#line 515 "grammar.y"
{ yyval.i = Q_PIM; }
break;
case 79:
-#line 513 "grammar.y"
+#line 516 "grammar.y"
{ yyval.i = Q_VRRP; }
break;
case 80:
-#line 514 "grammar.y"
+#line 517 "grammar.y"
{ yyval.i = Q_CARP; }
break;
case 81:
-#line 515 "grammar.y"
+#line 518 "grammar.y"
{ yyval.i = Q_ATALK; }
break;
case 82:
-#line 516 "grammar.y"
+#line 519 "grammar.y"
{ yyval.i = Q_AARP; }
break;
case 83:
-#line 517 "grammar.y"
+#line 520 "grammar.y"
{ yyval.i = Q_DECNET; }
break;
case 84:
-#line 518 "grammar.y"
+#line 521 "grammar.y"
{ yyval.i = Q_LAT; }
break;
case 85:
-#line 519 "grammar.y"
+#line 522 "grammar.y"
{ yyval.i = Q_SCA; }
break;
case 86:
-#line 520 "grammar.y"
+#line 523 "grammar.y"
{ yyval.i = Q_MOPDL; }
break;
case 87:
-#line 521 "grammar.y"
+#line 524 "grammar.y"
{ yyval.i = Q_MOPRC; }
break;
case 88:
-#line 522 "grammar.y"
+#line 525 "grammar.y"
{ yyval.i = Q_IPV6; }
break;
case 89:
-#line 523 "grammar.y"
+#line 526 "grammar.y"
{ yyval.i = Q_ICMPV6; }
break;
case 90:
-#line 524 "grammar.y"
+#line 527 "grammar.y"
{ yyval.i = Q_AH; }
break;
case 91:
-#line 525 "grammar.y"
+#line 528 "grammar.y"
{ yyval.i = Q_ESP; }
break;
case 92:
-#line 526 "grammar.y"
+#line 529 "grammar.y"
{ yyval.i = Q_ISO; }
break;
case 93:
-#line 527 "grammar.y"
+#line 530 "grammar.y"
{ yyval.i = Q_ESIS; }
break;
case 94:
-#line 528 "grammar.y"
+#line 531 "grammar.y"
{ yyval.i = Q_ISIS; }
break;
case 95:
-#line 529 "grammar.y"
+#line 532 "grammar.y"
{ yyval.i = Q_ISIS_L1; }
break;
case 96:
-#line 530 "grammar.y"
+#line 533 "grammar.y"
{ yyval.i = Q_ISIS_L2; }
break;
case 97:
-#line 531 "grammar.y"
+#line 534 "grammar.y"
{ yyval.i = Q_ISIS_IIH; }
break;
case 98:
-#line 532 "grammar.y"
+#line 535 "grammar.y"
{ yyval.i = Q_ISIS_LSP; }
break;
case 99:
-#line 533 "grammar.y"
+#line 536 "grammar.y"
{ yyval.i = Q_ISIS_SNP; }
break;
case 100:
-#line 534 "grammar.y"
+#line 537 "grammar.y"
{ yyval.i = Q_ISIS_PSNP; }
break;
case 101:
-#line 535 "grammar.y"
+#line 538 "grammar.y"
{ yyval.i = Q_ISIS_CSNP; }
break;
case 102:
-#line 536 "grammar.y"
+#line 539 "grammar.y"
{ yyval.i = Q_CLNP; }
break;
case 103:
-#line 537 "grammar.y"
+#line 540 "grammar.y"
{ yyval.i = Q_STP; }
break;
case 104:
-#line 538 "grammar.y"
+#line 541 "grammar.y"
{ yyval.i = Q_IPX; }
break;
case 105:
-#line 539 "grammar.y"
+#line 542 "grammar.y"
{ yyval.i = Q_NETBEUI; }
break;
case 106:
-#line 540 "grammar.y"
+#line 543 "grammar.y"
{ yyval.i = Q_RADIO; }
break;
case 107:
-#line 542 "grammar.y"
- { yyval.rblk = gen_broadcast(cstate, yystack.l_mark[-1].i); }
+#line 545 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_broadcast(cstate, yystack.l_mark[-1].i))); }
break;
case 108:
-#line 543 "grammar.y"
- { yyval.rblk = gen_multicast(cstate, yystack.l_mark[-1].i); }
+#line 546 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_multicast(cstate, yystack.l_mark[-1].i))); }
break;
case 109:
-#line 544 "grammar.y"
- { yyval.rblk = gen_less(cstate, yystack.l_mark[0].i); }
+#line 547 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_less(cstate, yystack.l_mark[0].i))); }
break;
case 110:
-#line 545 "grammar.y"
- { yyval.rblk = gen_greater(cstate, yystack.l_mark[0].i); }
+#line 548 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_greater(cstate, yystack.l_mark[0].i))); }
break;
case 111:
-#line 546 "grammar.y"
- { yyval.rblk = gen_byteop(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].i, yystack.l_mark[0].i); }
+#line 549 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_byteop(cstate, yystack.l_mark[-1].i, yystack.l_mark[-2].i, yystack.l_mark[0].i))); }
break;
case 112:
-#line 547 "grammar.y"
- { yyval.rblk = gen_inbound(cstate, 0); }
+#line 550 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_inbound(cstate, 0))); }
break;
case 113:
-#line 548 "grammar.y"
- { yyval.rblk = gen_inbound(cstate, 1); }
+#line 551 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_inbound(cstate, 1))); }
break;
case 114:
-#line 549 "grammar.y"
- { yyval.rblk = gen_vlan(cstate, yystack.l_mark[0].i); }
+#line 552 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_vlan(cstate, (bpf_u_int32)yystack.l_mark[0].i, 1))); }
break;
case 115:
-#line 550 "grammar.y"
- { yyval.rblk = gen_vlan(cstate, -1); }
+#line 553 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_vlan(cstate, 0, 0))); }
break;
case 116:
-#line 551 "grammar.y"
- { yyval.rblk = gen_mpls(cstate, yystack.l_mark[0].i); }
+#line 554 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_mpls(cstate, (bpf_u_int32)yystack.l_mark[0].i, 1))); }
break;
case 117:
-#line 552 "grammar.y"
- { yyval.rblk = gen_mpls(cstate, -1); }
+#line 555 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_mpls(cstate, 0, 0))); }
break;
case 118:
-#line 553 "grammar.y"
- { yyval.rblk = gen_pppoed(cstate); }
+#line 556 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_pppoed(cstate))); }
break;
case 119:
-#line 554 "grammar.y"
- { yyval.rblk = gen_pppoes(cstate, yystack.l_mark[0].i); }
+#line 557 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_pppoes(cstate, (bpf_u_int32)yystack.l_mark[0].i, 1))); }
break;
case 120:
-#line 555 "grammar.y"
- { yyval.rblk = gen_pppoes(cstate, -1); }
+#line 558 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_pppoes(cstate, 0, 0))); }
break;
case 121:
-#line 556 "grammar.y"
- { yyval.rblk = gen_geneve(cstate, yystack.l_mark[0].i); }
+#line 559 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_geneve(cstate, (bpf_u_int32)yystack.l_mark[0].i, 1))); }
break;
case 122:
-#line 557 "grammar.y"
- { yyval.rblk = gen_geneve(cstate, -1); }
+#line 560 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_geneve(cstate, 0, 0))); }
break;
case 123:
-#line 558 "grammar.y"
+#line 561 "grammar.y"
{ yyval.rblk = yystack.l_mark[0].rblk; }
break;
case 124:
-#line 559 "grammar.y"
+#line 562 "grammar.y"
{ yyval.rblk = yystack.l_mark[0].rblk; }
break;
case 125:
-#line 560 "grammar.y"
+#line 563 "grammar.y"
{ yyval.rblk = yystack.l_mark[0].rblk; }
break;
case 126:
-#line 563 "grammar.y"
- { yyval.rblk = gen_pf_ifname(cstate, yystack.l_mark[0].s); }
+#line 566 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.rblk = gen_pf_ifname(cstate, yystack.l_mark[0].s))); }
break;
case 127:
-#line 564 "grammar.y"
- { yyval.rblk = gen_pf_ruleset(cstate, yystack.l_mark[0].s); }
+#line 567 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_PTR_VAL((yyval.rblk = gen_pf_ruleset(cstate, yystack.l_mark[0].s))); }
break;
case 128:
-#line 565 "grammar.y"
- { yyval.rblk = gen_pf_rnr(cstate, yystack.l_mark[0].i); }
+#line 568 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_pf_rnr(cstate, yystack.l_mark[0].i))); }
break;
case 129:
-#line 566 "grammar.y"
- { yyval.rblk = gen_pf_srnr(cstate, yystack.l_mark[0].i); }
+#line 569 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_pf_srnr(cstate, yystack.l_mark[0].i))); }
break;
case 130:
-#line 567 "grammar.y"
- { yyval.rblk = gen_pf_reason(cstate, yystack.l_mark[0].i); }
+#line 570 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_pf_reason(cstate, yystack.l_mark[0].i))); }
break;
case 131:
-#line 568 "grammar.y"
- { yyval.rblk = gen_pf_action(cstate, yystack.l_mark[0].i); }
+#line 571 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_pf_action(cstate, yystack.l_mark[0].i))); }
break;
case 132:
-#line 572 "grammar.y"
- { yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[-2].i | yystack.l_mark[0].i,
+#line 575 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[-2].i | yystack.l_mark[0].i,
IEEE80211_FC0_TYPE_MASK |
- IEEE80211_FC0_SUBTYPE_MASK);
+ IEEE80211_FC0_SUBTYPE_MASK)));
}
break;
case 133:
-#line 576 "grammar.y"
- { yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[0].i,
- IEEE80211_FC0_TYPE_MASK);
+#line 579 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[0].i,
+ IEEE80211_FC0_TYPE_MASK)));
}
break;
case 134:
-#line 579 "grammar.y"
- { yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[0].i,
+#line 582 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_p80211_type(cstate, yystack.l_mark[0].i,
IEEE80211_FC0_TYPE_MASK |
- IEEE80211_FC0_SUBTYPE_MASK);
+ IEEE80211_FC0_SUBTYPE_MASK)));
}
break;
case 135:
-#line 583 "grammar.y"
- { yyval.rblk = gen_p80211_fcdir(cstate, yystack.l_mark[0].i); }
+#line 586 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_p80211_fcdir(cstate, yystack.l_mark[0].i))); }
break;
case 137:
-#line 587 "grammar.y"
- { yyval.i = str2tok(yystack.l_mark[0].s, ieee80211_types);
- if (yyval.i == -1)
- bpf_error(cstate, "unknown 802.11 type name");
+#line 590 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s);
+ yyval.i = str2tok(yystack.l_mark[0].s, ieee80211_types);
+ if (yyval.i == -1) {
+ bpf_set_error(cstate, "unknown 802.11 type name");
+ YYABORT;
+ }
}
break;
case 139:
-#line 594 "grammar.y"
+#line 600 "grammar.y"
{ const struct tok *types = NULL;
int i;
+ CHECK_PTR_VAL(yystack.l_mark[0].s);
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */
- bpf_error(cstate, "unknown 802.11 type");
- break;
+ bpf_set_error(cstate, "unknown 802.11 type");
+ YYABORT;
}
if (yystack.l_mark[-2].i == ieee80211_type_subtypes[i].type) {
types = ieee80211_type_subtypes[i].tok;
@@ -2043,18 +2058,21 @@ case 139:
}
yyval.i = str2tok(yystack.l_mark[0].s, types);
- if (yyval.i == -1)
- bpf_error(cstate, "unknown 802.11 subtype name");
+ if (yyval.i == -1) {
+ bpf_set_error(cstate, "unknown 802.11 subtype name");
+ YYABORT;
+ }
}
break;
case 140:
-#line 614 "grammar.y"
+#line 623 "grammar.y"
{ int i;
+ CHECK_PTR_VAL(yystack.l_mark[0].s);
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */
- bpf_error(cstate, "unknown 802.11 type name");
- break;
+ bpf_set_error(cstate, "unknown 802.11 type name");
+ YYABORT;
}
yyval.i = str2tok(yystack.l_mark[0].s, ieee80211_type_subtypes[i].tok);
if (yyval.i != -1) {
@@ -2065,39 +2083,43 @@ case 140:
}
break;
case 141:
-#line 630 "grammar.y"
- { yyval.rblk = gen_llc(cstate); }
+#line 640 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_llc(cstate))); }
break;
case 142:
-#line 631 "grammar.y"
- { if (pcap_strcasecmp(yystack.l_mark[0].s, "i") == 0)
- yyval.rblk = gen_llc_i(cstate);
- else if (pcap_strcasecmp(yystack.l_mark[0].s, "s") == 0)
- yyval.rblk = gen_llc_s(cstate);
- else if (pcap_strcasecmp(yystack.l_mark[0].s, "u") == 0)
- yyval.rblk = gen_llc_u(cstate);
- else {
+#line 641 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s);
+ if (pcap_strcasecmp(yystack.l_mark[0].s, "i") == 0) {
+ CHECK_PTR_VAL((yyval.rblk = gen_llc_i(cstate)));
+ } else if (pcap_strcasecmp(yystack.l_mark[0].s, "s") == 0) {
+ CHECK_PTR_VAL((yyval.rblk = gen_llc_s(cstate)));
+ } else if (pcap_strcasecmp(yystack.l_mark[0].s, "u") == 0) {
+ CHECK_PTR_VAL((yyval.rblk = gen_llc_u(cstate)));
+ } else {
int subtype;
subtype = str2tok(yystack.l_mark[0].s, llc_s_subtypes);
- if (subtype != -1)
- yyval.rblk = gen_llc_s_subtype(cstate, subtype);
- else {
+ if (subtype != -1) {
+ CHECK_PTR_VAL((yyval.rblk = gen_llc_s_subtype(cstate, subtype)));
+ } else {
subtype = str2tok(yystack.l_mark[0].s, llc_u_subtypes);
- if (subtype == -1)
- bpf_error(cstate, "unknown LLC type name \"%s\"", yystack.l_mark[0].s);
- yyval.rblk = gen_llc_u_subtype(cstate, subtype);
+ if (subtype == -1) {
+ bpf_set_error(cstate, "unknown LLC type name \"%s\"", yystack.l_mark[0].s);
+ YYABORT;
+ }
+ CHECK_PTR_VAL((yyval.rblk = gen_llc_u_subtype(cstate, subtype)));
}
}
}
break;
case 143:
-#line 652 "grammar.y"
- { yyval.rblk = gen_llc_s_subtype(cstate, LLC_RNR); }
+#line 665 "grammar.y"
+ { CHECK_PTR_VAL((yyval.rblk = gen_llc_s_subtype(cstate, LLC_RNR))); }
break;
case 145:
-#line 656 "grammar.y"
- { if (pcap_strcasecmp(yystack.l_mark[0].s, "nods") == 0)
+#line 669 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s);
+ if (pcap_strcasecmp(yystack.l_mark[0].s, "nods") == 0)
yyval.i = IEEE80211_FC1_DIR_NODS;
else if (pcap_strcasecmp(yystack.l_mark[0].s, "tods") == 0)
yyval.i = IEEE80211_FC1_DIR_TODS;
@@ -2105,281 +2127,283 @@ case 145:
yyval.i = IEEE80211_FC1_DIR_FROMDS;
else if (pcap_strcasecmp(yystack.l_mark[0].s, "dstods") == 0)
yyval.i = IEEE80211_FC1_DIR_DSTODS;
- else
- bpf_error(cstate, "unknown 802.11 direction");
+ else {
+ bpf_set_error(cstate, "unknown 802.11 direction");
+ YYABORT;
+ }
}
break;
case 146:
-#line 669 "grammar.y"
+#line 685 "grammar.y"
{ yyval.i = yystack.l_mark[0].i; }
break;
case 147:
-#line 670 "grammar.y"
- { yyval.i = pfreason_to_num(cstate, yystack.l_mark[0].s); }
+#line 686 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_INT_VAL((yyval.i = pfreason_to_num(cstate, yystack.l_mark[0].s))); }
break;
case 148:
-#line 673 "grammar.y"
- { yyval.i = pfaction_to_num(cstate, yystack.l_mark[0].s); }
+#line 689 "grammar.y"
+ { CHECK_PTR_VAL(yystack.l_mark[0].s); CHECK_INT_VAL((yyval.i = pfaction_to_num(cstate, yystack.l_mark[0].s))); }
break;
case 149:
-#line 676 "grammar.y"
+#line 692 "grammar.y"
{ yyval.i = BPF_JGT; }
break;
case 150:
-#line 677 "grammar.y"
+#line 693 "grammar.y"
{ yyval.i = BPF_JGE; }
break;
case 151:
-#line 678 "grammar.y"
+#line 694 "grammar.y"
{ yyval.i = BPF_JEQ; }
break;
case 152:
-#line 680 "grammar.y"
+#line 696 "grammar.y"
{ yyval.i = BPF_JGT; }
break;
case 153:
-#line 681 "grammar.y"
+#line 697 "grammar.y"
{ yyval.i = BPF_JGE; }
break;
case 154:
-#line 682 "grammar.y"
+#line 698 "grammar.y"
{ yyval.i = BPF_JEQ; }
break;
case 155:
-#line 684 "grammar.y"
- { yyval.a = gen_loadi(cstate, yystack.l_mark[0].i); }
+#line 700 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_loadi(cstate, yystack.l_mark[0].i))); }
break;
case 157:
-#line 687 "grammar.y"
- { yyval.a = gen_load(cstate, yystack.l_mark[-3].i, yystack.l_mark[-1].a, 1); }
+#line 703 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_load(cstate, yystack.l_mark[-3].i, yystack.l_mark[-1].a, 1))); }
break;
case 158:
-#line 688 "grammar.y"
- { yyval.a = gen_load(cstate, yystack.l_mark[-5].i, yystack.l_mark[-3].a, yystack.l_mark[-1].i); }
+#line 704 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_load(cstate, yystack.l_mark[-5].i, yystack.l_mark[-3].a, yystack.l_mark[-1].i))); }
break;
case 159:
-#line 689 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_ADD, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 705 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_ADD, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 160:
-#line 690 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_SUB, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 706 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_SUB, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 161:
-#line 691 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_MUL, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 707 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_MUL, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 162:
-#line 692 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_DIV, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 708 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_DIV, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 163:
-#line 693 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_MOD, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 709 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_MOD, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 164:
-#line 694 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_AND, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 710 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_AND, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 165:
-#line 695 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_OR, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 711 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_OR, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 166:
-#line 696 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_XOR, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 712 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_XOR, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 167:
-#line 697 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_LSH, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 713 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_LSH, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 168:
-#line 698 "grammar.y"
- { yyval.a = gen_arth(cstate, BPF_RSH, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+#line 714 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_arth(cstate, BPF_RSH, yystack.l_mark[-2].a, yystack.l_mark[0].a))); }
break;
case 169:
-#line 699 "grammar.y"
- { yyval.a = gen_neg(cstate, yystack.l_mark[0].a); }
+#line 715 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_neg(cstate, yystack.l_mark[0].a))); }
break;
case 170:
-#line 700 "grammar.y"
+#line 716 "grammar.y"
{ yyval.a = yystack.l_mark[-1].a; }
break;
case 171:
-#line 701 "grammar.y"
- { yyval.a = gen_loadlen(cstate); }
+#line 717 "grammar.y"
+ { CHECK_PTR_VAL((yyval.a = gen_loadlen(cstate))); }
break;
case 172:
-#line 703 "grammar.y"
+#line 719 "grammar.y"
{ yyval.i = '&'; }
break;
case 173:
-#line 704 "grammar.y"
+#line 720 "grammar.y"
{ yyval.i = '|'; }
break;
case 174:
-#line 705 "grammar.y"
+#line 721 "grammar.y"
{ yyval.i = '<'; }
break;
case 175:
-#line 706 "grammar.y"
+#line 722 "grammar.y"
{ yyval.i = '>'; }
break;
case 176:
-#line 707 "grammar.y"
+#line 723 "grammar.y"
{ yyval.i = '='; }
break;
case 178:
-#line 710 "grammar.y"
+#line 726 "grammar.y"
{ yyval.i = yystack.l_mark[-1].i; }
break;
case 179:
-#line 712 "grammar.y"
+#line 728 "grammar.y"
{ yyval.i = A_LANE; }
break;
case 180:
-#line 713 "grammar.y"
+#line 729 "grammar.y"
{ yyval.i = A_METAC; }
break;
case 181:
-#line 714 "grammar.y"
+#line 730 "grammar.y"
{ yyval.i = A_BCC; }
break;
case 182:
-#line 715 "grammar.y"
+#line 731 "grammar.y"
{ yyval.i = A_OAMF4EC; }
break;
case 183:
-#line 716 "grammar.y"
+#line 732 "grammar.y"
{ yyval.i = A_OAMF4SC; }
break;
case 184:
-#line 717 "grammar.y"
+#line 733 "grammar.y"
{ yyval.i = A_SC; }
break;
case 185:
-#line 718 "grammar.y"
+#line 734 "grammar.y"
{ yyval.i = A_ILMIC; }
break;
case 186:
-#line 720 "grammar.y"
+#line 736 "grammar.y"
{ yyval.i = A_OAM; }
break;
case 187:
-#line 721 "grammar.y"
+#line 737 "grammar.y"
{ yyval.i = A_OAMF4; }
break;
case 188:
-#line 722 "grammar.y"
+#line 738 "grammar.y"
{ yyval.i = A_CONNECTMSG; }
break;
case 189:
-#line 723 "grammar.y"
+#line 739 "grammar.y"
{ yyval.i = A_METACONNECT; }
break;
case 190:
-#line 726 "grammar.y"
+#line 742 "grammar.y"
{ yyval.blk.atmfieldtype = A_VPI; }
break;
case 191:
-#line 727 "grammar.y"
+#line 743 "grammar.y"
{ yyval.blk.atmfieldtype = A_VCI; }
break;
case 193:
-#line 730 "grammar.y"
- { yyval.blk.b = gen_atmfield_code(cstate, yystack.l_mark[-2].blk.atmfieldtype, (bpf_int32)yystack.l_mark[0].i, (bpf_u_int32)yystack.l_mark[-1].i, 0); }
+#line 746 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_atmfield_code(cstate, yystack.l_mark[-2].blk.atmfieldtype, (bpf_int32)yystack.l_mark[0].i, (bpf_u_int32)yystack.l_mark[-1].i, 0))); }
break;
case 194:
-#line 731 "grammar.y"
- { yyval.blk.b = gen_atmfield_code(cstate, yystack.l_mark[-2].blk.atmfieldtype, (bpf_int32)yystack.l_mark[0].i, (bpf_u_int32)yystack.l_mark[-1].i, 1); }
+#line 747 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_atmfield_code(cstate, yystack.l_mark[-2].blk.atmfieldtype, (bpf_int32)yystack.l_mark[0].i, (bpf_u_int32)yystack.l_mark[-1].i, 1))); }
break;
case 195:
-#line 732 "grammar.y"
+#line 748 "grammar.y"
{ yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = qerr; }
break;
case 196:
-#line 734 "grammar.y"
+#line 750 "grammar.y"
{
yyval.blk.atmfieldtype = yystack.l_mark[-1].blk.atmfieldtype;
if (yyval.blk.atmfieldtype == A_VPI ||
yyval.blk.atmfieldtype == A_VCI)
- yyval.blk.b = gen_atmfield_code(cstate, yyval.blk.atmfieldtype, (bpf_int32) yystack.l_mark[0].i, BPF_JEQ, 0);
+ CHECK_PTR_VAL((yyval.blk.b = gen_atmfield_code(cstate, yyval.blk.atmfieldtype, (bpf_int32) yystack.l_mark[0].i, BPF_JEQ, 0)));
}
break;
case 198:
-#line 742 "grammar.y"
+#line 758 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
case 199:
-#line 745 "grammar.y"
+#line 761 "grammar.y"
{ yyval.i = M_FISU; }
break;
case 200:
-#line 746 "grammar.y"
+#line 762 "grammar.y"
{ yyval.i = M_LSSU; }
break;
case 201:
-#line 747 "grammar.y"
+#line 763 "grammar.y"
{ yyval.i = M_MSU; }
break;
case 202:
-#line 748 "grammar.y"
+#line 764 "grammar.y"
{ yyval.i = MH_FISU; }
break;
case 203:
-#line 749 "grammar.y"
+#line 765 "grammar.y"
{ yyval.i = MH_LSSU; }
break;
case 204:
-#line 750 "grammar.y"
+#line 766 "grammar.y"
{ yyval.i = MH_MSU; }
break;
case 205:
-#line 753 "grammar.y"
+#line 769 "grammar.y"
{ yyval.blk.mtp3fieldtype = M_SIO; }
break;
case 206:
-#line 754 "grammar.y"
+#line 770 "grammar.y"
{ yyval.blk.mtp3fieldtype = M_OPC; }
break;
case 207:
-#line 755 "grammar.y"
+#line 771 "grammar.y"
{ yyval.blk.mtp3fieldtype = M_DPC; }
break;
case 208:
-#line 756 "grammar.y"
+#line 772 "grammar.y"
{ yyval.blk.mtp3fieldtype = M_SLS; }
break;
case 209:
-#line 757 "grammar.y"
+#line 773 "grammar.y"
{ yyval.blk.mtp3fieldtype = MH_SIO; }
break;
case 210:
-#line 758 "grammar.y"
+#line 774 "grammar.y"
{ yyval.blk.mtp3fieldtype = MH_OPC; }
break;
case 211:
-#line 759 "grammar.y"
+#line 775 "grammar.y"
{ yyval.blk.mtp3fieldtype = MH_DPC; }
break;
case 212:
-#line 760 "grammar.y"
+#line 776 "grammar.y"
{ yyval.blk.mtp3fieldtype = MH_SLS; }
break;
case 214:
-#line 763 "grammar.y"
- { yyval.blk.b = gen_mtp3field_code(cstate, yystack.l_mark[-2].blk.mtp3fieldtype, (u_int)yystack.l_mark[0].i, (u_int)yystack.l_mark[-1].i, 0); }
+#line 779 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_mtp3field_code(cstate, yystack.l_mark[-2].blk.mtp3fieldtype, (u_int)yystack.l_mark[0].i, (u_int)yystack.l_mark[-1].i, 0))); }
break;
case 215:
-#line 764 "grammar.y"
- { yyval.blk.b = gen_mtp3field_code(cstate, yystack.l_mark[-2].blk.mtp3fieldtype, (u_int)yystack.l_mark[0].i, (u_int)yystack.l_mark[-1].i, 1); }
+#line 780 "grammar.y"
+ { CHECK_PTR_VAL((yyval.blk.b = gen_mtp3field_code(cstate, yystack.l_mark[-2].blk.mtp3fieldtype, (u_int)yystack.l_mark[0].i, (u_int)yystack.l_mark[-1].i, 1))); }
break;
case 216:
-#line 765 "grammar.y"
+#line 781 "grammar.y"
{ yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = qerr; }
break;
case 217:
-#line 767 "grammar.y"
+#line 783 "grammar.y"
{
yyval.blk.mtp3fieldtype = yystack.l_mark[-1].blk.mtp3fieldtype;
if (yyval.blk.mtp3fieldtype == M_SIO ||
@@ -2390,14 +2414,14 @@ case 217:
yyval.blk.mtp3fieldtype == MH_OPC ||
yyval.blk.mtp3fieldtype == MH_DPC ||
yyval.blk.mtp3fieldtype == MH_SLS)
- yyval.blk.b = gen_mtp3field_code(cstate, yyval.blk.mtp3fieldtype, (u_int) yystack.l_mark[0].i, BPF_JEQ, 0);
+ CHECK_PTR_VAL((yyval.blk.b = gen_mtp3field_code(cstate, yyval.blk.mtp3fieldtype, (u_int) yystack.l_mark[0].i, BPF_JEQ, 0)));
}
break;
case 219:
-#line 781 "grammar.y"
+#line 797 "grammar.y"
{ gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
break;
-#line 2401 "grammar.c"
+#line 2425 "grammar.c"
}
yystack.s_mark -= yym;
yystate = *yystack.s_mark;
diff --git a/freebsd/contrib/libpcap/grammar.h b/freebsd/contrib/libpcap/grammar.h
index 35019dd2..197a45b9 100644
--- a/freebsd/contrib/libpcap/grammar.h
+++ b/freebsd/contrib/libpcap/grammar.h
@@ -114,9 +114,10 @@
#define HOPC 370
#define HDPC 371
#define HSLS 372
-#define OR 373
-#define AND 374
-#define UMINUS 375
+#define LEX_ERROR 373
+#define OR 374
+#define AND 375
+#define UMINUS 376
#ifdef YYSTYPE
#undef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
@@ -126,7 +127,6 @@
typedef union {
int i;
bpf_u_int32 h;
- u_char *e;
char *s;
struct stmt *stmt;
struct arth *a;
diff --git a/freebsd/contrib/libpcap/grammar.y b/freebsd/contrib/libpcap/grammar.y
index be80e2bf..32cb19c1 100644
--- a/freebsd/contrib/libpcap/grammar.y
+++ b/freebsd/contrib/libpcap/grammar.y
@@ -216,13 +216,12 @@ str2tok(const char *str, const struct tok *toks)
return (-1);
}
-static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
+static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
-static PCAP_NORETURN_DEF void
+static void
yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
{
- bpf_syntax_error(cstate, msg);
- /* NOTREACHED */
+ bpf_set_error(cstate, "can't parse filter expression: %s", msg);
}
#ifdef HAVE_NET_PFVAR_H
@@ -236,8 +235,8 @@ pfreason_to_num(compiler_state_t *cstate, const char *reason)
if (pcap_strcasecmp(reason, reasons[i]) == 0)
return (i);
}
- bpf_error(cstate, "unknown PF reason");
- /*NOTREACHED*/
+ bpf_set_error(cstate, "unknown PF reason");
+ return (-1);
}
static int
@@ -260,33 +259,38 @@ pfaction_to_num(compiler_state_t *cstate, const char *action)
return (PF_NORDR);
#endif
else {
- bpf_error(cstate, "unknown PF action");
- /*NOTREACHED*/
+ bpf_set_error(cstate, "unknown PF action");
+ return (-1);
}
}
#else /* !HAVE_NET_PFVAR_H */
-static PCAP_NORETURN_DEF int
+static int
pfreason_to_num(compiler_state_t *cstate, const char *reason _U_)
{
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
+ bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
+ return (-1);
}
-static PCAP_NORETURN_DEF int
+static int
pfaction_to_num(compiler_state_t *cstate, const char *action _U_)
{
- bpf_error(cstate, "libpcap was compiled on a machine without pf support");
- /*NOTREACHED*/
+ bpf_set_error(cstate, "libpcap was compiled on a machine without pf support");
+ return (-1);
}
#endif /* HAVE_NET_PFVAR_H */
+/*
+ * For calls that might return an "an error occurred" value.
+ */
+#define CHECK_INT_VAL(val) if (val == -1) YYABORT
+#define CHECK_PTR_VAL(val) if (val == NULL) YYABORT
+
DIAG_OFF_BISON_BYACC
%}
%union {
int i;
bpf_u_int32 h;
- u_char *e;
char *s;
struct stmt *stmt;
struct arth *a;
@@ -340,11 +344,9 @@ DIAG_OFF_BISON_BYACC
%token RADIO
%token FISU LSSU MSU HFISU HLSSU HMSU
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
+%token LEX_ERROR
-
-%type <s> ID
-%type <e> EID
-%type <e> AID
+%type <s> ID EID AID
%type <s> HID HID6
%type <i> NUM action reason type subtype type_subtype dir
@@ -359,7 +361,7 @@ DIAG_OFF_BISON_BYACC
%%
prog: null expr
{
- finish_parse(cstate, $2.b);
+ CHECK_INT_VAL(finish_parse(cstate, $2.b));
}
| null
;
@@ -376,64 +378,58 @@ and: AND { $$ = $<blk>0; }
or: OR { $$ = $<blk>0; }
;
id: nid
- | pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
- $$.q = $<blk>0.q); }
+ | pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
+ $$.q = $<blk>0.q))); }
| paren pid ')' { $$ = $2; }
;
-nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); }
- | HID '/' NUM { $$.b = gen_mcode(cstate, $1, NULL, $3,
- $$.q = $<blk>0.q); }
- | HID NETMASK HID { $$.b = gen_mcode(cstate, $1, $3, 0,
- $$.q = $<blk>0.q); }
+nid: ID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q))); }
+ | HID '/' NUM { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, NULL, $3,
+ $$.q = $<blk>0.q))); }
+ | HID NETMASK HID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_mcode(cstate, $1, $3, 0,
+ $$.q = $<blk>0.q))); }
| HID {
+ CHECK_PTR_VAL($1);
/* Decide how to parse HID based on proto */
$$.q = $<blk>0.q;
- if ($$.q.addr == Q_PORT)
- bpf_error(cstate, "'port' modifier applied to ip host");
- else if ($$.q.addr == Q_PORTRANGE)
- bpf_error(cstate, "'portrange' modifier applied to ip host");
- else if ($$.q.addr == Q_PROTO)
- bpf_error(cstate, "'proto' modifier applied to ip host");
- else if ($$.q.addr == Q_PROTOCHAIN)
- bpf_error(cstate, "'protochain' modifier applied to ip host");
- $$.b = gen_ncode(cstate, $1, 0, $$.q);
+ if ($$.q.addr == Q_PORT) {
+ bpf_set_error(cstate, "'port' modifier applied to ip host");
+ YYABORT;
+ } else if ($$.q.addr == Q_PORTRANGE) {
+ bpf_set_error(cstate, "'portrange' modifier applied to ip host");
+ YYABORT;
+ } else if ($$.q.addr == Q_PROTO) {
+ bpf_set_error(cstate, "'proto' modifier applied to ip host");
+ YYABORT;
+ } else if ($$.q.addr == Q_PROTOCHAIN) {
+ bpf_set_error(cstate, "'protochain' modifier applied to ip host");
+ YYABORT;
+ }
+ CHECK_PTR_VAL(($$.b = gen_ncode(cstate, $1, 0, $$.q)));
}
| HID6 '/' NUM {
+ CHECK_PTR_VAL($1);
#ifdef INET6
- $$.b = gen_mcode6(cstate, $1, NULL, $3,
- $$.q = $<blk>0.q);
+ CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, NULL, $3,
+ $$.q = $<blk>0.q)));
#else
- bpf_error(cstate, "'ip6addr/prefixlen' not supported "
+ bpf_set_error(cstate, "'ip6addr/prefixlen' not supported "
"in this configuration");
+ YYABORT;
#endif /*INET6*/
}
| HID6 {
+ CHECK_PTR_VAL($1);
#ifdef INET6
- $$.b = gen_mcode6(cstate, $1, 0, 128,
- $$.q = $<blk>0.q);
+ CHECK_PTR_VAL(($$.b = gen_mcode6(cstate, $1, 0, 128,
+ $$.q = $<blk>0.q)));
#else
- bpf_error(cstate, "'ip6addr' not supported "
+ bpf_set_error(cstate, "'ip6addr' not supported "
"in this configuration");
+ YYABORT;
#endif /*INET6*/
}
- | EID {
- $$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q);
- /*
- * $1 was allocated by "pcap_ether_aton()",
- * so we must free it now that we're done
- * with it.
- */
- free($1);
- }
- | AID {
- $$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q);
- /*
- * $1 was allocated by "pcap_ether_aton()",
- * so we must free it now that we're done
- * with it.
- */
- free($1);
- }
+ | EID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q))); }
+ | AID { CHECK_PTR_VAL($1); CHECK_PTR_VAL(($$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q))); }
| not id { gen_not($2.b); $$ = $2; }
;
not: '!' { $$ = $<blk>0; }
@@ -444,8 +440,8 @@ pid: nid
| qid and id { gen_and($1.b, $3.b); $$ = $3; }
| qid or id { gen_or($1.b, $3.b); $$ = $3; }
;
-qid: pnum { $$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
- $$.q = $<blk>0.q); }
+qid: pnum { CHECK_PTR_VAL(($$.b = gen_ncode(cstate, NULL, (bpf_u_int32)$1,
+ $$.q = $<blk>0.q))); }
| pid
;
term: rterm
@@ -455,21 +451,28 @@ head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
| pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
| pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
| pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
- | pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
+ | pqual PROTOCHAIN {
+#ifdef NO_PROTOCHAIN
+ bpf_set_error(cstate, "protochain not supported");
+ YYABORT;
+#else
+ QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN);
+#endif
+ }
| pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
;
rterm: head id { $$ = $2; }
| paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
- | pname { $$.b = gen_proto_abbrev(cstate, $1); $$.q = qerr; }
- | arth relop arth { $$.b = gen_relation(cstate, $2, $1, $3, 0);
+ | pname { CHECK_PTR_VAL(($$.b = gen_proto_abbrev(cstate, $1))); $$.q = qerr; }
+ | arth relop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 0)));
$$.q = qerr; }
- | arth irelop arth { $$.b = gen_relation(cstate, $2, $1, $3, 1);
+ | arth irelop arth { CHECK_PTR_VAL(($$.b = gen_relation(cstate, $2, $1, $3, 1)));
$$.q = qerr; }
| other { $$.b = $1; $$.q = qerr; }
- | atmtype { $$.b = gen_atmtype_abbrev(cstate, $1); $$.q = qerr; }
- | atmmultitype { $$.b = gen_atmmulti_abbrev(cstate, $1); $$.q = qerr; }
+ | atmtype { CHECK_PTR_VAL(($$.b = gen_atmtype_abbrev(cstate, $1))); $$.q = qerr; }
+ | atmmultitype { CHECK_PTR_VAL(($$.b = gen_atmmulti_abbrev(cstate, $1))); $$.q = qerr; }
| atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
- | mtp2type { $$.b = gen_mtp2type_abbrev(cstate, $1); $$.q = qerr; }
+ | mtp2type { CHECK_PTR_VAL(($$.b = gen_mtp2type_abbrev(cstate, $1))); $$.q = qerr; }
| mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
;
/* protocol level qualifiers */
@@ -539,65 +542,69 @@ pname: LINK { $$ = Q_LINK; }
| NETBEUI { $$ = Q_NETBEUI; }
| RADIO { $$ = Q_RADIO; }
;
-other: pqual TK_BROADCAST { $$ = gen_broadcast(cstate, $1); }
- | pqual TK_MULTICAST { $$ = gen_multicast(cstate, $1); }
- | LESS NUM { $$ = gen_less(cstate, $2); }
- | GREATER NUM { $$ = gen_greater(cstate, $2); }
- | CBYTE NUM byteop NUM { $$ = gen_byteop(cstate, $3, $2, $4); }
- | INBOUND { $$ = gen_inbound(cstate, 0); }
- | OUTBOUND { $$ = gen_inbound(cstate, 1); }
- | VLAN pnum { $$ = gen_vlan(cstate, $2); }
- | VLAN { $$ = gen_vlan(cstate, -1); }
- | MPLS pnum { $$ = gen_mpls(cstate, $2); }
- | MPLS { $$ = gen_mpls(cstate, -1); }
- | PPPOED { $$ = gen_pppoed(cstate); }
- | PPPOES pnum { $$ = gen_pppoes(cstate, $2); }
- | PPPOES { $$ = gen_pppoes(cstate, -1); }
- | GENEVE pnum { $$ = gen_geneve(cstate, $2); }
- | GENEVE { $$ = gen_geneve(cstate, -1); }
+other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
+ | pqual TK_MULTICAST { CHECK_PTR_VAL(($$ = gen_multicast(cstate, $1))); }
+ | LESS NUM { CHECK_PTR_VAL(($$ = gen_less(cstate, $2))); }
+ | GREATER NUM { CHECK_PTR_VAL(($$ = gen_greater(cstate, $2))); }
+ | CBYTE NUM byteop NUM { CHECK_PTR_VAL(($$ = gen_byteop(cstate, $3, $2, $4))); }
+ | INBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 0))); }
+ | OUTBOUND { CHECK_PTR_VAL(($$ = gen_inbound(cstate, 1))); }
+ | VLAN pnum { CHECK_PTR_VAL(($$ = gen_vlan(cstate, (bpf_u_int32)$2, 1))); }
+ | VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
+ | MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, (bpf_u_int32)$2, 1))); }
+ | MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
+ | PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
+ | PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, (bpf_u_int32)$2, 1))); }
+ | PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
+ | GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, (bpf_u_int32)$2, 1))); }
+ | GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
| pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; }
| pllc { $$ = $1; }
;
-pfvar: PF_IFNAME ID { $$ = gen_pf_ifname(cstate, $2); }
- | PF_RSET ID { $$ = gen_pf_ruleset(cstate, $2); }
- | PF_RNR NUM { $$ = gen_pf_rnr(cstate, $2); }
- | PF_SRNR NUM { $$ = gen_pf_srnr(cstate, $2); }
- | PF_REASON reason { $$ = gen_pf_reason(cstate, $2); }
- | PF_ACTION action { $$ = gen_pf_action(cstate, $2); }
+pfvar: PF_IFNAME ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ifname(cstate, $2))); }
+ | PF_RSET ID { CHECK_PTR_VAL($2); CHECK_PTR_VAL(($$ = gen_pf_ruleset(cstate, $2))); }
+ | PF_RNR NUM { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
+ | PF_SRNR NUM { CHECK_PTR_VAL(($$ = gen_pf_srnr(cstate, $2))); }
+ | PF_REASON reason { CHECK_PTR_VAL(($$ = gen_pf_reason(cstate, $2))); }
+ | PF_ACTION action { CHECK_PTR_VAL(($$ = gen_pf_action(cstate, $2))); }
;
p80211: TYPE type SUBTYPE subtype
- { $$ = gen_p80211_type(cstate, $2 | $4,
+ { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2 | $4,
IEEE80211_FC0_TYPE_MASK |
- IEEE80211_FC0_SUBTYPE_MASK);
+ IEEE80211_FC0_SUBTYPE_MASK)));
}
- | TYPE type { $$ = gen_p80211_type(cstate, $2,
- IEEE80211_FC0_TYPE_MASK);
+ | TYPE type { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
+ IEEE80211_FC0_TYPE_MASK)));
}
- | SUBTYPE type_subtype { $$ = gen_p80211_type(cstate, $2,
+ | SUBTYPE type_subtype { CHECK_PTR_VAL(($$ = gen_p80211_type(cstate, $2,
IEEE80211_FC0_TYPE_MASK |
- IEEE80211_FC0_SUBTYPE_MASK);
+ IEEE80211_FC0_SUBTYPE_MASK)));
}
- | DIR dir { $$ = gen_p80211_fcdir(cstate, $2); }
+ | DIR dir { CHECK_PTR_VAL(($$ = gen_p80211_fcdir(cstate, $2))); }
;
type: NUM
- | ID { $$ = str2tok($1, ieee80211_types);
- if ($$ == -1)
- bpf_error(cstate, "unknown 802.11 type name");
+ | ID { CHECK_PTR_VAL($1);
+ $$ = str2tok($1, ieee80211_types);
+ if ($$ == -1) {
+ bpf_set_error(cstate, "unknown 802.11 type name");
+ YYABORT;
+ }
}
;
subtype: NUM
| ID { const struct tok *types = NULL;
int i;
+ CHECK_PTR_VAL($1);
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */
- bpf_error(cstate, "unknown 802.11 type");
- break;
+ bpf_set_error(cstate, "unknown 802.11 type");
+ YYABORT;
}
if ($<i>-1 == ieee80211_type_subtypes[i].type) {
types = ieee80211_type_subtypes[i].tok;
@@ -606,17 +613,20 @@ subtype: NUM
}
$$ = str2tok($1, types);
- if ($$ == -1)
- bpf_error(cstate, "unknown 802.11 subtype name");
+ if ($$ == -1) {
+ bpf_set_error(cstate, "unknown 802.11 subtype name");
+ YYABORT;
+ }
}
;
type_subtype: ID { int i;
+ CHECK_PTR_VAL($1);
for (i = 0;; i++) {
if (ieee80211_type_subtypes[i].tok == NULL) {
/* Ran out of types */
- bpf_error(cstate, "unknown 802.11 type name");
- break;
+ bpf_set_error(cstate, "unknown 802.11 type name");
+ YYABORT;
}
$$ = str2tok($1, ieee80211_type_subtypes[i].tok);
if ($$ != -1) {
@@ -627,33 +637,37 @@ type_subtype: ID { int i;
}
;
-pllc: LLC { $$ = gen_llc(cstate); }
- | LLC ID { if (pcap_strcasecmp($2, "i") == 0)
- $$ = gen_llc_i(cstate);
- else if (pcap_strcasecmp($2, "s") == 0)
- $$ = gen_llc_s(cstate);
- else if (pcap_strcasecmp($2, "u") == 0)
- $$ = gen_llc_u(cstate);
- else {
+pllc: LLC { CHECK_PTR_VAL(($$ = gen_llc(cstate))); }
+ | LLC ID { CHECK_PTR_VAL($2);
+ if (pcap_strcasecmp($2, "i") == 0) {
+ CHECK_PTR_VAL(($$ = gen_llc_i(cstate)));
+ } else if (pcap_strcasecmp($2, "s") == 0) {
+ CHECK_PTR_VAL(($$ = gen_llc_s(cstate)));
+ } else if (pcap_strcasecmp($2, "u") == 0) {
+ CHECK_PTR_VAL(($$ = gen_llc_u(cstate)));
+ } else {
int subtype;
subtype = str2tok($2, llc_s_subtypes);
- if (subtype != -1)
- $$ = gen_llc_s_subtype(cstate, subtype);
- else {
+ if (subtype != -1) {
+ CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, subtype)));
+ } else {
subtype = str2tok($2, llc_u_subtypes);
- if (subtype == -1)
- bpf_error(cstate, "unknown LLC type name \"%s\"", $2);
- $$ = gen_llc_u_subtype(cstate, subtype);
+ if (subtype == -1) {
+ bpf_set_error(cstate, "unknown LLC type name \"%s\"", $2);
+ YYABORT;
+ }
+ CHECK_PTR_VAL(($$ = gen_llc_u_subtype(cstate, subtype)));
}
}
}
/* sigh, "rnr" is already a keyword for PF */
- | LLC PF_RNR { $$ = gen_llc_s_subtype(cstate, LLC_RNR); }
+ | LLC PF_RNR { CHECK_PTR_VAL(($$ = gen_llc_s_subtype(cstate, LLC_RNR))); }
;
dir: NUM
- | ID { if (pcap_strcasecmp($1, "nods") == 0)
+ | ID { CHECK_PTR_VAL($1);
+ if (pcap_strcasecmp($1, "nods") == 0)
$$ = IEEE80211_FC1_DIR_NODS;
else if (pcap_strcasecmp($1, "tods") == 0)
$$ = IEEE80211_FC1_DIR_TODS;
@@ -661,16 +675,18 @@ dir: NUM
$$ = IEEE80211_FC1_DIR_FROMDS;
else if (pcap_strcasecmp($1, "dstods") == 0)
$$ = IEEE80211_FC1_DIR_DSTODS;
- else
- bpf_error(cstate, "unknown 802.11 direction");
+ else {
+ bpf_set_error(cstate, "unknown 802.11 direction");
+ YYABORT;
+ }
}
;
reason: NUM { $$ = $1; }
- | ID { $$ = pfreason_to_num(cstate, $1); }
+ | ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfreason_to_num(cstate, $1))); }
;
-action: ID { $$ = pfaction_to_num(cstate, $1); }
+action: ID { CHECK_PTR_VAL($1); CHECK_INT_VAL(($$ = pfaction_to_num(cstate, $1))); }
;
relop: '>' { $$ = BPF_JGT; }
@@ -681,24 +697,24 @@ irelop: LEQ { $$ = BPF_JGT; }
| '<' { $$ = BPF_JGE; }
| NEQ { $$ = BPF_JEQ; }
;
-arth: pnum { $$ = gen_loadi(cstate, $1); }
+arth: pnum { CHECK_PTR_VAL(($$ = gen_loadi(cstate, $1))); }
| narth
;
-narth: pname '[' arth ']' { $$ = gen_load(cstate, $1, $3, 1); }
- | pname '[' arth ':' NUM ']' { $$ = gen_load(cstate, $1, $3, $5); }
- | arth '+' arth { $$ = gen_arth(cstate, BPF_ADD, $1, $3); }
- | arth '-' arth { $$ = gen_arth(cstate, BPF_SUB, $1, $3); }
- | arth '*' arth { $$ = gen_arth(cstate, BPF_MUL, $1, $3); }
- | arth '/' arth { $$ = gen_arth(cstate, BPF_DIV, $1, $3); }
- | arth '%' arth { $$ = gen_arth(cstate, BPF_MOD, $1, $3); }
- | arth '&' arth { $$ = gen_arth(cstate, BPF_AND, $1, $3); }
- | arth '|' arth { $$ = gen_arth(cstate, BPF_OR, $1, $3); }
- | arth '^' arth { $$ = gen_arth(cstate, BPF_XOR, $1, $3); }
- | arth LSH arth { $$ = gen_arth(cstate, BPF_LSH, $1, $3); }
- | arth RSH arth { $$ = gen_arth(cstate, BPF_RSH, $1, $3); }
- | '-' arth %prec UMINUS { $$ = gen_neg(cstate, $2); }
+narth: pname '[' arth ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, 1))); }
+ | pname '[' arth ':' NUM ']' { CHECK_PTR_VAL(($$ = gen_load(cstate, $1, $3, $5))); }
+ | arth '+' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_ADD, $1, $3))); }
+ | arth '-' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_SUB, $1, $3))); }
+ | arth '*' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MUL, $1, $3))); }
+ | arth '/' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_DIV, $1, $3))); }
+ | arth '%' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_MOD, $1, $3))); }
+ | arth '&' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_AND, $1, $3))); }
+ | arth '|' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_OR, $1, $3))); }
+ | arth '^' arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_XOR, $1, $3))); }
+ | arth LSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_LSH, $1, $3))); }
+ | arth RSH arth { CHECK_PTR_VAL(($$ = gen_arth(cstate, BPF_RSH, $1, $3))); }
+ | '-' arth %prec UMINUS { CHECK_PTR_VAL(($$ = gen_neg(cstate, $2))); }
| paren narth ')' { $$ = $2; }
- | LEN { $$ = gen_loadlen(cstate); }
+ | LEN { CHECK_PTR_VAL(($$ = gen_loadlen(cstate))); }
;
byteop: '&' { $$ = '&'; }
| '|' { $$ = '|'; }
@@ -727,15 +743,15 @@ atmfield: VPI { $$.atmfieldtype = A_VPI; }
| VCI { $$.atmfieldtype = A_VCI; }
;
atmvalue: atmfieldvalue
- | relop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
- | irelop NUM { $$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
+ | relop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0))); }
+ | irelop NUM { CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1))); }
| paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
;
atmfieldvalue: NUM {
$$.atmfieldtype = $<blk>0.atmfieldtype;
if ($$.atmfieldtype == A_VPI ||
$$.atmfieldtype == A_VCI)
- $$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
+ CHECK_PTR_VAL(($$.b = gen_atmfield_code(cstate, $$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0)));
}
;
atmlistvalue: atmfieldvalue
@@ -760,8 +776,8 @@ mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
| HSLS { $$.mtp3fieldtype = MH_SLS; }
;
mtp3value: mtp3fieldvalue
- | relop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
- | irelop NUM { $$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
+ | relop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0))); }
+ | irelop NUM { CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1))); }
| paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
;
mtp3fieldvalue: NUM {
@@ -774,7 +790,7 @@ mtp3fieldvalue: NUM {
$$.mtp3fieldtype == MH_OPC ||
$$.mtp3fieldtype == MH_DPC ||
$$.mtp3fieldtype == MH_SLS)
- $$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
+ CHECK_PTR_VAL(($$.b = gen_mtp3field_code(cstate, $$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0)));
}
;
mtp3listvalue: mtp3fieldvalue
diff --git a/freebsd/contrib/libpcap/nametoaddr.c b/freebsd/contrib/libpcap/nametoaddr.c
index 1d47ff9d..c77334c9 100644
--- a/freebsd/contrib/libpcap/nametoaddr.c
+++ b/freebsd/contrib/libpcap/nametoaddr.c
@@ -233,7 +233,22 @@ pcap_nametonetaddr(const char *name)
int h_errnoval;
int err;
- err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
+ /*
+ * Apparently, the man page at
+ *
+ * http://man7.org/linux/man-pages/man3/getnetbyname_r.3.html
+ *
+ * lies when it says
+ *
+ * If the function call successfully obtains a network record,
+ * then *result is set pointing to result_buf; otherwise, *result
+ * is set to NULL.
+ *
+ * and, in fact, at least in some versions of GNU libc, it does
+ * *not* always get set if getnetbyname_r() succeeds.
+ */
+ np = NULL;
+ err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
&h_errnoval);
if (err != 0) {
/*
@@ -308,7 +323,8 @@ pcap_nametoport(const char *name, int *port, int *proto)
hints.ai_protocol = IPPROTO_TCP;
error = getaddrinfo(NULL, name, &hints, &res);
if (error != 0) {
- if (error != EAI_NONAME) {
+ if (error != EAI_NONAME &&
+ error != EAI_SERVICE) {
/*
* This is a real error, not just "there's
* no such service name".
@@ -351,7 +367,8 @@ pcap_nametoport(const char *name, int *port, int *proto)
hints.ai_protocol = IPPROTO_UDP;
error = getaddrinfo(NULL, name, &hints, &res);
if (error != 0) {
- if (error != EAI_NONAME) {
+ if (error != EAI_NONAME &&
+ error != EAI_SERVICE) {
/*
* This is a real error, not just "there's
* no such service name".
@@ -638,8 +655,15 @@ __pcap_atoin(const char *s, bpf_u_int32 *addr)
len = 0;
for (;;) {
n = 0;
- while (*s && *s != '.')
+ while (*s && *s != '.') {
+ if (n > 25) {
+ /* The result will be > 255 */
+ return -1;
+ }
n = n * 10 + *s++ - '0';
+ }
+ if (n > 255)
+ return -1;
*addr <<= 8;
*addr |= n & 0xff;
len += 8;
diff --git a/freebsd/contrib/libpcap/optimize.c b/freebsd/contrib/libpcap/optimize.c
index 7d2a1826..3c401d7d 100644
--- a/freebsd/contrib/libpcap/optimize.c
+++ b/freebsd/contrib/libpcap/optimize.c
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
+#include <setjmp.h>
#include <string.h>
#include <errno.h>
@@ -229,6 +230,16 @@ struct vmapinfo {
typedef struct {
/*
+ * Place to longjmp to on an error.
+ */
+ jmp_buf top_ctx;
+
+ /*
+ * The buffer into which to put error message.
+ */
+ char *errbuf;
+
+ /*
* A flag to indicate that further optimization is needed.
* Iterative passes are continued until a given pass yields no
* branch movement.
@@ -254,19 +265,19 @@ typedef struct {
* True if a is in uset {p}
*/
#define SET_MEMBER(p, a) \
-((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
+((p)[(unsigned)(a) / BITS_PER_WORD] & ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD)))
/*
* Add 'a' to uset p.
*/
#define SET_INSERT(p, a) \
-(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
+(p)[(unsigned)(a) / BITS_PER_WORD] |= ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))
/*
* Delete 'a' from uset p.
*/
#define SET_DELETE(p, a) \
-(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
+(p)[(unsigned)(a) / BITS_PER_WORD] &= ~((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))
/*
* a := a intersect b
@@ -314,6 +325,16 @@ typedef struct {
typedef struct {
/*
+ * Place to longjmp to on an error.
+ */
+ jmp_buf top_ctx;
+
+ /*
+ * The buffer into which to put error message.
+ */
+ char *errbuf;
+
+ /*
* Some pointers used to convert the basic block form of the code,
* into the array form that BPF requires. 'fstart' will point to
* the malloc'd array while 'ftail' is used during the recursive
@@ -323,14 +344,16 @@ typedef struct {
struct bpf_insn *ftail;
} conv_state_t;
-static void opt_init(compiler_state_t *, opt_state_t *, struct icode *);
+static void opt_init(opt_state_t *, struct icode *);
static void opt_cleanup(opt_state_t *);
+static void PCAP_NORETURN opt_error(opt_state_t *, const char *, ...)
+ PCAP_PRINTFLIKE(2, 3);
static void intern_blocks(opt_state_t *, struct icode *);
static void find_inedges(opt_state_t *, struct block *);
#ifdef BDEBUG
-static void opt_dump(compiler_state_t *, struct icode *);
+static void opt_dump(opt_state_t *, struct icode *);
#endif
#ifndef MAX
@@ -663,7 +686,7 @@ F(opt_state_t *opt_state, int code, int v0, int v1)
int val;
struct valnode *p;
- hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
+ hash = (u_int)code ^ ((u_int)v0 << 4) ^ ((u_int)v1 << 8);
hash %= MODULUS;
for (p = opt_state->hashtbl[hash]; p; p = p->next)
@@ -701,8 +724,7 @@ vstore(struct stmt *s, int *valp, int newval, int alter)
* (Unary operators are handled elsewhere.)
*/
static void
-fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
- struct stmt *s, int v0, int v1)
+fold_op(opt_state_t *opt_state, struct stmt *s, int v0, int v1)
{
bpf_u_int32 a, b;
@@ -724,13 +746,13 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
case BPF_DIV:
if (b == 0)
- bpf_error(cstate, "division by zero");
+ opt_error(opt_state, "division by zero");
a /= b;
break;
case BPF_MOD:
if (b == 0)
- bpf_error(cstate, "modulus by zero");
+ opt_error(opt_state, "modulus by zero");
a %= b;
break;
@@ -747,11 +769,39 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
break;
case BPF_LSH:
- a <<= b;
+ /*
+ * A left shift of more than the width of the type
+ * is undefined in C; we'll just treat it as shifting
+ * all the bits out.
+ *
+ * XXX - the BPF interpreter doesn't check for this,
+ * so its behavior is dependent on the behavior of
+ * the processor on which it's running. There are
+ * processors on which it shifts all the bits out
+ * and processors on which it does no shift.
+ */
+ if (b < 32)
+ a <<= b;
+ else
+ a = 0;
break;
case BPF_RSH:
- a >>= b;
+ /*
+ * A right shift of more than the width of the type
+ * is undefined in C; we'll just treat it as shifting
+ * all the bits out.
+ *
+ * XXX - the BPF interpreter doesn't check for this,
+ * so its behavior is dependent on the behavior of
+ * the processor on which it's running. There are
+ * processors on which it shifts all the bits out
+ * and processors on which it does no shift.
+ */
+ if (b < 32)
+ a >>= b;
+ else
+ a = 0;
break;
default:
@@ -1043,8 +1093,7 @@ opt_peep(opt_state_t *opt_state, struct block *b)
* evaluation and code transformations weren't folded together.
*/
static void
-opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
- struct stmt *s, int val[], int alter)
+opt_stmt(opt_state_t *opt_state, struct stmt *s, int val[], int alter)
{
int op;
int v;
@@ -1096,7 +1145,23 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
case BPF_ALU|BPF_NEG:
if (alter && opt_state->vmap[val[A_ATOM]].is_const) {
s->code = BPF_LD|BPF_IMM;
- s->k = -opt_state->vmap[val[A_ATOM]].const_val;
+ /*
+ * Do this negation as unsigned arithmetic; that's
+ * what modern BPF engines do, and it guarantees
+ * that all possible values can be negated. (Yeah,
+ * negating 0x80000000, the minimum signed 32-bit
+ * two's-complement value, results in 0x80000000,
+ * so it's still negative, but we *should* be doing
+ * all unsigned arithmetic here, to match what
+ * modern BPF engines do.)
+ *
+ * Express it as 0U - (unsigned value) so that we
+ * don't get compiler warnings about negating an
+ * unsigned value and don't get UBSan warnings
+ * about the result of negating 0x80000000 being
+ * undefined.
+ */
+ s->k = 0U - (bpf_u_int32)(opt_state->vmap[val[A_ATOM]].const_val);
val[A_ATOM] = K(s->k);
}
else
@@ -1116,9 +1181,17 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
op = BPF_OP(s->code);
if (alter) {
if (s->k == 0) {
- /* don't optimize away "sub #0"
+ /*
+ * Optimize operations where the constant
+ * is zero.
+ *
+ * Don't optimize away "sub #0"
* as it may be needed later to
- * fixup the generated math code */
+ * fixup the generated math code.
+ *
+ * Fail if we're dividing by zero or taking
+ * a modulus by zero.
+ */
if (op == BPF_ADD ||
op == BPF_LSH || op == BPF_RSH ||
op == BPF_OR || op == BPF_XOR) {
@@ -1130,9 +1203,15 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
val[A_ATOM] = K(s->k);
break;
}
+ if (op == BPF_DIV)
+ opt_error(opt_state,
+ "division by zero");
+ if (op == BPF_MOD)
+ opt_error(opt_state,
+ "modulus by zero");
}
if (opt_state->vmap[val[A_ATOM]].is_const) {
- fold_op(cstate, opt_state, s, val[A_ATOM], K(s->k));
+ fold_op(opt_state, s, val[A_ATOM], K(s->k));
val[A_ATOM] = K(s->k);
break;
}
@@ -1153,12 +1232,22 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
op = BPF_OP(s->code);
if (alter && opt_state->vmap[val[X_ATOM]].is_const) {
if (opt_state->vmap[val[A_ATOM]].is_const) {
- fold_op(cstate, opt_state, s, val[A_ATOM], val[X_ATOM]);
+ fold_op(opt_state, s, val[A_ATOM], val[X_ATOM]);
val[A_ATOM] = K(s->k);
}
else {
s->code = BPF_ALU|BPF_K|op;
s->k = opt_state->vmap[val[X_ATOM]].const_val;
+ /*
+ * XXX - we need to make up our minds
+ * as to what integers are signed and
+ * what integers are unsigned in BPF
+ * programs and in our IR.
+ */
+ if ((op == BPF_LSH || op == BPF_RSH) &&
+ (s->k < 0 || s->k > 31))
+ opt_error(opt_state,
+ "shift by more than 31 bits");
opt_state->done = 0;
val[A_ATOM] =
F(opt_state, s->code, val[A_ATOM], K(s->k));
@@ -1277,8 +1366,7 @@ opt_deadstores(opt_state_t *opt_state, register struct block *b)
}
static void
-opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
- struct block *b, int do_stmts)
+opt_blk(opt_state_t *opt_state, struct block *b, int do_stmts)
{
struct slist *s;
struct edge *p;
@@ -1328,7 +1416,7 @@ opt_blk(compiler_state_t *cstate, opt_state_t *opt_state,
aval = b->val[A_ATOM];
xval = b->val[X_ATOM];
for (s = b->stmts; s; s = s->next)
- opt_stmt(cstate, opt_state, &s->s, b->val, do_stmts);
+ opt_stmt(opt_state, &s->s, b->val, do_stmts);
/*
* This is a special case: if we don't use anything from this
@@ -1482,7 +1570,7 @@ opt_j(opt_state_t *opt_state, struct edge *ep)
while (x != 0) {
k = lowest_set_bit(x);
- x &=~ (1 << k);
+ x &=~ ((bpf_u_int32)1 << k);
k += i * BITS_PER_WORD;
target = fold_edge(ep->succ, opt_state->edges[k]);
@@ -1689,8 +1777,7 @@ and_pullup(opt_state_t *opt_state, struct block *b)
}
static void
-opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
- int do_stmts)
+opt_blks(opt_state_t *opt_state, struct icode *ic, int do_stmts)
{
int i, maxlevel;
struct block *p;
@@ -1701,7 +1788,7 @@ opt_blks(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
find_inedges(opt_state, ic->root);
for (i = maxlevel; i >= 0; --i)
for (p = opt_state->levels[i]; p; p = p->link)
- opt_blk(cstate, opt_state, p, do_stmts);
+ opt_blk(opt_state, p, do_stmts);
if (do_stmts)
/*
@@ -1779,14 +1866,13 @@ opt_root(struct block **b)
}
static void
-opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
- int do_stmts)
+opt_loop(opt_state_t *opt_state, struct icode *ic, int do_stmts)
{
#ifdef BDEBUG
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) begin\n", do_stmts);
- opt_dump(cstate, ic);
+ opt_dump(opt_state, ic);
}
#endif
do {
@@ -1796,11 +1882,11 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
find_closure(opt_state, ic->root);
find_ud(opt_state, ic->root);
find_edom(opt_state, ic->root);
- opt_blks(cstate, opt_state, ic, do_stmts);
+ opt_blks(opt_state, ic, do_stmts);
#ifdef BDEBUG
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done);
- opt_dump(cstate, ic);
+ opt_dump(opt_state, ic);
}
#endif
} while (!opt_state->done);
@@ -1808,30 +1894,38 @@ opt_loop(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic,
/*
* Optimize the filter code in its dag representation.
+ * Return 0 on success, -1 on error.
*/
-void
-bpf_optimize(compiler_state_t *cstate, struct icode *ic)
+int
+bpf_optimize(struct icode *ic, char *errbuf)
{
opt_state_t opt_state;
- opt_init(cstate, &opt_state, ic);
- opt_loop(cstate, &opt_state, ic, 0);
- opt_loop(cstate, &opt_state, ic, 1);
+ memset(&opt_state, 0, sizeof(opt_state));
+ opt_state.errbuf = errbuf;
+ if (setjmp(opt_state.top_ctx)) {
+ opt_cleanup(&opt_state);
+ return -1;
+ }
+ opt_init(&opt_state, ic);
+ opt_loop(&opt_state, ic, 0);
+ opt_loop(&opt_state, ic, 1);
intern_blocks(&opt_state, ic);
#ifdef BDEBUG
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after intern_blocks()\n");
- opt_dump(cstate, ic);
+ opt_dump(&opt_state, ic);
}
#endif
opt_root(&ic->root);
#ifdef BDEBUG
if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after opt_root()\n");
- opt_dump(cstate, ic);
+ opt_dump(&opt_state, ic);
}
#endif
opt_cleanup(&opt_state);
+ return 0;
}
static void
@@ -1946,6 +2040,24 @@ opt_cleanup(opt_state_t *opt_state)
}
/*
+ * For optimizer errors.
+ */
+static void PCAP_NORETURN
+opt_error(opt_state_t *opt_state, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (opt_state->errbuf != NULL) {
+ va_start(ap, fmt);
+ (void)pcap_vsnprintf(opt_state->errbuf,
+ PCAP_ERRBUF_SIZE, fmt, ap);
+ va_end(ap);
+ }
+ longjmp(opt_state->top_ctx, 1);
+ /* NOTREACHED */
+}
+
+/*
* Return the number of stmts in 's'.
*/
static u_int
@@ -2029,7 +2141,7 @@ count_stmts(struct icode *ic, struct block *p)
* from the total number of blocks and/or statements.
*/
static void
-opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
+opt_init(opt_state_t *opt_state, struct icode *ic)
{
bpf_u_int32 *p;
int i, n, max_stmts;
@@ -2042,22 +2154,24 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
n = count_blocks(ic, ic->root);
opt_state->blocks = (struct block **)calloc(n, sizeof(*opt_state->blocks));
if (opt_state->blocks == NULL)
- bpf_error(cstate, "malloc");
+ opt_error(opt_state, "malloc");
unMarkAll(ic);
opt_state->n_blocks = 0;
number_blks_r(opt_state, ic, ic->root);
opt_state->n_edges = 2 * opt_state->n_blocks;
opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges));
- if (opt_state->edges == NULL)
- bpf_error(cstate, "malloc");
+ if (opt_state->edges == NULL) {
+ opt_error(opt_state, "malloc");
+ }
/*
* The number of levels is bounded by the number of nodes.
*/
opt_state->levels = (struct block **)calloc(opt_state->n_blocks, sizeof(*opt_state->levels));
- if (opt_state->levels == NULL)
- bpf_error(cstate, "malloc");
+ if (opt_state->levels == NULL) {
+ opt_error(opt_state, "malloc");
+ }
opt_state->edgewords = opt_state->n_edges / (8 * sizeof(bpf_u_int32)) + 1;
opt_state->nodewords = opt_state->n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
@@ -2065,8 +2179,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
/* XXX */
opt_state->space = (bpf_u_int32 *)malloc(2 * opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->space)
+ opt_state->n_edges * opt_state->edgewords * sizeof(*opt_state->space));
- if (opt_state->space == NULL)
- bpf_error(cstate, "malloc");
+ if (opt_state->space == NULL) {
+ opt_error(opt_state, "malloc");
+ }
p = opt_state->space;
opt_state->all_dom_sets = p;
for (i = 0; i < n; ++i) {
@@ -2103,9 +2218,13 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
*/
opt_state->maxval = 3 * max_stmts;
opt_state->vmap = (struct vmapinfo *)calloc(opt_state->maxval, sizeof(*opt_state->vmap));
+ if (opt_state->vmap == NULL) {
+ opt_error(opt_state, "malloc");
+ }
opt_state->vnode_base = (struct valnode *)calloc(opt_state->maxval, sizeof(*opt_state->vnode_base));
- if (opt_state->vmap == NULL || opt_state->vnode_base == NULL)
- bpf_error(cstate, "malloc");
+ if (opt_state->vnode_base == NULL) {
+ opt_error(opt_state, "malloc");
+ }
}
/*
@@ -2117,6 +2236,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
int bids[NBIDS];
#endif
+static void PCAP_NORETURN conv_error(conv_state_t *, const char *, ...)
+ PCAP_PRINTFLIKE(2, 3);
+
/*
* Returns true if successful. Returns false if a branch has
* an offset that is too large. If so, we have marked that
@@ -2124,8 +2246,7 @@ int bids[NBIDS];
* properly.
*/
static int
-convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
- struct icode *ic, struct block *p)
+convert_code_r(conv_state_t *conv_state, struct icode *ic, struct block *p)
{
struct bpf_insn *dst;
struct slist *src;
@@ -2138,9 +2259,9 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
return (1);
Mark(ic, p);
- if (convert_code_r(cstate, conv_state, ic, JF(p)) == 0)
+ if (convert_code_r(conv_state, ic, JF(p)) == 0)
return (0);
- if (convert_code_r(cstate, conv_state, ic, JT(p)) == 0)
+ if (convert_code_r(conv_state, ic, JT(p)) == 0)
return (0);
slen = slength(p->stmts);
@@ -2153,7 +2274,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
if (slen) {
offset = (struct slist **)calloc(slen, sizeof(struct slist *));
if (!offset) {
- bpf_error(cstate, "not enough core");
+ conv_error(conv_state, "not enough core");
/*NOTREACHED*/
}
}
@@ -2177,7 +2298,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
#if 0
if (src->s.jt || src->s.jf) {
- bpf_error(cstate, "illegal jmp destination");
+ free(offset);
+ conv_error(conv_state, "illegal jmp destination");
/*NOTREACHED*/
}
#endif
@@ -2197,7 +2319,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
#endif
if (!src->s.jt || !src->s.jf) {
- bpf_error(cstate, ljerr, "no jmp destination", off);
+ free(offset);
+ conv_error(conv_state, ljerr, "no jmp destination", off);
/*NOTREACHED*/
}
@@ -2205,12 +2328,14 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
for (i = 0; i < slen; i++) {
if (offset[i] == src->s.jt) {
if (jt) {
- bpf_error(cstate, ljerr, "multiple matches", off);
+ free(offset);
+ conv_error(conv_state, ljerr, "multiple matches", off);
/*NOTREACHED*/
}
if (i - off - 1 >= 256) {
- bpf_error(cstate, ljerr, "out-of-range jump", off);
+ free(offset);
+ conv_error(conv_state, ljerr, "out-of-range jump", off);
/*NOTREACHED*/
}
dst->jt = (u_char)(i - off - 1);
@@ -2218,11 +2343,13 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
}
if (offset[i] == src->s.jf) {
if (jf) {
- bpf_error(cstate, ljerr, "multiple matches", off);
+ free(offset);
+ conv_error(conv_state, ljerr, "multiple matches", off);
/*NOTREACHED*/
}
if (i - off - 1 >= 256) {
- bpf_error(cstate, ljerr, "out-of-range jump", off);
+ free(offset);
+ conv_error(conv_state, ljerr, "out-of-range jump", off);
/*NOTREACHED*/
}
dst->jf = (u_char)(i - off - 1);
@@ -2230,7 +2357,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
}
}
if (!jt || !jf) {
- bpf_error(cstate, ljerr, "no destination found", off);
+ free(offset);
+ conv_error(conv_state, ljerr, "no destination found", off);
/*NOTREACHED*/
}
}
@@ -2259,7 +2387,7 @@ filled:
}
/* branch if T to following jump */
if (extrajmps >= 256) {
- bpf_error(cstate, "too many extra jumps");
+ conv_error(conv_state, "too many extra jumps");
/*NOTREACHED*/
}
dst->jt = (u_char)extrajmps;
@@ -2280,7 +2408,7 @@ filled:
/* branch if F to following jump */
/* if two jumps are inserted, F goes to second one */
if (extrajmps >= 256) {
- bpf_error(cstate, "too many extra jumps");
+ conv_error(conv_state, "too many extra jumps");
/*NOTREACHED*/
}
dst->jf = (u_char)extrajmps;
@@ -2314,13 +2442,20 @@ filled:
* done with the filter program. See the pcap man page.
*/
struct bpf_insn *
-icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
- struct block *root, u_int *lenp)
+icode_to_fcode(struct icode *ic, struct block *root, u_int *lenp,
+ char *errbuf)
{
u_int n;
struct bpf_insn *fp;
conv_state_t conv_state;
+ conv_state.fstart = NULL;
+ conv_state.errbuf = errbuf;
+ if (setjmp(conv_state.top_ctx) != 0) {
+ free(conv_state.fstart);
+ return NULL;
+ }
+
/*
* Loop doing convert_code_r() until no branches remain
* with too-large offsets.
@@ -2330,14 +2465,18 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
n = *lenp = count_stmts(ic, root);
fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
- if (fp == NULL)
- bpf_error(cstate, "malloc");
+ if (fp == NULL) {
+ (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc");
+ free(fp);
+ return NULL;
+ }
memset((char *)fp, 0, sizeof(*fp) * n);
conv_state.fstart = fp;
conv_state.ftail = fp + n;
unMarkAll(ic);
- if (convert_code_r(cstate, &conv_state, ic, root))
+ if (convert_code_r(&conv_state, ic, root))
break;
free(fp);
}
@@ -2346,6 +2485,22 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
}
/*
+ * For iconv_to_fconv() errors.
+ */
+static void PCAP_NORETURN
+conv_error(conv_state_t *conv_state, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)pcap_vsnprintf(conv_state->errbuf,
+ PCAP_ERRBUF_SIZE, fmt, ap);
+ va_end(ap);
+ longjmp(conv_state->top_ctx, 1);
+ /* NOTREACHED */
+}
+
+/*
* Make a copy of a BPF program and put it in the "fcode" member of
* a "pcap_t".
*
@@ -2454,14 +2609,16 @@ dot_dump_edge(struct icode *ic, struct block *block, FILE *out)
* After install graphviz on http://www.graphviz.org/, save it as bpf.dot
* and run `dot -Tpng -O bpf.dot' to draw the graph.
*/
-static void
-dot_dump(compiler_state_t *cstate, struct icode *ic)
+static int
+dot_dump(struct icode *ic, char *errbuf)
{
struct bpf_program f;
FILE *out = stdout;
memset(bids, 0, sizeof bids);
- f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
+ f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
+ if (f.bf_insns == NULL)
+ return -1;
fprintf(out, "digraph BPF {\n");
unMarkAll(ic);
@@ -2471,30 +2628,39 @@ dot_dump(compiler_state_t *cstate, struct icode *ic)
fprintf(out, "}\n");
free((char *)f.bf_insns);
+ return 0;
}
-static void
-plain_dump(compiler_state_t *cstate, struct icode *ic)
+static int
+plain_dump(struct icode *ic, char *errbuf)
{
struct bpf_program f;
memset(bids, 0, sizeof bids);
- f.bf_insns = icode_to_fcode(cstate, ic, ic->root, &f.bf_len);
+ f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
+ if (f.bf_insns == NULL)
+ return -1;
bpf_dump(&f, 1);
putchar('\n');
free((char *)f.bf_insns);
+ return 0;
}
static void
-opt_dump(compiler_state_t *cstate, struct icode *ic)
+opt_dump(opt_state_t *opt_state, struct icode *ic)
{
+ int status;
+ char errbuf[PCAP_ERRBUF_SIZE];
+
/*
* If the CFG, in DOT format, is requested, output it rather than
* the code that would be generated from that graph.
*/
if (pcap_print_dot_graph)
- dot_dump(cstate, ic);
+ status = dot_dump(ic, errbuf);
else
- plain_dump(cstate, ic);
+ status = plain_dump(ic, errbuf);
+ if (status == -1)
+ opt_error(opt_state, "opt_dump: icode_to_fcode failed: %s", errbuf);
}
#endif
diff --git a/freebsd/contrib/libpcap/pcap-bpf.c b/freebsd/contrib/libpcap/pcap-bpf.c
index dc2942af..2ae88397 100644
--- a/freebsd/contrib/libpcap/pcap-bpf.c
+++ b/freebsd/contrib/libpcap/pcap-bpf.c
@@ -208,7 +208,7 @@ static int monitor_mode(pcap_t *, int);
# endif
# if defined(__APPLE__)
-static void remove_en(pcap_t *);
+static void remove_non_802_11(pcap_t *);
static void remove_802_11(pcap_t *);
# endif
@@ -739,10 +739,10 @@ get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
}
#endif
+#if defined(__APPLE__)
static int
pcap_can_set_rfmon_bpf(pcap_t *p)
{
-#if defined(__APPLE__)
struct utsname osinfo;
struct ifreq ifr;
int fd;
@@ -801,8 +801,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
errno, "socket");
return (PCAP_ERROR);
}
- strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
- strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
+ pcap_strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
+ pcap_strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
/*
* No such device?
@@ -882,7 +882,11 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
close(fd);
#endif /* BIOCGDLTLIST */
return (0);
+}
#elif defined(HAVE_BSD_IEEE80211)
+static int
+pcap_can_set_rfmon_bpf(pcap_t *p)
+{
int ret;
ret = monitor_mode(p, 0);
@@ -891,10 +895,14 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
if (ret == 0)
return (1); /* success */
return (ret);
+}
#else
+static int
+pcap_can_set_rfmon_bpf(pcap_t *p _U_)
+{
return (0);
-#endif
}
+#endif
static int
pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
@@ -1014,18 +1022,21 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
case EWOULDBLOCK:
return (0);
- case ENXIO:
+ case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */
+ case EIO: /* OpenBSD */
+ /* NetBSD appears not to return an error in this case */
/*
* The device on which we're capturing
* went away.
*
* XXX - we should really return
- * PCAP_ERROR_IFACE_NOT_UP, but
- * pcap_dispatch() etc. aren't
- * defined to retur that.
+ * an appropriate error for that,
+ * but pcap_dispatch() etc. aren't
+ * documented as having error returns
+ * other than PCAP_ERROR or PCAP_ERROR_BREAK.
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "The interface went down");
+ "The interface disappeared");
return (PCAP_ERROR);
#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4)
@@ -1360,8 +1371,8 @@ bpf_load(char *errbuf)
/* Check if the driver is loaded */
memset(&cfg_ld, 0x0, sizeof(cfg_ld));
+ pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME);
cfg_ld.path = buf;
- pcap_snprintf(cfg_ld.path, sizeof(cfg_ld.path), "%s/%s", DRIVER_PATH, BPF_NAME);
if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
(cfg_ld.kmid == 0)) {
/* Driver isn't loaded, load it now */
@@ -1471,7 +1482,7 @@ pcap_cleanup_bpf(pcap_t *p)
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (s >= 0) {
- strlcpy(ifr.ifr_name, pb->device,
+ pcap_strlcpy(ifr.ifr_name, pb->device,
sizeof(ifr.ifr_name));
ioctl(s, SIOCIFDESTROY, &ifr);
close(s);
@@ -1534,9 +1545,9 @@ check_setif_failure(pcap_t *p, int error)
*/
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd != -1) {
- strlcpy(ifr.ifr_name, "en",
+ pcap_strlcpy(ifr.ifr_name, "en",
sizeof(ifr.ifr_name));
- strlcat(ifr.ifr_name, p->opt.device + 3,
+ pcap_strlcat(ifr.ifr_name, p->opt.device + 3,
sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
/*
@@ -1723,7 +1734,7 @@ pcap_activate_bpf(pcap_t *p)
goto bad;
}
znamelen = zonesep - p->opt.device;
- (void) strlcpy(path_zname, p->opt.device, znamelen + 1);
+ (void) pcap_strlcpy(path_zname, p->opt.device, znamelen + 1);
ifr.lifr_zoneid = getzoneidbyname(path_zname);
if (ifr.lifr_zoneid == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -1788,7 +1799,7 @@ pcap_activate_bpf(pcap_t *p)
*/
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd != -1) {
- strlcpy(ifrname,
+ pcap_strlcpy(ifrname,
p->opt.device, ifnamsiz);
if (ioctl(sockfd, SIOCGIFFLAGS,
(char *)&ifr) < 0) {
@@ -1890,7 +1901,7 @@ pcap_activate_bpf(pcap_t *p)
/*
* Create the interface.
*/
- strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
+ pcap_strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) {
if (errno == EINVAL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
@@ -2189,7 +2200,7 @@ pcap_activate_bpf(pcap_t *p)
* of link-layer types, as selecting
* it will keep monitor mode off.
*/
- remove_en(p);
+ remove_non_802_11(p);
/*
* If the new mode we want isn't
@@ -2750,12 +2761,21 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
strncpy(req.ifm_name, name, sizeof(req.ifm_name));
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY ||
- errno == ENODEV) {
+ errno == ENODEV || errno == EPERM) {
/*
* Not supported, so we can't provide any
* additional information. Assume that
* this means that "connected" vs.
* "disconnected" doesn't apply.
+ *
+ * The ioctl routine for Apple's pktap devices,
+ * annoyingly, checks for "are you root?" before
+ * checking whether the ioctl is valid, so it
+ * returns EPERM, rather than ENOTSUP, for the
+ * invalid SIOCGIFMEDIA, unless you're root.
+ * So, just as we do for some ethtool ioctls
+ * on Linux, which makes the same mistake, we
+ * also treat EPERM as meaning "not supported".
*/
*flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
close(sock);
@@ -2892,7 +2912,7 @@ monitor_mode(pcap_t *p, int set)
default:
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
- errno, "SIOCGIFMEDIA 1");
+ errno, "SIOCGIFMEDIA");
close(sock);
return (PCAP_ERROR);
}
@@ -3034,8 +3054,12 @@ find_802_11(struct bpf_dltlist *bdlp)
new_dlt = bdlp->bfl_list[i];
break;
+#ifdef DLT_PRISM_HEADER
case DLT_PRISM_HEADER:
+#endif
+#ifdef DLT_AIRONET_HEADER
case DLT_AIRONET_HEADER:
+#endif
case DLT_IEEE802_11_RADIO_AVS:
/*
* 802.11 with radio, but not radiotap.
@@ -3070,24 +3094,25 @@ find_802_11(struct bpf_dltlist *bdlp)
#if defined(__APPLE__) && defined(BIOCGDLTLIST)
/*
- * Remove DLT_EN10MB from the list of DLT_ values, as we're in monitor mode,
- * and DLT_EN10MB isn't supported in monitor mode.
+ * Remove non-802.11 header types from the list of DLT_ values, as we're in
+ * monitor mode, and those header types aren't supported in monitor mode.
*/
static void
-remove_en(pcap_t *p)
+remove_non_802_11(pcap_t *p)
{
int i, j;
/*
- * Scan the list of DLT_ values and discard DLT_EN10MB.
+ * Scan the list of DLT_ values and discard non-802.11 ones.
*/
j = 0;
for (i = 0; i < p->dlt_count; i++) {
switch (p->dlt_list[i]) {
case DLT_EN10MB:
+ case DLT_RAW:
/*
- * Don't offer this one.
+ * Not 802.11. Don't offer this one.
*/
continue;
@@ -3129,10 +3154,17 @@ remove_802_11(pcap_t *p)
switch (p->dlt_list[i]) {
case DLT_IEEE802_11:
+#ifdef DLT_PRISM_HEADER
case DLT_PRISM_HEADER:
+#endif
+#ifdef DLT_AIRONET_HEADER
case DLT_AIRONET_HEADER:
+#endif
case DLT_IEEE802_11_RADIO:
case DLT_IEEE802_11_RADIO_AVS:
+#ifdef DLT_PPI
+ case DLT_PPI:
+#endif
/*
* 802.11. Don't offer this one.
*/
@@ -3224,10 +3256,10 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
* Set direction flag: Which packets do we accept on a forwarding
* single device? IN, OUT or both?
*/
+#if defined(BIOCSDIRECTION)
static int
pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
{
-#if defined(BIOCSDIRECTION)
u_int direction;
direction = (d == PCAP_D_IN) ? BPF_D_IN :
@@ -3240,7 +3272,11 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
return (-1);
}
return (0);
+}
#elif defined(BIOCSSEESENT)
+static int
+pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
+{
u_int seesent;
/*
@@ -3260,25 +3296,35 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
return (-1);
}
return (0);
+}
#else
+static int
+pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d _U_)
+{
(void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"This system doesn't support BIOCSSEESENT, so the direction can't be set");
return (-1);
-#endif
}
+#endif
+#ifdef BIOCSDLT
static int
pcap_set_datalink_bpf(pcap_t *p, int dlt)
{
-#ifdef BIOCSDLT
if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
errno, "Cannot set DLT %d", dlt);
return (-1);
}
-#endif
return (0);
}
+#else
+static int
+pcap_set_datalink_bpf(pcap_t *p _U_, int dlt _U_)
+{
+ return (0);
+}
+#endif
/*
* Platform-specific information.
diff --git a/freebsd/contrib/libpcap/pcap-common.c b/freebsd/contrib/libpcap/pcap-common.c
index 8219a031..c2f27003 100644
--- a/freebsd/contrib/libpcap/pcap-common.c
+++ b/freebsd/contrib/libpcap/pcap-common.c
@@ -516,11 +516,20 @@
#define LINKTYPE_RAIF1 198
/*
- * IPMB packet for IPMI, beginning with the I2C slave address, followed
- * by the netFn and LUN, etc.. Requested by Chanthy Toeung
- * <chanthy.toeung@ca.kontron.com>.
+ * IPMB packet for IPMI, beginning with a 2-byte header, followed by
+ * the I2C slave address, followed by the netFn and LUN, etc..
+ * Requested by Chanthy Toeung <chanthy.toeung@ca.kontron.com>.
+ *
+ * XXX - its DLT_ value used to be called DLT_IPMB, back when we got the
+ * impression from the email thread requesting it that the packet
+ * had no extra 2-byte header. We've renamed it; if anybody used
+ * DLT_IPMB and assumed no 2-byte header, this will cause the compile
+ * to fail, at which point we'll have to figure out what to do about
+ * the two header types using the same DLT_/LINKTYPE_ value. If that
+ * doesn't happen, we'll assume nobody used it and that the redefinition
+ * is safe.
*/
-#define LINKTYPE_IPMB 199
+#define LINKTYPE_IPMB_KONTRON 199
/*
* Juniper-private data link type, as per request from
@@ -551,15 +560,35 @@
*/
#define LINKTYPE_LAPD 203
+
/*
- * Variants of various link-layer headers, with a one-byte direction
- * pseudo-header prepended - zero means "received by this host",
- * non-zero (any non-zero value) means "sent by this host" - as per
- * Will Barker <w.barker@zen.co.uk>.
+ * PPP, with a one-byte direction pseudo-header prepended - zero means
+ * "received by this host", non-zero (any non-zero value) means "sent by
+ * this host" - as per Will Barker <w.barker@zen.co.uk>.
+ */
+#define LINKTYPE_PPP_WITH_DIR 204 /* Don't confuse with LINKTYPE_PPP_PPPD */
+
+/*
+ * Cisco HDLC, with a one-byte direction pseudo-header prepended - zero
+ * means "received by this host", non-zero (any non-zero value) means
+ * "sent by this host" - as per Will Barker <w.barker@zen.co.uk>.
*/
-#define LINKTYPE_PPP_WITH_DIR 204 /* PPP */
#define LINKTYPE_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
+
+/*
+ * Frame Relay, with a one-byte direction pseudo-header prepended - zero
+ * means "received by this host" (DCE -> DTE), non-zero (any non-zero
+ * value) means "sent by this host" (DTE -> DCE) - as per Will Barker
+ * <w.barker@zen.co.uk>.
+ */
#define LINKTYPE_FRELAY_WITH_DIR 206 /* Frame Relay */
+
+/*
+ * LAPB, with a one-byte direction pseudo-header prepended - zero means
+ * "received by this host" (DCE -> DTE), non-zero (any non-zero value)
+ * means "sent by this host" (DTE -> DCE)- as per Will Barker
+ * <w.barker@zen.co.uk>.
+ */
#define LINKTYPE_LAPB_WITH_DIR 207 /* LAPB */
/*
@@ -1083,7 +1112,21 @@
*/
#define LINKTYPE_DISPLAYPORT_AUX 275
-#define LINKTYPE_MATCHING_MAX 275 /* highest value in the "matching" range */
+/*
+ * Linux cooked sockets v2.
+ */
+#define LINKTYPE_LINUX_SLL2 276
+
+#define LINKTYPE_MATCHING_MAX 276 /* highest value in the "matching" range */
+
+/*
+ * The DLT_ and LINKTYPE_ values in the "matching" range should be the
+ * same, so DLT_MATCHING_MAX and LINKTYPE_MATCHING_MAX should be the
+ * same.
+ */
+#if LINKTYPE_MATCHING_MAX != DLT_MATCHING_MAX
+#error The LINKTYPE_ matching range does not match the DLT_ matching range
+#endif
static struct linktype_map {
int dlt;
@@ -1233,18 +1276,30 @@ linktype_to_dlt(int linktype)
/*
* Return the maximum snapshot length for a given DLT_ value.
*
- * For most link-layer types, we use MAXIMUM_SNAPLEN, but for DLT_DBUS,
- * the maximum is 134217728, as per
+ * For most link-layer types, we use MAXIMUM_SNAPLEN.
+ *
+ * For DLT_DBUS, the maximum is 128MiB, as per
*
* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
+ *
+ * For DLT_USBPCAP, the maximum is 1MiB, as per
+ *
+ * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=15985
*/
u_int
max_snaplen_for_dlt(int dlt)
{
- if (dlt == DLT_DBUS)
- return 134217728;
- else
+ switch (dlt) {
+
+ case DLT_DBUS:
+ return 128*1024*1024;
+
+ case DLT_USBPCAP:
+ return 1024*1024;
+
+ default:
return MAXIMUM_SNAPLEN;
+ }
}
/*
diff --git a/freebsd/contrib/libpcap/pcap-common.h b/freebsd/contrib/libpcap/pcap-common.h
index 88c057cb..8795a829 100644
--- a/freebsd/contrib/libpcap/pcap-common.h
+++ b/freebsd/contrib/libpcap/pcap-common.h
@@ -35,9 +35,13 @@
* machine (if the file was written in little-end order).
*/
#define SWAPLONG(y) \
-((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+ (((((u_int)(y))&0xff)<<24) | \
+ ((((u_int)(y))&0xff00)<<8) | \
+ ((((u_int)(y))&0xff0000)>>8) | \
+ ((((u_int)(y))>>24)&0xff))
#define SWAPSHORT(y) \
- ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
+ ((u_short)(((((u_int)(y))&0xff)<<8) | \
+ ((((u_int)(y))&0xff00)>>8)))
extern int dlt_to_linktype(int dlt);
diff --git a/freebsd/contrib/libpcap/pcap-int.h b/freebsd/contrib/libpcap/pcap-int.h
index 5888df72..5295f8fb 100644
--- a/freebsd/contrib/libpcap/pcap-int.h
+++ b/freebsd/contrib/libpcap/pcap-int.h
@@ -86,7 +86,12 @@ extern "C" {
* 2) small enough not to cause attempts to allocate huge amounts of
* memory; some applications might use the snapshot length in a
* savefile header to control the size of the buffer they allocate,
- * so a size of, say, 2^31-1 might not work well.
+ * so a size of, say, 2^31-1 might not work well. (libpcap uses it
+ * as a hint, but doesn't start out allocating a buffer bigger than
+ * 2 KiB, and grows the buffer as necessary, but not beyond the
+ * per-linktype maximum snapshot length. Other code might naively
+ * use it; we want to avoid writing a too-large snapshot length,
+ * in order not to cause that code problems.)
*
* We don't enforce this in pcap_set_snaplen(), but we use it internally.
*/
@@ -472,14 +477,39 @@ int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
* "pcap_open_offline_common()" allocates and fills in a pcap_t, for use
* by pcap_open_offline routines.
*
+ * "pcap_adjust_snapshot()" adjusts the snapshot to be non-zero and
+ * fit within an int.
+ *
* "sf_cleanup()" closes the file handle associated with a pcap_t, if
* appropriate, and frees all data common to all modules for handling
* savefile types.
*/
pcap_t *pcap_open_offline_common(char *ebuf, size_t size);
+bpf_u_int32 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen);
void sf_cleanup(pcap_t *p);
/*
+ * Internal interfaces for doing user-mode filtering of packets and
+ * validating filter programs.
+ */
+/*
+ * Auxiliary data, for use when interpreting a filter intended for the
+ * Linux kernel when the kernel rejects the filter (requiring us to
+ * run it in userland). It contains VLAN tag information.
+ */
+struct bpf_aux_data {
+ u_short vlan_tag_present;
+ u_short vlan_tag;
+};
+
+/*
+ * Filtering routine that takes the auxiliary data as an additional
+ * argument.
+ */
+u_int bpf_filter_with_aux_data(const struct bpf_insn *,
+ const u_char *, u_int, u_int, const struct bpf_aux_data *);
+
+/*
* Internal interfaces for both "pcap_create()" and routines that
* open savefiles.
*
@@ -488,10 +518,6 @@ void sf_cleanup(pcap_t *p);
*/
void pcap_oneshot(u_char *, const struct pcap_pkthdr *, const u_char *);
-#ifdef _WIN32
-void pcap_win32_err_to_str(DWORD, char *);
-#endif
-
int install_bpf_program(pcap_t *, struct bpf_program *);
int pcap_strcasecmp(const char *, const char *);
diff --git a/freebsd/contrib/libpcap/pcap.c b/freebsd/contrib/libpcap/pcap.c
index 4cf53b22..8ddeaec6 100644
--- a/freebsd/contrib/libpcap/pcap.c
+++ b/freebsd/contrib/libpcap/pcap.c
@@ -141,7 +141,7 @@ BOOL WINAPI DllMain(
/*
* Start WinSock.
- * Exported in case some applications using WinPcap called it,
+ * Exported in case some applications using WinPcap/Npcap called it,
* even though it wasn't exported.
*/
int
@@ -188,76 +188,165 @@ pcap_wsockinit(void)
PCAP_API char pcap_version[];
PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION;
-static int
-pcap_not_initialized(pcap_t *pcap)
+static void
+pcap_set_not_initialized_message(pcap_t *pcap)
{
if (pcap->activated) {
/* A module probably forgot to set the function pointer */
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
"This operation isn't properly handled by that device");
- return (PCAP_ERROR);
+ return;
}
/* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
"This handle hasn't been activated yet");
+}
+
+static int
+pcap_read_not_initialized(pcap_t *pcap, int cnt _U_, pcap_handler callback _U_,
+ u_char *user _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_inject_not_initialized(pcap_t *pcap, const void * buf _U_, size_t size _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_setfilter_not_initialized(pcap_t *pcap, struct bpf_program *fp _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_setdirection_not_initialized(pcap_t *pcap, pcap_direction_t d _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_set_datalink_not_initialized(pcap_t *pcap, int dlt _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_getnonblock_not_initialized(pcap_t *pcap)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_stats_not_initialized(pcap_t *pcap, struct pcap_stat *ps _U_)
+{
+ pcap_set_not_initialized_message(pcap);
/* this means 'not initialized' */
return (PCAP_ERROR_NOT_ACTIVATED);
}
#ifdef _WIN32
-static void *
-pcap_not_initialized_ptr(pcap_t *pcap)
+struct pcap_stat *
+pcap_stats_ex_not_initialized(pcap_t *pcap, int *pcap_stat_size _U_)
{
- if (pcap->activated) {
- /* A module probably forgot to set the function pointer */
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This operation isn't properly handled by that device");
- return (NULL);
- }
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This handle hasn't been activated yet");
+ pcap_set_not_initialized_message(pcap);
return (NULL);
}
+static int
+pcap_setbuff_not_initialized(pcap_t *pcap, int dim _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_setmode_not_initialized(pcap_t *pcap, int mode _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_setmintocopy_not_initialized(pcap_t *pcap, int size _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
static HANDLE
pcap_getevent_not_initialized(pcap_t *pcap)
{
- if (pcap->activated) {
- /* A module probably forgot to set the function pointer */
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This operation isn't properly handled by that device");
- return (INVALID_HANDLE_VALUE);
- }
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This handle hasn't been activated yet");
+ pcap_set_not_initialized_message(pcap);
return (INVALID_HANDLE_VALUE);
}
+static int
+pcap_oid_get_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
+ void *data _U_, size_t *lenp _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_oid_set_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
+ const void *data _U_, size_t *lenp _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
static u_int
pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync)
{
- if (pcap->activated) {
- /* A module probably forgot to set the function pointer */
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This operation isn't properly handled by that device");
- return (0);
- }
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This handle hasn't been activated yet");
+ pcap_set_not_initialized_message(pcap);
return (0);
}
+static int
+pcap_setuserbuffer_not_initialized(pcap_t *pcap, int size _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_live_dump_not_initialized(pcap_t *pcap, char *filename _U_, int maxsize _U_,
+ int maxpacks _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_live_dump_ended_not_initialized(pcap_t *pcap, int sync _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
static PAirpcapHandle
pcap_get_airpcap_handle_not_initialized(pcap_t *pcap)
{
- if (pcap->activated) {
- /* A module probably forgot to set the function pointer */
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This operation isn't properly handled by that device");
- return (NULL);
- }
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This handle hasn't been activated yet");
+ pcap_set_not_initialized_message(pcap);
return (NULL);
}
#endif
@@ -298,8 +387,17 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
if (p->tstamp_type_count == 0) {
/*
* We don't support multiple time stamp types.
+ * That means the only type we support is PCAP_TSTAMP_HOST;
+ * set up a list containing only that type.
*/
- *tstamp_typesp = NULL;
+ *tstamp_typesp = (int*)malloc(sizeof(**tstamp_typesp));
+ if (*tstamp_typesp == NULL) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "malloc");
+ return (PCAP_ERROR);
+ }
+ **tstamp_typesp = PCAP_TSTAMP_HOST;
+ return (1);
} else {
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
p->tstamp_type_count);
@@ -310,8 +408,8 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
}
(void)memcpy(*tstamp_typesp, p->tstamp_type_list,
sizeof(**tstamp_typesp) * p->tstamp_type_count);
+ return (p->tstamp_type_count);
}
- return (p->tstamp_type_count);
}
/*
@@ -661,7 +759,7 @@ get_if_description(const char *name)
* Get the description for the interface.
*/
memset(&ifrdesc, 0, sizeof ifrdesc);
- strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
+ pcap_strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) {
#ifdef __FreeBSD__
@@ -712,7 +810,7 @@ get_if_description(const char *name)
}
#endif /* __FreeBSD__ */
close(s);
- if (description != NULL && strlen(description) == 0) {
+ if (description != NULL && description[0] == '\0') {
/*
* Description is empty, so discard it.
*/
@@ -743,20 +841,13 @@ get_if_description(const char *name)
* OK, it's a valid number that's not
* bigger than INT_MAX. Construct
* a description from it.
+ * (If that fails, we don't worry about
+ * it, we just return NULL.)
*/
- static const char descr_prefix[] = "USB bus number ";
- size_t descr_size;
-
- /*
- * Allow enough room for a 32-bit bus number.
- * sizeof (descr_prefix) includes the
- * terminating NUL.
- */
- descr_size = sizeof (descr_prefix) + 10;
- description = malloc(descr_size);
- if (description != NULL) {
- pcap_snprintf(description, descr_size,
- "%s%ld", descr_prefix, busnum);
+ if (pcap_asprintf(&description,
+ "USB bus number %ld", busnum) == -1) {
+ /* Failed. */
+ description = NULL;
}
}
}
@@ -1294,14 +1385,14 @@ pcap_lookupdev(char *errbuf)
* on the list, there aren't any non-loopback devices,
* so why not just supply it as the default device?
*/
- (void)strlcpy(errbuf, "no suitable device found",
+ (void)pcap_strlcpy(errbuf, "no suitable device found",
PCAP_ERRBUF_SIZE);
ret = NULL;
} else {
/*
* Return the name of the first device on the list.
*/
- (void)strlcpy(device, alldevs->name, sizeof(device));
+ (void)pcap_strlcpy(device, alldevs->name, sizeof(device));
ret = device;
}
@@ -1368,7 +1459,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
/* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET;
#endif
- (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
if (errno == EADDRNOTAVAIL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
@@ -1387,7 +1478,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
/* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET;
#endif
- (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFNETMASK: %s", device);
@@ -1577,13 +1668,14 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
* the pathname.
*/
if (pcap_strcasecmp(scheme, "file") == 0) {
- *schemep = scheme;
*pathp = strdup(colonp + 3);
if (*pathp == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
+ free(scheme);
return (-1);
}
+ *schemep = scheme;
return (0);
}
@@ -1686,7 +1778,12 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
* Treat verything up to the closing square
* bracket as the IP-Literal; we don't worry
* about whether it's a valid IPv6address or
- * IPvFuture.
+ * IPvFuture (or an IPv4address, for that
+ * matter, just in case we get handed a
+ * URL with an IPv4 IP-Literal, of the sort
+ * that pcap_createsrcstr() used to generate,
+ * and that pcap_parsesrcstr(), in the original
+ * WinPcap code, accepted).
*/
bracketp = strchr(parsep, ']');
if (bracketp == NULL) {
@@ -1807,9 +1904,9 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
switch (type) {
case PCAP_SRC_FILE:
- strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
+ pcap_strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
if (name != NULL && *name != '\0') {
- strlcat(source, name, PCAP_BUF_SIZE);
+ pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0);
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
@@ -1818,7 +1915,7 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
}
case PCAP_SRC_IFREMOTE:
- strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
+ pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
if (host != NULL && *host != '\0') {
if (strchr(host, ':') != NULL) {
/*
@@ -1826,18 +1923,18 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
* probably an IPv6 address, and needs to
* be included in square brackets.
*/
- strlcat(source, "[", PCAP_BUF_SIZE);
- strlcat(source, host, PCAP_BUF_SIZE);
- strlcat(source, "]", PCAP_BUF_SIZE);
+ pcap_strlcat(source, "[", PCAP_BUF_SIZE);
+ pcap_strlcat(source, host, PCAP_BUF_SIZE);
+ pcap_strlcat(source, "]", PCAP_BUF_SIZE);
} else
- strlcat(source, host, PCAP_BUF_SIZE);
+ pcap_strlcat(source, host, PCAP_BUF_SIZE);
if (port != NULL && *port != '\0') {
- strlcat(source, ":", PCAP_BUF_SIZE);
- strlcat(source, port, PCAP_BUF_SIZE);
+ pcap_strlcat(source, ":", PCAP_BUF_SIZE);
+ pcap_strlcat(source, port, PCAP_BUF_SIZE);
}
- strlcat(source, "/", PCAP_BUF_SIZE);
+ pcap_strlcat(source, "/", PCAP_BUF_SIZE);
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"The host name cannot be NULL.");
@@ -1845,15 +1942,15 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
}
if (name != NULL && *name != '\0')
- strlcat(source, name, PCAP_BUF_SIZE);
+ pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0);
case PCAP_SRC_IFLOCAL:
- strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
+ pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
if (name != NULL && *name != '\0')
- strlcat(source, name, PCAP_BUF_SIZE);
+ pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0);
@@ -1892,7 +1989,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* Local device.
*/
if (name && tmppath)
- strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type)
*type = PCAP_SRC_IFLOCAL;
free(tmppath);
@@ -1914,12 +2011,12 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s",
tmpuserinfo, tmphost);
else
- strlcpy(host, tmphost, PCAP_BUF_SIZE);
+ pcap_strlcpy(host, tmphost, PCAP_BUF_SIZE);
}
if (port && tmpport)
- strlcpy(port, tmpport, PCAP_BUF_SIZE);
+ pcap_strlcpy(port, tmpport, PCAP_BUF_SIZE);
if (name && tmppath)
- strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type)
*type = PCAP_SRC_IFREMOTE;
free(tmppath);
@@ -1935,7 +2032,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* file://
*/
if (name && tmppath)
- strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type)
*type = PCAP_SRC_FILE;
free(tmppath);
@@ -1951,7 +2048,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* as a local device.
*/
if (name)
- strlcpy(name, source, PCAP_BUF_SIZE);
+ pcap_strlcpy(name, source, PCAP_BUF_SIZE);
if (type)
*type = PCAP_SRC_IFLOCAL;
free(tmppath);
@@ -1983,11 +2080,28 @@ pcap_create(const char *device, char *errbuf)
else {
#ifdef _WIN32
/*
- * If the string appears to be little-endian UCS-2/UTF-16,
- * convert it to ASCII.
+ * On Windows, for backwards compatibility reasons,
+ * pcap_lookupdev() returns a pointer to a sequence of
+ * pairs of UTF-16LE device names and local code page
+ * description strings.
+ *
+ * This means that if a program uses pcap_lookupdev()
+ * to get a default device, and hands that to an API
+ * that opens devices, we'll get handed a UTF-16LE
+ * string, not a string in the local code page.
*
- * XXX - to UTF-8 instead? Or report an error if any
- * character isn't ASCII?
+ * To work around that, we check whether the string
+ * looks as if it might be a UTF-16LE strinh and, if
+ * so, convert it back to the local code page's
+ * extended ASCII.
+ *
+ * XXX - you *cannot* reliably detect whether a
+ * string is UTF-16LE or not; "a" could either
+ * be a one-character ASCII string or the first
+ * character of a UTF-16LE string. This particular
+ * version of this heuristic dates back to WinPcap
+ * 4.1.1; PacketOpenAdapter() does uses the same
+ * heuristic, with the exact same vulnerability.
*/
if (device[0] != '\0' && device[1] == '\0') {
size_t length;
@@ -2079,25 +2193,25 @@ initialize_ops(pcap_t *p)
* an activated pcap_t to point to a routine that returns
* a "this isn't activated" error.
*/
- p->read_op = (read_op_t)pcap_not_initialized;
- p->inject_op = (inject_op_t)pcap_not_initialized;
- p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
- p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
- p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
- p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
- p->stats_op = (stats_op_t)pcap_not_initialized;
+ p->read_op = pcap_read_not_initialized;
+ p->inject_op = pcap_inject_not_initialized;
+ p->setfilter_op = pcap_setfilter_not_initialized;
+ p->setdirection_op = pcap_setdirection_not_initialized;
+ p->set_datalink_op = pcap_set_datalink_not_initialized;
+ p->getnonblock_op = pcap_getnonblock_not_initialized;
+ p->stats_op = pcap_stats_not_initialized;
#ifdef _WIN32
- p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
- p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
- p->setmode_op = (setmode_op_t)pcap_not_initialized;
- p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
+ p->stats_ex_op = pcap_stats_ex_not_initialized;
+ p->setbuff_op = pcap_setbuff_not_initialized;
+ p->setmode_op = pcap_setmode_not_initialized;
+ p->setmintocopy_op = pcap_setmintocopy_not_initialized;
p->getevent_op = pcap_getevent_not_initialized;
- p->oid_get_request_op = (oid_get_request_op_t)pcap_not_initialized;
- p->oid_set_request_op = (oid_set_request_op_t)pcap_not_initialized;
+ p->oid_get_request_op = pcap_oid_get_request_not_initialized;
+ p->oid_set_request_op = pcap_oid_set_request_not_initialized;
p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized;
- p->setuserbuffer_op = (setuserbuffer_op_t)pcap_not_initialized;
- p->live_dump_op = (live_dump_op_t)pcap_not_initialized;
- p->live_dump_ended_op = (live_dump_ended_op_t)pcap_not_initialized;
+ p->setuserbuffer_op = pcap_setuserbuffer_not_initialized;
+ p->live_dump_op = pcap_live_dump_not_initialized;
+ p->live_dump_ended_op = pcap_live_dump_ended_not_initialized;
p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized;
#endif
@@ -2126,14 +2240,23 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
* plus a structure following it of size "size". The
* structure following it is a private data structure
* for the routines that handle this pcap_t.
+ *
+ * The structure following it must be aligned on
+ * the appropriate alignment boundary for this platform.
+ * We align on an 8-byte boundary as that's probably what
+ * at least some platforms do, even with 32-bit integers,
+ * and because we can't be sure that some values won't
+ * require 8-byte alignment even on platforms with 32-bit
+ * integers.
*/
- chunk = malloc(sizeof (pcap_t) + size);
+#define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7U) & ~0x7U)
+ chunk = malloc(PCAP_T_ALIGNED_SIZE + size);
if (chunk == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
return (NULL);
}
- memset(chunk, 0, sizeof (pcap_t) + size);
+ memset(chunk, 0, PCAP_T_ALIGNED_SIZE + size);
/*
* Get a pointer to the pcap_t at the beginning.
@@ -2158,7 +2281,7 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
* Set the pointer to the private data; that's the structure
* of size "size" following the pcap_t.
*/
- p->priv = (void *)(chunk + sizeof (pcap_t));
+ p->priv = (void *)(chunk + PCAP_T_ALIGNED_SIZE);
}
return (p);
@@ -2454,6 +2577,16 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
int srctype;
/*
+ * A null device name is equivalent to the "any" device -
+ * which might not be supported on this platform, but
+ * this means that you'll get a "not supported" error
+ * rather than, say, a crash when we try to dereference
+ * the null pointer.
+ */
+ if (device == NULL)
+ device = "any";
+
+ /*
* Retrofit - we have to make older applications compatible with
* remote capture.
* So we're calling pcap_open_remote() from here; this is a very
@@ -2524,13 +2657,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
return (p);
fail:
if (status == PCAP_ERROR)
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
- p->errbuf);
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %.*s", device,
+ PCAP_ERRBUF_SIZE - 3, p->errbuf);
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
status == PCAP_ERROR_PERM_DENIED ||
status == PCAP_ERROR_PROMISC_PERM_DENIED)
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device,
- pcap_statustostr(status), p->errbuf);
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)", device,
+ pcap_statustostr(status), PCAP_ERRBUF_SIZE - 6, p->errbuf);
else
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
pcap_statustostr(status));
@@ -2843,7 +2976,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(FRELAY, "Frame Relay"),
DLT_CHOICE(LOOP, "OpenBSD loopback"),
DLT_CHOICE(ENC, "OpenBSD encapsulated IP"),
- DLT_CHOICE(LINUX_SLL, "Linux cooked"),
+ DLT_CHOICE(LINUX_SLL, "Linux cooked v1"),
DLT_CHOICE(LTALK, "Localtalk"),
DLT_CHOICE(PFLOG, "OpenBSD pflog file"),
DLT_CHOICE(PFSYNC, "Packet filter state syncing"),
@@ -2877,7 +3010,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(GPF_T, "GPF-T"),
DLT_CHOICE(GPF_F, "GPF-F"),
DLT_CHOICE(JUNIPER_PIC_PEER, "Juniper PIC Peer"),
- DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
+ DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
DLT_CHOICE(ERF_POS, "Packet-over-SONET with Endace ERF header"),
DLT_CHOICE(LINUX_LAPD, "Linux vISDN LAPD"),
DLT_CHOICE(JUNIPER_ETHER, "Juniper Ethernet"),
@@ -2901,10 +3034,11 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(SITA, "SITA pseudo-header"),
DLT_CHOICE(ERF, "Endace ERF header"),
DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-header"),
- DLT_CHOICE(IPMB, "IPMB"),
+ DLT_CHOICE(IPMB_KONTRON, "IPMB with Kontron pseudo-header"),
DLT_CHOICE(JUNIPER_ST, "Juniper Secure Tunnel"),
DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
DLT_CHOICE(AX25_KISS, "AX.25 with KISS header"),
+ DLT_CHOICE(IPMB_LINUX, "IPMB with Linux/Pigeon Point pseudo-header"),
DLT_CHOICE(IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
DLT_CHOICE(MPLS, "MPLS with label as link-layer header"),
DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"),
@@ -2961,6 +3095,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DOCSIS31_XRA31, "Excentis XRA-31 DOCSIS 3.1 RF sniffer frames"),
DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"),
DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"),
+ DLT_CHOICE(LINUX_SLL2, "Linux cooked v2"),
DLT_CHOICE_SENTINEL
};
@@ -3000,6 +3135,21 @@ pcap_datalink_val_to_description(int dlt)
return (NULL);
}
+const char *
+pcap_datalink_val_to_description_or_dlt(int dlt)
+{
+ static char unkbuf[40];
+ const char *description;
+
+ description = pcap_datalink_val_to_description(dlt);
+ if (description != NULL) {
+ return description;
+ } else {
+ (void)pcap_snprintf(unkbuf, sizeof(unkbuf), "DLT %u", dlt);
+ return unkbuf;
+ }
+}
+
struct tstamp_type_choice {
const char *name;
const char *description;
@@ -3152,7 +3302,7 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
* We copy the error message to errbuf, so callers
* can find it in either place.
*/
- strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
+ pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
@@ -3196,7 +3346,7 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
* We copy the error message to errbuf, so callers
* can find it in either place.
*/
- strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
+ pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
@@ -3232,35 +3382,6 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock)
}
#endif
-#ifdef _WIN32
-/*
- * Generate a string for a Win32-specific error (i.e. an error generated when
- * calling a Win32 API).
- * For errors occurred during standard C calls, we still use pcap_strerror()
- */
-void
-pcap_win32_err_to_str(DWORD error, char *errbuf)
-{
- size_t errlen;
- char *p;
-
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
- PCAP_ERRBUF_SIZE, NULL);
-
- /*
- * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
- * message. Get rid of it.
- */
- errlen = strlen(errbuf);
- if (errlen >= 2) {
- errbuf[errlen - 1] = '\0';
- errbuf[errlen - 2] = '\0';
- }
- p = strchr(errbuf, '\0');
- pcap_snprintf (p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error);
-}
-#endif
-
/*
* Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values.
*/
@@ -3332,7 +3453,7 @@ pcap_strerror(int errnum)
errno_t err = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
if (err != 0) /* err = 0 if successful */
- strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
+ pcap_strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
return (errbuf);
#else
return (strerror(errnum));
@@ -3554,7 +3675,7 @@ pcap_do_addexit(pcap_t *p)
/*
* "atexit()" failed; let our caller know.
*/
- strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
+ pcap_strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
return (0);
}
did_atexit = 1;
diff --git a/freebsd/contrib/libpcap/pcap/compiler-tests.h b/freebsd/contrib/libpcap/pcap/compiler-tests.h
index 5e17853a..ea5962c7 100644
--- a/freebsd/contrib/libpcap/pcap/compiler-tests.h
+++ b/freebsd/contrib/libpcap/pcap/compiler-tests.h
@@ -160,4 +160,4 @@
(__HP_aCC >= ((major)*10000 + (minor)*100))
#endif
-#endif /* lib_pcap_funcattrs_h */
+#endif /* lib_pcap_compiler_tests_h */
diff --git a/freebsd/contrib/libpcap/pcap/funcattrs.h b/freebsd/contrib/libpcap/pcap/funcattrs.h
index a8b1932f..e64da93a 100644
--- a/freebsd/contrib/libpcap/pcap/funcattrs.h
+++ b/freebsd/contrib/libpcap/pcap/funcattrs.h
@@ -164,10 +164,11 @@
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
/*
- * Compiler with support for __attribute((noreturn)), or GCC 2.5 and
- * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1
- * and later (do any earlier versions of XL C support this?), or
- * HP aCC A.06.10 and later.
+ * Compiler with support for __attribute((noreturn)), or GCC 2.5 or
+ * later, or some compiler asserting compatibility with GCC 2.5 or
+ * later, or Solaris Studio 12 (Sun C 5.9) or later, or IBM XL C 10.1
+ * or later (do any earlier versions of XL C support this?), or HP aCC
+ * A.06.10 or later.
*/
#define PCAP_NORETURN __attribute((noreturn))
#define PCAP_NORETURN_DEF __attribute((noreturn))
@@ -193,7 +194,8 @@
|| PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \
|| PCAP_IS_AT_LEAST_HP_C_VERSION(6,10)
/*
- * Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1
+ * Compiler with support for it, or GCC 2.3 or later, or some compiler
+ * asserting compatibility with GCC 2.3 or later, or IBM XL C 10.1
* and later (do any earlier versions of XL C support this?),
* or HP aCC A.06.10 and later.
*/
@@ -216,7 +218,7 @@
|| PCAP_IS_AT_LEAST_SUNC_VERSION(5,13)
/*
* Compiler that supports __has_attribute and __attribute__((deprecated)),
- * or GCC 4.5 and later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
+ * or GCC 4.5 or later, or Sun/Oracle C 12.4 (Sun C 5.13) or later.
*
* Those support __attribute__((deprecated(msg))) (we assume, perhaps
* incorrectly, that anything that supports __has_attribute() is
diff --git a/freebsd/contrib/libpcap/pcap/nflog.h b/freebsd/contrib/libpcap/pcap/nflog.h
index 29a71d2d..f7c85b54 100644
--- a/freebsd/contrib/libpcap/pcap/nflog.h
+++ b/freebsd/contrib/libpcap/pcap/nflog.h
@@ -32,7 +32,7 @@
/*
* Structure of an NFLOG header and TLV parts, as described at
- * http://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
+ * https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
*
* The NFLOG header is big-endian.
*
@@ -42,27 +42,27 @@
* data, etc.).
*/
typedef struct nflog_hdr {
- uint8_t nflog_family; /* address family */
- uint8_t nflog_version; /* version */
- uint16_t nflog_rid; /* resource ID */
+ uint8_t nflog_family; /* address family */
+ uint8_t nflog_version; /* version */
+ uint16_t nflog_rid; /* resource ID */
} nflog_hdr_t;
typedef struct nflog_tlv {
- uint16_t tlv_length; /* tlv length */
- uint16_t tlv_type; /* tlv type */
+ uint16_t tlv_length; /* tlv length */
+ uint16_t tlv_type; /* tlv type */
/* value follows this */
} nflog_tlv_t;
typedef struct nflog_packet_hdr {
uint16_t hw_protocol; /* hw protocol */
- uint8_t hook; /* netfilter hook */
- uint8_t pad; /* padding to 32 bits */
+ uint8_t hook; /* netfilter hook */
+ uint8_t pad; /* padding to 32 bits */
} nflog_packet_hdr_t;
typedef struct nflog_hwaddr {
uint16_t hw_addrlen; /* address length */
uint16_t pad; /* padding to 32-bit boundary */
- uint8_t hw_addr[8]; /* address, up to 8 bytes */
+ uint8_t hw_addr[8]; /* address, up to 8 bytes */
} nflog_hwaddr_t;
typedef struct nflog_timestamp {
diff --git a/freebsd/contrib/libpcap/pcap/pcap-inttypes.h b/freebsd/contrib/libpcap/pcap/pcap-inttypes.h
index af2c23c8..8b1eb8b9 100644
--- a/freebsd/contrib/libpcap/pcap/pcap-inttypes.h
+++ b/freebsd/contrib/libpcap/pcap/pcap-inttypes.h
@@ -106,12 +106,23 @@
#define PRIu64 "llu"
#endif
#endif
+
+ /*
+ * MSVC's support library doesn't support %zu to print a size_t until
+ * Visual Studio 2017, but supports %Iu earlier, so use that.
+ */
+ #define PRIsize "Iu"
#elif defined(__MINGW32__) || !defined(_WIN32)
/*
* Compiler is MinGW or target is UN*X or MS-DOS. Just use
* <inttypes.h>.
*/
#include <inttypes.h>
+
+ /*
+ * Assume the support library supports %zu; it's required by C99.
+ */
+ #define PRIsize "zu"
#endif
#endif /* pcap/pcap-inttypes.h */
diff --git a/freebsd/contrib/libpcap/pcap/pcap.h b/freebsd/contrib/libpcap/pcap/pcap.h
index dbe70dfd..a2d6003c 100644
--- a/freebsd/contrib/libpcap/pcap/pcap.h
+++ b/freebsd/contrib/libpcap/pcap/pcap.h
@@ -84,6 +84,7 @@
#include <sys/time.h>
#endif /* _WIN32/MSDOS/UN*X */
+#include <pcap/socket.h> /* for SOCKET, as the active-mode rpcap APIs use it */
#include <net/bpf.h>
#include <stdio.h>
@@ -346,7 +347,7 @@ PCAP_API const char *pcap_tstamp_type_val_to_name(int);
PCAP_API const char *pcap_tstamp_type_val_to_description(int);
#ifdef __linux__
-PCAP_API int pcap_set_protocol(pcap_t *, int);
+PCAP_API int pcap_set_protocol_linux(pcap_t *, int);
#endif
/*
@@ -466,6 +467,7 @@ PCAP_API void pcap_free_datalinks(int *);
PCAP_API int pcap_datalink_name_to_val(const char *);
PCAP_API const char *pcap_datalink_val_to_name(int);
PCAP_API const char *pcap_datalink_val_to_description(int);
+PCAP_API const char *pcap_datalink_val_to_description_or_dlt(int);
PCAP_API int pcap_snapshot(pcap_t *);
PCAP_API int pcap_is_swapped(pcap_t *);
PCAP_API int pcap_major_version(pcap_t *);
@@ -481,7 +483,28 @@ PCAP_API int pcap_fileno(pcap_t *);
#endif
PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
-PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
+#ifdef _WIN32
+ PCAP_API pcap_dumper_t *pcap_dump_hopen(pcap_t *, intptr_t);
+ /*
+ * If we're building libpcap, this is an internal routine in sf-pcap.c, so
+ * we must not define it as a macro.
+ *
+ * If we're not building libpcap, given that the version of the C runtime
+ * with which libpcap was built might be different from the version
+ * of the C runtime with which an application using libpcap was built,
+ * and that a FILE structure may differ between the two versions of the
+ * C runtime, calls to _fileno() must use the version of _fileno() in
+ * the C runtime used to open the FILE *, not the version in the C
+ * runtime with which libpcap was built. (Maybe once the Universal CRT
+ * rules the world, this will cease to be a problem.)
+ */
+ #ifndef BUILDING_PCAP
+ #define pcap_dump_fopen(p,f) \
+ pcap_dump_hopen(p, _get_osfhandle(_fileno(f)))
+ #endif
+#else /*_WIN32*/
+ PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
+#endif /*_WIN32*/
PCAP_API pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *);
PCAP_API FILE *pcap_dump_file(pcap_dumper_t *);
PCAP_API long pcap_dump_ftell(pcap_dumper_t *);
@@ -857,8 +880,8 @@ PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host,
* For listing remote capture devices, pcap_findalldevs_ex() is currently
* the only API available.
*/
-PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth,
- pcap_if_t **alldevs, char *errbuf);
+PCAP_API int pcap_findalldevs_ex(const char *source,
+ struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
/*
* Sampling methods.
@@ -936,27 +959,6 @@ PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p);
/* Maximum length of an host name (needed for the RPCAP active mode) */
#define RPCAP_HOSTLIST_SIZE 1024
-/*
- * Some minor differences between UN*X sockets and and Winsock sockets.
- */
-#ifndef _WIN32
- /*!
- * \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
- * a file descriptor, and therefore a signed integer.
- * We define SOCKET to be a signed integer on UN*X, so that it can
- * be used on both platforms.
- */
- #define SOCKET int
-
- /*!
- * \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
- * in UN*X, it's -1.
- * We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
- * both platforms.
- */
- #define INVALID_SOCKET -1
-#endif
-
PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port,
const char *hostlist, char *connectinghost,
struct pcap_rmtauth *auth, char *errbuf);
diff --git a/freebsd/contrib/libpcap/pcap/sll.h b/freebsd/contrib/libpcap/pcap/sll.h
index c4d08862..392faae4 100644
--- a/freebsd/contrib/libpcap/pcap/sll.h
+++ b/freebsd/contrib/libpcap/pcap/sll.h
@@ -74,27 +74,44 @@
#ifndef lib_pcap_sll_h
#define lib_pcap_sll_h
+#include <pcap/pcap-inttypes.h>
+
/*
* A DLT_LINUX_SLL fake link-layer header.
*/
#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */
-#include <pcap/pcap-inttypes.h>
-
struct sll_header {
uint16_t sll_pkttype; /* packet type */
uint16_t sll_hatype; /* link-layer address type */
uint16_t sll_halen; /* link-layer address length */
- uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
+ uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
uint16_t sll_protocol; /* protocol */
};
/*
- * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
- * PACKET_ values on Linux, but are defined here so that they're
- * available even on systems other than Linux, and so that they
- * don't change even if the PACKET_ values change.
+ * A DLT_LINUX_SLL2 fake link-layer header.
+ */
+#define SLL2_HDR_LEN 20 /* total header length */
+
+struct sll2_header {
+ uint16_t sll2_protocol; /* protocol */
+ uint16_t sll2_reserved_mbz; /* reserved - must be zero */
+ uint32_t sll2_if_index; /* 1-based interface index */
+ uint16_t sll2_hatype; /* link-layer address type */
+ uint8_t sll2_pkttype; /* packet type */
+ uint8_t sll2_halen; /* link-layer address length */
+ uint8_t sll2_addr[SLL_ADDRLEN]; /* link-layer address */
+};
+
+/*
+ * The LINUX_SLL_ values for "sll_pkttype" and LINUX_SLL2_ values for
+ * "sll2_pkttype"; these correspond to the PACKET_ values on Linux,
+ * which are defined by a header under include/uapi in the current
+ * kernel source, and are thus not going to change on Linux. We
+ * define them here so that they're available even on systems other
+ * than Linux.
*/
#define LINUX_SLL_HOST 0
#define LINUX_SLL_BROADCAST 1
@@ -103,10 +120,11 @@ struct sll_header {
#define LINUX_SLL_OUTGOING 4
/*
- * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
- * ETH_P_ values on Linux, but are defined here so that they're
- * available even on systems other than Linux. We assume, for now,
- * that the ETH_P_ values won't change in Linux; if they do, then:
+ * The LINUX_SLL_ values for "sll_protocol" and LINUX_SLL2_ values for
+ * "sll2_protocol"; these correspond to the ETH_P_ values on Linux, but
+ * are defined here so that they're available even on systems other than
+ * Linux. We assume, for now, that the ETH_P_ values won't change in
+ * Linux; if they do, then:
*
* if we don't translate them in "pcap-linux.c", capture files
* won't necessarily be readable if captured on a system that
diff --git a/freebsd/contrib/libpcap/pcap/socket.h b/freebsd/contrib/libpcap/pcap/socket.h
new file mode 100644
index 00000000..6f27cba1
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/socket.h
@@ -0,0 +1,93 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. 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 the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ */
+
+#ifndef lib_pcap_socket_h
+#define lib_pcap_socket_h
+
+/*
+ * Some minor differences between sockets on various platforms.
+ * We include whatever sockets are needed for Internet-protocol
+ * socket access on UN*X and Windows.
+ */
+#ifdef _WIN32
+ /* Need windef.h for defines used in winsock2.h under MingW32 */
+ #ifdef __MINGW32__
+ #include <windef.h>
+ #endif
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+
+ /*
+ * Winsock doesn't have this UN*X type; it's used in the UN*X
+ * sockets API.
+ *
+ * XXX - do we need to worry about UN*Xes so old that *they*
+ * don't have it, either?
+ */
+ typedef int socklen_t;
+
+ /*
+ * Winsock doesn't have this POSIX type; it's used for the
+ * tv_usec value of struct timeval.
+ */
+ typedef long suseconds_t;
+#else /* _WIN32 */
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netdb.h> /* for struct addrinfo/getaddrinfo() */
+ #include <netinet/in.h> /* for sockaddr_in, in BSD at least */
+ #include <arpa/inet.h>
+
+ /*!
+ * \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's
+ * a file descriptor, and therefore a signed integer.
+ * We define SOCKET to be a signed integer on UN*X, so that it can
+ * be used on both platforms.
+ */
+ #ifndef SOCKET
+ #define SOCKET int
+ #endif
+
+ /*!
+ * \brief In Winsock, the error return if socket() fails is INVALID_SOCKET;
+ * in UN*X, it's -1.
+ * We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on
+ * both platforms.
+ */
+ #ifndef INVALID_SOCKET
+ #define INVALID_SOCKET -1
+ #endif
+#endif /* _WIN32 */
+
+#endif /* lib_pcap_socket_h */
diff --git a/freebsd/contrib/libpcap/portability.h b/freebsd/contrib/libpcap/portability.h
index b3612542..543846e8 100644
--- a/freebsd/contrib/libpcap/portability.h
+++ b/freebsd/contrib/libpcap/portability.h
@@ -38,6 +38,7 @@
* Helpers for portability between Windows and UN*X and between different
* flavors of UN*X.
*/
+#include <stdarg.h> /* we declare varargs functions on some platforms */
#include "pcap/funcattrs.h"
@@ -45,49 +46,45 @@
extern "C" {
#endif
-#ifndef HAVE_STRLCPY
- /*
- * Macro that does the same thing as strlcpy().
- */
- #if defined(_MSC_VER) || defined(__MINGW32__)
- /*
- * strncpy_s() is supported at least back to Visual
- * Studio 2005.
- */
- #define strlcpy(x, y, z) \
- strncpy_s((x), (z), (y), _TRUNCATE)
-
- #else
- #define strlcpy(x, y, z) \
- (strncpy((x), (y), (z)), \
- ((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \
- (void) strlen((y)))
- #endif
+#ifdef HAVE_STRLCAT
+ #define pcap_strlcat strlcat
+#else
+ #if defined(_MSC_VER) || defined(__MINGW32__)
+ /*
+ * strncat_s() is supported at least back to Visual
+ * Studio 2005.
+ */
+ #define pcap_strlcat(x, y, z) \
+ strncat_s((x), (z), (y), _TRUNCATE)
+ #else
+ /*
+ * Define it ourselves.
+ */
+ extern size_t pcap_strlcat(char * restrict dst, const char * restrict src, size_t dstsize);
+ #endif
#endif
-#ifndef HAVE_STRLCAT
- /*
- * Macro that does the same thing as strlcat().
- */
- #if defined(_MSC_VER) || defined(__MINGW32__)
- /*
- * strncat_s() is supported at least back to Visual
- * Studio 2005.
- */
- #define strlcat(x, y, z) \
- strncat_s((x), (z), (y), _TRUNCATE)
- #else
- /*
- * ANSI C says strncat() always null-terminates its first argument,
- * so 1) we don't need to explicitly null-terminate the string
- * ourselves and 2) we need to leave room for the null terminator.
- */
- #define strlcat(x, y, z) \
- strncat((x), (y), (z) - strlen((x)) - 1)
- #endif
+#ifdef HAVE_STRLCPY
+ #define pcap_strlcpy strlcpy
+#else
+ #if defined(_MSC_VER) || defined(__MINGW32__)
+ /*
+ * strncpy_s() is supported at least back to Visual
+ * Studio 2005.
+ */
+ #define pcap_strlcpy(x, y, z) \
+ strncpy_s((x), (z), (y), _TRUNCATE)
+ #else
+ /*
+ * Define it ourselves.
+ */
+ extern size_t pcap_strlcpy(char * restrict dst, const char * restrict src, size_t dstsize);
+ #endif
#endif
#ifdef _MSC_VER
+ #define isascii __isascii
+
/*
* If <crtdbg.h> has been included, and _DEBUG is defined, and
* __STDC__ is zero, <crtdbg.h> will define strdup() to call
@@ -134,6 +131,23 @@ extern int pcap_snprintf(char *, size_t, PCAP_FORMAT_STRING(const char *), ...)
extern int pcap_vsnprintf(char *, size_t, const char *, va_list ap);
#endif
+/*
+ * We also want asprintf(), for some cases where we use it to construct
+ * dynamically-allocated variable-length strings.
+ */
+#ifdef HAVE_ASPRINTF
+#define pcap_asprintf asprintf
+#else
+extern int pcap_asprintf(char **, PCAP_FORMAT_STRING(const char *), ...)
+ PCAP_PRINTFLIKE(2, 3);
+#endif
+
+#ifdef HAVE_VASPRINTF
+#define pcap_vasprintf vasprintf
+#else
+extern int pcap_vasprintf(char **, const char *, va_list ap);
+#endif
+
#ifdef HAVE_STRTOK_R
#define pcap_strtok_r strtok_r
#else
@@ -146,7 +160,6 @@ extern int pcap_vsnprintf(char *, size_t, const char *, va_list ap);
/*
* Define it ourselves.
*/
- #define NEED_STRTOK_R
extern char *pcap_strtok_r(char *, const char *, char **);
#endif
#endif /* HAVE_STRTOK_R */
diff --git a/freebsd/contrib/libpcap/savefile.c b/freebsd/contrib/libpcap/savefile.c
index 6b0cc86e..a3af1fa8 100644
--- a/freebsd/contrib/libpcap/savefile.c
+++ b/freebsd/contrib/libpcap/savefile.c
@@ -45,6 +45,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h> /* for INT_MAX */
#include "pcap-int.h"
@@ -54,12 +55,13 @@
#include "sf-pcap.h"
#include "sf-pcapng.h"
+#include "pcap-common.h"
#ifdef _WIN32
/*
* These aren't exported on Windows, because they would only work if both
- * WinPcap and the code using it were to use the Universal CRT; otherwise,
- * a FILE structure in WinPcap and a FILE structure in the code using it
+ * WinPcap/Npcap and the code using it were to use the Universal CRT; otherwise,
+ * a FILE structure in WinPcap/Npcap and a FILE structure in the code using it
* could be different if they're using different versions of the C runtime.
*
* Instead, pcap/pcap.h defines them as macros that wrap the hopen versions,
@@ -181,7 +183,7 @@ sf_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
static u_int
sf_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue, int sync)
{
- strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
+ pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
PCAP_ERRBUF_SIZE);
return (0);
}
@@ -220,7 +222,7 @@ sf_get_airpcap_handle(pcap_t *pcap)
static int
sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
{
- strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
+ pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
PCAP_ERRBUF_SIZE);
return (-1);
}
@@ -319,6 +321,7 @@ pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision,
{
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "_fdopen");
+ _close(fd);
return NULL;
}
@@ -333,7 +336,34 @@ pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
}
#endif
-static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, u_int, char *, int *) = {
+/*
+ * Given a link-layer header type and snapshot length, return a
+ * snapshot length to use when reading the file; it's guaranteed
+ * to be > 0 and <= INT_MAX.
+ *
+ * XXX - the only reason why we limit it to <= INT_MAX is so that
+ * it fits in p->snapshot, and the only reason that p->snapshot is
+ * signed is that pcap_snapshot() returns an int, not an unsigned int.
+ */
+bpf_u_int32
+pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen)
+{
+ if (snaplen == 0 || snaplen > INT_MAX) {
+ /*
+ * Bogus snapshot length; use the maximum for this
+ * link-layer type as a fallback.
+ *
+ * XXX - we don't clamp snapshot lengths that are
+ * <= INT_MAX but > max_snaplen_for_dlt(linktype),
+ * so a capture file could cause us to allocate
+ * a Really Big Buffer.
+ */
+ snaplen = max_snaplen_for_dlt(linktype);
+ }
+ return snaplen;
+}
+
+static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = {
pcap_check_header,
pcap_ng_check_header
};
@@ -348,7 +378,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
char *errbuf)
{
register pcap_t *p;
- bpf_u_int32 magic;
+ uint8_t magic[4];
size_t amt_read;
u_int i;
int err;
@@ -360,16 +390,15 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
* Windows Sniffer, and Microsoft Network Monitor) all have magic
* numbers that are unique in their first 4 bytes.
*/
- amt_read = fread((char *)&magic, 1, sizeof(magic), fp);
+ amt_read = fread(&magic, 1, sizeof(magic), fp);
if (amt_read != sizeof(magic)) {
if (ferror(fp)) {
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "error reading dump file");
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %lu file header bytes, only got %lu",
- (unsigned long)sizeof(magic),
- (unsigned long)amt_read);
+ "truncated dump file; tried to read %" PRIsize " file header bytes, only got %" PRIsize,
+ sizeof(magic), amt_read);
}
return (NULL);
}
diff --git a/freebsd/contrib/libpcap/scanner.c b/freebsd/contrib/libpcap/scanner.c
index 3a477eb5..66902abf 100644
--- a/freebsd/contrib/libpcap/scanner.c
+++ b/freebsd/contrib/libpcap/scanner.c
@@ -391,8 +391,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ) __dead2;
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 184
-#define YY_END_OF_BUFFER 185
+#define YY_NUM_RULES 183
+#define YY_END_OF_BUFFER 184
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -400,198 +400,198 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[1729] =
+static yyconst flex_int16_t yy_accept[1724] =
{ 0,
- 0, 0, 185, 182, 113, 113, 113, 114, 182, 114,
- 114, 114, 183, 123, 123, 114, 114, 114, 114, 180,
- 180, 182, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 114, 182, 117, 121, 67, 0, 180, 123,
- 0, 180, 180, 180, 0, 125, 119, 116, 118, 115,
- 120, 180, 181, 181, 180, 180, 180, 20, 180, 180,
+ 0, 0, 184, 182, 113, 113, 114, 182, 114, 114,
+ 123, 123, 114, 114, 114, 114, 180, 180, 182, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 114,
+ 117, 121, 67, 0, 180, 123, 0, 180, 180, 180,
+ 0, 125, 119, 116, 118, 115, 120, 180, 181, 180,
+ 180, 180, 20, 180, 180, 180, 180, 180, 180, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 7, 180, 34, 35,
- 180, 7, 180, 34, 35, 180, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 92,
- 180, 68, 180, 180, 180, 180, 180, 180, 60, 180,
- 180, 180, 180, 86, 180, 180, 180, 180, 180, 180,
- 61, 180, 4, 180, 180, 180, 180, 180, 180, 180,
- 68, 121, 180, 124, 124, 180, 123, 180, 0, 125,
- 123, 125, 125, 125, 180, 180, 180, 67, 5, 180,
- 81, 180, 180, 180, 180, 180, 180, 180, 55, 107,
- 1, 0, 180, 21, 180, 180, 180, 180, 180, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
-
- 180, 180, 36, 180, 180, 18, 43, 0, 180, 29,
- 180, 25, 70, 180, 180, 79, 37, 180, 100, 180,
- 180, 180, 180, 101, 180, 46, 69, 82, 106, 180,
- 14, 180, 3, 180, 180, 180, 180, 180, 94, 180,
- 180, 26, 180, 105, 180, 108, 38, 2, 180, 42,
- 180, 9, 180, 10, 89, 180, 88, 180, 180, 0,
- 180, 180, 124, 180, 180, 180, 180, 123, 0, 180,
- 0, 126, 125, 125, 0, 125, 0, 125, 0, 125,
- 0, 23, 180, 180, 180, 180, 64, 16, 41, 180,
- 39, 180, 180, 180, 30, 180, 98, 180, 180, 180,
-
- 111, 180, 180, 104, 110, 45, 109, 112, 11, 180,
- 12, 13, 180, 180, 180, 32, 78, 180, 62, 3,
- 99, 47, 180, 180, 180, 74, 180, 180, 180, 180,
- 48, 180, 180, 40, 180, 6, 180, 93, 180, 8,
- 95, 180, 180, 0, 180, 53, 73, 15, 180, 124,
- 124, 180, 124, 124, 124, 180, 123, 180, 0, 125,
- 180, 0, 0, 125, 0, 125, 126, 125, 0, 0,
- 0, 0, 125, 125, 125, 125, 125, 0, 180, 56,
- 57, 58, 59, 180, 22, 180, 180, 180, 180, 31,
- 180, 180, 180, 102, 103, 0, 19, 180, 180, 180,
-
- 87, 180, 33, 180, 80, 28, 27, 180, 180, 83,
- 180, 180, 180, 50, 17, 180, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 0,
- 180, 180, 124, 180, 180, 180, 180, 124, 124, 180,
- 123, 180, 0, 0, 125, 125, 125, 0, 0, 126,
- 125, 125, 126, 125, 0, 0, 125, 125, 125, 125,
- 125, 0, 0, 0, 0, 125, 125, 0, 125, 0,
- 125, 0, 97, 180, 180, 180, 24, 180, 180, 77,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 0,
- 180, 180, 180, 180, 180, 70, 180, 180, 180, 180,
-
- 180, 180, 180, 75, 76, 180, 96, 180, 180, 180,
+ 180, 180, 180, 180, 92, 180, 68, 180, 180, 180,
+ 180, 180, 180, 60, 180, 180, 180, 180, 86, 180,
+ 180, 180, 180, 180, 180, 61, 180, 4, 180, 180,
+ 180, 180, 180, 180, 180, 68, 121, 180, 124, 124,
+ 180, 123, 180, 0, 125, 123, 125, 125, 125, 180,
+ 180, 180, 67, 5, 180, 81, 180, 180, 180, 180,
+ 180, 180, 180, 55, 107, 1, 0, 180, 21, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 124, 124, 180, 124, 124, 124, 124, 180, 123,
- 180, 0, 125, 125, 0, 125, 0, 0, 125, 0,
- 125, 126, 125, 0, 0, 0, 125, 125, 0, 125,
- 126, 125, 0, 0, 0, 0, 0, 0, 0, 125,
- 125, 125, 125, 125, 0, 180, 180, 180, 180, 52,
- 63, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 36, 180, 180,
+
+ 18, 43, 0, 180, 29, 180, 25, 70, 180, 180,
+ 79, 37, 180, 100, 180, 180, 180, 180, 101, 180,
+ 46, 69, 82, 106, 180, 14, 180, 3, 180, 180,
+ 180, 180, 180, 94, 180, 180, 26, 180, 105, 180,
+ 108, 38, 2, 180, 42, 180, 9, 180, 10, 89,
+ 180, 88, 180, 180, 0, 180, 180, 124, 180, 180,
+ 180, 180, 123, 0, 180, 0, 126, 125, 125, 0,
+ 125, 0, 125, 0, 125, 0, 23, 180, 180, 180,
+ 180, 64, 16, 41, 180, 39, 180, 180, 180, 30,
+ 180, 98, 180, 180, 180, 111, 180, 180, 104, 110,
+
+ 45, 109, 112, 11, 180, 12, 13, 180, 180, 180,
+ 32, 78, 180, 62, 3, 99, 47, 180, 180, 180,
+ 74, 180, 180, 180, 180, 48, 180, 180, 40, 180,
+ 6, 180, 93, 180, 8, 95, 180, 180, 0, 180,
+ 53, 73, 15, 180, 124, 124, 180, 124, 124, 124,
+ 180, 123, 180, 0, 125, 180, 0, 0, 125, 0,
+ 125, 126, 125, 0, 0, 0, 0, 125, 125, 125,
+ 125, 125, 0, 180, 56, 57, 58, 59, 180, 22,
+ 180, 180, 180, 180, 31, 180, 180, 180, 102, 103,
+ 0, 19, 180, 180, 180, 87, 180, 33, 180, 80,
+
+ 28, 27, 180, 180, 83, 180, 180, 180, 50, 17,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 71, 180, 180, 44, 84, 85, 180, 180,
-
- 180, 180, 54, 176, 179, 178, 172, 180, 174, 173,
- 177, 180, 0, 180, 180, 124, 180, 180, 180, 124,
- 180, 123, 180, 0, 0, 125, 125, 125, 125, 125,
- 125, 0, 0, 126, 125, 125, 125, 0, 0, 125,
- 125, 125, 125, 125, 0, 0, 0, 0, 0, 0,
+ 180, 180, 180, 180, 0, 180, 180, 124, 180, 180,
+ 180, 180, 124, 124, 180, 123, 180, 0, 0, 125,
+ 125, 125, 0, 0, 126, 125, 125, 126, 125, 0,
0, 125, 125, 125, 125, 125, 0, 0, 0, 0,
- 0, 125, 125, 0, 125, 0, 125, 0, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 125, 125, 0, 125, 0, 125, 0, 97, 180, 180,
+ 180, 24, 180, 180, 77, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 0, 180, 180, 180, 180, 180,
+ 70, 180, 180, 180, 180, 180, 180, 180, 75, 76,
+
+ 180, 96, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 124, 124, 180, 124,
+ 124, 124, 124, 180, 123, 180, 0, 125, 125, 0,
+ 125, 0, 0, 125, 0, 125, 126, 125, 0, 0,
+ 0, 125, 125, 0, 125, 126, 125, 0, 0, 0,
+ 0, 0, 0, 0, 125, 125, 125, 125, 125, 0,
+ 180, 180, 180, 180, 52, 63, 180, 180, 180, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 128, 127, 180, 180, 72, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 71, 180, 180,
+ 44, 84, 85, 180, 180, 180, 180, 54, 176, 179,
- 180, 175, 171, 180, 180, 124, 124, 124, 124, 180,
- 123, 180, 0, 125, 125, 0, 125, 125, 0, 125,
- 0, 0, 125, 0, 125, 126, 125, 0, 0, 0,
- 125, 125, 0, 125, 126, 125, 0, 0, 0, 0,
- 0, 125, 125, 0, 125, 126, 125, 0, 125, 125,
- 0, 0, 0, 0, 0, 0, 0, 125, 125, 125,
- 125, 125, 0, 65, 180, 55, 133, 140, 180, 180,
+ 178, 172, 180, 174, 173, 177, 180, 0, 180, 180,
+ 124, 180, 180, 180, 124, 180, 123, 180, 0, 0,
+ 125, 125, 125, 125, 125, 125, 0, 0, 126, 125,
+ 125, 125, 0, 0, 125, 125, 125, 125, 125, 0,
+ 0, 0, 0, 0, 0, 0, 125, 125, 125, 125,
+ 125, 0, 0, 0, 0, 0, 125, 125, 0, 125,
+ 0, 125, 0, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 128, 127,
+ 180, 180, 72, 180, 180, 180, 175, 171, 180, 180,
+
+ 124, 124, 124, 124, 180, 123, 180, 0, 125, 125,
+ 0, 125, 125, 0, 125, 0, 0, 125, 0, 125,
+ 126, 125, 0, 0, 0, 125, 125, 0, 125, 126,
+ 125, 0, 0, 0, 0, 0, 125, 125, 0, 125,
+ 126, 125, 0, 125, 125, 0, 0, 0, 0, 0,
+ 0, 0, 125, 125, 125, 125, 125, 0, 65, 180,
+ 55, 133, 140, 180, 180, 180, 180, 180, 180, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 145, 144, 180, 66,
- 49, 180, 180, 0, 180, 180, 180, 180, 180, 123,
+ 180, 145, 144, 180, 66, 49, 180, 180, 0, 180,
+ 180, 180, 180, 180, 123, 180, 0, 0, 125, 125,
- 180, 0, 0, 125, 125, 125, 125, 125, 125, 125,
- 125, 125, 0, 0, 126, 125, 125, 125, 0, 0,
- 125, 125, 125, 125, 125, 0, 0, 0, 0, 0,
- 0, 0, 125, 125, 125, 125, 125, 0, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 0, 0, 126,
+ 125, 125, 125, 0, 0, 125, 125, 125, 125, 125,
0, 0, 0, 0, 0, 0, 0, 125, 125, 125,
- 125, 125, 0, 0, 0, 0, 0, 0, 125, 125,
- 0, 125, 0, 125, 0, 90, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 146, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 51, 122, 122,
- 124, 124, 180, 123, 180, 0, 125, 125, 0, 125,
-
- 125, 0, 125, 125, 0, 125, 0, 122, 125, 0,
- 125, 126, 125, 0, 0, 0, 125, 125, 0, 125,
- 126, 125, 0, 0, 0, 0, 0, 125, 125, 0,
- 125, 126, 125, 0, 0, 0, 0, 0, 0, 125,
- 125, 0, 125, 126, 125, 0, 125, 125, 125, 0,
- 0, 0, 0, 0, 0, 0, 125, 125, 125, 125,
- 125, 0, 180, 180, 180, 180, 180, 180, 180, 180,
- 138, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 91, 122, 122, 124, 180, 122, 122, 0,
- 0, 125, 125, 125, 125, 125, 125, 125, 125, 125,
-
- 125, 125, 125, 0, 122, 126, 125, 125, 125, 0,
- 0, 125, 125, 125, 125, 125, 0, 0, 0, 0,
- 0, 0, 0, 125, 125, 125, 125, 125, 0, 125,
- 125, 0, 0, 0, 0, 0, 0, 0, 125, 125,
- 125, 125, 125, 0, 125, 125, 125, 0, 0, 0,
- 0, 0, 0, 0, 125, 125, 125, 125, 125, 0,
- 0, 0, 0, 0, 0, 125, 125, 0, 125, 0,
- 125, 0, 180, 180, 180, 142, 180, 180, 180, 180,
- 180, 180, 180, 130, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 180, 124, 180, 123, 0, 125, 125,
-
+ 125, 125, 0, 125, 125, 0, 0, 0, 0, 0,
+ 0, 0, 125, 125, 125, 125, 125, 0, 0, 0,
+ 0, 0, 0, 125, 125, 0, 125, 0, 125, 0,
+ 90, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 146, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 51, 122, 122, 124, 124, 180, 123, 180,
0, 125, 125, 0, 125, 125, 0, 125, 125, 0,
- 125, 0, 0, 0, 125, 0, 0, 125, 126, 125,
- 0, 0, 0, 125, 125, 0, 125, 126, 125, 0,
+
+ 125, 0, 122, 125, 0, 125, 126, 125, 0, 0,
+ 0, 125, 125, 0, 125, 126, 125, 0, 0, 0,
+ 0, 0, 125, 125, 0, 125, 126, 125, 0, 0,
0, 0, 0, 0, 125, 125, 0, 125, 126, 125,
- 0, 0, 0, 0, 0, 0, 125, 125, 0, 125,
- 126, 125, 0, 0, 0, 0, 0, 0, 125, 125,
- 0, 125, 126, 125, 0, 125, 125, 125, 0, 0,
- 0, 0, 0, 0, 0, 125, 125, 125, 125, 125,
- 0, 180, 180, 180, 180, 132, 180, 180, 180, 136,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 0, 125, 125, 125, 0, 0, 0, 0, 0, 0,
+ 0, 125, 125, 125, 125, 125, 0, 180, 180, 180,
+ 180, 180, 180, 180, 180, 138, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 91, 122, 122,
+ 124, 180, 122, 122, 0, 0, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 0, 122,
- 180, 180, 180, 122, 0, 0, 125, 125, 125, 125,
- 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
- 125, 0, 0, 0, 126, 0, 0, 125, 0, 0,
- 125, 125, 125, 0, 0, 0, 0, 0, 0, 0,
+ 126, 125, 125, 125, 0, 0, 125, 125, 125, 125,
+ 125, 0, 0, 0, 0, 0, 0, 0, 125, 125,
125, 125, 125, 0, 125, 125, 0, 0, 0, 0,
- 0, 0, 0, 125, 125, 125, 0, 125, 125, 125,
- 0, 0, 0, 0, 0, 0, 0, 125, 125, 125,
- 0, 125, 125, 125, 0, 0, 0, 0, 0, 0,
- 0, 125, 125, 125, 0, 0, 0, 0, 0, 0,
- 125, 125, 0, 125, 0, 125, 0, 129, 141, 143,
-
- 137, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 155, 180, 180, 180, 0, 0, 125,
- 0, 125, 0, 125, 125, 0, 125, 125, 0, 125,
- 125, 0, 125, 125, 0, 125, 0, 0, 0, 0,
- 125, 125, 0, 125, 0, 0, 125, 125, 125, 0,
- 0, 0, 0, 125, 125, 125, 0, 0, 0, 0,
- 0, 125, 125, 125, 0, 0, 0, 0, 0, 125,
- 125, 125, 0, 0, 0, 0, 0, 125, 125, 125,
+ 0, 0, 0, 125, 125, 125, 125, 125, 0, 125,
+ 125, 125, 0, 0, 0, 0, 0, 0, 0, 125,
+ 125, 125, 125, 125, 0, 0, 0, 0, 0, 0,
+ 125, 125, 0, 125, 0, 125, 0, 180, 180, 180,
+ 142, 180, 180, 180, 180, 180, 180, 180, 130, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 124,
+ 180, 123, 0, 125, 125, 0, 125, 125, 0, 125,
+
+ 125, 0, 125, 125, 0, 125, 0, 0, 0, 125,
+ 0, 0, 125, 126, 125, 0, 0, 0, 125, 125,
+ 0, 125, 126, 125, 0, 0, 0, 0, 0, 125,
+ 125, 0, 125, 126, 125, 0, 0, 0, 0, 0,
+ 0, 125, 125, 0, 125, 126, 125, 0, 0, 0,
+ 0, 0, 0, 125, 125, 0, 125, 126, 125, 0,
125, 125, 125, 0, 0, 0, 0, 0, 0, 0,
- 125, 125, 125, 0, 180, 180, 180, 180, 180, 180,
-
- 147, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 0, 0, 0, 125, 125, 125, 125, 125, 125,
- 0, 0, 0, 0, 125, 125, 0, 0, 0, 0,
- 125, 125, 125, 0, 0, 0, 0, 0, 125, 125,
- 125, 125, 0, 0, 0, 0, 0, 125, 125, 125,
- 125, 0, 0, 0, 0, 0, 125, 125, 125, 125,
- 0, 0, 0, 0, 0, 125, 0, 0, 0, 0,
- 0, 125, 125, 125, 180, 180, 180, 139, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 125, 125, 125, 125, 125, 125, 125, 125, 0,
+ 125, 125, 125, 125, 125, 0, 180, 180, 180, 180,
+ 132, 180, 180, 180, 136, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 122, 0,
- 0, 0, 0, 125, 125, 0, 0, 125, 0, 0,
- 0, 125, 0, 0, 0, 125, 0, 0, 0, 125,
- 0, 0, 0, 125, 125, 125, 125, 0, 0, 0,
- 0, 0, 125, 134, 180, 131, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 156, 180, 125,
- 0, 0, 125, 125, 0, 125, 125, 125, 0, 125,
- 125, 125, 0, 125, 125, 125, 0, 125, 125, 125,
- 0, 0, 0, 0, 125, 135, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 152, 180, 125, 125,
+ 0, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 0, 0, 0, 126,
+ 0, 0, 125, 0, 0, 125, 125, 125, 0, 0,
+ 0, 0, 0, 0, 0, 125, 125, 125, 0, 125,
+ 125, 0, 0, 0, 0, 0, 0, 0, 125, 125,
+ 125, 0, 125, 125, 125, 0, 0, 0, 0, 0,
+ 0, 0, 125, 125, 125, 0, 125, 125, 125, 0,
0, 0, 0, 0, 0, 0, 125, 125, 125, 0,
+ 0, 0, 0, 0, 0, 125, 125, 0, 125, 0,
+ 125, 0, 129, 141, 143, 137, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 155, 180,
+ 180, 180, 0, 0, 125, 0, 125, 0, 125, 125,
+ 0, 125, 125, 0, 125, 125, 0, 125, 125, 0,
+ 125, 0, 0, 0, 0, 125, 125, 0, 125, 0,
+ 0, 125, 125, 125, 0, 0, 0, 0, 125, 125,
+ 125, 0, 0, 0, 0, 0, 125, 125, 125, 0,
+ 0, 0, 0, 0, 125, 125, 125, 0, 0, 0,
+ 0, 0, 125, 125, 125, 125, 125, 125, 0, 0,
+ 0, 0, 0, 0, 0, 125, 125, 125, 0, 180,
+ 180, 180, 180, 180, 180, 147, 180, 180, 180, 180,
+
+ 180, 180, 180, 180, 180, 180, 0, 0, 0, 125,
+ 125, 125, 125, 125, 125, 0, 0, 0, 0, 125,
+ 125, 0, 0, 0, 0, 125, 125, 125, 0, 0,
+ 0, 0, 0, 125, 125, 125, 125, 0, 0, 0,
+ 0, 0, 125, 125, 125, 125, 0, 0, 0, 0,
+ 0, 125, 125, 125, 125, 0, 0, 0, 0, 0,
+ 125, 0, 0, 0, 0, 0, 125, 125, 125, 180,
+ 180, 180, 139, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 125, 125, 125, 125,
+ 125, 125, 125, 125, 0, 0, 0, 0, 125, 125,
+
+ 0, 0, 125, 0, 0, 0, 125, 0, 0, 0,
+ 125, 0, 0, 0, 125, 0, 0, 0, 125, 125,
+ 125, 125, 0, 0, 0, 0, 0, 125, 134, 180,
+ 131, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 156, 180, 125, 0, 0, 125, 125, 0,
+ 125, 125, 125, 0, 125, 125, 125, 0, 125, 125,
+ 125, 0, 125, 125, 125, 0, 0, 0, 0, 125,
+ 135, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 152, 180, 125, 125, 0, 0, 0, 0, 0,
+ 0, 125, 125, 125, 0, 180, 180, 180, 180, 180,
+
+ 180, 180, 180, 180, 180, 180, 151, 0, 125, 125,
+ 125, 125, 125, 0, 167, 180, 180, 180, 180, 180,
+ 180, 180, 154, 180, 180, 125, 125, 166, 180, 180,
+ 180, 180, 180, 180, 153, 180, 180, 180, 180, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 151, 0, 125, 125, 125, 125, 125, 0, 167,
- 180, 180, 180, 180, 180, 180, 180, 154, 180, 180,
- 125, 125, 166, 180, 180, 180, 180, 180, 180, 153,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 165, 180,
180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 165, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 164, 180, 180, 180,
- 180, 180, 170, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 157, 180, 180, 180, 180, 180, 150,
-
- 180, 180, 168, 180, 180, 180, 180, 180, 180, 148,
- 180, 169, 180, 163, 180, 180, 180, 180, 158, 180,
- 160, 180, 180, 162, 159, 149, 161, 0
+ 180, 164, 180, 180, 180, 180, 180, 170, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 157, 180,
+ 180, 180, 180, 180, 150, 180, 180, 168, 180, 180,
+
+ 180, 180, 180, 180, 148, 180, 169, 180, 163, 180,
+ 180, 180, 180, 158, 180, 160, 180, 180, 162, 159,
+ 149, 161, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -605,11 +605,11 @@ static yyconst flex_int32_t yy_ec[256] =
21, 22, 1, 1, 23, 23, 23, 23, 23, 23,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 25, 24, 24,
- 26, 27, 26, 7, 28, 1, 29, 30, 31, 32,
+ 7, 26, 7, 7, 27, 1, 28, 29, 30, 31,
- 33, 34, 35, 36, 37, 24, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 24, 1, 53, 1, 1, 1, 1, 1, 1,
+ 32, 33, 34, 35, 36, 24, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 24, 1, 52, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -626,2250 +626,2198 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[54] =
+static yyconst flex_int32_t yy_meta[53] =
{ 0,
- 1, 2, 2, 1, 2, 1, 1, 3, 2, 4,
- 5, 6, 6, 6, 6, 6, 6, 6, 7, 3,
- 3, 3, 8, 4, 9, 3, 1, 4, 8, 8,
- 8, 8, 8, 8, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 9, 4, 3
+ 1, 2, 2, 1, 2, 1, 1, 1, 2, 3,
+ 4, 5, 5, 5, 5, 5, 5, 5, 6, 1,
+ 1, 1, 7, 3, 8, 1, 3, 7, 7, 7,
+ 7, 7, 7, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 8,
+ 3, 1
} ;
-static yyconst flex_int16_t yy_base[2189] =
+static yyconst flex_int16_t yy_base[2184] =
{ 0,
- 0, 0, 5455, 53, 7856, 7856, 57, 5433, 64, 81,
- 5445, 7856, 7856, 99, 30, 151, 46, 5430, 52, 168,
- 210, 168, 160, 44, 125, 60, 31, 58, 132, 170,
- 214, 217, 229, 59, 170, 222, 237, 243, 250, 5418,
- 255, 5410, 5380, 300, 7856, 0, 7856, 316, 339, 363,
- 5413, 387, 0, 394, 0, 428, 7856, 7856, 7856, 7856,
- 7856, 296, 316, 0, 5386, 5383, 5397, 0, 5395, 5383,
- 5396, 5378, 5366, 5360, 5361, 5362, 5360, 5344, 5352, 5337,
- 5350, 5331, 116, 5341, 5312, 5297, 5295, 5299, 5305, 5294,
- 5299, 5279, 5278, 56, 68, 5263, 5261, 80, 5265, 5259,
-
- 5267, 68, 166, 0, 0, 15, 122, 5255, 5264, 189,
- 5238, 5236, 5219, 5222, 5212, 5219, 5209, 5208, 5214, 0,
- 5212, 0, 5195, 5181, 5175, 5176, 5175, 5174, 128, 5185,
- 5168, 5167, 5160, 159, 5147, 201, 5144, 38, 5137, 5149,
- 0, 5133, 0, 5112, 5111, 5094, 5090, 5078, 5048, 5062,
- 7856, 7856, 453, 477, 236, 518, 542, 566, 5071, 573,
- 5078, 597, 248, 5054, 5029, 5034, 5025, 0, 0, 5030,
- 0, 5038, 5033, 5022, 5006, 5007, 5004, 5005, 5012, 0,
- 0, 5006, 4996, 0, 5008, 4988, 4976, 4990, 4989, 4992,
- 4988, 4972, 4971, 4953, 4969, 4952, 4956, 4951, 4952, 4965,
-
- 4950, 4934, 0, 4939, 4933, 0, 0, 4937, 4927, 0,
- 4938, 0, 4935, 4907, 4912, 0, 0, 4901, 0, 4909,
- 4917, 244, 4899, 0, 4887, 4882, 0, 4877, 0, 4880,
- 0, 4861, 4864, 4857, 4845, 4850, 4843, 4839, 0, 4837,
- 4849, 0, 4838, 0, 4837, 0, 0, 0, 4819, 0,
- 153, 156, 4830, 0, 0, 4821, 0, 4818, 4818, 637,
- 4847, 660, 684, 4830, 691, 500, 281, 715, 4821, 739,
- 4820, 4819, 747, 290, 4818, 4816, 507, 788, 811, 4815,
- 0, 0, 4775, 350, 4778, 4783, 0, 0, 0, 4781,
- 0, 4777, 4762, 4746, 0, 4746, 0, 4740, 4739, 4740,
-
- 0, 4722, 4721, 0, 0, 0, 0, 0, 614, 4728,
- 0, 0, 4736, 4715, 4700, 0, 0, 4698, 0, 0,
- 0, 0, 4713, 4704, 4710, 0, 4703, 4706, 4707, 4679,
- 4675, 4667, 4639, 0, 4632, 0, 4607, 0, 275, 0,
- 0, 4599, 4592, 817, 4585, 0, 0, 0, 856, 880,
- 293, 921, 4610, 4608, 405, 944, 968, 992, 4598, 999,
- 621, 4581, 4579, 1022, 770, 1046, 1069, 4562, 0, 4553,
- 427, 428, 1093, 4552, 1117, 333, 4551, 4550, 4519, 0,
- 0, 0, 0, 4491, 0, 4504, 4502, 4469, 4460, 0,
- 4477, 4472, 4463, 0, 0, 1136, 293, 4453, 4420, 4437,
-
- 0, 4427, 0, 4429, 4422, 0, 0, 4420, 4394, 292,
- 4393, 4411, 387, 4408, 0, 4390, 4382, 4394, 4368, 4362,
- 4372, 4350, 4357, 4338, 4317, 4318, 4310, 4278, 4292, 1173,
- 4310, 1196, 1220, 4305, 1227, 777, 285, 1251, 334, 1291,
- 1314, 1338, 4294, 4293, 1346, 336, 4291, 4256, 4255, 4254,
- 1387, 363, 4252, 4251, 515, 631, 1428, 4250, 1452, 364,
- 4240, 4247, 4218, 840, 0, 371, 4214, 903, 1493, 1516,
- 4212, 0, 0, 4184, 4200, 4149, 0, 4158, 4140, 0,
- 4145, 4158, 4143, 4126, 4125, 380, 4109, 427, 4108, 1121,
- 4106, 4095, 4082, 4067, 4076, 0, 4066, 4077, 4025, 4028,
-
- 4026, 4015, 4014, 0, 0, 4018, 0, 3981, 3973, 3986,
- 3984, 3976, 3949, 3960, 3929, 3923, 3918, 3909, 3888, 3885,
- 1541, 1565, 423, 1606, 3892, 3888, 633, 1630, 1654, 1661,
- 1685, 3877, 1692, 1716, 1739, 3876, 3857, 3856, 1762, 910,
- 1786, 1809, 3852, 0, 1274, 0, 461, 3837, 1281, 1833,
- 1856, 3833, 0, 785, 824, 3820, 485, 853, 856, 1880,
- 3810, 1904, 424, 3809, 3798, 529, 3762, 3765, 3739, 0,
- 0, 3742, 3729, 3715, 3691, 3703, 3683, 3666, 3672, 3664,
- 3643, 3632, 3633, 3619, 3601, 56, 504, 646, 3609, 3575,
- 3584, 3582, 0, 3573, 3567, 0, 0, 0, 3580, 3552,
-
- 3533, 3519, 0, 0, 0, 0, 0, 3523, 0, 0,
- 0, 3512, 1944, 3547, 1967, 1991, 3514, 1998, 325, 2022,
- 2046, 2053, 2077, 3505, 3474, 2085, 452, 3434, 2126, 476,
- 3393, 3386, 3385, 3365, 2167, 513, 3345, 918, 938, 2208,
- 3344, 2232, 542, 3343, 3348, 1142, 1149, 3347, 3314, 1167,
- 1169, 2273, 3305, 2297, 543, 3304, 3310, 1369, 0, 1376,
- 0, 486, 3282, 1410, 2338, 2361, 3278, 0, 2384, 374,
- 115, 389, 150, 672, 205, 610, 3235, 550, 403, 313,
- 783, 553, 761, 522, 800, 451, 578, 893, 633, 829,
- 571, 1108, 1112, 3231, 3228, 1123, 3206, 3189, 1130, 1128,
-
- 593, 3186, 3185, 2422, 2459, 2495, 2531, 634, 2555, 258,
- 2563, 2587, 3194, 2594, 2618, 2641, 3193, 2665, 2688, 3191,
- 3188, 3185, 2711, 1417, 2735, 2758, 3184, 0, 1475, 0,
- 723, 3172, 1482, 2782, 2805, 3147, 0, 1588, 0, 1595,
- 0, 724, 3146, 1927, 2829, 2852, 3135, 0, 661, 1934,
- 3122, 1290, 1425, 3114, 3111, 1490, 1510, 2876, 3101, 2900,
- 662, 3090, 3061, 636, 803, 653, 1290, 1427, 1492, 2095,
- 1604, 708, 849, 937, 2122, 872, 1605, 1944, 804, 1187,
- 1242, 2099, 936, 960, 1532, 2101, 874, 938, 1015, 962,
- 1014, 2124, 2163, 2942, 1016, 2965, 1038, 2988, 2154, 3012,
-
- 3036, 3052, 3051, 3044, 686, 3049, 3085, 967, 3047, 3126,
- 969, 3046, 3045, 3020, 3017, 3167, 970, 2967, 1541, 1733,
- 3208, 2966, 3232, 1022, 2947, 2953, 2096, 2163, 2951, 2950,
- 2164, 2182, 3273, 2909, 3297, 1042, 2908, 2915, 1043, 2255,
- 2913, 2183, 2184, 2911, 2892, 2205, 2249, 3338, 2882, 3362,
- 1045, 2881, 2886, 0, 2263, 0, 2320, 0, 756, 2857,
- 2327, 3403, 3426, 2853, 0, 1061, 1062, 1087, 1111, 2337,
- 1188, 1943, 1189, 1244, 2376, 1534, 2377, 2336, 1109, 1243,
- 2402, 2013, 1306, 2096, 2378, 1446, 2375, 1245, 3451, 3474,
- 3498, 1066, 3538, 3562, 3586, 2834, 3593, 3617, 3640, 2830,
-
- 3664, 3687, 2811, 3711, 3734, 2810, 2806, 2791, 3757, 2445,
- 3781, 3804, 2789, 0, 2482, 0, 1008, 2787, 2502, 3828,
- 3851, 2744, 0, 2509, 0, 2516, 0, 1153, 2741, 2523,
- 3875, 3898, 2740, 0, 0, 2923, 0, 2930, 0, 1300,
- 2718, 3067, 3922, 3945, 2717, 0, 0, 1198, 3074, 2724,
- 2399, 2417, 2721, 2701, 2453, 2454, 3969, 2670, 3993, 1285,
- 2649, 2655, 2401, 2438, 3083, 2398, 1558, 2457, 2940, 1708,
- 3084, 1557, 1385, 1709, 1508, 1754, 1710, 1755, 1778, 3120,
- 1779, 3118, 1801, 1803, 1825, 4035, 4059, 4068, 1826, 2646,
- 2643, 4086, 1287, 2624, 4127, 1288, 2600, 4168, 1315, 2599,
-
- 4209, 1345, 2597, 2596, 2595, 4249, 4273, 1427, 2594, 2635,
- 2682, 4314, 2572, 4338, 1429, 2571, 2578, 2938, 2942, 2577,
- 2576, 3096, 3142, 4379, 2566, 4403, 1489, 2540, 2544, 1600,
- 3156, 2542, 3151, 3164, 2541, 2540, 3183, 3184, 4444, 2531,
- 4468, 1603, 2468, 2469, 0, 1605, 3255, 2438, 3203, 3205,
- 2372, 2371, 3249, 3268, 4509, 2343, 4533, 1606, 2341, 2348,
- 0, 3320, 0, 3327, 0, 1396, 2306, 3385, 4574, 4597,
- 2299, 0, 3095, 3096, 3178, 1827, 3122, 2399, 1848, 3420,
- 2959, 1849, 1850, 1872, 3248, 3380, 1874, 1896, 3490, 2014,
- 3492, 1959, 2016, 3337, 4622, 4646, 4655, 2275, 4672, 4696,
-
- 4719, 2263, 4743, 4766, 2239, 4790, 4813, 2234, 4837, 4860,
- 2198, 2194, 4884, 1630, 2192, 2145, 3523, 4925, 2144, 2107,
- 0, 3530, 0, 1615, 2106, 4016, 4949, 2103, 2060, 0,
- 4023, 0, 4075, 0, 1639, 2059, 4109, 4973, 2058, 2055,
- 0, 0, 4116, 0, 4150, 0, 1669, 2000, 4157, 4997,
- 1999, 1976, 0, 0, 4191, 0, 4198, 0, 1748, 1951,
- 4232, 5021, 1945, 1913, 0, 0, 1660, 4239, 1917, 3335,
- 3399, 1914, 1897, 3400, 3420, 5045, 1882, 5069, 1661, 1842,
- 1846, 2102, 2177, 2200, 2289, 2103, 2612, 4283, 2226, 2473,
- 4266, 2680, 4348, 4267, 4331, 3249, 3271, 4289, 4332, 3399,
-
- 2610, 2611, 4396, 5111, 1815, 5128, 5152, 1662, 1814, 5193,
- 1689, 1811, 5234, 1736, 1795, 5275, 1879, 1791, 5316, 1880,
- 1747, 1744, 4365, 5357, 1741, 1698, 0, 1697, 3634, 3681,
- 5381, 1670, 1664, 1671, 3728, 4289, 1616, 1580, 4374, 4418,
- 5405, 1568, 1565, 1552, 1938, 4432, 1527, 4441, 4478, 1508,
- 1506, 4479, 4483, 5429, 1494, 1454, 1442, 0, 1940, 4497,
- 1438, 4506, 4543, 1437, 1400, 4544, 4548, 5453, 1390, 1389,
- 1363, 0, 1941, 4562, 1362, 4571, 4591, 83, 110, 4666,
- 4667, 5477, 195, 198, 225, 0, 4907, 0, 4914, 0,
- 2006, 307, 5092, 5501, 0, 348, 0, 2474, 2635, 2657,
-
- 2659, 2681, 3003, 5107, 5162, 4670, 2703, 4291, 4356, 2682,
- 4376, 4923, 4443, 2728, 2729, 5108, 5163, 5525, 1943, 0,
- 372, 5566, 0, 399, 5590, 0, 418, 5614, 0, 480,
- 5638, 0, 520, 5662, 0, 544, 4671, 4713, 5686, 551,
- 580, 582, 610, 604, 5180, 0, 2061, 624, 643, 5216,
- 0, 5223, 0, 2062, 696, 697, 0, 5257, 0, 5264,
- 0, 2109, 698, 720, 0, 5298, 0, 5305, 0, 2142,
- 721, 749, 0, 5339, 0, 5346, 0, 2193, 750, 752,
- 0, 1995, 5548, 762, 4760, 4807, 763, 798, 4854, 5086,
- 5710, 793, 0, 804, 4508, 2751, 2752, 2774, 2775, 5146,
-
- 2776, 2799, 2822, 2823, 5720, 2845, 5703, 5722, 2846, 3270,
- 3489, 5755, 820, 864, 0, 0, 0, 0, 0, 0,
- 5555, 0, 2282, 880, 887, 0, 5127, 5354, 897, 930,
- 0, 1997, 5739, 931, 5563, 5724, 934, 976, 0, 0,
- 2024, 5778, 985, 5752, 5772, 1012, 1039, 0, 0, 2151,
- 5792, 1063, 5787, 5788, 1102, 1103, 0, 0, 2181, 5802,
- 1107, 5800, 5810, 1132, 1160, 0, 0, 5814, 0, 5828,
- 0, 2347, 1176, 0, 5085, 3553, 2868, 2870, 3103, 5824,
- 5827, 5837, 5838, 5839, 5826, 3379, 5843, 2892, 4573, 5736,
- 2981, 0, 7856, 0, 0, 0, 0, 0, 0, 5845,
-
- 5847, 1190, 1235, 0, 7856, 5871, 0, 7856, 0, 5887,
- 0, 7856, 0, 5894, 0, 7856, 0, 5901, 0, 7856,
- 0, 5908, 0, 7856, 0, 2270, 5915, 1236, 5923, 5924,
- 1237, 2414, 0, 2980, 5086, 2982, 3004, 5926, 5356, 5565,
- 3201, 5849, 4287, 3005, 5927, 5106, 5850, 3006, 5928, 0,
- 5927, 0, 2272, 5954, 1240, 0, 2273, 5964, 1264, 0,
- 2338, 5971, 1306, 0, 2396, 5978, 1322, 0, 2531, 5985,
- 1356, 0, 5992, 0, 7856, 3177, 6001, 3442, 3444, 3467,
- 6002, 6004, 6005, 6008, 3491, 6006, 3378, 6007, 2532, 6007,
- 1357, 0, 0, 0, 0, 0, 0, 2533, 6043, 1361,
-
- 6016, 6037, 5852, 6039, 3554, 6040, 3555, 3556, 6017, 6052,
- 6056, 3419, 0, 0, 0, 0, 0, 0, 0, 3466,
- 6059, 3611, 3658, 3705, 6060, 6062, 6063, 3468, 6065, 6066,
- 0, 0, 3609, 3610, 3634, 3656, 6067, 3680, 6068, 3681,
- 6073, 6082, 6092, 6095, 3727, 6101, 3728, 6103, 3749, 5102,
- 3773, 3774, 3797, 6106, 6111, 6115, 3775, 6116, 6122, 3820,
- 6123, 6126, 6128, 3822, 6114, 6142, 6148, 3844, 3845, 6152,
- 6153, 6154, 6155, 3869, 3890, 6158, 3891, 6162, 3914, 6163,
- 6167, 3915, 3916, 3938, 6169, 6177, 4737, 6191, 3939, 6182,
- 6194, 6197, 6198, 3961, 6204, 6203, 6205, 3963, 6206, 3985,
-
- 4084, 6213, 3987, 6218, 6227, 4125, 4613, 6219, 4308, 4032,
- 6228, 4033, 4615, 4085, 6238, 6229, 6240, 4784, 4166, 6239,
- 4207, 6241, 6268, 4208, 4665, 4666, 4669, 7856, 6296, 6304,
- 6308, 6311, 6314, 6317, 6320, 6323, 6326, 6329, 6332, 6335,
- 6338, 6341, 6344, 6347, 6350, 6353, 6356, 6360, 6364, 6367,
- 6370, 6373, 6376, 6379, 6382, 6385, 6388, 6392, 6396, 6399,
- 6402, 6406, 6408, 6411, 6414, 6417, 6420, 6423, 6426, 6429,
- 6432, 6436, 6438, 6441, 6445, 6450, 6454, 6457, 6461, 6464,
- 6467, 6470, 6473, 6476, 6479, 6482, 6486, 6490, 6493, 6497,
- 6501, 6506, 6510, 6512, 6516, 6519, 6523, 6526, 6529, 6533,
-
- 6535, 6538, 6541, 6544, 6547, 6550, 6553, 6556, 6559, 6562,
- 6566, 6568, 6571, 6574, 6577, 6581, 6583, 6586, 6589, 6594,
- 6598, 6603, 6607, 6609, 6613, 6616, 6620, 6625, 6629, 6632,
- 6635, 6638, 6641, 6644, 6647, 6650, 6654, 6658, 6661, 6665,
- 6669, 6674, 6678, 6680, 6684, 6687, 6691, 6694, 6699, 6703,
- 6708, 6712, 6714, 6718, 6721, 6725, 6728, 6731, 6734, 6738,
- 6740, 6743, 6748, 6752, 6755, 6758, 6761, 6764, 6767, 6770,
- 6773, 6776, 6780, 6782, 6785, 6788, 6791, 6795, 6797, 6800,
- 6803, 6806, 6809, 6813, 6815, 6818, 6821, 6824, 6829, 6833,
- 6838, 6842, 6844, 6848, 6851, 6855, 6860, 6864, 6867, 6870,
-
- 6873, 6876, 6879, 6882, 6885, 6889, 6893, 6896, 6900, 6904,
- 6909, 6913, 6915, 6919, 6922, 6926, 6929, 6934, 6938, 6943,
- 6947, 6949, 6953, 6956, 6960, 6963, 6966, 6971, 6975, 6980,
- 6984, 6986, 6990, 6993, 6997, 7000, 7003, 7006, 7010, 7012,
- 7015, 7020, 7024, 7027, 7030, 7033, 7036, 7039, 7042, 7045,
- 7048, 7051, 7054, 7057, 7061, 7063, 7066, 7069, 7072, 7075,
- 7079, 7081, 7084, 7087, 7090, 7093, 7096, 7100, 7102, 7105,
- 7108, 7111, 7114, 7117, 7121, 7123, 7126, 7129, 7132, 7135,
- 7140, 7144, 7149, 7153, 7155, 7159, 7162, 7166, 7171, 7175,
- 7178, 7181, 7184, 7187, 7190, 7193, 7196, 7199, 7202, 7206,
-
- 7210, 7213, 7217, 7221, 7226, 7230, 7232, 7236, 7239, 7243,
- 7246, 7251, 7255, 7260, 7264, 7266, 7270, 7273, 7277, 7280,
- 7283, 7288, 7292, 7297, 7301, 7303, 7307, 7310, 7314, 7317,
- 7320, 7325, 7329, 7334, 7338, 7340, 7344, 7347, 7351, 7354,
- 7357, 7360, 7364, 7366, 7369, 7372, 7377, 7381, 7384, 7387,
- 7390, 7393, 7396, 7399, 7402, 7405, 7408, 7411, 7414, 7418,
- 7422, 7425, 7428, 7432, 7435, 7438, 7442, 7444, 7447, 7450,
- 7454, 7456, 7459, 7462, 7465, 7469, 7471, 7474, 7477, 7480,
- 7484, 7486, 7489, 7492, 7495, 7499, 7501, 7504, 7507, 7512,
- 7516, 7521, 7525, 7527, 7531, 7534, 7538, 7543, 7547, 7550,
-
- 7553, 7556, 7559, 7562, 7565, 7568, 7571, 7575, 7577, 7580,
- 7584, 7589, 7593, 7594, 7597, 7602, 7606, 7611, 7615, 7616,
- 7619, 7622, 7627, 7631, 7636, 7640, 7641, 7644, 7647, 7652,
- 7656, 7661, 7665, 7666, 7669, 7672, 7677, 7681, 7686, 7690,
- 7691, 7694, 7697, 7700, 7704, 7706, 7711, 7715, 7718, 7721,
- 7724, 7727, 7730, 7733, 7737, 7742, 7746, 7747, 7750, 7753,
- 7756, 7759, 7762, 7765, 7768, 7771, 7774, 7777, 7782, 7786,
- 7789, 7792, 7795, 7799, 7803, 7807, 7811, 7815, 7818, 7821,
- 7825, 7828, 7831, 7834, 7837, 7840, 7844, 7847
+ 0, 0, 6066, 7626, 7626, 7626, 6044, 0, 7626, 6056,
+ 43, 70, 6044, 43, 6040, 75, 110, 151, 0, 70,
+ 85, 102, 67, 61, 77, 105, 113, 155, 158, 170,
+ 70, 176, 165, 110, 189, 148, 6025, 184, 6016, 6001,
+ 7626, 0, 7626, 225, 247, 270, 6030, 293, 0, 300,
+ 0, 322, 7626, 7626, 7626, 7626, 7626, 344, 0, 6003,
+ 6000, 6013, 0, 6008, 5996, 6007, 6001, 5986, 5960, 5946,
+ 5947, 5946, 5939, 5948, 5923, 5926, 5906, 284, 5907, 5907,
+ 5875, 5868, 5857, 5849, 5816, 5811, 5801, 5794, 89, 81,
+ 5765, 5752, 109, 5704, 5698, 5705, 123, 211, 0, 0,
+
+ 99, 168, 5686, 5695, 204, 5676, 5656, 5659, 5635, 5624,
+ 5610, 5600, 5591, 5597, 0, 5584, 0, 5567, 5573, 5567,
+ 5568, 5567, 5567, 200, 5549, 5532, 5543, 5536, 131, 5532,
+ 327, 5519, 194, 5518, 5530, 0, 5513, 0, 5510, 5509,
+ 5514, 5488, 5479, 5467, 5482, 7626, 7626, 363, 386, 180,
+ 426, 449, 472, 5475, 479, 5482, 502, 241, 5472, 5446,
+ 5430, 5421, 0, 0, 5426, 0, 5435, 5430, 5419, 5413,
+ 5414, 5374, 5375, 5382, 0, 0, 5377, 5366, 0, 5378,
+ 5373, 5346, 5360, 5359, 5362, 5358, 5342, 5325, 5321, 5337,
+ 5319, 5304, 5299, 5300, 5294, 5277, 5257, 0, 5262, 5254,
+
+ 0, 0, 5258, 5216, 0, 5226, 0, 5222, 5191, 5196,
+ 0, 0, 5166, 0, 5175, 5182, 201, 5163, 0, 5146,
+ 5161, 0, 5156, 0, 5138, 0, 5120, 5123, 5116, 5101,
+ 5085, 5076, 5053, 0, 5051, 5062, 0, 5051, 0, 5018,
+ 0, 0, 0, 5013, 0, 223, 240, 5023, 0, 0,
+ 5014, 0, 5011, 5001, 541, 5010, 563, 586, 5006, 593,
+ 352, 260, 616, 4996, 639, 4995, 4994, 647, 271, 4982,
+ 4961, 408, 687, 709, 4960, 0, 0, 4936, 374, 4937,
+ 4930, 0, 0, 0, 4927, 0, 4924, 4925, 4908, 0,
+ 4908, 0, 4900, 4900, 4901, 0, 4886, 4853, 0, 0,
+
+ 0, 0, 0, 519, 4858, 0, 0, 4865, 4847, 4830,
+ 0, 0, 4825, 0, 0, 0, 0, 4825, 4789, 4790,
+ 0, 4783, 4765, 4780, 4751, 4727, 4737, 4726, 0, 4708,
+ 0, 4707, 0, 250, 0, 0, 4699, 4693, 715, 4688,
+ 0, 0, 0, 753, 776, 272, 816, 4714, 4712, 360,
+ 838, 861, 884, 4702, 891, 415, 4683, 4681, 913, 526,
+ 936, 958, 4661, 0, 4660, 423, 511, 981, 4658, 1004,
+ 294, 4657, 4664, 4602, 0, 0, 0, 0, 4596, 0,
+ 4609, 4586, 4548, 4528, 0, 4543, 4537, 4517, 0, 0,
+ 1023, 516, 4506, 4494, 4497, 0, 4487, 0, 4491, 4483,
+
+ 0, 0, 4492, 4457, 515, 4455, 4456, 73, 4451, 0,
+ 4439, 4431, 4407, 4381, 4373, 4360, 4340, 4356, 4349, 4320,
+ 4320, 4311, 4299, 4314, 1059, 4328, 1081, 1104, 4313, 1111,
+ 669, 313, 1134, 324, 1173, 1195, 1218, 4295, 4286, 1226,
+ 357, 4257, 4198, 4197, 4194, 1266, 358, 4193, 4160, 663,
+ 683, 1306, 4159, 1329, 420, 4155, 4161, 4135, 737, 0,
+ 394, 4134, 798, 1369, 1391, 4131, 0, 0, 4104, 4088,
+ 4065, 0, 4055, 4039, 0, 4043, 4056, 4009, 4022, 4020,
+ 703, 4005, 728, 3990, 1008, 3987, 3974, 3993, 3981, 3960,
+ 0, 3948, 3958, 3949, 3954, 3942, 3911, 3908, 0, 0,
+
+ 3911, 0, 3906, 3898, 3900, 3879, 3869, 3860, 3860, 3850,
+ 3807, 3804, 3806, 3787, 3786, 1415, 1438, 421, 1478, 3779,
+ 3765, 684, 1501, 1524, 1531, 1554, 3739, 1561, 1584, 1606,
+ 3737, 3734, 3689, 1628, 805, 1651, 1673, 3668, 0, 1156,
+ 0, 571, 3646, 1163, 1696, 1718, 3644, 0, 747, 750,
+ 3651, 601, 813, 832, 1741, 3625, 1764, 425, 3624, 3631,
+ 490, 3594, 3581, 3577, 0, 0, 3563, 3565, 3533, 3532,
+ 3544, 3526, 3506, 3494, 3485, 3484, 3476, 3476, 3463, 3448,
+ 227, 998, 1009, 3455, 3441, 3429, 3411, 0, 3398, 3371,
+ 0, 0, 0, 3384, 3362, 3367, 3353, 0, 0, 0,
+
+ 0, 0, 3357, 0, 0, 0, 3346, 1803, 3358, 1825,
+ 1848, 3356, 1855, 330, 1878, 1901, 1908, 1931, 3347, 3346,
+ 1939, 426, 3343, 1979, 449, 3342, 3324, 3323, 3321, 2019,
+ 498, 3320, 1031, 1035, 2059, 3319, 2082, 538, 3318, 3295,
+ 1053, 1055, 3294, 3290, 1172, 1236, 2122, 3262, 2145, 564,
+ 3261, 3267, 1250, 0, 1257, 0, 624, 3237, 1288, 2185,
+ 2207, 3236, 0, 2229, 301, 407, 302, 246, 1012, 522,
+ 700, 3191, 539, 19, 538, 661, 569, 790, 650, 682,
+ 406, 757, 1015, 834, 887, 454, 999, 1054, 3189, 3188,
+ 1168, 3186, 3184, 1214, 1017, 571, 3166, 3164, 2266, 2289,
+
+ 2311, 2346, 617, 2369, 625, 2377, 2400, 3178, 2407, 2430,
+ 2452, 3168, 2475, 2497, 3167, 3163, 3133, 2519, 1295, 2542,
+ 2564, 3130, 0, 1351, 0, 1119, 3105, 1358, 2587, 2609,
+ 3104, 0, 1460, 0, 1467, 0, 1142, 3103, 1786, 2632,
+ 2654, 3093, 0, 706, 1793, 3078, 1303, 1366, 3075, 3071,
+ 1385, 1415, 2677, 3052, 2700, 752, 3042, 3048, 518, 854,
+ 663, 1172, 1305, 1368, 1949, 1476, 907, 832, 930, 1974,
+ 702, 1477, 1803, 951, 1950, 1951, 1953, 974, 953, 1990,
+ 1993, 769, 831, 952, 997, 1074, 2013, 2018, 2741, 1127,
+ 2763, 1407, 2785, 2046, 2808, 2831, 3037, 3005, 2839, 810,
+
+ 3004, 2879, 860, 3001, 2919, 861, 2986, 2985, 2983, 2964,
+ 2959, 862, 2961, 1600, 2016, 2999, 2960, 3022, 888, 2927,
+ 2932, 2054, 2056, 2930, 2929, 2092, 2097, 3062, 2920, 3085,
+ 978, 2908, 2895, 1058, 2111, 2892, 2119, 2155, 2890, 2889,
+ 2156, 2160, 3125, 2880, 3148, 1081, 2868, 2855, 0, 2174,
+ 0, 2251, 0, 1486, 2846, 2318, 3188, 3210, 2844, 0,
+ 1188, 1323, 1432, 1577, 2184, 1578, 1802, 1621, 1622, 2243,
+ 1645, 2244, 2058, 1666, 1689, 2155, 2329, 1870, 2710, 2246,
+ 1668, 2202, 1384, 3234, 3256, 3279, 1082, 3318, 3341, 3364,
+ 2842, 3371, 3394, 3416, 2841, 3439, 3461, 2840, 3484, 3506,
+
+ 2815, 2813, 2811, 3528, 2328, 3551, 3573, 2810, 0, 2335,
+ 0, 1539, 2790, 2726, 3596, 3618, 2786, 0, 2861, 0,
+ 2868, 0, 1863, 2766, 2901, 3641, 3663, 2728, 0, 0,
+ 2908, 0, 2941, 0, 1916, 2708, 2948, 3686, 3708, 2707,
+ 0, 0, 1108, 2981, 2713, 2263, 2266, 2692, 2691, 2446,
+ 2491, 3731, 2682, 3754, 1110, 2680, 2686, 2245, 2328, 2958,
+ 2327, 1712, 2738, 2976, 1711, 2998, 2725, 1734, 1758, 1757,
+ 2777, 1818, 1955, 1431, 2694, 1871, 3016, 1956, 1995, 2121,
+ 3795, 3818, 3827, 2222, 2660, 2659, 3844, 1167, 2655, 3884,
+ 1169, 2637, 3924, 1170, 2635, 3964, 1301, 2616, 2614, 2592,
+
+ 4003, 4026, 1306, 2572, 2711, 2738, 4066, 2570, 4089, 1365,
+ 2569, 2558, 2956, 2996, 2555, 2553, 3033, 3037, 4129, 2527,
+ 4152, 1412, 2525, 2513, 1475, 3051, 2510, 3059, 3095, 2508,
+ 2488, 3096, 3100, 4192, 2478, 4215, 1477, 2460, 2465, 0,
+ 1501, 3114, 2463, 3122, 3158, 2462, 2441, 3159, 3163, 4255,
+ 2413, 4278, 1503, 2412, 2418, 0, 3177, 0, 3301, 0,
+ 1962, 2409, 3308, 4318, 4340, 2408, 0, 3158, 3764, 3765,
+ 2223, 3078, 3317, 2283, 3204, 2735, 2423, 2424, 2224, 3768,
+ 3318, 2445, 2282, 3837, 2490, 3839, 2468, 2513, 3771, 4364,
+ 4387, 4396, 2384, 4412, 4435, 4457, 2383, 4480, 4502, 2380,
+
+ 4525, 4547, 2349, 4570, 4592, 2348, 2347, 4615, 1530, 2296,
+ 2289, 3869, 4655, 2212, 2209, 0, 3906, 0, 1995, 2208,
+ 3913, 4678, 2188, 2164, 0, 3946, 0, 3953, 0, 2005,
+ 2160, 3986, 4701, 2153, 2130, 0, 0, 3993, 0, 4048,
+ 0, 2035, 2101, 4055, 4724, 2100, 2097, 0, 0, 4111,
+ 0, 4118, 0, 2385, 2067, 4174, 4747, 2064, 2037, 0,
+ 0, 1531, 4181, 2014, 3204, 3410, 2010, 2008, 3455, 3500,
+ 4770, 1996, 4793, 1532, 1960, 1964, 2512, 2535, 2557, 2580,
+ 2558, 2604, 4225, 2602, 2603, 4209, 2800, 4288, 3838, 4272,
+ 3861, 4002, 4065, 4608, 3843, 2626, 2648, 4609, 4834, 1955,
+
+ 4850, 4873, 1558, 1915, 4913, 1602, 1914, 4953, 1648, 1913,
+ 4993, 1695, 1911, 5033, 1715, 1910, 1909, 4241, 5073, 1880,
+ 1806, 0, 1804, 3769, 4002, 5096, 1767, 1747, 1707, 4063,
+ 4126, 1706, 1686, 4189, 4250, 5119, 1658, 1652, 1622, 1738,
+ 4304, 1619, 4314, 4334, 1617, 1615, 4406, 4407, 5142, 1587,
+ 1567, 1574, 0, 1797, 4639, 1541, 4409, 4411, 1511, 1510,
+ 4451, 4496, 5165, 1480, 1479, 1446, 0, 1799, 4646, 121,
+ 4541, 4803, 145, 164, 4804, 4806, 5188, 168, 308, 373,
+ 0, 4820, 0, 4895, 0, 3038, 393, 4902, 5211, 0,
+ 450, 0, 2649, 2671, 2757, 2779, 2801, 4803, 4830, 4912,
+
+ 4128, 3124, 4191, 4317, 3226, 4831, 4930, 4411, 2780, 3250,
+ 4832, 4924, 5234, 1802, 0, 505, 5274, 0, 532, 5297,
+ 0, 548, 5320, 0, 568, 5343, 0, 600, 5366, 0,
+ 618, 4849, 4910, 5389, 619, 621, 622, 657, 650, 4975,
+ 0, 3264, 672, 673, 4982, 0, 5015, 0, 3379, 692,
+ 755, 0, 5022, 0, 5055, 0, 3777, 759, 761, 0,
+ 5062, 0, 5256, 0, 3778, 779, 818, 0, 5263, 0,
+ 5411, 0, 3782, 821, 864, 0, 1826, 5418, 904, 5070,
+ 5271, 905, 924, 5426, 5427, 5467, 918, 0, 945, 5072,
+ 3410, 3455, 3249, 3272, 5429, 2878, 3387, 3432, 3454, 5430,
+
+ 3499, 5431, 5432, 3409, 4313, 5433, 5490, 939, 983, 0,
+ 0, 0, 0, 0, 0, 5432, 0, 4230, 986, 987,
+ 0, 5442, 5462, 1014, 1015, 0, 1850, 5512, 1046, 5464,
+ 5506, 1068, 1091, 0, 0, 1852, 5520, 1125, 5528, 5529,
+ 1144, 1145, 0, 0, 1854, 5529, 1182, 5537, 5538, 1210,
+ 1237, 0, 0, 1993, 5552, 1239, 5546, 5547, 1241, 1242,
+ 0, 0, 5568, 0, 5577, 0, 4231, 1268, 0, 4927,
+ 5588, 5590, 2918, 3500, 5589, 5592, 5593, 5594, 5595, 5591,
+ 3545, 5596, 3567, 5273, 5599, 3522, 0, 7626, 0, 0,
+ 0, 0, 0, 0, 5622, 5624, 1277, 1279, 0, 7626,
+
+ 5627, 0, 7626, 0, 5638, 0, 7626, 0, 5645, 0,
+ 7626, 0, 5652, 0, 7626, 0, 5663, 0, 7626, 0,
+ 2030, 5670, 1281, 5678, 5679, 1282, 4293, 0, 3544, 5681,
+ 3589, 3590, 5682, 5685, 5686, 3611, 5687, 5688, 3613, 5683,
+ 5690, 5695, 3656, 5684, 0, 5730, 0, 2059, 5737, 1316,
+ 0, 2093, 5744, 1319, 0, 2096, 5751, 1378, 0, 2159,
+ 5758, 1382, 0, 2347, 5765, 1402, 0, 5772, 0, 7626,
+ 3657, 5689, 3658, 3680, 3702, 5781, 5783, 5784, 5696, 3703,
+ 5785, 3679, 5786, 2348, 5785, 1425, 0, 0, 0, 0,
+ 0, 0, 2376, 5802, 1428, 5795, 5797, 5697, 5796, 3724,
+
+ 5815, 3725, 4083, 5817, 5818, 5821, 3701, 0, 0, 0,
+ 0, 0, 0, 0, 3790, 5824, 4254, 4563, 5825, 5826,
+ 5828, 5830, 3841, 5833, 5840, 0, 0, 3881, 4356, 4450,
+ 4473, 5839, 4496, 5849, 3883, 5855, 5859, 5861, 5862, 4250,
+ 5873, 4406, 5851, 4540, 5874, 4585, 4541, 4586, 5877, 5875,
+ 5881, 5880, 5899, 5883, 4671, 5886, 5905, 5906, 3923, 5908,
+ 5909, 5912, 4672, 4695, 5919, 5930, 5920, 5931, 4718, 4741,
+ 5933, 3963, 5935, 4763, 5934, 5938, 4764, 4252, 5090, 5943,
+ 5953, 5956, 5961, 5112, 5958, 5962, 5967, 5971, 4587, 5981,
+ 5982, 5983, 5113, 5987, 4866, 5136, 5990, 4992, 5991, 5995,
+
+ 5158, 5159, 6001, 5205, 5032, 6002, 5204, 5228, 5227, 6005,
+ 6006, 6015, 6009, 5291, 6014, 5313, 6016, 6045, 5314, 5336,
+ 5337, 5359, 7626, 6068, 6075, 6079, 6082, 6085, 6088, 6091,
+ 6094, 6097, 6100, 6103, 6106, 6109, 6112, 6115, 6118, 6121,
+ 6124, 6127, 6131, 6135, 6138, 6141, 6144, 6147, 6150, 6153,
+ 6156, 6159, 6163, 6167, 6170, 6173, 6177, 6179, 6182, 6185,
+ 6188, 6191, 6194, 6197, 6200, 6203, 6207, 6209, 6212, 6216,
+ 6221, 6225, 6228, 6232, 6235, 6238, 6241, 6244, 6247, 6250,
+ 6253, 6257, 6261, 6264, 6268, 6272, 6277, 6281, 6283, 6287,
+ 6290, 6294, 6297, 6300, 6304, 6306, 6309, 6312, 6315, 6318,
+
+ 6321, 6324, 6327, 6330, 6333, 6337, 6339, 6342, 6345, 6348,
+ 6352, 6354, 6357, 6360, 6365, 6369, 6374, 6378, 6380, 6384,
+ 6387, 6391, 6396, 6400, 6403, 6406, 6409, 6412, 6415, 6418,
+ 6421, 6425, 6429, 6432, 6436, 6440, 6445, 6449, 6451, 6455,
+ 6458, 6462, 6465, 6470, 6474, 6479, 6483, 6485, 6489, 6492,
+ 6496, 6499, 6502, 6505, 6509, 6511, 6514, 6519, 6523, 6526,
+ 6529, 6532, 6535, 6538, 6541, 6544, 6547, 6551, 6553, 6556,
+ 6559, 6562, 6566, 6568, 6571, 6574, 6577, 6580, 6584, 6586,
+ 6589, 6592, 6595, 6600, 6604, 6609, 6613, 6615, 6619, 6622,
+ 6626, 6631, 6635, 6638, 6641, 6644, 6647, 6650, 6653, 6656,
+
+ 6660, 6664, 6667, 6671, 6675, 6680, 6684, 6686, 6690, 6693,
+ 6697, 6700, 6705, 6709, 6714, 6718, 6720, 6724, 6727, 6731,
+ 6734, 6737, 6742, 6746, 6751, 6755, 6757, 6761, 6764, 6768,
+ 6771, 6774, 6777, 6781, 6783, 6786, 6791, 6795, 6798, 6801,
+ 6804, 6807, 6810, 6813, 6816, 6819, 6822, 6825, 6828, 6832,
+ 6834, 6837, 6840, 6843, 6846, 6850, 6852, 6855, 6858, 6861,
+ 6864, 6867, 6871, 6873, 6876, 6879, 6882, 6885, 6888, 6892,
+ 6894, 6897, 6900, 6903, 6906, 6911, 6915, 6920, 6924, 6926,
+ 6930, 6933, 6937, 6942, 6946, 6949, 6952, 6955, 6958, 6961,
+ 6964, 6967, 6970, 6973, 6977, 6981, 6984, 6988, 6992, 6997,
+
+ 7001, 7003, 7007, 7010, 7014, 7017, 7022, 7026, 7031, 7035,
+ 7037, 7041, 7044, 7048, 7051, 7054, 7059, 7063, 7068, 7072,
+ 7074, 7078, 7081, 7085, 7088, 7091, 7096, 7100, 7105, 7109,
+ 7111, 7115, 7118, 7122, 7125, 7128, 7131, 7135, 7137, 7140,
+ 7143, 7148, 7152, 7155, 7158, 7161, 7164, 7167, 7170, 7173,
+ 7176, 7179, 7182, 7185, 7189, 7193, 7196, 7199, 7203, 7206,
+ 7209, 7213, 7215, 7218, 7221, 7225, 7227, 7230, 7233, 7236,
+ 7240, 7242, 7245, 7248, 7251, 7255, 7257, 7260, 7263, 7266,
+ 7270, 7272, 7275, 7278, 7283, 7287, 7292, 7296, 7298, 7302,
+ 7305, 7309, 7314, 7318, 7321, 7324, 7327, 7330, 7333, 7336,
+
+ 7339, 7342, 7346, 7348, 7351, 7355, 7360, 7364, 7365, 7368,
+ 7373, 7377, 7382, 7386, 7387, 7390, 7393, 7398, 7402, 7407,
+ 7411, 7412, 7415, 7418, 7423, 7427, 7432, 7436, 7437, 7440,
+ 7443, 7448, 7452, 7457, 7461, 7462, 7465, 7468, 7471, 7475,
+ 7477, 7482, 7486, 7489, 7492, 7495, 7498, 7501, 7504, 7508,
+ 7513, 7517, 7518, 7521, 7524, 7527, 7530, 7533, 7536, 7539,
+ 7542, 7545, 7548, 7553, 7557, 7560, 7563, 7566, 7570, 7574,
+ 7578, 7582, 7586, 7589, 7592, 7596, 7599, 7602, 7605, 7608,
+ 7611, 7615, 7618
} ;
-static yyconst flex_int16_t yy_def[2189] =
+static yyconst flex_int16_t yy_def[2184] =
{ 0,
- 1728, 1, 1728, 1728, 1728, 1728, 1728, 1728, 1729, 1728,
- 1728, 1728, 1728, 1728, 14, 1728, 1728, 1728, 1728, 14,
- 20, 1730, 20, 20, 20, 20, 20, 20, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 1728, 1728, 1728, 1731, 1728, 21, 21, 20,
- 1732, 50, 21, 21, 21, 1728, 1728, 1728, 1728, 1728,
- 1728, 49, 1730, 1730, 52, 52, 52, 21, 21, 21,
- 21, 52, 21, 21, 52, 21, 21, 21, 52, 21,
- 21, 21, 21, 21, 52, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 1728, 1728, 21, 21, 154, 21, 21, 157, 1733, 1728,
- 54, 1728, 162, 1734, 21, 21, 158, 21, 21, 21,
- 158, 21, 21, 21, 21, 21, 21, 158, 21, 21,
- 21, 21, 21, 21, 21, 158, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 262, 263, 158, 1735, 268,
- 1736, 1737, 1728, 273, 1738, 1739, 1728, 1728, 1728, 1740,
- 1741, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 350, 21, 263, 265, 263, 265, 265, 357, 1742, 1728,
- 356, 1743, 1744, 1728, 1728, 1728, 1728, 1745, 1746, 1747,
- 1748, 1748, 1728, 1749, 1728, 375, 1750, 1741, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 432, 433, 433, 438, 432,
- 357, 441, 1751, 1752, 1728, 445, 1753, 1728, 1754, 1755,
- 1728, 451, 1756, 1757, 1758, 1758, 1728, 1759, 1728, 459,
- 1760, 1746, 1728, 1728, 1761, 1762, 1728, 1728, 1728, 1728,
- 1763, 1764, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 522, 21, 433, 435, 433, 433, 528, 441,
- 530, 1765, 1728, 1728, 1728, 1766, 1767, 1768, 1728, 1728,
- 1728, 1728, 1769, 1770, 1728, 1771, 1772, 1728, 1728, 1728,
- 1728, 1773, 1774, 1775, 1775, 1761, 1762, 1776, 1776, 1728,
- 1777, 1728, 562, 1778, 1779, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 616, 616,
- 620, 530, 622, 1780, 1781, 1728, 626, 1782, 1728, 629,
- 1783, 1728, 1784, 1785, 1728, 635, 1786, 1787, 1787, 1728,
- 1788, 1728, 642, 1789, 1790, 1791, 1791, 1792, 1793, 1794,
- 1794, 1728, 1795, 1728, 654, 1796, 1797, 1728, 1798, 1728,
- 1799, 1800, 1728, 1728, 1728, 1728, 1801, 1802, 623, 669,
- 669, 669, 669, 669, 669, 669, 669, 669, 669, 669,
- 669, 669, 669, 669, 669, 669, 669, 669, 669, 669,
- 669, 669, 669, 669, 669, 669, 669, 669, 669, 669,
-
- 669, 669, 669, 669, 669, 669, 706, 706, 706, 669,
- 706, 711, 1803, 1728, 1728, 1728, 1804, 1728, 1728, 1805,
- 1806, 1807, 1728, 1728, 1728, 1728, 1808, 1809, 1728, 1810,
- 1811, 1728, 1728, 1728, 1728, 1812, 1813, 1728, 1814, 1728,
- 1815, 1816, 1728, 1728, 1728, 1728, 1817, 1818, 1819, 1728,
- 1820, 1821, 1821, 1822, 1823, 1824, 1824, 1728, 1825, 1728,
- 760, 1826, 1827, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
- 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
- 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
- 1828, 1828, 1828, 1828, 1828, 794, 1828, 794, 798, 798,
-
- 800, 1829, 1830, 1728, 804, 1831, 1728, 807, 1832, 1728,
- 810, 1833, 1728, 1834, 1835, 1728, 816, 1836, 1837, 1837,
- 1728, 1838, 1728, 823, 1839, 1840, 1841, 1841, 1842, 1843,
- 1844, 1844, 1728, 1845, 1728, 835, 1846, 1847, 1848, 1728,
- 1849, 1850, 1850, 1851, 1852, 1853, 1853, 1728, 1854, 1728,
- 850, 1855, 1856, 1857, 1728, 1858, 1728, 1859, 1860, 1728,
- 1728, 1728, 1728, 1861, 1862, 1863, 1863, 1863, 1863, 1863,
- 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863,
- 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 1863, 889,
- 889, 891, 889, 889, 894, 1864, 1728, 1728, 1728, 1865,
-
- 1728, 1728, 1866, 1728, 1728, 1867, 1868, 1869, 1728, 1728,
- 1728, 1728, 1870, 1871, 1728, 1872, 1873, 1728, 1728, 1728,
- 1728, 1874, 1875, 1728, 1876, 1728, 1877, 1878, 1728, 1728,
- 1728, 1728, 1879, 1880, 1881, 1728, 1882, 1728, 1883, 1884,
- 1728, 1728, 1728, 1728, 1885, 1886, 1887, 1888, 1728, 1889,
- 1890, 1890, 1891, 1892, 1893, 1893, 1728, 1894, 1728, 959,
- 1895, 1896, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
- 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
- 1897, 1897, 1897, 1897, 1897, 1897, 986, 1897, 1897, 1898,
- 1899, 1728, 992, 1900, 1728, 995, 1901, 1728, 998, 1902,
-
- 1728, 1001, 1903, 1728, 1904, 1728, 1728, 1007, 1905, 1906,
- 1906, 1728, 1907, 1728, 1014, 1908, 1909, 1910, 1910, 1911,
- 1912, 1913, 1913, 1728, 1914, 1728, 1026, 1915, 1916, 1917,
- 1728, 1918, 1919, 1919, 1920, 1921, 1922, 1922, 1728, 1923,
- 1728, 1041, 1924, 1925, 1926, 1927, 1728, 1928, 1929, 1929,
- 1930, 1931, 1932, 1932, 1728, 1933, 1728, 1057, 1934, 1935,
- 1936, 1728, 1937, 1728, 1938, 1939, 1728, 1728, 1728, 1728,
- 1940, 1941, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
- 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
- 1942, 1942, 1942, 1942, 1942, 1095, 1942, 1943, 1728, 1728,
-
- 1728, 1944, 1728, 1728, 1945, 1728, 1728, 1946, 1728, 1728,
- 1947, 1948, 1728, 1113, 1949, 1950, 1728, 1728, 1951, 1952,
- 1953, 1728, 1954, 1955, 1728, 1728, 1728, 1956, 1957, 1958,
- 1728, 1959, 1728, 1960, 1961, 1728, 1728, 1728, 1962, 1963,
- 1964, 1965, 1728, 1966, 1728, 1967, 1968, 1728, 1728, 1728,
- 1969, 1970, 1971, 1972, 1728, 1973, 1728, 1974, 1975, 1728,
- 1728, 1728, 1976, 1977, 1978, 1979, 1980, 1728, 1981, 1982,
- 1982, 1983, 1984, 1985, 1985, 1728, 1986, 1728, 1178, 1987,
- 1988, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989,
- 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989, 1989,
-
- 1989, 1989, 1989, 1989, 1990, 1728, 1728, 1207, 1991, 1728,
- 1210, 1992, 1728, 1213, 1993, 1728, 1216, 1994, 1728, 1219,
- 1995, 1728, 1728, 1728, 1996, 1997, 1998, 1999, 2000, 2000,
- 1728, 2001, 2002, 2003, 2004, 2004, 2005, 2006, 2007, 2007,
- 1728, 2008, 2009, 2010, 2011, 1728, 2012, 2013, 2013, 2014,
- 2015, 2016, 2016, 1728, 2017, 2018, 2019, 2020, 2021, 1728,
- 2022, 2023, 2023, 2024, 2025, 2026, 2026, 1728, 2027, 2028,
- 2029, 2030, 2031, 1728, 2032, 2033, 2033, 2034, 2035, 2036,
- 2036, 1728, 2037, 2038, 2039, 2040, 1728, 2041, 1728, 2042,
- 2043, 1728, 1728, 1728, 2044, 2045, 2046, 2047, 2047, 2047,
-
- 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047, 2047,
- 2047, 2047, 2047, 2047, 2047, 2047, 2047, 1728, 1318, 2048,
- 2049, 1728, 2050, 2051, 1728, 2052, 2053, 1728, 2054, 2055,
- 1728, 2056, 2057, 1728, 2058, 2059, 2060, 2060, 1728, 2061,
- 2062, 2063, 2064, 2065, 1728, 2066, 2067, 1728, 2068, 1728,
- 2069, 1728, 2070, 2071, 1728, 2072, 2073, 1728, 2074, 1728,
- 2075, 2076, 1728, 2077, 2078, 1728, 2079, 1728, 2080, 2081,
- 1728, 2082, 2083, 1728, 2084, 1728, 2085, 2086, 1728, 2087,
- 2088, 2089, 1728, 2090, 2091, 2091, 2092, 2093, 2094, 2094,
- 1728, 2095, 2096, 2097, 2098, 2098, 2098, 2098, 2098, 2098,
-
- 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098,
- 2098, 1728, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106,
- 1728, 2107, 2108, 1728, 2109, 2110, 2111, 2111, 2112, 2113,
- 2114, 2115, 1728, 2116, 2117, 2117, 2118, 2119, 2120, 2121,
- 2122, 1728, 2123, 2124, 2124, 2125, 2126, 2127, 2128, 2129,
- 1728, 2130, 2131, 2131, 2132, 2133, 2134, 2135, 2136, 1728,
- 2137, 2138, 2138, 2139, 2140, 2141, 2142, 1728, 2143, 1728,
- 2144, 2145, 1728, 2146, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2148, 1728, 2149, 2150, 2151, 2152, 2153, 2154, 2155,
-
- 2155, 2156, 2157, 2158, 1728, 1728, 2159, 1728, 2160, 1728,
- 2161, 1728, 2162, 1728, 2163, 1728, 2164, 1728, 2165, 1728,
- 2166, 1728, 2167, 1728, 2142, 2168, 1728, 2143, 2169, 2169,
- 2144, 2145, 2170, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2171,
- 1728, 2172, 2173, 1728, 2159, 2160, 2174, 1728, 2161, 2162,
- 2175, 1728, 2163, 2164, 2176, 1728, 2165, 2166, 2177, 1728,
- 2167, 2178, 1728, 2179, 1728, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2180, 1728,
- 2172, 2181, 2182, 2183, 2184, 2185, 2178, 2186, 1728, 2179,
-
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2187, 2181, 2182, 2183, 2184, 2185, 2188, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2187, 2188, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
-
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147, 2147,
- 2147, 2147, 2147, 2147, 2147, 2147, 2147, 0, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
-
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
-
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
-
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
-
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728
+ 1723, 1, 1723, 1723, 1723, 1723, 1723, 1724, 1723, 1723,
+ 1723, 11, 1723, 1723, 1723, 1723, 11, 17, 1725, 17,
+ 17, 17, 17, 17, 17, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 1723,
+ 1723, 1726, 1723, 18, 18, 17, 1727, 46, 18, 18,
+ 18, 1723, 1723, 1723, 1723, 1723, 1723, 45, 1725, 48,
+ 48, 48, 18, 18, 18, 18, 48, 18, 18, 48,
+ 18, 18, 18, 48, 18, 18, 18, 18, 18, 48,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 1723, 1723, 18, 18, 149,
+ 18, 18, 152, 1728, 1723, 50, 1723, 157, 1729, 18,
+ 18, 153, 18, 18, 18, 153, 18, 18, 18, 18,
+ 18, 18, 153, 18, 18, 18, 18, 18, 18, 18,
+ 153, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 257, 258, 153, 1730, 263, 1731, 1732, 1723, 268, 1733,
+ 1734, 1723, 1723, 1723, 1735, 1736, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 345, 18, 258, 260, 258,
+ 260, 260, 352, 1737, 1723, 351, 1738, 1739, 1723, 1723,
+ 1723, 1723, 1740, 1741, 1742, 1743, 1743, 1723, 1744, 1723,
+ 370, 1745, 1736, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 427, 428, 428, 433, 427, 352, 436, 1746, 1747, 1723,
+ 440, 1748, 1723, 1749, 1750, 1723, 446, 1751, 1752, 1753,
+ 1753, 1723, 1754, 1723, 454, 1755, 1741, 1723, 1723, 1756,
+ 1757, 1723, 1723, 1723, 1723, 1758, 1759, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 517, 18, 428,
+ 430, 428, 428, 523, 436, 525, 1760, 1723, 1723, 1723,
+ 1761, 1762, 1763, 1723, 1723, 1723, 1723, 1764, 1765, 1723,
+ 1766, 1767, 1723, 1723, 1723, 1723, 1768, 1769, 1770, 1770,
+ 1756, 1757, 1771, 1771, 1723, 1772, 1723, 557, 1773, 1774,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 611, 611, 615, 525, 617, 1775, 1776,
+ 1723, 621, 1777, 1723, 624, 1778, 1723, 1779, 1780, 1723,
+ 630, 1781, 1782, 1782, 1723, 1783, 1723, 637, 1784, 1785,
+ 1786, 1786, 1787, 1788, 1789, 1789, 1723, 1790, 1723, 649,
+ 1791, 1792, 1723, 1793, 1723, 1794, 1795, 1723, 1723, 1723,
+ 1723, 1796, 1797, 618, 664, 664, 664, 664, 664, 664,
+ 664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
+ 664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
+ 664, 664, 664, 664, 664, 664, 664, 664, 618, 618,
+
+ 664, 701, 701, 701, 664, 701, 706, 1798, 1723, 1723,
+ 1723, 1799, 1723, 1723, 1800, 1801, 1802, 1723, 1723, 1723,
+ 1723, 1803, 1804, 1723, 1805, 1806, 1723, 1723, 1723, 1723,
+ 1807, 1808, 1723, 1809, 1723, 1810, 1811, 1723, 1723, 1723,
+ 1723, 1812, 1813, 1814, 1723, 1815, 1816, 1816, 1817, 1818,
+ 1819, 1819, 1723, 1820, 1723, 755, 1821, 1822, 1823, 1823,
+ 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823,
+ 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823,
+ 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823,
+ 789, 1823, 789, 793, 793, 795, 1824, 1825, 1723, 799,
+
+ 1826, 1723, 802, 1827, 1723, 805, 1828, 1723, 1829, 1830,
+ 1723, 811, 1831, 1832, 1832, 1723, 1833, 1723, 818, 1834,
+ 1835, 1836, 1836, 1837, 1838, 1839, 1839, 1723, 1840, 1723,
+ 830, 1841, 1842, 1843, 1723, 1844, 1845, 1845, 1846, 1847,
+ 1848, 1848, 1723, 1849, 1723, 845, 1850, 1851, 1852, 1723,
+ 1853, 1723, 1854, 1855, 1723, 1723, 1723, 1723, 1856, 1857,
+ 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858,
+ 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858,
+ 1858, 1858, 1858, 1858, 884, 884, 886, 884, 884, 889,
+ 1859, 1723, 1723, 1723, 1860, 1723, 1723, 1861, 1723, 1723,
+
+ 1862, 1863, 1864, 1723, 1723, 1723, 1723, 1865, 1866, 1723,
+ 1867, 1868, 1723, 1723, 1723, 1723, 1869, 1870, 1723, 1871,
+ 1723, 1872, 1873, 1723, 1723, 1723, 1723, 1874, 1875, 1876,
+ 1723, 1877, 1723, 1878, 1879, 1723, 1723, 1723, 1723, 1880,
+ 1881, 1882, 1883, 1723, 1884, 1885, 1885, 1886, 1887, 1888,
+ 1888, 1723, 1889, 1723, 954, 1890, 1891, 1892, 1892, 1892,
+ 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892,
+ 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892,
+ 1892, 981, 1892, 1892, 1893, 1894, 1723, 987, 1895, 1723,
+ 990, 1896, 1723, 993, 1897, 1723, 996, 1898, 1723, 1899,
+
+ 1723, 1723, 1002, 1900, 1901, 1901, 1723, 1902, 1723, 1009,
+ 1903, 1904, 1905, 1905, 1906, 1907, 1908, 1908, 1723, 1909,
+ 1723, 1021, 1910, 1911, 1912, 1723, 1913, 1914, 1914, 1915,
+ 1916, 1917, 1917, 1723, 1918, 1723, 1036, 1919, 1920, 1921,
+ 1922, 1723, 1923, 1924, 1924, 1925, 1926, 1927, 1927, 1723,
+ 1928, 1723, 1052, 1929, 1930, 1931, 1723, 1932, 1723, 1933,
+ 1934, 1723, 1723, 1723, 1723, 1935, 1936, 1937, 1937, 1937,
+ 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937,
+ 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937,
+ 1090, 1937, 1938, 1723, 1723, 1723, 1939, 1723, 1723, 1940,
+
+ 1723, 1723, 1941, 1723, 1723, 1942, 1943, 1723, 1108, 1944,
+ 1945, 1723, 1723, 1946, 1947, 1948, 1723, 1949, 1950, 1723,
+ 1723, 1723, 1951, 1952, 1953, 1723, 1954, 1723, 1955, 1956,
+ 1723, 1723, 1723, 1957, 1958, 1959, 1960, 1723, 1961, 1723,
+ 1962, 1963, 1723, 1723, 1723, 1964, 1965, 1966, 1967, 1723,
+ 1968, 1723, 1969, 1970, 1723, 1723, 1723, 1971, 1972, 1973,
+ 1974, 1975, 1723, 1976, 1977, 1977, 1978, 1979, 1980, 1980,
+ 1723, 1981, 1723, 1173, 1982, 1983, 1984, 1984, 1984, 1984,
+ 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984,
+ 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1985,
+
+ 1723, 1723, 1202, 1986, 1723, 1205, 1987, 1723, 1208, 1988,
+ 1723, 1211, 1989, 1723, 1214, 1990, 1723, 1723, 1723, 1991,
+ 1992, 1993, 1994, 1995, 1995, 1723, 1996, 1997, 1998, 1999,
+ 1999, 2000, 2001, 2002, 2002, 1723, 2003, 2004, 2005, 2006,
+ 1723, 2007, 2008, 2008, 2009, 2010, 2011, 2011, 1723, 2012,
+ 2013, 2014, 2015, 2016, 1723, 2017, 2018, 2018, 2019, 2020,
+ 2021, 2021, 1723, 2022, 2023, 2024, 2025, 2026, 1723, 2027,
+ 2028, 2028, 2029, 2030, 2031, 2031, 1723, 2032, 2033, 2034,
+ 2035, 1723, 2036, 1723, 2037, 2038, 1723, 1723, 1723, 2039,
+ 2040, 2041, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042,
+
+ 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2042,
+ 2042, 2042, 1723, 1313, 2043, 2044, 1723, 2045, 2046, 1723,
+ 2047, 2048, 1723, 2049, 2050, 1723, 2051, 2052, 1723, 2053,
+ 2054, 2055, 2055, 1723, 2056, 2057, 2058, 2059, 2060, 1723,
+ 2061, 2062, 1723, 2063, 1723, 2064, 1723, 2065, 2066, 1723,
+ 2067, 2068, 1723, 2069, 1723, 2070, 2071, 1723, 2072, 2073,
+ 1723, 2074, 1723, 2075, 2076, 1723, 2077, 2078, 1723, 2079,
+ 1723, 2080, 2081, 1723, 2082, 2083, 2084, 1723, 2085, 2086,
+ 2086, 2087, 2088, 2089, 2089, 1723, 2090, 2091, 2092, 2093,
+ 2093, 2093, 2093, 2093, 2093, 2093, 2093, 2093, 2093, 2093,
+
+ 2093, 2093, 2093, 2093, 2093, 2093, 1723, 2094, 2095, 2096,
+ 2097, 2098, 2099, 2100, 2101, 1723, 2102, 2103, 1723, 2104,
+ 2105, 2106, 2106, 2107, 2108, 2109, 2110, 1723, 2111, 2112,
+ 2112, 2113, 2114, 2115, 2116, 2117, 1723, 2118, 2119, 2119,
+ 2120, 2121, 2122, 2123, 2124, 1723, 2125, 2126, 2126, 2127,
+ 2128, 2129, 2130, 2131, 1723, 2132, 2133, 2133, 2134, 2135,
+ 2136, 2137, 1723, 2138, 1723, 2139, 2140, 1723, 2141, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2143, 1723, 2144, 2145,
+ 2146, 2147, 2148, 2149, 2150, 2150, 2151, 2152, 2153, 1723,
+
+ 1723, 2154, 1723, 2155, 1723, 2156, 1723, 2157, 1723, 2158,
+ 1723, 2159, 1723, 2160, 1723, 2161, 1723, 2162, 1723, 2137,
+ 2163, 1723, 2138, 2164, 2164, 2139, 2140, 2165, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2166, 1723, 2167, 2168, 1723, 2154,
+ 2155, 2169, 1723, 2156, 2157, 2170, 1723, 2158, 2159, 2171,
+ 1723, 2160, 2161, 2172, 1723, 2162, 2173, 1723, 2174, 1723,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2175, 1723, 2167, 2176, 2177, 2178, 2179,
+ 2180, 2173, 2181, 1723, 2174, 2142, 2142, 2142, 2142, 2142,
+
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2182, 2176, 2177,
+ 2178, 2179, 2180, 2183, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2182, 2183, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 0, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723
} ;
-static yyconst flex_int16_t yy_nxt[7910] =
+static yyconst flex_int16_t yy_nxt[7679] =
{ 0,
- 4, 5, 6, 7, 8, 9, 10, 11, 12, 12,
- 13, 14, 15, 15, 15, 15, 15, 15, 16, 17,
- 18, 19, 20, 21, 21, 12, 22, 13, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 21, 32, 33,
- 34, 35, 36, 21, 37, 38, 39, 40, 41, 42,
- 21, 21, 43, 44, 53, 211, 44, 44, 44, 44,
- 44, 212, 44, 44, 44, 57, 58, 44, 248, 44,
- 44, 44, 60, 61, 72, 44, 83, 84, 249, 44,
- 53, 44, 44, 44, 44, 206, 44, 44, 73, 85,
- 44, 117, 79, 1157, 86, 74, 80, 686, 195, 44,
-
- 118, 196, 81, 687, 197, 82, 198, 44, 48, 49,
- 50, 50, 50, 50, 50, 50, 50, 51, 207, 201,
- 942, 52, 53, 54, 202, 182, 55, 52, 52, 52,
- 52, 52, 52, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 54,
- 53, 44, 183, 75, 44, 766, 44, 44, 184, 236,
- 87, 53, 213, 76, 88, 344, 77, 214, 63, 56,
- 78, 63, 237, 63, 63, 208, 89, 44, 62, 52,
- 52, 52, 52, 52, 52, 52, 63, 242, 65, 345,
- 66, 67, 53, 768, 63, 68, 53, 342, 119, 343,
-
- 69, 90, 209, 91, 70, 243, 71, 210, 92, 93,
- 120, 94, 121, 1335, 122, 95, 453, 123, 53, 55,
- 53, 53, 53, 53, 53, 53, 53, 53, 1728, 104,
- 105, 217, 53, 770, 218, 1161, 219, 245, 53, 53,
- 53, 53, 53, 53, 96, 106, 246, 97, 98, 107,
- 99, 53, 100, 108, 101, 109, 102, 111, 124, 103,
- 53, 112, 110, 125, 126, 129, 127, 128, 799, 130,
- 113, 114, 1728, 134, 115, 324, 116, 131, 141, 135,
- 142, 136, 132, 137, 133, 146, 53, 138, 325, 139,
- 140, 53, 355, 147, 143, 53, 527, 148, 1728, 149,
-
- 44, 144, 490, 44, 53, 44, 44, 156, 156, 156,
- 156, 156, 156, 156, 1728, 417, 63, 53, 44, 63,
- 418, 63, 63, 491, 500, 1070, 44, 153, 153, 153,
- 153, 153, 153, 153, 63, 53, 708, 501, 153, 492,
- 1728, 775, 63, 53, 153, 153, 153, 153, 153, 153,
- 154, 155, 155, 155, 155, 155, 155, 1728, 53, 53,
- 1728, 156, 380, 381, 382, 383, 1295, 156, 156, 156,
- 156, 156, 156, 49, 157, 157, 157, 157, 157, 157,
- 157, 277, 384, 1728, 53, 158, 1728, 1728, 1728, 279,
- 1413, 158, 158, 158, 158, 158, 158, 62, 158, 158,
-
- 158, 158, 158, 158, 158, 161, 161, 161, 161, 161,
- 161, 161, 576, 1728, 1728, 437, 161, 1323, 504, 765,
- 53, 577, 161, 161, 161, 161, 161, 161, 44, 265,
- 767, 44, 505, 44, 44, 53, 1326, 464, 464, 162,
- 163, 163, 163, 163, 163, 163, 44, 53, 1728, 53,
- 164, 465, 1728, 774, 44, 265, 164, 164, 164, 164,
- 164, 164, 260, 579, 261, 261, 261, 261, 261, 261,
- 261, 365, 580, 53, 1728, 261, 1728, 465, 1728, 535,
- 781, 261, 261, 261, 261, 261, 261, 262, 263, 263,
- 263, 263, 263, 263, 263, 277, 468, 53, 1329, 264,
-
- 1728, 265, 1728, 1728, 470, 264, 264, 264, 264, 264,
- 264, 352, 352, 352, 352, 352, 352, 352, 371, 372,
- 372, 372, 372, 372, 372, 545, 1728, 265, 266, 264,
- 264, 264, 264, 264, 264, 264, 688, 1728, 1332, 546,
- 264, 380, 381, 382, 383, 689, 264, 264, 264, 264,
- 264, 264, 267, 268, 268, 268, 268, 268, 268, 268,
- 269, 779, 1335, 1728, 270, 546, 1728, 1728, 53, 1413,
- 270, 270, 270, 270, 270, 270, 53, 270, 270, 270,
- 270, 270, 270, 270, 273, 274, 274, 274, 274, 274,
- 274, 275, 1728, 1728, 773, 276, 53, 777, 453, 53,
-
- 453, 276, 276, 276, 276, 276, 276, 277, 278, 278,
- 278, 278, 278, 278, 278, 279, 782, 53, 786, 280,
- 1223, 281, 453, 396, 53, 280, 280, 280, 280, 280,
- 280, 397, 440, 440, 440, 440, 440, 440, 440, 53,
- 793, 545, 1323, 619, 398, 55, 771, 281, 349, 349,
- 349, 349, 349, 349, 349, 1728, 53, 435, 618, 349,
- 399, 453, 55, 55, 784, 349, 349, 349, 349, 349,
- 349, 350, 351, 351, 351, 351, 351, 351, 690, 53,
- 55, 1728, 352, 435, 618, 854, 1728, 691, 352, 352,
- 352, 352, 352, 352, 262, 353, 353, 353, 353, 353,
-
- 353, 353, 354, 354, 354, 354, 354, 354, 354, 769,
- 1728, 854, 1728, 354, 1326, 453, 1329, 55, 53, 354,
- 354, 354, 354, 354, 354, 356, 357, 357, 357, 357,
- 357, 357, 357, 540, 549, 55, 1728, 358, 453, 1332,
- 872, 716, 719, 358, 358, 358, 358, 358, 358, 361,
- 358, 358, 358, 358, 358, 358, 358, 365, 366, 366,
- 366, 366, 366, 366, 366, 367, 664, 453, 1335, 368,
- 453, 369, 1287, 1289, 666, 368, 368, 368, 368, 368,
- 368, 455, 456, 456, 456, 456, 456, 456, 524, 524,
- 524, 524, 524, 524, 524, 658, 778, 369, 277, 373,
-
- 373, 373, 373, 373, 373, 373, 279, 53, 1068, 659,
- 374, 1295, 55, 55, 1293, 776, 374, 374, 374, 374,
- 374, 374, 375, 376, 376, 376, 376, 376, 376, 53,
- 55, 55, 780, 377, 658, 659, 879, 866, 1493, 377,
- 377, 377, 377, 377, 377, 421, 53, 422, 1728, 423,
- 424, 554, 555, 555, 555, 555, 555, 555, 55, 425,
- 785, 426, 427, 660, 428, 430, 660, 431, 431, 431,
- 431, 431, 431, 431, 1728, 53, 55, 661, 431, 873,
- 1728, 55, 1413, 55, 431, 431, 431, 431, 431, 431,
- 432, 433, 433, 433, 433, 433, 433, 433, 1413, 55,
-
- 876, 55, 434, 661, 435, 453, 1728, 1345, 434, 434,
- 434, 434, 434, 434, 558, 559, 559, 559, 559, 559,
- 559, 638, 639, 639, 639, 639, 639, 639, 729, 783,
- 435, 436, 434, 434, 434, 434, 434, 434, 434, 53,
- 1117, 1350, 730, 434, 1352, 55, 55, 55, 729, 434,
- 434, 434, 434, 434, 434, 438, 439, 439, 439, 439,
- 439, 439, 1728, 55, 55, 55, 440, 874, 730, 55,
- 883, 55, 440, 440, 440, 440, 440, 440, 267, 441,
- 441, 441, 441, 441, 441, 441, 1126, 55, 1728, 55,
- 442, 1728, 884, 1728, 1728, 1358, 442, 442, 442, 442,
-
- 442, 442, 53, 442, 442, 442, 442, 442, 442, 442,
- 445, 446, 446, 446, 446, 446, 446, 1728, 724, 1728,
- 1728, 447, 1360, 55, 55, 794, 899, 447, 447, 447,
- 447, 447, 447, 451, 452, 452, 452, 452, 452, 452,
- 453, 55, 55, 55, 454, 887, 1728, 55, 796, 1137,
- 454, 454, 454, 454, 454, 454, 365, 457, 457, 457,
- 457, 457, 457, 457, 367, 55, 1728, 935, 458, 1728,
- 55, 55, 1728, 1366, 458, 458, 458, 458, 458, 458,
- 459, 460, 460, 460, 460, 460, 460, 453, 55, 55,
- 53, 461, 1728, 935, 963, 1728, 55, 461, 461, 461,
-
- 461, 461, 461, 277, 466, 466, 466, 466, 466, 466,
- 466, 279, 1368, 1149, 55, 467, 53, 1374, 55, 964,
- 55, 467, 467, 467, 467, 467, 467, 468, 469, 469,
- 469, 469, 469, 469, 469, 470, 55, 975, 55, 471,
- 787, 472, 1376, 965, 788, 471, 471, 471, 471, 471,
- 471, 582, 738, 583, 53, 789, 584, 585, 53, 738,
- 586, 587, 791, 733, 792, 588, 739, 472, 482, 53,
- 1161, 902, 483, 1728, 53, 484, 53, 740, 485, 740,
- 486, 487, 488, 489, 521, 521, 521, 521, 521, 521,
- 521, 741, 739, 1728, 1295, 521, 55, 55, 55, 1728,
-
- 1421, 521, 521, 521, 521, 521, 521, 522, 523, 523,
- 523, 523, 523, 523, 55, 55, 55, 741, 524, 1728,
- 967, 969, 1061, 880, 524, 524, 524, 524, 524, 524,
- 432, 525, 525, 525, 525, 525, 525, 525, 526, 526,
- 526, 526, 526, 526, 526, 1223, 1468, 1470, 1061, 526,
- 1506, 55, 55, 55, 55, 526, 526, 526, 526, 526,
- 526, 437, 528, 528, 528, 528, 528, 528, 528, 55,
- 55, 55, 55, 529, 1510, 265, 970, 976, 881, 529,
- 529, 529, 529, 529, 529, 646, 647, 647, 647, 647,
- 647, 647, 650, 651, 651, 651, 651, 651, 651, 55,
-
- 855, 265, 529, 529, 529, 529, 529, 529, 529, 1728,
- 744, 1728, 1728, 529, 856, 55, 1514, 55, 905, 529,
- 529, 529, 529, 529, 529, 530, 530, 530, 530, 530,
- 530, 530, 1518, 55, 867, 1728, 531, 1728, 1728, 1728,
- 856, 979, 531, 531, 531, 531, 531, 531, 53, 531,
- 531, 531, 531, 531, 531, 531, 365, 534, 534, 534,
- 534, 534, 534, 534, 535, 1728, 1522, 1551, 536, 1728,
- 369, 1573, 1155, 1149, 536, 536, 536, 536, 536, 536,
- 749, 750, 750, 750, 750, 750, 750, 752, 753, 753,
- 753, 753, 753, 753, 55, 1728, 369, 540, 541, 541,
-
- 541, 541, 541, 541, 541, 542, 861, 453, 1332, 543,
- 930, 544, 55, 1085, 863, 543, 543, 543, 543, 543,
- 543, 756, 757, 757, 757, 757, 757, 757, 819, 820,
- 820, 820, 820, 820, 820, 855, 55, 544, 365, 547,
- 547, 547, 547, 547, 547, 547, 535, 1145, 1143, 1728,
- 548, 1728, 1137, 1728, 55, 55, 548, 548, 548, 548,
- 548, 548, 549, 550, 550, 550, 550, 550, 550, 550,
- 551, 868, 453, 55, 552, 1728, 553, 1728, 982, 1728,
- 552, 552, 552, 552, 552, 552, 827, 828, 828, 828,
- 828, 828, 828, 831, 832, 832, 832, 832, 832, 832,
-
- 857, 55, 553, 468, 560, 560, 560, 560, 560, 560,
- 560, 470, 1329, 1728, 858, 561, 919, 55, 1133, 55,
- 857, 561, 561, 561, 561, 561, 561, 562, 563, 563,
- 563, 563, 563, 563, 1728, 55, 869, 1131, 564, 1728,
- 858, 55, 1087, 55, 564, 564, 564, 564, 564, 564,
- 613, 915, 614, 614, 614, 614, 614, 614, 614, 55,
- 1728, 55, 1126, 614, 972, 916, 55, 55, 885, 614,
- 614, 614, 614, 614, 614, 615, 616, 616, 616, 616,
- 616, 616, 616, 453, 55, 55, 1326, 617, 1078, 618,
- 910, 916, 1084, 617, 617, 617, 617, 617, 617, 839,
-
- 840, 840, 840, 840, 840, 840, 842, 843, 843, 843,
- 843, 843, 843, 55, 55, 618, 615, 617, 617, 617,
- 617, 617, 617, 617, 1142, 910, 1122, 1728, 617, 1154,
- 1728, 55, 55, 1101, 617, 617, 617, 617, 617, 617,
- 437, 620, 620, 620, 620, 620, 620, 620, 871, 919,
- 1142, 877, 621, 1728, 1728, 1154, 1728, 1104, 621, 621,
- 621, 621, 621, 621, 53, 621, 621, 621, 621, 621,
- 621, 621, 622, 622, 622, 622, 622, 622, 622, 930,
- 1728, 1117, 453, 623, 1286, 1728, 1728, 1107, 1323, 623,
- 623, 623, 623, 623, 623, 53, 623, 623, 623, 623,
-
- 623, 623, 623, 626, 627, 627, 627, 627, 627, 627,
- 1286, 1728, 1728, 1728, 628, 453, 1225, 55, 55, 55,
- 628, 628, 628, 628, 628, 628, 365, 457, 457, 457,
- 457, 457, 457, 457, 535, 55, 55, 55, 458, 1728,
- 1082, 1086, 1089, 915, 458, 458, 458, 458, 458, 458,
- 629, 630, 630, 630, 630, 630, 630, 1728, 942, 1342,
- 1728, 631, 1206, 55, 55, 1335, 1110, 631, 631, 631,
- 631, 631, 631, 635, 636, 636, 636, 636, 636, 636,
- 453, 55, 55, 1728, 637, 1090, 1728, 55, 55, 1088,
- 637, 637, 637, 637, 637, 637, 540, 640, 640, 640,
-
- 640, 640, 640, 640, 542, 55, 55, 1091, 641, 1332,
- 55, 1093, 55, 1329, 641, 641, 641, 641, 641, 641,
- 642, 643, 643, 643, 643, 643, 643, 453, 55, 1326,
- 55, 644, 1323, 1206, 55, 55, 55, 644, 644, 644,
- 644, 644, 644, 549, 652, 652, 652, 652, 652, 652,
- 652, 551, 55, 55, 55, 653, 1068, 55, 55, 55,
- 1295, 653, 653, 653, 653, 653, 653, 654, 655, 655,
- 655, 655, 655, 655, 453, 55, 55, 55, 656, 1187,
- 1190, 55, 1191, 55, 656, 656, 656, 656, 656, 656,
- 468, 662, 662, 662, 662, 662, 662, 662, 470, 55,
-
- 1070, 55, 663, 1728, 1728, 55, 1194, 861, 663, 663,
- 663, 663, 663, 663, 664, 665, 665, 665, 665, 665,
- 665, 665, 666, 55, 1064, 1195, 667, 1062, 668, 1728,
- 1728, 1163, 667, 667, 667, 667, 667, 667, 846, 847,
- 847, 847, 847, 847, 847, 750, 750, 750, 750, 750,
- 750, 750, 55, 55, 668, 704, 704, 704, 704, 704,
- 704, 704, 1357, 453, 1365, 1373, 704, 1728, 55, 1110,
- 55, 55, 704, 704, 704, 704, 704, 704, 705, 705,
- 705, 705, 705, 705, 705, 878, 55, 968, 1357, 705,
- 1365, 1373, 1199, 1728, 1151, 705, 705, 705, 705, 705,
-
- 705, 615, 706, 706, 706, 706, 706, 706, 706, 707,
- 707, 707, 707, 707, 707, 707, 1068, 453, 1107, 1467,
- 707, 1509, 55, 55, 1070, 55, 707, 707, 707, 707,
- 707, 707, 437, 709, 709, 709, 709, 709, 709, 709,
- 55, 55, 1197, 55, 710, 1467, 1200, 1509, 1513, 978,
- 710, 710, 710, 710, 710, 710, 53, 710, 710, 710,
- 710, 710, 710, 710, 711, 711, 711, 711, 711, 711,
- 711, 1117, 1126, 1139, 1513, 712, 453, 1104, 1128, 1323,
- 1326, 712, 712, 712, 712, 712, 712, 53, 712, 712,
- 712, 712, 712, 712, 712, 540, 715, 715, 715, 715,
-
- 715, 715, 715, 716, 55, 55, 924, 717, 55, 544,
- 55, 55, 55, 717, 717, 717, 717, 717, 717, 1137,
- 925, 453, 55, 55, 1101, 1119, 55, 1329, 55, 55,
- 55, 55, 980, 55, 870, 544, 549, 718, 718, 718,
- 718, 718, 718, 718, 719, 882, 925, 886, 720, 55,
- 553, 55, 1149, 1298, 720, 720, 720, 720, 720, 720,
- 1332, 875, 453, 1225, 888, 893, 893, 893, 893, 893,
- 893, 893, 55, 924, 926, 1517, 553, 724, 725, 725,
- 725, 725, 725, 725, 725, 726, 55, 1728, 927, 727,
- 55, 728, 926, 936, 936, 727, 727, 727, 727, 727,
-
- 727, 1517, 341, 1161, 55, 1521, 1728, 937, 1728, 55,
- 453, 1335, 1206, 1728, 927, 938, 1110, 728, 540, 731,
- 731, 731, 731, 731, 731, 731, 716, 55, 1299, 939,
- 732, 1521, 1728, 937, 1728, 55, 732, 732, 732, 732,
- 732, 732, 733, 734, 734, 734, 734, 734, 734, 734,
- 735, 1300, 1107, 55, 736, 939, 737, 1104, 1304, 938,
- 736, 736, 736, 736, 736, 736, 840, 840, 840, 840,
- 840, 840, 840, 1728, 948, 949, 949, 949, 949, 949,
- 949, 1101, 737, 549, 742, 742, 742, 742, 742, 742,
- 742, 719, 1223, 1206, 1572, 743, 1592, 1593, 55, 1728,
-
- 1413, 743, 743, 743, 743, 743, 743, 744, 745, 745,
- 745, 745, 745, 745, 745, 746, 55, 1070, 1301, 747,
- 1572, 748, 1592, 1593, 863, 747, 747, 747, 747, 747,
- 747, 951, 952, 952, 952, 952, 952, 952, 955, 956,
- 956, 956, 956, 956, 956, 55, 55, 748, 664, 758,
- 758, 758, 758, 758, 758, 758, 666, 1293, 942, 1163,
- 759, 1110, 1594, 55, 55, 1295, 759, 759, 759, 759,
- 759, 759, 760, 761, 761, 761, 761, 761, 761, 966,
- 974, 744, 938, 762, 55, 55, 55, 55, 1594, 762,
- 762, 762, 762, 762, 762, 53, 53, 53, 53, 53,
-
- 53, 53, 55, 55, 55, 55, 53, 55, 55, 1062,
- 55, 55, 53, 53, 53, 53, 53, 53, 971, 973,
- 1595, 983, 981, 1063, 1293, 55, 55, 1062, 55, 55,
- 764, 794, 1728, 795, 795, 795, 795, 795, 795, 795,
- 977, 1728, 1077, 1073, 795, 1186, 1595, 55, 936, 1063,
- 795, 795, 795, 795, 795, 795, 1010, 1011, 1011, 1011,
- 1011, 1011, 1011, 1064, 1064, 55, 55, 1728, 53, 796,
- 797, 797, 797, 797, 797, 797, 797, 1065, 1728, 930,
- 1074, 797, 55, 55, 55, 1079, 1151, 797, 797, 797,
- 797, 797, 797, 1018, 1019, 1019, 1019, 1019, 1019, 1019,
-
- 55, 55, 1080, 1065, 1728, 53, 706, 706, 706, 706,
- 706, 706, 706, 1022, 1023, 1023, 1023, 1023, 1023, 1023,
- 1030, 1031, 1031, 1031, 1031, 1031, 1031, 1033, 1034, 1034,
- 1034, 1034, 1034, 1034, 1037, 1038, 1038, 1038, 1038, 1038,
- 1038, 53, 707, 707, 707, 707, 707, 707, 707, 1107,
- 733, 926, 924, 707, 919, 1596, 1613, 1619, 1139, 707,
- 707, 707, 707, 707, 707, 798, 353, 353, 353, 353,
- 353, 353, 353, 267, 800, 800, 800, 800, 800, 800,
- 800, 1596, 1613, 1619, 1104, 801, 724, 915, 910, 1128,
- 1101, 801, 801, 801, 801, 801, 801, 53, 801, 801,
-
- 801, 801, 801, 801, 801, 804, 805, 805, 805, 805,
- 805, 805, 1119, 1006, 991, 1110, 806, 1107, 1104, 55,
- 55, 55, 806, 806, 806, 806, 806, 806, 540, 640,
- 640, 640, 640, 640, 640, 640, 716, 55, 55, 55,
- 641, 1315, 1101, 1316, 55, 1122, 641, 641, 641, 641,
- 641, 641, 807, 808, 808, 808, 808, 808, 808, 1123,
- 1302, 1099, 55, 809, 991, 861, 55, 1070, 55, 809,
- 809, 809, 809, 809, 809, 549, 652, 652, 652, 652,
- 652, 652, 652, 719, 55, 1123, 55, 653, 863, 55,
- 55, 55, 1122, 653, 653, 653, 653, 653, 653, 810,
-
- 811, 811, 811, 811, 811, 811, 1728, 55, 55, 55,
- 812, 664, 55, 1395, 1404, 1306, 812, 812, 812, 812,
- 812, 812, 816, 817, 817, 817, 817, 817, 817, 453,
- 55, 857, 1728, 818, 855, 944, 905, 55, 55, 818,
- 818, 818, 818, 818, 818, 724, 821, 821, 821, 821,
- 821, 821, 821, 726, 1401, 55, 55, 822, 932, 902,
- 55, 55, 921, 822, 822, 822, 822, 822, 822, 823,
- 824, 824, 824, 824, 824, 824, 453, 1409, 55, 55,
- 825, 1476, 1477, 55, 55, 55, 825, 825, 825, 825,
- 825, 825, 733, 833, 833, 833, 833, 833, 833, 833,
-
- 735, 55, 55, 55, 834, 899, 1479, 912, 55, 1006,
- 834, 834, 834, 834, 834, 834, 835, 836, 836, 836,
- 836, 836, 836, 453, 991, 1478, 55, 837, 905, 902,
- 1481, 55, 55, 837, 837, 837, 837, 837, 837, 744,
- 848, 848, 848, 848, 848, 848, 848, 746, 899, 55,
- 55, 849, 991, 1482, 55, 55, 1483, 849, 849, 849,
- 849, 849, 849, 850, 851, 851, 851, 851, 851, 851,
- 453, 863, 55, 55, 852, 666, 1486, 55, 1489, 55,
- 852, 852, 852, 852, 852, 852, 664, 859, 859, 859,
- 859, 859, 859, 859, 666, 55, 744, 55, 860, 944,
-
- 905, 55, 549, 1536, 860, 860, 860, 860, 860, 860,
- 861, 862, 862, 862, 862, 862, 862, 862, 863, 55,
- 1546, 740, 864, 738, 865, 733, 932, 902, 864, 864,
- 864, 864, 864, 864, 1046, 1047, 1047, 1047, 1047, 1047,
- 1047, 1049, 1050, 1050, 1050, 1050, 1050, 1050, 1131, 55,
- 865, 55, 1131, 889, 889, 889, 889, 889, 889, 889,
- 540, 729, 1132, 724, 889, 921, 1728, 55, 55, 55,
- 889, 889, 889, 889, 889, 889, 890, 890, 890, 890,
- 890, 890, 890, 1081, 899, 912, 55, 890, 1132, 55,
- 55, 55, 1728, 890, 890, 890, 890, 890, 890, 891,
-
- 892, 892, 892, 892, 892, 892, 1189, 55, 55, 55,
- 893, 1549, 55, 55, 55, 55, 893, 893, 893, 893,
- 893, 893, 267, 894, 894, 894, 894, 894, 894, 894,
- 55, 55, 55, 55, 895, 909, 1577, 1584, 815, 1396,
- 895, 895, 895, 895, 895, 895, 53, 895, 895, 895,
- 895, 895, 895, 895, 724, 898, 898, 898, 898, 898,
- 898, 898, 899, 803, 905, 902, 900, 899, 728, 897,
- 803, 664, 900, 900, 900, 900, 900, 900, 1053, 1054,
- 1054, 1054, 1054, 1054, 1054, 949, 949, 949, 949, 949,
- 949, 949, 55, 55, 728, 733, 901, 901, 901, 901,
-
- 901, 901, 901, 902, 55, 55, 1133, 903, 863, 737,
- 55, 55, 55, 903, 903, 903, 903, 903, 903, 666,
- 1134, 468, 55, 55, 660, 1075, 1076, 55, 1083, 55,
- 55, 55, 658, 1182, 1183, 737, 744, 904, 904, 904,
- 904, 904, 904, 904, 905, 55, 1134, 55, 906, 55,
- 748, 1537, 1133, 746, 906, 906, 906, 906, 906, 906,
- 1092, 1143, 1094, 1185, 719, 735, 1728, 1031, 1031, 1031,
- 1031, 1031, 1031, 1031, 1143, 1144, 748, 910, 911, 911,
- 911, 911, 911, 911, 911, 912, 55, 55, 1728, 913,
- 716, 914, 1728, 1145, 1145, 913, 913, 913, 913, 913,
-
- 913, 1144, 726, 815, 55, 55, 803, 1146, 1728, 719,
- 55, 716, 803, 1155, 1728, 1155, 1184, 914, 724, 917,
- 917, 917, 917, 917, 917, 917, 899, 1156, 55, 1728,
- 918, 53, 53, 1146, 1728, 53, 918, 918, 918, 918,
- 918, 918, 919, 920, 920, 920, 920, 920, 920, 920,
- 921, 1581, 790, 1156, 922, 1728, 923, 55, 55, 1157,
- 922, 922, 922, 922, 922, 922, 1047, 1047, 1047, 1047,
- 1047, 1047, 1047, 1158, 53, 55, 55, 53, 1157, 55,
- 55, 772, 923, 733, 928, 928, 928, 928, 928, 928,
- 928, 902, 1728, 1310, 1192, 929, 666, 55, 55, 1158,
-
- 470, 929, 929, 929, 929, 929, 929, 930, 931, 931,
- 931, 931, 931, 931, 931, 932, 1311, 1490, 1728, 933,
- 549, 934, 746, 719, 365, 933, 933, 933, 933, 933,
- 933, 1167, 1168, 1168, 1168, 1168, 1168, 1168, 1170, 1171,
- 1171, 1171, 1171, 1171, 1171, 1287, 55, 934, 744, 940,
- 940, 940, 940, 940, 940, 940, 905, 545, 540, 1288,
- 941, 735, 716, 726, 55, 1201, 941, 941, 941, 941,
- 941, 941, 942, 943, 943, 943, 943, 943, 943, 943,
- 944, 1202, 1203, 723, 945, 1288, 946, 55, 55, 55,
- 945, 945, 945, 945, 945, 945, 1174, 1175, 1175, 1175,
-
- 1175, 1175, 1175, 634, 625, 55, 55, 55, 55, 1287,
- 1289, 719, 946, 861, 957, 957, 957, 957, 957, 957,
- 957, 863, 1193, 1728, 1290, 958, 55, 1544, 55, 55,
- 1289, 958, 958, 958, 958, 958, 958, 959, 960, 960,
- 960, 960, 960, 960, 1728, 1314, 55, 55, 961, 1728,
- 1290, 55, 716, 55, 961, 961, 961, 961, 961, 961,
- 55, 1188, 984, 984, 984, 984, 984, 984, 984, 55,
- 1728, 55, 1602, 984, 1603, 55, 55, 55, 55, 984,
- 984, 984, 984, 984, 984, 985, 985, 985, 985, 985,
- 985, 985, 714, 55, 55, 55, 985, 1604, 55, 55,
-
- 55, 55, 985, 985, 985, 985, 985, 985, 619, 986,
- 986, 986, 986, 986, 986, 986, 55, 55, 55, 55,
- 987, 1610, 435, 625, 615, 1491, 987, 987, 987, 987,
- 987, 987, 1196, 1198, 1229, 1230, 1230, 1230, 1230, 1230,
- 1230, 1235, 1236, 1236, 1236, 1236, 1236, 1236, 435, 987,
- 987, 987, 987, 987, 987, 987, 613, 703, 702, 701,
- 987, 700, 55, 55, 55, 55, 987, 987, 987, 987,
- 987, 987, 267, 988, 988, 988, 988, 988, 988, 988,
- 55, 55, 55, 55, 989, 1624, 699, 1626, 1627, 1535,
- 989, 989, 989, 989, 989, 989, 53, 989, 989, 989,
-
- 989, 989, 989, 989, 992, 993, 993, 993, 993, 993,
- 993, 698, 697, 696, 695, 994, 694, 693, 55, 55,
- 55, 994, 994, 994, 994, 994, 994, 724, 821, 821,
- 821, 821, 821, 821, 821, 899, 55, 55, 55, 822,
- 692, 685, 1642, 55, 1345, 822, 822, 822, 822, 822,
- 822, 995, 996, 996, 996, 996, 996, 996, 1346, 1634,
- 684, 55, 997, 683, 682, 55, 1643, 55, 997, 997,
- 997, 997, 997, 997, 733, 833, 833, 833, 833, 833,
- 833, 833, 902, 55, 1346, 55, 834, 681, 1644, 55,
- 55, 1345, 834, 834, 834, 834, 834, 834, 998, 999,
-
- 999, 999, 999, 999, 999, 1728, 1635, 55, 55, 1000,
- 680, 679, 1646, 678, 55, 1000, 1000, 1000, 1000, 1000,
- 1000, 744, 848, 848, 848, 848, 848, 848, 848, 905,
- 677, 1728, 55, 849, 676, 675, 55, 55, 1350, 849,
- 849, 849, 849, 849, 849, 1001, 1002, 1002, 1002, 1002,
- 1002, 1002, 1351, 1636, 55, 55, 1003, 1655, 55, 1657,
- 674, 673, 1003, 1003, 1003, 1003, 1003, 1003, 1007, 1008,
- 1008, 1008, 1008, 1008, 1008, 453, 55, 672, 1351, 1009,
- 671, 1659, 55, 55, 55, 1009, 1009, 1009, 1009, 1009,
- 1009, 910, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 912,
-
- 55, 55, 55, 1013, 670, 1661, 55, 669, 468, 1013,
- 1013, 1013, 1013, 1013, 1013, 1014, 1015, 1015, 1015, 1015,
- 1015, 1015, 453, 1669, 55, 1662, 1016, 666, 470, 55,
- 464, 55, 1016, 1016, 1016, 1016, 1016, 1016, 919, 1024,
- 1024, 1024, 1024, 1024, 1024, 1024, 921, 55, 1663, 55,
- 1025, 551, 1672, 55, 55, 535, 1025, 1025, 1025, 1025,
- 1025, 1025, 1026, 1027, 1027, 1027, 1027, 1027, 1027, 453,
- 542, 55, 55, 1028, 634, 625, 1680, 1681, 55, 1028,
- 1028, 1028, 1028, 1028, 1028, 930, 1039, 1039, 1039, 1039,
- 1039, 1039, 1039, 932, 535, 625, 55, 1040, 619, 55,
-
- 55, 1686, 619, 1040, 1040, 1040, 1040, 1040, 1040, 1041,
- 1042, 1042, 1042, 1042, 1042, 1042, 453, 55, 55, 612,
- 1043, 1687, 611, 55, 55, 55, 1043, 1043, 1043, 1043,
- 1043, 1043, 942, 1055, 1055, 1055, 1055, 1055, 1055, 1055,
- 944, 55, 55, 55, 1056, 1693, 1690, 55, 55, 610,
- 1056, 1056, 1056, 1056, 1056, 1056, 1057, 1058, 1058, 1058,
- 1058, 1058, 1058, 453, 609, 55, 55, 1059, 608, 607,
- 55, 1700, 55, 1059, 1059, 1059, 1059, 1059, 1059, 861,
- 1066, 1066, 1066, 1066, 1066, 1066, 1066, 863, 55, 1694,
- 55, 1067, 606, 605, 55, 1708, 55, 1067, 1067, 1067,
-
- 1067, 1067, 1067, 1068, 1069, 1069, 1069, 1069, 1069, 1069,
- 1069, 1070, 55, 604, 55, 1071, 603, 1072, 602, 338,
- 239, 1071, 1071, 1071, 1071, 1071, 1071, 1239, 1240, 1240,
- 1240, 1240, 1240, 1240, 1245, 1246, 1246, 1246, 1246, 1246,
- 1246, 55, 55, 1072, 55, 619, 1095, 1095, 1095, 1095,
- 1095, 1095, 1095, 601, 600, 599, 598, 1096, 597, 55,
- 55, 596, 55, 1096, 1096, 1096, 1096, 1096, 1096, 53,
- 1096, 1096, 1096, 1096, 1096, 1096, 1096, 55, 267, 1097,
- 1097, 1097, 1097, 1097, 1097, 1097, 1248, 1249, 1249, 1249,
- 1249, 1249, 1249, 55, 55, 55, 910, 1100, 1100, 1100,
-
- 1100, 1100, 1100, 1100, 1101, 595, 594, 593, 1102, 592,
- 914, 55, 55, 591, 1102, 1102, 1102, 1102, 1102, 1102,
- 1252, 1253, 1253, 1253, 1253, 1253, 1253, 1259, 1260, 1260,
- 1260, 1260, 1260, 1260, 55, 1710, 914, 919, 1103, 1103,
- 1103, 1103, 1103, 1103, 1103, 1104, 590, 589, 581, 1105,
- 578, 923, 55, 575, 574, 1105, 1105, 1105, 1105, 1105,
- 1105, 1262, 1263, 1263, 1263, 1263, 1263, 1263, 1266, 1267,
- 1267, 1267, 1267, 1267, 1267, 55, 1714, 923, 930, 1106,
- 1106, 1106, 1106, 1106, 1106, 1106, 1107, 573, 572, 571,
- 1108, 570, 934, 55, 569, 568, 1108, 1108, 1108, 1108,
-
- 1108, 1108, 1273, 1274, 1274, 1274, 1274, 1274, 1274, 1276,
- 1277, 1277, 1277, 1277, 1277, 1277, 55, 55, 934, 942,
- 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1110, 567, 566,
- 470, 1111, 279, 946, 55, 55, 453, 1111, 1111, 1111,
- 1111, 1111, 1111, 1280, 1281, 1281, 1281, 1281, 1281, 1281,
- 1168, 1168, 1168, 1168, 1168, 1168, 1168, 365, 551, 946,
- 1113, 1114, 1114, 1114, 1114, 1114, 1114, 1115, 535, 542,
- 453, 1116, 539, 450, 444, 55, 55, 1116, 1116, 1116,
- 1116, 1116, 1116, 1117, 1118, 1118, 1118, 1118, 1118, 1118,
- 1118, 1119, 55, 55, 55, 1120, 55, 1121, 55, 1350,
-
- 55, 1120, 1120, 1120, 1120, 1120, 1120, 1308, 1305, 535,
- 55, 533, 444, 1728, 55, 436, 55, 55, 55, 430,
- 520, 1303, 519, 1121, 910, 1124, 1124, 1124, 1124, 1124,
- 1124, 1124, 1101, 1312, 1583, 55, 1125, 1402, 1717, 1728,
- 55, 55, 1125, 1125, 1125, 1125, 1125, 1125, 1126, 1127,
- 1127, 1127, 1127, 1127, 1127, 1127, 1128, 55, 55, 55,
- 1129, 518, 1130, 517, 516, 55, 1129, 1129, 1129, 1129,
- 1129, 1129, 1309, 1313, 515, 55, 1337, 1338, 1338, 1338,
- 1338, 1338, 1338, 55, 1352, 55, 1307, 514, 1130, 919,
- 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1104, 1353, 513,
-
- 1403, 1136, 512, 55, 511, 55, 510, 1136, 1136, 1136,
- 1136, 1136, 1136, 1137, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1139, 1405, 55, 1353, 1140, 509, 1141, 1352, 508,
- 507, 1140, 1140, 1140, 1140, 1140, 1140, 1317, 506, 503,
- 502, 499, 1728, 1246, 1246, 1246, 1246, 1246, 1246, 1246,
- 498, 1358, 55, 1141, 930, 1147, 1147, 1147, 1147, 1147,
- 1147, 1147, 1107, 497, 496, 1359, 1148, 495, 1728, 120,
- 55, 494, 1148, 1148, 1148, 1148, 1148, 1148, 1149, 1150,
- 1150, 1150, 1150, 1150, 1150, 1150, 1151, 1408, 1358, 1360,
- 1152, 1359, 1153, 1360, 493, 481, 1152, 1152, 1152, 1152,
-
- 1152, 1152, 1728, 1361, 480, 479, 478, 1728, 1260, 1260,
- 1260, 1260, 1260, 1260, 1260, 477, 1366, 55, 1153, 942,
- 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1110, 1728, 1361,
- 1367, 1160, 476, 1728, 475, 55, 474, 1160, 1160, 1160,
- 1160, 1160, 1160, 1161, 1162, 1162, 1162, 1162, 1162, 1162,
- 1162, 1163, 1475, 1366, 1368, 1164, 1367, 1165, 1368, 473,
- 277, 1164, 1164, 1164, 1164, 1164, 1164, 1728, 1369, 470,
- 279, 453, 1728, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- 367, 1374, 55, 1165, 1068, 1176, 1176, 1176, 1176, 1176,
- 1176, 1176, 1070, 1728, 1369, 1375, 1177, 450, 1728, 444,
-
- 55, 1374, 1177, 1177, 1177, 1177, 1177, 1177, 1178, 1179,
- 1179, 1179, 1179, 1179, 1179, 1728, 444, 1547, 437, 1180,
- 437, 1375, 55, 429, 55, 1180, 1180, 1180, 1180, 1180,
- 1180, 55, 619, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
- 55, 1728, 55, 420, 989, 1715, 419, 1719, 416, 55,
- 989, 989, 989, 989, 989, 989, 53, 989, 989, 989,
- 989, 989, 989, 989, 55, 267, 1097, 1097, 1097, 1097,
- 1097, 1097, 1097, 415, 55, 55, 1376, 1376, 55, 55,
- 414, 1421, 55, 1207, 1208, 1208, 1208, 1208, 1208, 1208,
- 1377, 1728, 55, 55, 1209, 1422, 55, 55, 1399, 413,
-
- 1209, 1209, 1209, 1209, 1209, 1209, 910, 1012, 1012, 1012,
- 1012, 1012, 1012, 1012, 1101, 1400, 1377, 1728, 1013, 412,
- 411, 1422, 410, 1421, 1013, 1013, 1013, 1013, 1013, 1013,
- 1210, 1211, 1211, 1211, 1211, 1211, 1211, 1728, 409, 408,
- 407, 1212, 406, 405, 404, 403, 55, 1212, 1212, 1212,
- 1212, 1212, 1212, 919, 1024, 1024, 1024, 1024, 1024, 1024,
- 1024, 1104, 402, 1728, 55, 1025, 401, 400, 395, 394,
- 1468, 1025, 1025, 1025, 1025, 1025, 1025, 1213, 1214, 1214,
- 1214, 1214, 1214, 1214, 1469, 1698, 393, 392, 1215, 391,
- 320, 390, 389, 55, 1215, 1215, 1215, 1215, 1215, 1215,
-
- 930, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1107, 388,
- 1469, 55, 1040, 387, 386, 385, 379, 1468, 1040, 1040,
- 1040, 1040, 1040, 1040, 1216, 1217, 1217, 1217, 1217, 1217,
- 1217, 1728, 1723, 279, 367, 1218, 275, 364, 272, 360,
- 266, 1218, 1218, 1218, 1218, 1218, 1218, 942, 1055, 1055,
- 1055, 1055, 1055, 1055, 1055, 1110, 260, 1728, 143, 1056,
- 348, 347, 346, 341, 1470, 1056, 1056, 1056, 1056, 1056,
- 1056, 1219, 1220, 1220, 1220, 1220, 1220, 1220, 1471, 320,
- 340, 339, 1221, 338, 337, 336, 335, 334, 1221, 1221,
- 1221, 1221, 1221, 1221, 1223, 1224, 1224, 1224, 1224, 1224,
-
- 1224, 1224, 1225, 333, 1471, 332, 1226, 331, 1227, 330,
- 329, 328, 1226, 1226, 1226, 1226, 1226, 1226, 1382, 1383,
- 1383, 1383, 1383, 1383, 1383, 1385, 1386, 1386, 1386, 1386,
- 1386, 1386, 55, 327, 1227, 1117, 1231, 1231, 1231, 1231,
- 1231, 1231, 1231, 1119, 326, 323, 322, 1232, 321, 320,
- 55, 1406, 319, 1232, 1232, 1232, 1232, 1232, 1232, 1126,
- 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1128, 1407, 318,
- 317, 1242, 316, 315, 314, 313, 312, 1242, 1242, 1242,
- 1242, 1242, 1242, 1137, 1254, 1254, 1254, 1254, 1254, 1254,
- 1254, 1139, 311, 310, 309, 1255, 308, 307, 306, 305,
-
- 304, 1255, 1255, 1255, 1255, 1255, 1255, 1149, 1268, 1268,
- 1268, 1268, 1268, 1268, 1268, 1151, 303, 302, 301, 1269,
- 300, 299, 298, 297, 143, 1269, 1269, 1269, 1269, 1269,
- 1269, 1161, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1163,
- 296, 295, 294, 1283, 293, 292, 291, 290, 289, 1283,
- 1283, 1283, 1283, 1283, 1283, 1068, 1291, 1291, 1291, 1291,
- 1291, 1291, 1291, 1070, 288, 287, 286, 1292, 285, 284,
- 283, 282, 279, 1292, 1292, 1292, 1292, 1292, 1292, 1293,
- 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1295, 267, 272,
- 259, 1296, 258, 1297, 55, 55, 1470, 1296, 1296, 1296,
-
- 1296, 1296, 1296, 1389, 1390, 1390, 1390, 1390, 1390, 1390,
- 1728, 55, 55, 55, 257, 55, 55, 55, 256, 1297,
- 55, 619, 525, 525, 525, 525, 525, 525, 525, 55,
- 255, 1534, 1576, 55, 55, 55, 1728, 1506, 55, 1318,
- 1319, 1319, 1319, 1319, 1319, 1319, 1320, 1397, 1410, 1660,
- 1321, 1507, 1586, 254, 253, 55, 1321, 1321, 1321, 1321,
- 1321, 1321, 1117, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- 1323, 55, 55, 55, 1324, 252, 1121, 1507, 251, 250,
- 1324, 1324, 1324, 1324, 1324, 1324, 247, 1480, 244, 55,
- 55, 1427, 1428, 1428, 1428, 1428, 1428, 1428, 241, 240,
-
- 1398, 1411, 1121, 1126, 1325, 1325, 1325, 1325, 1325, 1325,
- 1325, 1326, 239, 238, 235, 1327, 234, 1130, 233, 232,
- 231, 1327, 1327, 1327, 1327, 1327, 1327, 1432, 1433, 1433,
- 1433, 1433, 1433, 1433, 1435, 1436, 1436, 1436, 1436, 1436,
- 1436, 230, 229, 1130, 1137, 1328, 1328, 1328, 1328, 1328,
- 1328, 1328, 1329, 228, 227, 226, 1330, 225, 1141, 224,
- 223, 222, 1330, 1330, 1330, 1330, 1330, 1330, 1441, 1442,
- 1442, 1442, 1442, 1442, 1442, 1444, 1445, 1445, 1445, 1445,
- 1445, 1445, 221, 220, 1141, 1149, 1331, 1331, 1331, 1331,
- 1331, 1331, 1331, 1332, 216, 215, 205, 1333, 204, 1153,
-
- 203, 200, 199, 1333, 1333, 1333, 1333, 1333, 1333, 1450,
- 1451, 1451, 1451, 1451, 1451, 1451, 1453, 1454, 1454, 1454,
- 1454, 1454, 1454, 194, 193, 1153, 1161, 1334, 1334, 1334,
- 1334, 1334, 1334, 1334, 1335, 192, 191, 190, 1336, 189,
- 1165, 188, 187, 186, 1336, 1336, 1336, 1336, 1336, 1336,
- 1459, 1460, 1460, 1460, 1460, 1460, 1460, 1462, 1463, 1463,
- 1463, 1463, 1463, 1463, 1506, 55, 1165, 1223, 1339, 1339,
- 1339, 1339, 1339, 1339, 1339, 1225, 185, 181, 1728, 1340,
- 180, 179, 178, 55, 177, 1340, 1340, 1340, 1340, 1340,
- 1340, 1117, 1347, 1347, 1347, 1347, 1347, 1347, 1347, 1323,
-
- 176, 1579, 175, 1348, 1728, 174, 173, 172, 171, 1348,
- 1348, 1348, 1348, 1348, 1348, 1126, 1354, 1354, 1354, 1354,
- 1354, 1354, 1354, 1326, 170, 169, 168, 1355, 167, 166,
- 165, 160, 151, 1355, 1355, 1355, 1355, 1355, 1355, 1137,
- 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1329, 150, 145,
- 59, 1363, 47, 45, 1728, 1728, 1728, 1363, 1363, 1363,
- 1363, 1363, 1363, 1149, 1370, 1370, 1370, 1370, 1370, 1370,
- 1370, 1332, 1728, 1728, 1728, 1371, 1728, 1728, 1728, 1728,
- 1728, 1371, 1371, 1371, 1371, 1371, 1371, 1161, 1378, 1378,
- 1378, 1378, 1378, 1378, 1378, 1335, 1728, 1728, 1728, 1379,
-
- 1728, 1728, 1728, 1728, 1728, 1379, 1379, 1379, 1379, 1379,
- 1379, 1293, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1295,
- 1728, 1728, 1728, 1392, 1728, 1728, 1728, 1728, 1728, 1392,
- 1392, 1392, 1392, 1392, 1392, 1223, 1412, 1412, 1412, 1412,
- 1412, 1412, 1412, 1413, 1728, 1728, 1728, 1414, 1728, 1227,
- 1728, 1728, 1728, 1414, 1414, 1414, 1414, 1414, 1414, 1383,
- 1383, 1383, 1383, 1383, 1383, 1383, 1500, 1501, 1501, 1501,
- 1501, 1501, 1501, 1510, 55, 1227, 1117, 1231, 1231, 1231,
- 1231, 1231, 1231, 1231, 1323, 1728, 1728, 1511, 1232, 1728,
- 1728, 1728, 55, 1728, 1232, 1232, 1232, 1232, 1232, 1232,
-
- 1126, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1326, 1728,
- 1580, 1728, 1242, 1511, 1728, 1728, 1728, 1728, 1242, 1242,
- 1242, 1242, 1242, 1242, 1137, 1254, 1254, 1254, 1254, 1254,
- 1254, 1254, 1329, 1728, 1728, 1728, 1255, 1728, 1728, 1728,
- 1728, 1728, 1255, 1255, 1255, 1255, 1255, 1255, 1149, 1268,
- 1268, 1268, 1268, 1268, 1268, 1268, 1332, 1728, 1728, 1728,
- 1269, 1728, 1728, 1728, 1728, 1728, 1269, 1269, 1269, 1269,
- 1269, 1269, 1161, 1282, 1282, 1282, 1282, 1282, 1282, 1282,
- 1335, 1728, 1728, 1728, 1283, 1728, 1728, 1728, 1728, 1728,
- 1283, 1283, 1283, 1283, 1283, 1283, 1223, 1423, 1423, 1423,
-
- 1423, 1423, 1423, 1423, 1413, 1728, 1728, 1728, 1424, 1728,
- 1728, 1728, 55, 1728, 1424, 1424, 1424, 1424, 1424, 1424,
- 1293, 1472, 1472, 1472, 1472, 1472, 1472, 1472, 1295, 55,
- 55, 55, 1473, 1728, 1510, 1728, 1728, 1728, 1473, 1473,
- 1473, 1473, 1473, 1473, 1487, 55, 1728, 55, 1728, 55,
- 1433, 1433, 1433, 1433, 1433, 1433, 1433, 1728, 1484, 1728,
- 1728, 1488, 1514, 55, 1485, 1223, 1339, 1339, 1339, 1339,
- 1339, 1339, 1339, 1413, 1728, 1548, 1515, 1340, 1728, 1728,
- 1728, 1728, 1514, 1340, 1340, 1340, 1340, 1340, 1340, 1442,
- 1442, 1442, 1442, 1442, 1442, 1442, 1728, 1518, 1518, 1728,
-
- 1728, 1728, 1515, 1451, 1451, 1451, 1451, 1451, 1451, 1451,
- 1522, 1519, 1728, 1460, 1460, 1460, 1460, 1460, 1460, 1460,
- 1522, 1728, 1728, 1728, 1523, 1526, 1527, 1527, 1527, 1527,
- 1527, 1527, 1728, 55, 1728, 55, 55, 1519, 1728, 1529,
- 1530, 1530, 1530, 1530, 1530, 1530, 55, 55, 55, 1728,
- 1523, 55, 55, 55, 55, 1551, 1728, 1551, 55, 55,
- 1728, 55, 1538, 1539, 55, 55, 55, 1543, 1728, 1552,
- 55, 1728, 1728, 1540, 1541, 1542, 55, 55, 1728, 55,
- 1728, 1545, 1553, 1554, 1554, 1554, 1554, 1554, 1554, 1728,
- 1728, 1728, 1728, 1622, 1582, 1552, 1587, 1728, 1557, 1558,
-
- 1558, 1558, 1558, 1558, 1558, 1561, 1562, 1562, 1562, 1562,
- 1562, 1562, 1565, 1566, 1566, 1566, 1566, 1566, 1566, 1569,
- 1570, 1570, 1570, 1570, 1570, 1570, 1527, 1527, 1527, 1527,
- 1527, 1527, 1527, 1573, 1573, 55, 55, 55, 1589, 1590,
- 1590, 1590, 1590, 1590, 1590, 1728, 1728, 1574, 1728, 1728,
- 1728, 1728, 1728, 55, 55, 55, 1728, 1728, 1728, 1728,
- 1728, 1728, 1578, 1585, 1588, 1554, 1554, 1554, 1554, 1554,
- 1554, 1554, 1728, 1574, 1728, 1558, 1558, 1558, 1558, 1558,
- 1558, 1558, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1566,
- 1566, 1566, 1566, 1566, 1566, 1566, 1570, 1570, 1570, 1570,
-
- 1570, 1570, 1570, 1598, 1599, 1599, 1599, 1599, 1599, 1599,
- 55, 55, 1728, 55, 55, 55, 55, 55, 1590, 1590,
- 1590, 1590, 1590, 1590, 1590, 55, 55, 1728, 55, 55,
- 1605, 55, 55, 55, 55, 55, 1728, 1728, 1728, 1728,
- 1728, 1728, 1611, 55, 55, 1601, 55, 1606, 55, 55,
- 1607, 1608, 1609, 1612, 1599, 1599, 1599, 1599, 1599, 1599,
- 1599, 55, 1620, 1628, 55, 55, 55, 55, 55, 55,
- 1728, 55, 55, 1621, 55, 55, 55, 55, 1728, 55,
- 1623, 1625, 55, 55, 1728, 1728, 55, 55, 1629, 55,
- 55, 55, 55, 55, 55, 55, 1647, 1630, 1637, 1728,
-
- 55, 55, 1638, 1645, 55, 1633, 1641, 1639, 1728, 55,
- 55, 1640, 55, 1648, 1649, 55, 1650, 1651, 1728, 55,
- 55, 1728, 55, 55, 55, 55, 1652, 1728, 55, 1728,
- 55, 55, 55, 55, 1728, 55, 1653, 55, 55, 1654,
- 1728, 55, 55, 55, 1658, 1656, 1666, 1665, 1728, 55,
- 55, 55, 1664, 55, 1670, 55, 1675, 55, 1667, 1668,
- 1677, 55, 55, 55, 55, 1728, 1671, 55, 1673, 55,
- 1674, 55, 55, 1676, 1728, 55, 55, 1728, 55, 55,
- 55, 55, 55, 1678, 1728, 55, 55, 1728, 1682, 55,
- 55, 55, 1683, 1728, 55, 1679, 55, 1685, 1684, 1688,
-
- 55, 1728, 1689, 55, 55, 1691, 55, 55, 1728, 55,
- 1695, 1692, 55, 55, 55, 55, 1728, 1728, 55, 1696,
- 1697, 55, 55, 1728, 55, 55, 1701, 55, 55, 1699,
- 55, 55, 55, 55, 1704, 1702, 55, 55, 55, 1728,
- 55, 1706, 1709, 1703, 1705, 55, 55, 55, 55, 55,
- 55, 1728, 1707, 1728, 55, 55, 55, 1711, 1728, 1728,
- 1728, 1728, 1728, 1716, 1712, 55, 55, 55, 55, 1728,
- 1728, 1728, 1713, 1728, 1718, 1721, 1722, 55, 1728, 1728,
- 1726, 1727, 1728, 1720, 1728, 1724, 1728, 1725, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 55, 46, 1728, 1728, 1728,
-
- 1728, 46, 46, 46, 64, 1728, 64, 64, 64, 64,
- 64, 64, 64, 152, 1728, 152, 159, 159, 159, 271,
- 271, 271, 280, 280, 280, 359, 359, 359, 362, 362,
- 362, 363, 363, 363, 370, 370, 370, 368, 368, 368,
- 374, 374, 374, 378, 1728, 378, 443, 443, 443, 448,
- 448, 448, 449, 449, 449, 458, 458, 458, 462, 1728,
- 462, 463, 463, 463, 372, 372, 1728, 1728, 372, 467,
- 467, 467, 471, 471, 471, 362, 362, 362, 532, 532,
- 532, 536, 536, 536, 537, 537, 537, 538, 538, 538,
- 370, 370, 370, 543, 543, 543, 456, 456, 1728, 1728,
-
- 456, 548, 548, 548, 552, 552, 552, 556, 1728, 556,
- 557, 557, 557, 561, 561, 561, 565, 1728, 565, 624,
- 624, 624, 458, 458, 458, 632, 632, 632, 633, 633,
- 633, 641, 641, 641, 645, 1728, 645, 648, 1728, 648,
- 649, 649, 649, 653, 653, 653, 657, 1728, 657, 555,
- 555, 1728, 1728, 555, 559, 559, 1728, 1728, 559, 663,
- 663, 663, 667, 667, 667, 565, 565, 1728, 565, 537,
- 537, 537, 713, 713, 713, 717, 717, 717, 720, 720,
- 720, 721, 721, 721, 722, 722, 722, 727, 727, 727,
- 639, 639, 1728, 1728, 639, 732, 732, 732, 736, 736,
-
- 736, 645, 645, 1728, 645, 647, 647, 1728, 1728, 647,
- 648, 648, 1728, 648, 649, 649, 651, 651, 1728, 1728,
- 651, 743, 743, 743, 747, 747, 747, 657, 657, 1728,
- 657, 751, 1728, 751, 754, 1728, 754, 755, 755, 755,
- 759, 759, 759, 763, 1728, 763, 802, 802, 802, 641,
- 641, 641, 653, 653, 653, 813, 813, 813, 814, 814,
- 814, 822, 822, 822, 826, 1728, 826, 829, 1728, 829,
- 830, 830, 830, 834, 834, 834, 838, 1728, 838, 841,
- 1728, 841, 844, 1728, 844, 845, 845, 845, 849, 849,
- 849, 853, 1728, 853, 750, 1728, 1728, 750, 751, 751,
-
- 1728, 751, 753, 753, 1728, 1728, 753, 754, 754, 1728,
- 754, 755, 755, 757, 757, 1728, 1728, 757, 860, 860,
- 860, 864, 864, 864, 763, 763, 1728, 763, 53, 53,
- 53, 1728, 53, 53, 721, 721, 721, 896, 896, 896,
- 900, 900, 900, 903, 903, 903, 906, 906, 906, 907,
- 907, 907, 908, 908, 908, 913, 913, 913, 820, 820,
- 1728, 1728, 820, 918, 918, 918, 922, 922, 922, 826,
- 826, 1728, 826, 828, 828, 1728, 1728, 828, 829, 829,
- 1728, 829, 830, 830, 832, 832, 1728, 1728, 832, 929,
- 929, 929, 933, 933, 933, 838, 838, 1728, 838, 840,
-
- 1728, 1728, 840, 841, 841, 1728, 841, 843, 843, 1728,
- 1728, 843, 844, 844, 1728, 844, 845, 845, 847, 847,
- 1728, 1728, 847, 941, 941, 941, 945, 945, 945, 853,
- 853, 1728, 853, 947, 1728, 947, 950, 1728, 950, 953,
- 1728, 953, 954, 954, 954, 958, 958, 958, 962, 1728,
- 962, 53, 53, 53, 1728, 53, 53, 990, 990, 990,
- 822, 822, 822, 834, 834, 834, 849, 849, 849, 1004,
- 1004, 1004, 1005, 1005, 1005, 1013, 1013, 1013, 1017, 1728,
- 1017, 1020, 1728, 1020, 1021, 1021, 1021, 1025, 1025, 1025,
- 1029, 1728, 1029, 1032, 1728, 1032, 1035, 1728, 1035, 1036,
-
- 1036, 1036, 1040, 1040, 1040, 1044, 1728, 1044, 1045, 1728,
- 1045, 1048, 1728, 1048, 1051, 1728, 1051, 1052, 1052, 1052,
- 1056, 1056, 1056, 1060, 1728, 1060, 947, 1728, 947, 949,
- 1728, 1728, 949, 950, 950, 1728, 950, 952, 952, 1728,
- 1728, 952, 953, 953, 1728, 953, 954, 954, 956, 956,
- 1728, 1728, 956, 1067, 1067, 1067, 1071, 1071, 1071, 962,
- 962, 1728, 962, 53, 53, 53, 1728, 53, 53, 907,
- 907, 907, 1098, 1098, 1098, 1102, 1102, 1102, 1105, 1105,
- 1105, 1108, 1108, 1108, 1111, 1111, 1111, 1112, 1112, 1112,
- 1120, 1120, 1120, 1011, 1011, 1728, 1728, 1011, 1125, 1125,
-
- 1125, 1129, 1129, 1129, 1017, 1017, 1728, 1017, 1019, 1019,
- 1728, 1728, 1019, 1020, 1020, 1728, 1020, 1021, 1021, 1023,
- 1023, 1728, 1728, 1023, 1136, 1136, 1136, 1140, 1140, 1140,
- 1029, 1029, 1728, 1029, 1031, 1728, 1728, 1031, 1032, 1032,
- 1728, 1032, 1034, 1034, 1728, 1728, 1034, 1035, 1035, 1728,
- 1035, 1036, 1036, 1038, 1038, 1728, 1728, 1038, 1148, 1148,
- 1148, 1152, 1152, 1152, 1044, 1044, 1728, 1044, 1045, 1728,
- 1045, 1047, 1728, 1728, 1047, 1048, 1048, 1728, 1048, 1050,
- 1050, 1728, 1728, 1050, 1051, 1051, 1728, 1051, 1052, 1052,
- 1054, 1054, 1728, 1728, 1054, 1160, 1160, 1160, 1164, 1164,
-
- 1164, 1060, 1060, 1728, 1060, 1166, 1728, 1166, 1169, 1728,
- 1169, 1172, 1728, 1172, 1173, 1173, 1173, 1177, 1177, 1177,
- 1181, 1728, 1181, 53, 53, 53, 1728, 53, 53, 1205,
- 1205, 1205, 1013, 1013, 1013, 1025, 1025, 1025, 1040, 1040,
- 1040, 1056, 1056, 1056, 1222, 1222, 1222, 1228, 1228, 1228,
- 1226, 1226, 1226, 1233, 1233, 1233, 1232, 1232, 1232, 1234,
- 1728, 1234, 1237, 1728, 1237, 1238, 1238, 1238, 1243, 1243,
- 1243, 1242, 1242, 1242, 1244, 1728, 1244, 1247, 1728, 1247,
- 1250, 1728, 1250, 1251, 1251, 1251, 1256, 1256, 1256, 1255,
- 1255, 1255, 1257, 1728, 1257, 1258, 1728, 1258, 1261, 1728,
-
- 1261, 1264, 1728, 1264, 1265, 1265, 1265, 1270, 1270, 1270,
- 1269, 1269, 1269, 1271, 1728, 1271, 1272, 1728, 1272, 1275,
- 1728, 1275, 1278, 1728, 1278, 1279, 1279, 1279, 1284, 1284,
- 1284, 1283, 1283, 1283, 1285, 1728, 1285, 1166, 1728, 1166,
- 1168, 1728, 1728, 1168, 1169, 1169, 1728, 1169, 1171, 1171,
- 1728, 1728, 1171, 1172, 1172, 1728, 1172, 1173, 1173, 1175,
- 1175, 1728, 1728, 1175, 1292, 1292, 1292, 1296, 1296, 1296,
- 1181, 1181, 1728, 1181, 53, 53, 53, 1728, 53, 53,
- 1112, 1112, 1112, 1324, 1324, 1324, 1327, 1327, 1327, 1330,
- 1330, 1330, 1333, 1333, 1333, 1336, 1336, 1336, 1341, 1341,
-
- 1341, 1340, 1340, 1340, 1343, 1728, 1343, 1344, 1344, 1344,
- 1230, 1230, 1728, 1728, 1230, 1348, 1348, 1348, 1349, 1349,
- 1349, 1234, 1234, 1728, 1234, 1236, 1236, 1728, 1728, 1236,
- 1237, 1237, 1728, 1237, 1238, 1238, 1240, 1240, 1728, 1728,
- 1240, 1355, 1355, 1355, 1356, 1356, 1356, 1244, 1244, 1728,
- 1244, 1246, 1728, 1728, 1246, 1247, 1247, 1728, 1247, 1249,
- 1249, 1728, 1728, 1249, 1250, 1250, 1728, 1250, 1251, 1251,
- 1253, 1253, 1728, 1728, 1253, 1363, 1363, 1363, 1364, 1364,
- 1364, 1257, 1257, 1728, 1257, 1258, 1728, 1258, 1260, 1728,
- 1728, 1260, 1261, 1261, 1728, 1261, 1263, 1263, 1728, 1728,
-
- 1263, 1264, 1264, 1728, 1264, 1265, 1265, 1267, 1267, 1728,
- 1728, 1267, 1371, 1371, 1371, 1372, 1372, 1372, 1271, 1271,
- 1728, 1271, 1272, 1728, 1272, 1274, 1728, 1728, 1274, 1275,
- 1275, 1728, 1275, 1277, 1277, 1728, 1728, 1277, 1278, 1278,
- 1728, 1278, 1279, 1279, 1281, 1281, 1728, 1728, 1281, 1379,
- 1379, 1379, 1380, 1380, 1380, 1285, 1285, 1728, 1285, 1381,
- 1728, 1381, 1384, 1728, 1384, 1387, 1728, 1387, 1388, 1388,
- 1388, 1393, 1728, 1393, 1392, 1392, 1392, 1394, 1728, 1394,
- 53, 53, 53, 1728, 53, 53, 1415, 1728, 1415, 1414,
- 1414, 1414, 1416, 1728, 1416, 1232, 1232, 1232, 1417, 1728,
-
- 1417, 1242, 1242, 1242, 1418, 1728, 1418, 1255, 1255, 1255,
- 1419, 1728, 1419, 1269, 1269, 1269, 1420, 1728, 1420, 1283,
- 1283, 1283, 1338, 1338, 1728, 1728, 1338, 1424, 1424, 1424,
- 1425, 1425, 1425, 370, 370, 370, 1343, 1343, 1728, 1343,
- 1426, 1426, 1426, 1429, 1728, 1429, 1430, 1430, 1430, 1431,
- 1431, 1431, 1434, 1728, 1434, 1437, 1728, 1437, 1438, 1438,
- 1438, 1439, 1439, 1439, 1440, 1728, 1440, 1443, 1728, 1443,
- 1446, 1728, 1446, 1447, 1447, 1447, 1448, 1448, 1448, 1449,
- 1728, 1449, 1452, 1728, 1452, 1455, 1728, 1455, 1456, 1456,
- 1456, 1457, 1457, 1457, 1458, 1728, 1458, 1461, 1728, 1461,
-
- 1464, 1728, 1464, 1465, 1465, 1465, 1466, 1466, 1466, 1381,
- 1728, 1381, 1383, 1728, 1728, 1383, 1384, 1384, 1728, 1384,
- 1386, 1386, 1728, 1728, 1386, 1387, 1387, 1728, 1387, 1388,
- 1388, 1390, 1390, 1728, 1728, 1390, 1473, 1473, 1473, 1474,
- 1728, 1474, 1394, 1394, 1728, 1394, 53, 53, 53, 1728,
- 53, 53, 1492, 1492, 1492, 1340, 1340, 1340, 1494, 1728,
- 1494, 1495, 1728, 1495, 1496, 1728, 1496, 1497, 1728, 1497,
- 1498, 1728, 1498, 1499, 1728, 1499, 1502, 1728, 1502, 1503,
- 1503, 1503, 1504, 1504, 1504, 1505, 1728, 1505, 1428, 1428,
- 1728, 1728, 1428, 1429, 1429, 1728, 1429, 1430, 1430, 1508,
-
- 1728, 1508, 1433, 1728, 1728, 1433, 1434, 1434, 1728, 1434,
- 1436, 1436, 1728, 1728, 1436, 1437, 1437, 1728, 1437, 1438,
- 1438, 1512, 1728, 1512, 1440, 1728, 1440, 1442, 1728, 1728,
- 1442, 1443, 1443, 1728, 1443, 1445, 1445, 1728, 1728, 1445,
- 1446, 1446, 1728, 1446, 1447, 1447, 1516, 1728, 1516, 1449,
- 1728, 1449, 1451, 1728, 1728, 1451, 1452, 1452, 1728, 1452,
- 1454, 1454, 1728, 1728, 1454, 1455, 1455, 1728, 1455, 1456,
- 1456, 1520, 1728, 1520, 1458, 1728, 1458, 1460, 1728, 1728,
- 1460, 1461, 1461, 1728, 1461, 1463, 1463, 1728, 1728, 1463,
- 1464, 1464, 1728, 1464, 1465, 1465, 1524, 1728, 1524, 1525,
-
- 1728, 1525, 1528, 1728, 1528, 1531, 1728, 1531, 1532, 1532,
- 1532, 1533, 1728, 1533, 53, 53, 53, 1728, 53, 53,
- 1550, 1728, 1550, 1426, 1728, 1426, 1431, 1728, 1431, 1439,
- 1728, 1439, 1448, 1728, 1448, 1457, 1728, 1457, 1466, 1728,
- 1466, 1501, 1501, 1728, 1728, 1501, 1502, 1502, 1728, 1502,
- 1503, 1503, 1493, 1728, 1493, 1555, 1728, 1555, 1556, 1728,
- 1556, 1559, 1728, 1559, 1560, 1728, 1560, 1563, 1728, 1563,
- 1564, 1728, 1564, 1567, 1728, 1567, 1568, 1728, 1568, 1571,
- 1728, 1571, 1527, 1728, 1728, 1527, 1530, 1530, 1728, 1728,
- 1530, 1575, 1728, 1575, 1504, 1728, 1504, 1591, 1728, 1591,
-
- 1554, 1728, 1728, 1554, 1558, 1728, 1728, 1558, 1562, 1728,
- 1728, 1562, 1566, 1728, 1728, 1566, 1570, 1728, 1728, 1570,
- 1597, 1728, 1597, 1600, 1728, 1600, 1590, 1728, 1728, 1590,
- 1614, 1728, 1614, 1615, 1728, 1615, 1616, 1728, 1616, 1617,
- 1728, 1617, 1618, 1728, 1618, 1599, 1728, 1728, 1599, 1631,
- 1728, 1631, 1632, 1728, 1632, 3, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
-
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728
+ 4, 5, 6, 5, 7, 8, 9, 10, 9, 9,
+ 4, 11, 12, 12, 12, 12, 12, 12, 13, 14,
+ 15, 16, 17, 18, 18, 19, 4, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 18, 29, 30, 31,
+ 32, 33, 18, 34, 35, 36, 37, 38, 39, 18,
+ 18, 40, 44, 45, 46, 46, 46, 46, 46, 46,
+ 46, 47, 53, 54, 49, 48, 49, 50, 769, 51,
+ 48, 48, 48, 48, 48, 48, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 50, 49, 49, 56, 57, 60, 74, 61,
+
+ 62, 112, 75, 499, 63, 78, 79, 80, 76, 64,
+ 113, 77, 81, 65, 67, 66, 192, 500, 193, 49,
+ 58, 48, 48, 48, 48, 48, 48, 48, 68, 70,
+ 190, 1150, 82, 191, 49, 69, 83, 124, 206, 71,
+ 201, 125, 72, 85, 207, 86, 73, 196, 84, 126,
+ 87, 88, 197, 89, 127, 1152, 128, 90, 237, 49,
+ 51, 49, 49, 49, 49, 49, 49, 49, 49, 1723,
+ 99, 100, 202, 49, 937, 136, 238, 137, 49, 49,
+ 49, 49, 49, 49, 91, 101, 1330, 92, 93, 102,
+ 94, 138, 95, 103, 96, 104, 97, 106, 139, 98,
+
+ 119, 107, 105, 114, 49, 120, 121, 208, 122, 123,
+ 108, 109, 209, 141, 110, 115, 111, 116, 129, 117,
+ 203, 142, 118, 243, 130, 143, 131, 144, 132, 49,
+ 231, 319, 133, 244, 134, 135, 148, 148, 148, 148,
+ 148, 148, 148, 232, 320, 212, 204, 148, 213, 339,
+ 214, 205, 148, 148, 148, 148, 148, 148, 149, 150,
+ 150, 150, 150, 150, 150, 1723, 337, 681, 338, 151,
+ 49, 350, 340, 682, 151, 151, 151, 151, 151, 151,
+ 45, 152, 152, 152, 152, 152, 152, 152, 763, 412,
+ 1723, 49, 153, 177, 413, 1723, 49, 153, 153, 153,
+
+ 153, 153, 153, 58, 153, 153, 153, 153, 153, 153,
+ 153, 156, 156, 156, 156, 156, 156, 156, 1723, 178,
+ 1723, 49, 156, 49, 522, 179, 448, 156, 156, 156,
+ 156, 156, 156, 157, 158, 158, 158, 158, 158, 158,
+ 49, 703, 762, 1723, 159, 760, 49, 49, 49, 159,
+ 159, 159, 159, 159, 159, 151, 151, 151, 151, 151,
+ 151, 151, 240, 347, 347, 347, 347, 347, 347, 347,
+ 432, 241, 255, 49, 256, 256, 256, 256, 256, 256,
+ 256, 1723, 1723, 1156, 260, 256, 375, 376, 377, 378,
+ 256, 256, 256, 256, 256, 256, 257, 258, 258, 258,
+
+ 258, 258, 258, 258, 272, 379, 1723, 1723, 259, 260,
+ 260, 1065, 274, 259, 259, 259, 259, 259, 259, 366,
+ 367, 367, 367, 367, 367, 367, 435, 435, 435, 435,
+ 435, 435, 435, 459, 776, 260, 261, 259, 259, 259,
+ 259, 259, 259, 259, 1723, 49, 761, 460, 259, 1723,
+ 1723, 49, 49, 259, 259, 259, 259, 259, 259, 262,
+ 263, 263, 263, 263, 263, 263, 263, 264, 1290, 1723,
+ 49, 265, 460, 1723, 1723, 1723, 265, 265, 265, 265,
+ 265, 265, 49, 265, 265, 265, 265, 265, 265, 265,
+ 268, 269, 269, 269, 269, 269, 269, 270, 1723, 49,
+
+ 781, 271, 375, 376, 377, 378, 271, 271, 271, 271,
+ 271, 271, 272, 273, 273, 273, 273, 273, 273, 273,
+ 274, 459, 1723, 1408, 275, 485, 276, 51, 391, 275,
+ 275, 275, 275, 275, 275, 1723, 392, 450, 451, 451,
+ 451, 451, 451, 451, 51, 486, 495, 1723, 393, 765,
+ 1318, 276, 344, 344, 344, 344, 344, 344, 344, 496,
+ 1723, 487, 1723, 344, 394, 770, 1321, 49, 344, 344,
+ 344, 344, 344, 344, 345, 346, 346, 346, 346, 346,
+ 346, 360, 768, 49, 49, 347, 1324, 1723, 1723, 530,
+ 347, 347, 347, 347, 347, 347, 257, 348, 348, 348,
+
+ 348, 348, 348, 348, 349, 349, 349, 349, 349, 349,
+ 349, 272, 772, 1723, 49, 349, 49, 788, 1327, 1723,
+ 349, 349, 349, 349, 349, 349, 351, 352, 352, 352,
+ 352, 352, 352, 352, 463, 794, 1330, 1408, 353, 448,
+ 448, 613, 465, 353, 353, 353, 353, 353, 353, 356,
+ 353, 353, 353, 353, 353, 353, 353, 360, 361, 361,
+ 361, 361, 361, 361, 361, 362, 613, 1218, 448, 363,
+ 49, 364, 51, 540, 363, 363, 363, 363, 363, 363,
+ 519, 519, 519, 519, 519, 519, 519, 541, 774, 51,
+ 1318, 448, 771, 540, 614, 49, 364, 272, 368, 368,
+
+ 368, 368, 368, 368, 368, 274, 49, 1723, 430, 369,
+ 1321, 51, 541, 775, 369, 369, 369, 369, 369, 369,
+ 370, 371, 371, 371, 371, 371, 371, 49, 51, 871,
+ 849, 372, 1723, 430, 571, 766, 372, 372, 372, 372,
+ 372, 372, 416, 572, 417, 49, 418, 419, 549, 550,
+ 550, 550, 550, 550, 550, 849, 420, 653, 421, 422,
+ 653, 423, 425, 574, 426, 426, 426, 426, 426, 426,
+ 426, 654, 575, 448, 1723, 426, 1723, 1324, 51, 448,
+ 426, 426, 426, 426, 426, 426, 427, 428, 428, 428,
+ 428, 428, 428, 428, 777, 51, 654, 1327, 429, 1723,
+
+ 430, 1723, 49, 429, 429, 429, 429, 429, 429, 553,
+ 554, 554, 554, 554, 554, 554, 633, 634, 634, 634,
+ 634, 634, 634, 655, 773, 430, 431, 429, 429, 429,
+ 429, 429, 429, 429, 1723, 49, 448, 656, 429, 1330,
+ 51, 51, 655, 429, 429, 429, 429, 429, 429, 433,
+ 434, 434, 434, 434, 434, 434, 1723, 51, 51, 1723,
+ 435, 868, 656, 51, 779, 435, 435, 435, 435, 435,
+ 435, 262, 436, 436, 436, 436, 436, 436, 436, 49,
+ 51, 1723, 448, 437, 1723, 1723, 1723, 861, 437, 437,
+ 437, 437, 437, 437, 49, 437, 437, 437, 437, 437,
+
+ 437, 437, 440, 441, 441, 441, 441, 441, 441, 1723,
+ 1723, 1723, 1723, 442, 1282, 1284, 51, 780, 442, 442,
+ 442, 442, 442, 442, 446, 447, 447, 447, 447, 447,
+ 447, 448, 49, 51, 1063, 449, 1290, 1723, 867, 51,
+ 449, 449, 449, 449, 449, 449, 360, 452, 452, 452,
+ 452, 452, 452, 452, 362, 1288, 51, 1488, 453, 869,
+ 51, 51, 51, 453, 453, 453, 453, 453, 453, 454,
+ 455, 455, 455, 455, 455, 455, 448, 51, 51, 51,
+ 456, 882, 874, 51, 879, 456, 456, 456, 456, 456,
+ 456, 272, 461, 461, 461, 461, 461, 461, 461, 274,
+
+ 51, 1408, 1723, 462, 1408, 448, 51, 878, 462, 462,
+ 462, 462, 462, 462, 463, 464, 464, 464, 464, 464,
+ 464, 464, 465, 51, 1340, 1112, 466, 1723, 467, 683,
+ 782, 466, 466, 466, 466, 466, 466, 577, 684, 578,
+ 685, 724, 579, 580, 49, 724, 581, 582, 764, 686,
+ 778, 583, 787, 467, 477, 725, 1345, 49, 478, 1723,
+ 49, 479, 49, 733, 480, 733, 481, 482, 483, 484,
+ 516, 516, 516, 516, 516, 516, 516, 734, 1347, 1723,
+ 725, 516, 930, 51, 1723, 783, 516, 516, 516, 516,
+ 516, 516, 517, 518, 518, 518, 518, 518, 518, 49,
+
+ 51, 1121, 734, 519, 1723, 1723, 49, 930, 519, 519,
+ 519, 519, 519, 519, 427, 520, 520, 520, 520, 520,
+ 520, 520, 521, 521, 521, 521, 521, 521, 521, 535,
+ 1723, 49, 1056, 521, 1723, 1353, 789, 711, 521, 521,
+ 521, 521, 521, 521, 432, 523, 523, 523, 523, 523,
+ 523, 523, 544, 51, 1355, 1132, 524, 1056, 260, 1723,
+ 714, 524, 524, 524, 524, 524, 524, 641, 642, 642,
+ 642, 642, 642, 642, 645, 646, 646, 646, 646, 646,
+ 646, 51, 735, 260, 524, 524, 524, 524, 524, 524,
+ 524, 1723, 1361, 1723, 1723, 524, 736, 51, 51, 784,
+
+ 524, 524, 524, 524, 524, 524, 525, 525, 525, 525,
+ 525, 525, 525, 49, 51, 862, 1723, 526, 1723, 1723,
+ 1363, 736, 526, 526, 526, 526, 526, 526, 49, 526,
+ 526, 526, 526, 526, 526, 526, 360, 529, 529, 529,
+ 529, 529, 529, 529, 530, 786, 735, 1144, 531, 1369,
+ 364, 1371, 1156, 531, 531, 531, 531, 531, 531, 49,
+ 1723, 744, 745, 745, 745, 745, 745, 745, 747, 748,
+ 748, 748, 748, 748, 748, 364, 535, 536, 536, 536,
+ 536, 536, 536, 536, 537, 1723, 1290, 1416, 538, 1218,
+ 539, 1463, 1465, 538, 538, 538, 538, 538, 538, 751,
+
+ 752, 752, 752, 752, 752, 752, 814, 815, 815, 815,
+ 815, 815, 815, 850, 51, 539, 360, 542, 542, 542,
+ 542, 542, 542, 542, 530, 1723, 1501, 851, 543, 1505,
+ 1723, 51, 51, 543, 543, 543, 543, 543, 543, 544,
+ 545, 545, 545, 545, 545, 545, 545, 546, 863, 51,
+ 1723, 547, 851, 548, 958, 1723, 547, 547, 547, 547,
+ 547, 547, 822, 823, 823, 823, 823, 823, 823, 826,
+ 827, 827, 827, 827, 827, 827, 850, 51, 548, 463,
+ 555, 555, 555, 555, 555, 555, 555, 465, 1509, 1723,
+ 1723, 556, 1513, 51, 51, 852, 556, 556, 556, 556,
+
+ 556, 556, 557, 558, 558, 558, 558, 558, 558, 853,
+ 51, 864, 1517, 559, 1723, 1723, 51, 791, 559, 559,
+ 559, 559, 559, 559, 608, 852, 609, 609, 609, 609,
+ 609, 609, 609, 51, 853, 1546, 1723, 609, 1568, 1723,
+ 51, 51, 609, 609, 609, 609, 609, 609, 610, 611,
+ 611, 611, 611, 611, 611, 611, 1144, 51, 51, 1086,
+ 612, 1723, 613, 959, 1723, 612, 612, 612, 612, 612,
+ 612, 834, 835, 835, 835, 835, 835, 835, 837, 838,
+ 838, 838, 838, 838, 838, 51, 51, 613, 610, 612,
+ 612, 612, 612, 612, 612, 612, 659, 448, 1327, 1137,
+
+ 612, 1723, 51, 51, 661, 612, 612, 612, 612, 612,
+ 612, 432, 615, 615, 615, 615, 615, 615, 615, 866,
+ 925, 1140, 872, 616, 1137, 1149, 1723, 1723, 616, 616,
+ 616, 616, 616, 616, 49, 616, 616, 616, 616, 616,
+ 616, 616, 617, 617, 617, 617, 617, 617, 617, 719,
+ 1149, 1138, 1723, 618, 1723, 1281, 1723, 894, 618, 618,
+ 618, 618, 618, 618, 49, 618, 618, 618, 618, 618,
+ 618, 618, 621, 622, 622, 622, 622, 622, 622, 1723,
+ 1281, 1723, 1723, 623, 1132, 448, 51, 51, 623, 623,
+ 623, 623, 623, 623, 360, 452, 452, 452, 452, 452,
+
+ 452, 452, 530, 51, 51, 1324, 453, 1723, 960, 962,
+ 910, 453, 453, 453, 453, 453, 453, 624, 625, 625,
+ 625, 625, 625, 625, 911, 914, 1723, 1128, 626, 1126,
+ 51, 51, 1121, 626, 626, 626, 626, 626, 626, 630,
+ 631, 631, 631, 631, 631, 631, 448, 51, 51, 911,
+ 632, 1723, 964, 965, 51, 632, 632, 632, 632, 632,
+ 632, 535, 635, 635, 635, 635, 635, 635, 635, 537,
+ 448, 51, 1723, 636, 967, 51, 1321, 51, 636, 636,
+ 636, 636, 636, 636, 637, 638, 638, 638, 638, 638,
+ 638, 448, 51, 970, 51, 639, 905, 1723, 51, 977,
+
+ 639, 639, 639, 639, 639, 639, 544, 647, 647, 647,
+ 647, 647, 647, 647, 546, 51, 1117, 1112, 648, 1723,
+ 51, 51, 971, 648, 648, 648, 648, 648, 648, 649,
+ 650, 650, 650, 650, 650, 650, 448, 51, 51, 1723,
+ 651, 1073, 1077, 51, 1723, 651, 651, 651, 651, 651,
+ 651, 463, 657, 657, 657, 657, 657, 657, 657, 465,
+ 51, 1080, 1352, 658, 1723, 448, 51, 51, 658, 658,
+ 658, 658, 658, 658, 659, 660, 660, 660, 660, 660,
+ 660, 660, 661, 51, 51, 1318, 662, 1352, 663, 1081,
+ 1082, 662, 662, 662, 662, 662, 662, 841, 842, 842,
+
+ 842, 842, 842, 842, 745, 745, 745, 745, 745, 745,
+ 745, 51, 51, 663, 699, 699, 699, 699, 699, 699,
+ 699, 1360, 448, 1368, 1220, 699, 1723, 51, 51, 51,
+ 699, 699, 699, 699, 699, 699, 700, 700, 700, 700,
+ 700, 700, 700, 873, 51, 963, 1360, 700, 1368, 1084,
+ 1462, 1723, 700, 700, 700, 700, 700, 700, 610, 701,
+ 701, 701, 701, 701, 701, 701, 702, 702, 702, 702,
+ 702, 702, 702, 728, 1504, 1462, 1508, 702, 1512, 51,
+ 51, 897, 702, 702, 702, 702, 702, 702, 432, 704,
+ 704, 704, 704, 704, 704, 704, 51, 51, 1337, 1504,
+
+ 705, 1508, 1088, 1512, 974, 705, 705, 705, 705, 705,
+ 705, 49, 705, 705, 705, 705, 705, 705, 705, 706,
+ 706, 706, 706, 706, 706, 706, 739, 1201, 1330, 1327,
+ 707, 1324, 1321, 1318, 900, 707, 707, 707, 707, 707,
+ 707, 49, 707, 707, 707, 707, 707, 707, 707, 535,
+ 710, 710, 710, 710, 710, 710, 710, 711, 51, 51,
+ 51, 712, 51, 539, 51, 51, 712, 712, 712, 712,
+ 712, 712, 856, 1201, 1063, 51, 51, 51, 1290, 51,
+ 858, 51, 51, 51, 1085, 875, 876, 865, 539, 544,
+ 713, 713, 713, 713, 713, 713, 713, 714, 877, 51,
+
+ 51, 715, 51, 548, 51, 905, 715, 715, 715, 715,
+ 715, 715, 870, 1096, 1065, 914, 51, 1516, 856, 51,
+ 1059, 51, 51, 1099, 1057, 880, 910, 51, 548, 719,
+ 720, 720, 720, 720, 720, 720, 720, 721, 881, 51,
+ 1723, 722, 1516, 723, 51, 925, 722, 722, 722, 722,
+ 722, 722, 883, 1102, 1567, 1158, 336, 888, 888, 888,
+ 888, 888, 888, 888, 919, 1723, 919, 51, 723, 535,
+ 726, 726, 726, 726, 726, 726, 726, 711, 920, 1567,
+ 1723, 727, 448, 1587, 51, 1105, 727, 727, 727, 727,
+ 727, 727, 728, 729, 729, 729, 729, 729, 729, 729,
+
+ 730, 969, 921, 920, 731, 1723, 732, 921, 1587, 731,
+ 731, 731, 731, 731, 731, 1146, 922, 1588, 448, 1102,
+ 1589, 1723, 835, 835, 835, 835, 835, 835, 835, 931,
+ 51, 732, 544, 737, 737, 737, 737, 737, 737, 737,
+ 714, 922, 1588, 932, 738, 1589, 1723, 51, 1134, 738,
+ 738, 738, 738, 738, 738, 739, 740, 740, 740, 740,
+ 740, 740, 740, 741, 51, 931, 933, 742, 932, 743,
+ 933, 448, 742, 742, 742, 742, 742, 742, 1099, 1723,
+ 934, 51, 1123, 1590, 1723, 943, 944, 944, 944, 944,
+ 944, 944, 972, 51, 743, 659, 753, 753, 753, 753,
+
+ 753, 753, 753, 661, 1723, 934, 448, 754, 1590, 1723,
+ 51, 51, 754, 754, 754, 754, 754, 754, 755, 756,
+ 756, 756, 756, 756, 756, 961, 1096, 1114, 51, 757,
+ 448, 51, 51, 51, 757, 757, 757, 757, 757, 757,
+ 49, 49, 49, 49, 49, 49, 49, 978, 51, 51,
+ 51, 49, 51, 51, 51, 51, 49, 49, 49, 49,
+ 49, 49, 946, 947, 947, 947, 947, 947, 947, 51,
+ 51, 51, 51, 1057, 759, 789, 1057, 790, 790, 790,
+ 790, 790, 790, 790, 966, 968, 1068, 1058, 790, 976,
+ 1723, 51, 51, 790, 790, 790, 790, 790, 790, 791,
+
+ 792, 792, 792, 792, 792, 792, 792, 1220, 51, 51,
+ 1190, 792, 1058, 1182, 448, 1723, 792, 792, 792, 792,
+ 792, 792, 701, 701, 701, 701, 701, 701, 701, 950,
+ 951, 951, 951, 951, 951, 951, 51, 51, 51, 1005,
+ 1006, 1006, 1006, 1006, 1006, 1006, 1013, 1014, 1014, 1014,
+ 1014, 1014, 1014, 51, 51, 51, 49, 702, 702, 702,
+ 702, 702, 702, 702, 973, 1201, 1105, 1102, 702, 1069,
+ 1072, 1591, 1608, 702, 702, 702, 702, 702, 702, 793,
+ 348, 348, 348, 348, 348, 348, 348, 262, 795, 795,
+ 795, 795, 795, 795, 795, 937, 1591, 1608, 1099, 796,
+
+ 1614, 1096, 1201, 1105, 796, 796, 796, 796, 796, 796,
+ 49, 796, 796, 796, 796, 796, 796, 796, 799, 800,
+ 800, 800, 800, 800, 800, 1614, 1065, 858, 937, 801,
+ 1158, 1105, 51, 51, 801, 801, 801, 801, 801, 801,
+ 535, 635, 635, 635, 635, 635, 635, 635, 711, 51,
+ 51, 739, 636, 1185, 51, 1186, 1059, 636, 636, 636,
+ 636, 636, 636, 802, 803, 803, 803, 803, 803, 803,
+ 1060, 51, 933, 931, 804, 925, 1189, 51, 1146, 804,
+ 804, 804, 804, 804, 804, 544, 647, 647, 647, 647,
+ 647, 647, 647, 714, 51, 1060, 1102, 648, 728, 51,
+
+ 1194, 1059, 648, 648, 648, 648, 648, 648, 805, 806,
+ 806, 806, 806, 806, 806, 1723, 51, 1192, 921, 807,
+ 919, 51, 51, 914, 807, 807, 807, 807, 807, 807,
+ 811, 812, 812, 812, 812, 812, 812, 448, 51, 51,
+ 1723, 813, 1195, 1134, 51, 1099, 813, 813, 813, 813,
+ 813, 813, 719, 816, 816, 816, 816, 816, 816, 816,
+ 721, 51, 1293, 719, 817, 910, 51, 51, 905, 817,
+ 817, 817, 817, 817, 817, 818, 819, 819, 819, 819,
+ 819, 819, 448, 51, 51, 1294, 820, 1123, 1096, 51,
+ 1114, 820, 820, 820, 820, 820, 820, 728, 828, 828,
+
+ 828, 828, 828, 828, 828, 730, 51, 1295, 1296, 829,
+ 1001, 51, 51, 51, 829, 829, 829, 829, 829, 829,
+ 830, 831, 831, 831, 831, 831, 831, 448, 51, 51,
+ 51, 832, 986, 1299, 1105, 51, 832, 832, 832, 832,
+ 832, 832, 739, 843, 843, 843, 843, 843, 843, 843,
+ 741, 1297, 51, 1102, 844, 1099, 1310, 51, 51, 844,
+ 844, 844, 844, 844, 844, 845, 846, 846, 846, 846,
+ 846, 846, 448, 1096, 51, 51, 847, 1094, 986, 1311,
+ 51, 847, 847, 847, 847, 847, 847, 659, 854, 854,
+ 854, 854, 854, 854, 854, 661, 856, 51, 1065, 855,
+
+ 858, 659, 852, 51, 855, 855, 855, 855, 855, 855,
+ 856, 857, 857, 857, 857, 857, 857, 857, 858, 51,
+ 51, 1117, 859, 850, 860, 939, 900, 859, 859, 859,
+ 859, 859, 859, 1087, 51, 1118, 51, 1017, 1018, 1018,
+ 1018, 1018, 1018, 1018, 51, 975, 927, 51, 1117, 860,
+ 51, 51, 884, 884, 884, 884, 884, 884, 884, 1079,
+ 1118, 51, 1723, 884, 51, 1074, 51, 51, 884, 884,
+ 884, 884, 884, 884, 885, 885, 885, 885, 885, 885,
+ 885, 1184, 1075, 51, 897, 885, 51, 1723, 51, 51,
+ 885, 885, 885, 885, 885, 885, 886, 887, 887, 887,
+
+ 887, 887, 887, 51, 916, 51, 51, 888, 894, 51,
+ 51, 1083, 888, 888, 888, 888, 888, 888, 262, 889,
+ 889, 889, 889, 889, 889, 889, 51, 51, 907, 1001,
+ 890, 986, 1390, 900, 1301, 890, 890, 890, 890, 890,
+ 890, 49, 890, 890, 890, 890, 890, 890, 890, 719,
+ 893, 893, 893, 893, 893, 893, 893, 894, 897, 894,
+ 986, 895, 858, 723, 661, 739, 895, 895, 895, 895,
+ 895, 895, 1025, 1026, 1026, 1026, 1026, 1026, 1026, 1028,
+ 1029, 1029, 1029, 1029, 1029, 1029, 939, 51, 723, 728,
+ 896, 896, 896, 896, 896, 896, 896, 897, 900, 544,
+
+ 735, 898, 733, 732, 51, 728, 898, 898, 898, 898,
+ 898, 898, 1032, 1033, 1033, 1033, 1033, 1033, 1033, 1041,
+ 1042, 1042, 1042, 1042, 1042, 1042, 927, 51, 732, 739,
+ 899, 899, 899, 899, 899, 899, 899, 900, 897, 535,
+ 724, 901, 719, 743, 51, 916, 901, 901, 901, 901,
+ 901, 901, 1044, 1045, 1045, 1045, 1045, 1045, 1045, 1048,
+ 1049, 1049, 1049, 1049, 1049, 1049, 1126, 51, 743, 905,
+ 906, 906, 906, 906, 906, 906, 906, 907, 894, 907,
+ 1127, 908, 904, 909, 51, 51, 908, 908, 908, 908,
+ 908, 908, 944, 944, 944, 944, 944, 944, 944, 1070,
+
+ 1071, 810, 51, 798, 900, 1127, 1126, 51, 909, 719,
+ 912, 912, 912, 912, 912, 912, 912, 894, 1076, 897,
+ 1723, 913, 894, 892, 51, 51, 913, 913, 913, 913,
+ 913, 913, 914, 915, 915, 915, 915, 915, 915, 915,
+ 916, 1078, 51, 1128, 917, 1723, 918, 1128, 1063, 917,
+ 917, 917, 917, 917, 917, 798, 1065, 1129, 659, 1089,
+ 858, 1723, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1138,
+ 661, 918, 728, 923, 923, 923, 923, 923, 923, 923,
+ 897, 463, 1129, 1139, 924, 655, 1723, 51, 653, 924,
+ 924, 924, 924, 924, 924, 925, 926, 926, 926, 926,
+
+ 926, 926, 926, 927, 51, 1138, 1140, 928, 1139, 929,
+ 1140, 741, 928, 928, 928, 928, 928, 928, 1180, 1723,
+ 1141, 714, 730, 711, 1723, 1042, 1042, 1042, 1042, 1042,
+ 1042, 1042, 1150, 51, 929, 739, 935, 935, 935, 935,
+ 935, 935, 935, 900, 1723, 1141, 1151, 936, 721, 1723,
+ 51, 810, 936, 936, 936, 936, 936, 936, 937, 938,
+ 938, 938, 938, 938, 938, 938, 939, 51, 1150, 1152,
+ 940, 1151, 941, 1152, 1396, 940, 940, 940, 940, 940,
+ 940, 798, 1723, 1153, 51, 714, 711, 1723, 1162, 1163,
+ 1163, 1163, 1163, 1163, 1163, 1177, 798, 941, 856, 952,
+
+ 952, 952, 952, 952, 952, 952, 858, 1723, 1153, 49,
+ 953, 49, 1723, 51, 1282, 953, 953, 953, 953, 953,
+ 953, 954, 955, 955, 955, 955, 955, 955, 1283, 49,
+ 51, 785, 956, 49, 49, 51, 767, 956, 956, 956,
+ 956, 956, 956, 51, 1183, 979, 979, 979, 979, 979,
+ 979, 979, 51, 1283, 661, 465, 979, 1399, 51, 51,
+ 51, 979, 979, 979, 979, 979, 979, 980, 980, 980,
+ 980, 980, 980, 980, 1112, 51, 51, 544, 980, 741,
+ 714, 51, 1318, 980, 980, 980, 980, 980, 980, 614,
+ 981, 981, 981, 981, 981, 981, 981, 1404, 51, 1473,
+
+ 360, 982, 1474, 430, 540, 535, 982, 982, 982, 982,
+ 982, 982, 1165, 1166, 1166, 1166, 1166, 1166, 1166, 1169,
+ 1170, 1170, 1170, 1170, 1170, 1170, 51, 51, 430, 982,
+ 982, 982, 982, 982, 982, 982, 730, 711, 721, 718,
+ 982, 629, 620, 51, 51, 982, 982, 982, 982, 982,
+ 982, 262, 983, 983, 983, 983, 983, 983, 983, 1188,
+ 714, 711, 1181, 984, 709, 620, 610, 608, 984, 984,
+ 984, 984, 984, 984, 49, 984, 984, 984, 984, 984,
+ 984, 984, 987, 988, 988, 988, 988, 988, 988, 1121,
+ 698, 697, 696, 989, 695, 694, 51, 1321, 989, 989,
+
+ 989, 989, 989, 989, 719, 816, 816, 816, 816, 816,
+ 816, 816, 894, 51, 693, 692, 817, 1476, 51, 51,
+ 1282, 817, 817, 817, 817, 817, 817, 990, 991, 991,
+ 991, 991, 991, 991, 1723, 51, 51, 691, 992, 1471,
+ 1484, 51, 690, 992, 992, 992, 992, 992, 992, 728,
+ 828, 828, 828, 828, 828, 828, 828, 897, 51, 1723,
+ 689, 829, 1477, 51, 51, 1284, 829, 829, 829, 829,
+ 829, 829, 993, 994, 994, 994, 994, 994, 994, 1285,
+ 51, 51, 688, 995, 1472, 687, 1478, 680, 995, 995,
+ 995, 995, 995, 995, 739, 843, 843, 843, 843, 843,
+
+ 843, 843, 900, 679, 1285, 678, 844, 677, 51, 51,
+ 1284, 844, 844, 844, 844, 844, 844, 996, 997, 997,
+ 997, 997, 997, 997, 1723, 51, 51, 676, 998, 1481,
+ 675, 51, 674, 998, 998, 998, 998, 998, 998, 1002,
+ 1003, 1003, 1003, 1003, 1003, 1003, 448, 1532, 51, 1723,
+ 1004, 1544, 673, 51, 51, 1004, 1004, 1004, 1004, 1004,
+ 1004, 905, 1007, 1007, 1007, 1007, 1007, 1007, 1007, 907,
+ 51, 51, 672, 1008, 671, 670, 51, 669, 1008, 1008,
+ 1008, 1008, 1008, 1008, 1009, 1010, 1010, 1010, 1010, 1010,
+ 1010, 448, 1539, 51, 1541, 1011, 668, 667, 51, 51,
+
+ 1011, 1011, 1011, 1011, 1011, 1011, 914, 1019, 1019, 1019,
+ 1019, 1019, 1019, 1019, 916, 51, 51, 666, 1020, 665,
+ 51, 1572, 51, 1020, 1020, 1020, 1020, 1020, 1020, 1021,
+ 1022, 1022, 1022, 1022, 1022, 1022, 448, 51, 664, 51,
+ 1023, 463, 661, 465, 1579, 1023, 1023, 1023, 1023, 1023,
+ 1023, 925, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 927,
+ 1576, 459, 546, 1035, 530, 51, 51, 51, 1035, 1035,
+ 1035, 1035, 1035, 1035, 1036, 1037, 1037, 1037, 1037, 1037,
+ 1037, 448, 51, 51, 51, 1038, 537, 1597, 51, 51,
+ 1038, 1038, 1038, 1038, 1038, 1038, 937, 1050, 1050, 1050,
+
+ 1050, 1050, 1050, 1050, 939, 51, 51, 629, 1051, 1598,
+ 51, 51, 51, 1051, 1051, 1051, 1051, 1051, 1051, 1052,
+ 1053, 1053, 1053, 1053, 1053, 1053, 448, 51, 51, 51,
+ 1054, 1599, 1605, 51, 51, 1054, 1054, 1054, 1054, 1054,
+ 1054, 856, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 858,
+ 51, 51, 620, 1062, 1619, 530, 1621, 620, 1062, 1062,
+ 1062, 1062, 1062, 1062, 1063, 1064, 1064, 1064, 1064, 1064,
+ 1064, 1064, 1065, 51, 51, 614, 1066, 51, 1067, 1340,
+ 51, 1066, 1066, 1066, 1066, 1066, 1066, 1132, 1144, 614,
+ 51, 51, 1156, 1341, 51, 1324, 1327, 51, 1196, 51,
+
+ 1330, 1178, 1179, 1067, 51, 614, 1090, 1090, 1090, 1090,
+ 1090, 1090, 1090, 1187, 1197, 1198, 51, 1091, 1341, 607,
+ 606, 51, 1091, 1091, 1091, 1091, 1091, 1091, 49, 1091,
+ 1091, 1091, 1091, 1091, 1091, 1091, 51, 262, 1092, 1092,
+ 1092, 1092, 1092, 1092, 1092, 605, 51, 51, 51, 604,
+ 51, 603, 51, 51, 905, 1095, 1095, 1095, 1095, 1095,
+ 1095, 1095, 1096, 51, 51, 51, 1097, 51, 909, 51,
+ 51, 1097, 1097, 1097, 1097, 1097, 1097, 1303, 1191, 1193,
+ 1224, 1225, 1225, 1225, 1225, 1225, 1225, 51, 1309, 602,
+ 51, 601, 51, 909, 914, 1098, 1098, 1098, 1098, 1098,
+
+ 1098, 1098, 1099, 600, 1305, 599, 1100, 51, 918, 51,
+ 598, 1100, 1100, 1100, 1100, 1100, 1100, 1230, 1231, 1231,
+ 1231, 1231, 1231, 1231, 1234, 1235, 1235, 1235, 1235, 1235,
+ 1235, 597, 51, 918, 925, 1101, 1101, 1101, 1101, 1101,
+ 1101, 1101, 1102, 333, 234, 596, 1103, 595, 929, 51,
+ 594, 1103, 1103, 1103, 1103, 1103, 1103, 1240, 1241, 1241,
+ 1241, 1241, 1241, 1241, 1243, 1244, 1244, 1244, 1244, 1244,
+ 1244, 593, 51, 929, 937, 1104, 1104, 1104, 1104, 1104,
+ 1104, 1104, 1105, 592, 591, 590, 1106, 589, 941, 51,
+ 588, 1106, 1106, 1106, 1106, 1106, 1106, 1247, 1248, 1248,
+
+ 1248, 1248, 1248, 1248, 1254, 1255, 1255, 1255, 1255, 1255,
+ 1255, 51, 1340, 941, 1108, 1109, 1109, 1109, 1109, 1109,
+ 1109, 1110, 587, 586, 585, 1111, 1723, 584, 51, 576,
+ 1111, 1111, 1111, 1111, 1111, 1111, 1112, 1113, 1113, 1113,
+ 1113, 1113, 1113, 1113, 1114, 573, 1306, 570, 1115, 569,
+ 1116, 1723, 568, 1115, 1115, 1115, 1115, 1115, 1115, 1257,
+ 1258, 1258, 1258, 1258, 1258, 1258, 1261, 1262, 1262, 1262,
+ 1262, 1262, 1262, 1345, 51, 1116, 905, 1119, 1119, 1119,
+ 1119, 1119, 1119, 1119, 1096, 567, 566, 1346, 1120, 565,
+ 564, 51, 51, 1120, 1120, 1120, 1120, 1120, 1120, 1121,
+
+ 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1123, 1307, 51,
+ 563, 1124, 1346, 1125, 1622, 562, 1124, 1124, 1124, 1124,
+ 1124, 1124, 1268, 1269, 1269, 1269, 1269, 1269, 1269, 1271,
+ 1272, 1272, 1272, 1272, 1272, 1272, 1345, 51, 1125, 914,
+ 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1099, 561, 465,
+ 1723, 1131, 274, 448, 51, 1394, 1131, 1131, 1131, 1131,
+ 1131, 1131, 1132, 1133, 1133, 1133, 1133, 1133, 1133, 1133,
+ 1134, 360, 1395, 546, 1135, 1723, 1136, 530, 537, 1135,
+ 1135, 1135, 1135, 1135, 1135, 1275, 1276, 1276, 1276, 1276,
+ 1276, 1276, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1347,
+
+ 51, 1136, 925, 1142, 1142, 1142, 1142, 1142, 1142, 1142,
+ 1102, 448, 534, 1348, 1143, 445, 439, 51, 51, 1143,
+ 1143, 1143, 1143, 1143, 1143, 1144, 1145, 1145, 1145, 1145,
+ 1145, 1145, 1145, 1146, 51, 51, 1397, 1147, 1348, 1148,
+ 1218, 1288, 1147, 1147, 1147, 1147, 1147, 1147, 1408, 1290,
+ 1300, 51, 1332, 1333, 1333, 1333, 1333, 1333, 1333, 51,
+ 1347, 51, 1298, 51, 1148, 937, 1154, 1154, 1154, 1154,
+ 1154, 1154, 1154, 1105, 1723, 530, 51, 1155, 51, 1650,
+ 51, 51, 1155, 1155, 1155, 1155, 1155, 1155, 1156, 1157,
+ 1157, 1157, 1157, 1157, 1157, 1157, 1158, 51, 51, 1723,
+
+ 1159, 1629, 1160, 1288, 528, 1159, 1159, 1159, 1159, 1159,
+ 1159, 1723, 1304, 439, 51, 1241, 1241, 1241, 1241, 1241,
+ 1241, 1241, 51, 431, 1353, 1302, 51, 1160, 1063, 1171,
+ 1171, 1171, 1171, 1171, 1171, 1171, 1065, 425, 1354, 51,
+ 1172, 515, 514, 51, 1353, 1172, 1172, 1172, 1172, 1172,
+ 1172, 1173, 1174, 1174, 1174, 1174, 1174, 1174, 1723, 1485,
+ 1398, 513, 1175, 1354, 512, 51, 511, 1175, 1175, 1175,
+ 1175, 1175, 1175, 51, 614, 1199, 1199, 1199, 1199, 1199,
+ 1199, 1199, 51, 1723, 510, 509, 984, 1637, 508, 507,
+ 51, 984, 984, 984, 984, 984, 984, 49, 984, 984,
+
+ 984, 984, 984, 984, 984, 51, 262, 1092, 1092, 1092,
+ 1092, 1092, 1092, 1092, 506, 51, 1355, 1355, 505, 1361,
+ 51, 1361, 51, 1202, 1203, 1203, 1203, 1203, 1203, 1203,
+ 1356, 1723, 51, 1362, 1204, 1723, 1652, 51, 504, 1204,
+ 1204, 1204, 1204, 1204, 1204, 905, 1007, 1007, 1007, 1007,
+ 1007, 1007, 1007, 1096, 1403, 1356, 1723, 1008, 1362, 51,
+ 1723, 1363, 1008, 1008, 1008, 1008, 1008, 1008, 1205, 1206,
+ 1206, 1206, 1206, 1206, 1206, 1364, 51, 503, 502, 1207,
+ 501, 1638, 51, 498, 1207, 1207, 1207, 1207, 1207, 1207,
+ 914, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1099, 51,
+
+ 1364, 497, 1020, 494, 1639, 51, 1363, 1020, 1020, 1020,
+ 1020, 1020, 1020, 1208, 1209, 1209, 1209, 1209, 1209, 1209,
+ 1723, 493, 51, 492, 1210, 491, 490, 1641, 115, 1210,
+ 1210, 1210, 1210, 1210, 1210, 925, 1034, 1034, 1034, 1034,
+ 1034, 1034, 1034, 1102, 489, 1723, 488, 1035, 476, 51,
+ 51, 1369, 1035, 1035, 1035, 1035, 1035, 1035, 1211, 1212,
+ 1212, 1212, 1212, 1212, 1212, 1370, 51, 51, 475, 1213,
+ 474, 1654, 51, 473, 1213, 1213, 1213, 1213, 1213, 1213,
+ 937, 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1105, 51,
+ 1370, 1657, 1051, 472, 51, 51, 51, 1051, 1051, 1051,
+
+ 1051, 1051, 1051, 1214, 1215, 1215, 1215, 1215, 1215, 1215,
+ 1630, 51, 51, 51, 1216, 471, 1656, 51, 51, 1216,
+ 1216, 1216, 1216, 1216, 1216, 1218, 1219, 1219, 1219, 1219,
+ 1219, 1219, 1219, 1220, 51, 51, 1658, 1221, 470, 1222,
+ 469, 468, 1221, 1221, 1221, 1221, 1221, 1221, 1308, 1312,
+ 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1269, 1269, 1269,
+ 1269, 1269, 1269, 1269, 1222, 1112, 1226, 1226, 1226, 1226,
+ 1226, 1226, 1226, 1114, 272, 465, 274, 1227, 448, 362,
+ 51, 51, 1227, 1227, 1227, 1227, 1227, 1227, 1121, 1236,
+ 1236, 1236, 1236, 1236, 1236, 1236, 1123, 51, 51, 445,
+
+ 1237, 439, 1667, 1675, 51, 1237, 1237, 1237, 1237, 1237,
+ 1237, 1132, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1134,
+ 439, 51, 432, 1250, 432, 424, 1676, 51, 1250, 1250,
+ 1250, 1250, 1250, 1250, 1144, 1263, 1263, 1263, 1263, 1263,
+ 1263, 1263, 1146, 415, 51, 414, 1264, 411, 410, 1681,
+ 51, 1264, 1264, 1264, 1264, 1264, 1264, 1156, 1277, 1277,
+ 1277, 1277, 1277, 1277, 1277, 1158, 409, 51, 408, 1278,
+ 407, 1682, 51, 51, 1278, 1278, 1278, 1278, 1278, 1278,
+ 1063, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1065, 51,
+ 51, 406, 1287, 1688, 1685, 405, 404, 1287, 1287, 1287,
+
+ 1287, 1287, 1287, 1288, 1289, 1289, 1289, 1289, 1289, 1289,
+ 1289, 1290, 51, 1369, 1371, 1291, 1371, 1292, 403, 402,
+ 1291, 1291, 1291, 1291, 1291, 1291, 401, 1723, 1372, 51,
+ 1723, 1377, 1378, 1378, 1378, 1378, 1378, 1378, 1391, 51,
+ 51, 51, 1292, 51, 614, 520, 520, 520, 520, 520,
+ 520, 520, 1723, 1372, 400, 1723, 51, 51, 51, 1416,
+ 51, 1313, 1314, 1314, 1314, 1314, 1314, 1314, 1315, 1392,
+ 399, 1405, 1316, 1417, 398, 51, 1400, 1316, 1316, 1316,
+ 1316, 1316, 1316, 1112, 1317, 1317, 1317, 1317, 1317, 1317,
+ 1317, 1318, 51, 397, 396, 1319, 395, 1116, 1417, 390,
+
+ 1319, 1319, 1319, 1319, 1319, 1319, 1380, 1381, 1381, 1381,
+ 1381, 1381, 1381, 1384, 1385, 1385, 1385, 1385, 1385, 1385,
+ 1416, 51, 1116, 1121, 1320, 1320, 1320, 1320, 1320, 1320,
+ 1320, 1321, 389, 51, 1723, 1322, 51, 1125, 51, 51,
+ 1322, 1322, 1322, 1322, 1322, 1322, 388, 387, 386, 1393,
+ 51, 315, 385, 51, 384, 383, 51, 1401, 382, 1723,
+ 381, 1406, 1125, 1132, 1323, 1323, 1323, 1323, 1323, 1323,
+ 1323, 1324, 1529, 380, 1402, 1325, 374, 1136, 274, 362,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1422, 1423, 1423, 1423,
+ 1423, 1423, 1423, 1427, 1428, 1428, 1428, 1428, 1428, 1428,
+
+ 270, 51, 1136, 1144, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1327, 359, 267, 355, 1328, 261, 1148, 51, 255,
+ 1328, 1328, 1328, 1328, 1328, 1328, 1430, 1431, 1431, 1431,
+ 1431, 1431, 1431, 1436, 1437, 1437, 1437, 1437, 1437, 1437,
+ 138, 51, 1148, 1156, 1329, 1329, 1329, 1329, 1329, 1329,
+ 1329, 1330, 343, 342, 341, 1331, 336, 1160, 51, 315,
+ 1331, 1331, 1331, 1331, 1331, 1331, 1439, 1440, 1440, 1440,
+ 1440, 1440, 1440, 1445, 1446, 1446, 1446, 1446, 1446, 1446,
+ 1463, 51, 1160, 1218, 1334, 1334, 1334, 1334, 1334, 1334,
+ 1334, 1220, 335, 334, 1464, 1335, 333, 332, 51, 51,
+
+ 1335, 1335, 1335, 1335, 1335, 1335, 1112, 1342, 1342, 1342,
+ 1342, 1342, 1342, 1342, 1318, 1470, 51, 331, 1343, 1464,
+ 330, 51, 51, 1343, 1343, 1343, 1343, 1343, 1343, 1121,
+ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1321, 51, 51,
+ 1689, 1350, 329, 1695, 1703, 51, 1350, 1350, 1350, 1350,
+ 1350, 1350, 1132, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1324, 328, 51, 327, 1358, 326, 325, 51, 51, 1358,
+ 1358, 1358, 1358, 1358, 1358, 1144, 1365, 1365, 1365, 1365,
+ 1365, 1365, 1365, 1327, 51, 51, 1705, 1366, 324, 323,
+ 1710, 322, 1366, 1366, 1366, 1366, 1366, 1366, 1156, 1373,
+
+ 1373, 1373, 1373, 1373, 1373, 1373, 1330, 321, 1709, 318,
+ 1374, 317, 316, 51, 51, 1374, 1374, 1374, 1374, 1374,
+ 1374, 1288, 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1290,
+ 51, 51, 315, 1387, 1712, 314, 51, 51, 1387, 1387,
+ 1387, 1387, 1387, 1387, 1218, 1407, 1407, 1407, 1407, 1407,
+ 1407, 1407, 1408, 51, 51, 313, 1409, 312, 1222, 1714,
+ 311, 1409, 1409, 1409, 1409, 1409, 1409, 1448, 1449, 1449,
+ 1449, 1449, 1449, 1449, 1454, 1455, 1455, 1455, 1455, 1455,
+ 1455, 1463, 51, 1222, 1112, 1226, 1226, 1226, 1226, 1226,
+ 1226, 1226, 1318, 310, 309, 1723, 1227, 308, 307, 51,
+
+ 51, 1227, 1227, 1227, 1227, 1227, 1227, 1121, 1236, 1236,
+ 1236, 1236, 1236, 1236, 1236, 1321, 1542, 51, 306, 1237,
+ 1723, 305, 51, 51, 1237, 1237, 1237, 1237, 1237, 1237,
+ 1132, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1324, 51,
+ 51, 304, 1250, 303, 302, 51, 51, 1250, 1250, 1250,
+ 1250, 1250, 1250, 1144, 1263, 1263, 1263, 1263, 1263, 1263,
+ 1263, 1327, 51, 51, 301, 1264, 300, 299, 51, 298,
+ 1264, 1264, 1264, 1264, 1264, 1264, 1156, 1277, 1277, 1277,
+ 1277, 1277, 1277, 1277, 1330, 51, 297, 296, 1278, 295,
+ 294, 293, 292, 1278, 1278, 1278, 1278, 1278, 1278, 1218,
+
+ 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1408, 138, 291,
+ 290, 1419, 289, 288, 287, 286, 1419, 1419, 1419, 1419,
+ 1419, 1419, 1457, 1458, 1458, 1458, 1458, 1458, 1458, 1378,
+ 1378, 1378, 1378, 1378, 1378, 1378, 1465, 1465, 51, 51,
+ 51, 51, 51, 1495, 1496, 1496, 1496, 1496, 1496, 1496,
+ 1466, 1723, 1501, 285, 284, 51, 51, 51, 51, 51,
+ 283, 282, 281, 280, 279, 278, 1502, 1479, 1486, 1475,
+ 1483, 1482, 1501, 1480, 1505, 1466, 1723, 1288, 1467, 1467,
+ 1467, 1467, 1467, 1467, 1467, 1290, 1723, 277, 1506, 1468,
+ 274, 1502, 262, 267, 1468, 1468, 1468, 1468, 1468, 1468,
+
+ 1218, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1408, 254,
+ 253, 1723, 1335, 1506, 252, 251, 1505, 1335, 1335, 1335,
+ 1335, 1335, 1335, 1428, 1428, 1428, 1428, 1428, 1428, 1428,
+ 1723, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1509, 1509,
+ 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1513, 1513, 250,
+ 249, 248, 1510, 1723, 247, 1723, 1517, 1517, 246, 245,
+ 242, 1514, 1723, 1455, 1455, 1455, 1455, 1455, 1455, 1455,
+ 1518, 1723, 239, 236, 235, 234, 233, 1510, 1723, 1521,
+ 1522, 1522, 1522, 1522, 1522, 1522, 1514, 1723, 1524, 1525,
+ 1525, 1525, 1525, 1525, 1525, 1518, 1723, 51, 51, 51,
+
+ 51, 51, 51, 51, 51, 51, 230, 229, 51, 228,
+ 227, 226, 225, 224, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 1530, 1531, 51, 1533, 1534, 1535, 1536,
+ 1537, 1538, 1546, 1540, 1546, 223, 222, 1543, 1548, 1549,
+ 1549, 1549, 1549, 1549, 1549, 221, 1547, 220, 1723, 1552,
+ 1553, 1553, 1553, 1553, 1553, 1553, 1556, 1557, 1557, 1557,
+ 1557, 1557, 1557, 1560, 1561, 1561, 1561, 1561, 1561, 1561,
+ 219, 1547, 218, 1723, 1564, 1565, 1565, 1565, 1565, 1565,
+ 1565, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1568, 1568,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+
+ 217, 216, 1569, 1723, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 1573, 1580, 1583,
+ 215, 51, 51, 51, 211, 210, 1571, 1569, 1723, 1574,
+ 1575, 1577, 1596, 200, 1578, 1581, 199, 1617, 198, 1604,
+ 1582, 1584, 1585, 1585, 1585, 1585, 1585, 1585, 1549, 1549,
+ 1549, 1549, 1549, 1549, 1549, 1553, 1553, 1553, 1553, 1553,
+ 1553, 1553, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1561,
+ 1561, 1561, 1561, 1561, 1561, 1561, 1565, 1565, 1565, 1565,
+ 1565, 1565, 1565, 1593, 1594, 1594, 1594, 1594, 1594, 1594,
+ 51, 195, 51, 51, 51, 51, 1585, 1585, 1585, 1585,
+
+ 1585, 1585, 1585, 194, 51, 51, 51, 51, 1600, 51,
+ 51, 51, 51, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
+ 1606, 51, 51, 51, 51, 1601, 51, 51, 1602, 1603,
+ 51, 1607, 1616, 51, 51, 51, 1618, 51, 189, 51,
+ 1615, 51, 51, 51, 51, 188, 187, 51, 51, 51,
+ 51, 51, 51, 1624, 51, 1620, 51, 186, 51, 51,
+ 51, 1625, 1623, 1632, 51, 51, 51, 1633, 51, 1628,
+ 51, 51, 1631, 1634, 1640, 51, 1642, 51, 1635, 1636,
+ 185, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 1653, 51, 1643, 1644, 51, 184, 1645, 1646, 51,
+
+ 51, 51, 1647, 51, 1648, 1649, 51, 51, 51, 51,
+ 1660, 1661, 51, 183, 51, 51, 1651, 51, 51, 182,
+ 1655, 51, 1659, 1662, 1663, 51, 1666, 1664, 51, 51,
+ 1668, 51, 51, 1670, 51, 51, 1665, 181, 51, 51,
+ 51, 180, 51, 51, 51, 51, 51, 51, 1669, 1673,
+ 1671, 176, 51, 1672, 1677, 175, 51, 51, 1674, 51,
+ 51, 51, 51, 1679, 51, 51, 174, 51, 1678, 51,
+ 51, 51, 1680, 1683, 1684, 1686, 51, 173, 172, 51,
+ 51, 1687, 51, 1690, 51, 171, 170, 51, 51, 169,
+ 51, 51, 51, 51, 1691, 1692, 51, 51, 1694, 51,
+
+ 51, 1696, 1697, 1693, 51, 168, 1699, 51, 51, 51,
+ 51, 51, 1698, 51, 51, 51, 51, 51, 51, 1701,
+ 1700, 51, 1704, 51, 51, 51, 167, 51, 51, 1702,
+ 166, 51, 51, 1706, 165, 51, 1707, 164, 163, 1708,
+ 51, 51, 51, 162, 1711, 161, 160, 1713, 155, 1715,
+ 1717, 1716, 146, 145, 51, 140, 1718, 1721, 1722, 1719,
+ 55, 1720, 52, 43, 41, 1723, 1723, 1723, 1723, 1723,
+ 1723, 51, 42, 1723, 42, 59, 1723, 59, 59, 59,
+ 59, 59, 59, 147, 1723, 147, 154, 154, 154, 266,
+ 266, 266, 275, 275, 275, 354, 354, 354, 357, 357,
+
+ 357, 358, 358, 358, 365, 365, 365, 363, 363, 363,
+ 369, 369, 369, 373, 1723, 373, 438, 438, 438, 443,
+ 443, 443, 444, 444, 444, 453, 453, 453, 457, 1723,
+ 457, 458, 458, 458, 367, 367, 1723, 1723, 367, 462,
+ 462, 462, 466, 466, 466, 357, 357, 357, 527, 527,
+ 527, 531, 531, 531, 532, 532, 532, 533, 533, 533,
+ 365, 365, 365, 538, 538, 538, 451, 451, 1723, 1723,
+ 451, 543, 543, 543, 547, 547, 547, 551, 1723, 551,
+ 552, 552, 552, 556, 556, 556, 560, 1723, 560, 619,
+ 619, 619, 453, 453, 453, 627, 627, 627, 628, 628,
+
+ 628, 636, 636, 636, 640, 1723, 640, 643, 1723, 643,
+ 644, 644, 644, 648, 648, 648, 652, 1723, 652, 550,
+ 550, 1723, 1723, 550, 554, 554, 1723, 1723, 554, 658,
+ 658, 658, 662, 662, 662, 560, 560, 1723, 560, 532,
+ 532, 532, 708, 708, 708, 712, 712, 712, 715, 715,
+ 715, 716, 716, 716, 717, 717, 717, 722, 722, 722,
+ 634, 634, 1723, 1723, 634, 727, 727, 727, 731, 731,
+ 731, 640, 640, 1723, 640, 642, 642, 1723, 1723, 642,
+ 643, 643, 1723, 643, 644, 644, 646, 646, 1723, 1723,
+ 646, 738, 738, 738, 742, 742, 742, 652, 652, 1723,
+
+ 652, 746, 1723, 746, 749, 1723, 749, 750, 750, 750,
+ 754, 754, 754, 758, 1723, 758, 797, 797, 797, 636,
+ 636, 636, 648, 648, 648, 808, 808, 808, 809, 809,
+ 809, 817, 817, 817, 821, 1723, 821, 824, 1723, 824,
+ 825, 825, 825, 829, 829, 829, 833, 1723, 833, 836,
+ 1723, 836, 839, 1723, 839, 840, 840, 840, 844, 844,
+ 844, 848, 1723, 848, 745, 1723, 1723, 745, 746, 746,
+ 1723, 746, 748, 748, 1723, 1723, 748, 749, 749, 1723,
+ 749, 750, 750, 752, 752, 1723, 1723, 752, 855, 855,
+ 855, 859, 859, 859, 758, 758, 1723, 758, 49, 49,
+
+ 49, 1723, 49, 49, 716, 716, 716, 891, 891, 891,
+ 895, 895, 895, 898, 898, 898, 901, 901, 901, 902,
+ 902, 902, 903, 903, 903, 908, 908, 908, 815, 815,
+ 1723, 1723, 815, 913, 913, 913, 917, 917, 917, 821,
+ 821, 1723, 821, 823, 823, 1723, 1723, 823, 824, 824,
+ 1723, 824, 825, 825, 827, 827, 1723, 1723, 827, 924,
+ 924, 924, 928, 928, 928, 833, 833, 1723, 833, 835,
+ 1723, 1723, 835, 836, 836, 1723, 836, 838, 838, 1723,
+ 1723, 838, 839, 839, 1723, 839, 840, 840, 842, 842,
+ 1723, 1723, 842, 936, 936, 936, 940, 940, 940, 848,
+
+ 848, 1723, 848, 942, 1723, 942, 945, 1723, 945, 948,
+ 1723, 948, 949, 949, 949, 953, 953, 953, 957, 1723,
+ 957, 49, 49, 49, 1723, 49, 49, 985, 985, 985,
+ 817, 817, 817, 829, 829, 829, 844, 844, 844, 999,
+ 999, 999, 1000, 1000, 1000, 1008, 1008, 1008, 1012, 1723,
+ 1012, 1015, 1723, 1015, 1016, 1016, 1016, 1020, 1020, 1020,
+ 1024, 1723, 1024, 1027, 1723, 1027, 1030, 1723, 1030, 1031,
+ 1031, 1031, 1035, 1035, 1035, 1039, 1723, 1039, 1040, 1723,
+ 1040, 1043, 1723, 1043, 1046, 1723, 1046, 1047, 1047, 1047,
+ 1051, 1051, 1051, 1055, 1723, 1055, 942, 1723, 942, 944,
+
+ 1723, 1723, 944, 945, 945, 1723, 945, 947, 947, 1723,
+ 1723, 947, 948, 948, 1723, 948, 949, 949, 951, 951,
+ 1723, 1723, 951, 1062, 1062, 1062, 1066, 1066, 1066, 957,
+ 957, 1723, 957, 49, 49, 49, 1723, 49, 49, 902,
+ 902, 902, 1093, 1093, 1093, 1097, 1097, 1097, 1100, 1100,
+ 1100, 1103, 1103, 1103, 1106, 1106, 1106, 1107, 1107, 1107,
+ 1115, 1115, 1115, 1006, 1006, 1723, 1723, 1006, 1120, 1120,
+ 1120, 1124, 1124, 1124, 1012, 1012, 1723, 1012, 1014, 1014,
+ 1723, 1723, 1014, 1015, 1015, 1723, 1015, 1016, 1016, 1018,
+ 1018, 1723, 1723, 1018, 1131, 1131, 1131, 1135, 1135, 1135,
+
+ 1024, 1024, 1723, 1024, 1026, 1723, 1723, 1026, 1027, 1027,
+ 1723, 1027, 1029, 1029, 1723, 1723, 1029, 1030, 1030, 1723,
+ 1030, 1031, 1031, 1033, 1033, 1723, 1723, 1033, 1143, 1143,
+ 1143, 1147, 1147, 1147, 1039, 1039, 1723, 1039, 1040, 1723,
+ 1040, 1042, 1723, 1723, 1042, 1043, 1043, 1723, 1043, 1045,
+ 1045, 1723, 1723, 1045, 1046, 1046, 1723, 1046, 1047, 1047,
+ 1049, 1049, 1723, 1723, 1049, 1155, 1155, 1155, 1159, 1159,
+ 1159, 1055, 1055, 1723, 1055, 1161, 1723, 1161, 1164, 1723,
+ 1164, 1167, 1723, 1167, 1168, 1168, 1168, 1172, 1172, 1172,
+ 1176, 1723, 1176, 49, 49, 49, 1723, 49, 49, 1200,
+
+ 1200, 1200, 1008, 1008, 1008, 1020, 1020, 1020, 1035, 1035,
+ 1035, 1051, 1051, 1051, 1217, 1217, 1217, 1223, 1223, 1223,
+ 1221, 1221, 1221, 1228, 1228, 1228, 1227, 1227, 1227, 1229,
+ 1723, 1229, 1232, 1723, 1232, 1233, 1233, 1233, 1238, 1238,
+ 1238, 1237, 1237, 1237, 1239, 1723, 1239, 1242, 1723, 1242,
+ 1245, 1723, 1245, 1246, 1246, 1246, 1251, 1251, 1251, 1250,
+ 1250, 1250, 1252, 1723, 1252, 1253, 1723, 1253, 1256, 1723,
+ 1256, 1259, 1723, 1259, 1260, 1260, 1260, 1265, 1265, 1265,
+ 1264, 1264, 1264, 1266, 1723, 1266, 1267, 1723, 1267, 1270,
+ 1723, 1270, 1273, 1723, 1273, 1274, 1274, 1274, 1279, 1279,
+
+ 1279, 1278, 1278, 1278, 1280, 1723, 1280, 1161, 1723, 1161,
+ 1163, 1723, 1723, 1163, 1164, 1164, 1723, 1164, 1166, 1166,
+ 1723, 1723, 1166, 1167, 1167, 1723, 1167, 1168, 1168, 1170,
+ 1170, 1723, 1723, 1170, 1287, 1287, 1287, 1291, 1291, 1291,
+ 1176, 1176, 1723, 1176, 49, 49, 49, 1723, 49, 49,
+ 1107, 1107, 1107, 1319, 1319, 1319, 1322, 1322, 1322, 1325,
+ 1325, 1325, 1328, 1328, 1328, 1331, 1331, 1331, 1336, 1336,
+ 1336, 1335, 1335, 1335, 1338, 1723, 1338, 1339, 1339, 1339,
+ 1225, 1225, 1723, 1723, 1225, 1343, 1343, 1343, 1344, 1344,
+ 1344, 1229, 1229, 1723, 1229, 1231, 1231, 1723, 1723, 1231,
+
+ 1232, 1232, 1723, 1232, 1233, 1233, 1235, 1235, 1723, 1723,
+ 1235, 1350, 1350, 1350, 1351, 1351, 1351, 1239, 1239, 1723,
+ 1239, 1241, 1723, 1723, 1241, 1242, 1242, 1723, 1242, 1244,
+ 1244, 1723, 1723, 1244, 1245, 1245, 1723, 1245, 1246, 1246,
+ 1248, 1248, 1723, 1723, 1248, 1358, 1358, 1358, 1359, 1359,
+ 1359, 1252, 1252, 1723, 1252, 1253, 1723, 1253, 1255, 1723,
+ 1723, 1255, 1256, 1256, 1723, 1256, 1258, 1258, 1723, 1723,
+ 1258, 1259, 1259, 1723, 1259, 1260, 1260, 1262, 1262, 1723,
+ 1723, 1262, 1366, 1366, 1366, 1367, 1367, 1367, 1266, 1266,
+ 1723, 1266, 1267, 1723, 1267, 1269, 1723, 1723, 1269, 1270,
+
+ 1270, 1723, 1270, 1272, 1272, 1723, 1723, 1272, 1273, 1273,
+ 1723, 1273, 1274, 1274, 1276, 1276, 1723, 1723, 1276, 1374,
+ 1374, 1374, 1375, 1375, 1375, 1280, 1280, 1723, 1280, 1376,
+ 1723, 1376, 1379, 1723, 1379, 1382, 1723, 1382, 1383, 1383,
+ 1383, 1388, 1723, 1388, 1387, 1387, 1387, 1389, 1723, 1389,
+ 49, 49, 49, 1723, 49, 49, 1410, 1723, 1410, 1409,
+ 1409, 1409, 1411, 1723, 1411, 1227, 1227, 1227, 1412, 1723,
+ 1412, 1237, 1237, 1237, 1413, 1723, 1413, 1250, 1250, 1250,
+ 1414, 1723, 1414, 1264, 1264, 1264, 1415, 1723, 1415, 1278,
+ 1278, 1278, 1333, 1333, 1723, 1723, 1333, 1419, 1419, 1419,
+
+ 1420, 1420, 1420, 365, 365, 365, 1338, 1338, 1723, 1338,
+ 1421, 1421, 1421, 1424, 1723, 1424, 1425, 1425, 1425, 1426,
+ 1426, 1426, 1429, 1723, 1429, 1432, 1723, 1432, 1433, 1433,
+ 1433, 1434, 1434, 1434, 1435, 1723, 1435, 1438, 1723, 1438,
+ 1441, 1723, 1441, 1442, 1442, 1442, 1443, 1443, 1443, 1444,
+ 1723, 1444, 1447, 1723, 1447, 1450, 1723, 1450, 1451, 1451,
+ 1451, 1452, 1452, 1452, 1453, 1723, 1453, 1456, 1723, 1456,
+ 1459, 1723, 1459, 1460, 1460, 1460, 1461, 1461, 1461, 1376,
+ 1723, 1376, 1378, 1723, 1723, 1378, 1379, 1379, 1723, 1379,
+ 1381, 1381, 1723, 1723, 1381, 1382, 1382, 1723, 1382, 1383,
+
+ 1383, 1385, 1385, 1723, 1723, 1385, 1468, 1468, 1468, 1469,
+ 1723, 1469, 1389, 1389, 1723, 1389, 49, 49, 49, 1723,
+ 49, 49, 1487, 1487, 1487, 1335, 1335, 1335, 1489, 1723,
+ 1489, 1490, 1723, 1490, 1491, 1723, 1491, 1492, 1723, 1492,
+ 1493, 1723, 1493, 1494, 1723, 1494, 1497, 1723, 1497, 1498,
+ 1498, 1498, 1499, 1499, 1499, 1500, 1723, 1500, 1423, 1423,
+ 1723, 1723, 1423, 1424, 1424, 1723, 1424, 1425, 1425, 1503,
+ 1723, 1503, 1428, 1723, 1723, 1428, 1429, 1429, 1723, 1429,
+ 1431, 1431, 1723, 1723, 1431, 1432, 1432, 1723, 1432, 1433,
+ 1433, 1507, 1723, 1507, 1435, 1723, 1435, 1437, 1723, 1723,
+
+ 1437, 1438, 1438, 1723, 1438, 1440, 1440, 1723, 1723, 1440,
+ 1441, 1441, 1723, 1441, 1442, 1442, 1511, 1723, 1511, 1444,
+ 1723, 1444, 1446, 1723, 1723, 1446, 1447, 1447, 1723, 1447,
+ 1449, 1449, 1723, 1723, 1449, 1450, 1450, 1723, 1450, 1451,
+ 1451, 1515, 1723, 1515, 1453, 1723, 1453, 1455, 1723, 1723,
+ 1455, 1456, 1456, 1723, 1456, 1458, 1458, 1723, 1723, 1458,
+ 1459, 1459, 1723, 1459, 1460, 1460, 1519, 1723, 1519, 1520,
+ 1723, 1520, 1523, 1723, 1523, 1526, 1723, 1526, 1527, 1527,
+ 1527, 1528, 1723, 1528, 49, 49, 49, 1723, 49, 49,
+ 1545, 1723, 1545, 1421, 1723, 1421, 1426, 1723, 1426, 1434,
+
+ 1723, 1434, 1443, 1723, 1443, 1452, 1723, 1452, 1461, 1723,
+ 1461, 1496, 1496, 1723, 1723, 1496, 1497, 1497, 1723, 1497,
+ 1498, 1498, 1488, 1723, 1488, 1550, 1723, 1550, 1551, 1723,
+ 1551, 1554, 1723, 1554, 1555, 1723, 1555, 1558, 1723, 1558,
+ 1559, 1723, 1559, 1562, 1723, 1562, 1563, 1723, 1563, 1566,
+ 1723, 1566, 1522, 1723, 1723, 1522, 1525, 1525, 1723, 1723,
+ 1525, 1570, 1723, 1570, 1499, 1723, 1499, 1586, 1723, 1586,
+ 1549, 1723, 1723, 1549, 1553, 1723, 1723, 1553, 1557, 1723,
+ 1723, 1557, 1561, 1723, 1723, 1561, 1565, 1723, 1723, 1565,
+ 1592, 1723, 1592, 1595, 1723, 1595, 1585, 1723, 1723, 1585,
+
+ 1609, 1723, 1609, 1610, 1723, 1610, 1611, 1723, 1611, 1612,
+ 1723, 1612, 1613, 1723, 1613, 1594, 1723, 1723, 1594, 1626,
+ 1723, 1626, 1627, 1723, 1627, 3, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723
} ;
-static yyconst flex_int16_t yy_chk[7910] =
+static yyconst flex_int16_t yy_chk[7679] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 4, 15, 106, 4, 7, 4, 4,
- 7, 106, 7, 7, 9, 17, 17, 9, 138, 9,
- 9, 4, 19, 19, 24, 7, 27, 27, 138, 4,
- 15, 10, 9, 7, 10, 102, 10, 10, 24, 28,
- 9, 34, 26, 1278, 28, 24, 26, 586, 94, 10,
-
- 34, 94, 26, 586, 95, 26, 95, 10, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 102, 98,
- 1279, 14, 14, 14, 98, 83, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 16, 83, 25, 16, 671, 16, 16, 83, 129,
- 29, 671, 107, 25, 29, 252, 25, 107, 22, 16,
- 25, 22, 129, 22, 22, 103, 29, 16, 20, 20,
- 20, 20, 20, 20, 20, 20, 22, 134, 23, 252,
- 23, 23, 20, 673, 22, 23, 673, 251, 35, 251,
-
- 23, 30, 103, 30, 23, 134, 23, 103, 30, 30,
- 35, 30, 35, 1283, 35, 30, 1284, 35, 20, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 32,
- 32, 110, 21, 675, 110, 1285, 110, 136, 21, 21,
- 21, 21, 21, 21, 31, 32, 136, 31, 31, 32,
- 31, 675, 31, 32, 31, 32, 31, 33, 36, 31,
- 155, 33, 32, 36, 36, 37, 36, 36, 710, 37,
- 33, 33, 163, 38, 33, 222, 33, 37, 39, 38,
- 39, 38, 37, 38, 37, 41, 155, 38, 222, 38,
- 38, 267, 267, 41, 39, 437, 437, 41, 163, 41,
-
- 44, 39, 397, 44, 710, 44, 44, 62, 62, 62,
- 62, 62, 62, 62, 274, 339, 63, 351, 44, 63,
- 339, 63, 63, 397, 410, 1292, 44, 48, 48, 48,
- 48, 48, 48, 48, 63, 619, 619, 410, 48, 397,
- 274, 680, 63, 351, 48, 48, 48, 48, 48, 48,
- 49, 49, 49, 49, 49, 49, 49, 376, 439, 680,
- 446, 49, 284, 284, 284, 284, 1296, 49, 49, 49,
- 49, 49, 49, 50, 50, 50, 50, 50, 50, 50,
- 50, 466, 284, 376, 439, 50, 446, 452, 460, 466,
- 1321, 50, 50, 50, 50, 50, 50, 52, 52, 52,
-
- 52, 52, 52, 52, 52, 54, 54, 54, 54, 54,
- 54, 54, 486, 452, 460, 355, 54, 1324, 413, 670,
- 670, 486, 54, 54, 54, 54, 54, 54, 56, 355,
- 672, 56, 413, 56, 56, 672, 1327, 371, 372, 56,
- 56, 56, 56, 56, 56, 56, 56, 523, 563, 679,
- 56, 371, 372, 679, 56, 355, 56, 56, 56, 56,
- 56, 56, 153, 488, 153, 153, 153, 153, 153, 153,
- 153, 547, 488, 523, 563, 153, 627, 371, 372, 547,
- 686, 153, 153, 153, 153, 153, 153, 154, 154, 154,
- 154, 154, 154, 154, 154, 557, 662, 686, 1330, 154,
-
- 630, 154, 627, 557, 662, 154, 154, 154, 154, 154,
- 154, 266, 266, 266, 266, 266, 266, 266, 277, 277,
- 277, 277, 277, 277, 277, 455, 630, 154, 156, 156,
- 156, 156, 156, 156, 156, 156, 587, 636, 1333, 455,
- 156, 566, 566, 566, 566, 587, 156, 156, 156, 156,
- 156, 156, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 684, 1336, 636, 157, 455, 643, 655, 684, 1340,
- 157, 157, 157, 157, 157, 157, 158, 158, 158, 158,
- 158, 158, 158, 158, 160, 160, 160, 160, 160, 160,
- 160, 160, 643, 655, 678, 160, 678, 682, 1341, 682,
-
- 1342, 160, 160, 160, 160, 160, 160, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 687, 691, 691, 162,
- 1343, 162, 1344, 309, 687, 162, 162, 162, 162, 162,
- 162, 309, 361, 361, 361, 361, 361, 361, 361, 701,
- 701, 456, 1348, 527, 309, 764, 676, 162, 260, 260,
- 260, 260, 260, 260, 260, 456, 676, 527, 708, 260,
- 309, 1349, 766, 764, 689, 260, 260, 260, 260, 260,
- 260, 262, 262, 262, 262, 262, 262, 262, 588, 689,
- 766, 456, 262, 527, 708, 749, 761, 588, 262, 262,
- 262, 262, 262, 262, 263, 263, 263, 263, 263, 263,
-
- 263, 263, 265, 265, 265, 265, 265, 265, 265, 674,
- 805, 749, 761, 265, 1355, 1356, 1363, 772, 674, 265,
- 265, 265, 265, 265, 265, 268, 268, 268, 268, 268,
- 268, 268, 268, 731, 742, 772, 805, 268, 1364, 1371,
- 772, 731, 742, 268, 268, 268, 268, 268, 268, 270,
- 270, 270, 270, 270, 270, 270, 270, 273, 273, 273,
- 273, 273, 273, 273, 273, 273, 859, 1372, 1379, 273,
- 1380, 273, 1384, 1387, 859, 273, 273, 273, 273, 273,
- 273, 365, 365, 365, 365, 365, 365, 365, 436, 436,
- 436, 436, 436, 436, 436, 554, 683, 273, 278, 278,
-
- 278, 278, 278, 278, 278, 278, 278, 683, 1388, 554,
- 278, 1392, 765, 779, 1394, 681, 278, 278, 278, 278,
- 278, 278, 279, 279, 279, 279, 279, 279, 279, 681,
- 765, 779, 685, 279, 555, 554, 779, 765, 1413, 279,
- 279, 279, 279, 279, 279, 344, 685, 344, 555, 344,
- 344, 464, 464, 464, 464, 464, 464, 464, 773, 344,
- 690, 344, 344, 558, 344, 349, 559, 349, 349, 349,
- 349, 349, 349, 349, 555, 690, 773, 558, 349, 773,
- 559, 776, 1414, 787, 349, 349, 349, 349, 349, 349,
- 350, 350, 350, 350, 350, 350, 350, 350, 1424, 776,
-
- 776, 787, 350, 558, 350, 1425, 559, 1429, 350, 350,
- 350, 350, 350, 350, 468, 468, 468, 468, 468, 468,
- 468, 540, 540, 540, 540, 540, 540, 540, 638, 688,
- 350, 352, 352, 352, 352, 352, 352, 352, 352, 688,
- 1430, 1434, 638, 352, 1437, 783, 774, 788, 639, 352,
- 352, 352, 352, 352, 352, 356, 356, 356, 356, 356,
- 356, 356, 639, 783, 774, 788, 356, 774, 638, 784,
- 783, 790, 356, 356, 356, 356, 356, 356, 357, 357,
- 357, 357, 357, 357, 357, 357, 1438, 784, 639, 790,
- 357, 808, 784, 811, 817, 1443, 357, 357, 357, 357,
-
- 357, 357, 358, 358, 358, 358, 358, 358, 358, 358,
- 360, 360, 360, 360, 360, 360, 360, 808, 917, 811,
- 817, 360, 1446, 791, 789, 795, 917, 360, 360, 360,
- 360, 360, 360, 364, 364, 364, 364, 364, 364, 364,
- 364, 791, 789, 795, 364, 789, 824, 797, 797, 1447,
- 364, 364, 364, 364, 364, 364, 366, 366, 366, 366,
- 366, 366, 366, 366, 366, 797, 836, 839, 366, 851,
- 866, 867, 824, 1452, 366, 366, 366, 366, 366, 366,
- 367, 367, 367, 367, 367, 367, 367, 367, 866, 867,
- 892, 367, 836, 839, 867, 851, 868, 367, 367, 367,
-
- 367, 367, 367, 373, 373, 373, 373, 373, 373, 373,
- 373, 373, 1455, 1456, 868, 373, 892, 1461, 879, 868,
- 869, 373, 373, 373, 373, 373, 373, 375, 375, 375,
- 375, 375, 375, 375, 375, 375, 879, 879, 869, 375,
- 692, 375, 1464, 869, 693, 375, 375, 375, 375, 375,
- 375, 490, 646, 490, 692, 696, 490, 490, 693, 647,
- 490, 490, 699, 928, 700, 490, 646, 375, 396, 696,
- 1465, 928, 396, 647, 700, 396, 699, 650, 396, 651,
- 396, 396, 396, 396, 430, 430, 430, 430, 430, 430,
- 430, 650, 646, 651, 1473, 430, 780, 871, 873, 647,
-
- 1502, 430, 430, 430, 430, 430, 430, 432, 432, 432,
- 432, 432, 432, 432, 780, 871, 873, 650, 432, 651,
- 871, 873, 948, 780, 432, 432, 432, 432, 432, 432,
- 433, 433, 433, 433, 433, 433, 433, 433, 435, 435,
- 435, 435, 435, 435, 435, 1503, 1528, 1531, 948, 435,
- 1555, 781, 880, 874, 888, 435, 435, 435, 435, 435,
- 435, 438, 438, 438, 438, 438, 438, 438, 438, 781,
- 880, 874, 888, 438, 1559, 438, 874, 880, 781, 438,
- 438, 438, 438, 438, 438, 545, 545, 545, 545, 545,
- 545, 545, 549, 549, 549, 549, 549, 549, 549, 767,
-
- 752, 438, 440, 440, 440, 440, 440, 440, 440, 960,
- 940, 993, 996, 440, 752, 883, 1563, 767, 940, 440,
- 440, 440, 440, 440, 440, 441, 441, 441, 441, 441,
- 441, 441, 1567, 883, 767, 960, 441, 993, 996, 999,
- 752, 883, 441, 441, 441, 441, 441, 441, 442, 442,
- 442, 442, 442, 442, 442, 442, 445, 445, 445, 445,
- 445, 445, 445, 445, 445, 999, 1571, 1591, 445, 1002,
- 445, 1600, 1275, 1271, 445, 445, 445, 445, 445, 445,
- 658, 658, 658, 658, 658, 658, 658, 660, 660, 660,
- 660, 660, 660, 660, 973, 1002, 445, 451, 451, 451,
-
- 451, 451, 451, 451, 451, 451, 1066, 1270, 1269, 451,
- 1265, 451, 973, 973, 1066, 451, 451, 451, 451, 451,
- 451, 664, 664, 664, 664, 664, 664, 664, 724, 724,
- 724, 724, 724, 724, 724, 753, 768, 451, 457, 457,
- 457, 457, 457, 457, 457, 457, 457, 1264, 1261, 753,
- 457, 1008, 1257, 1015, 768, 886, 457, 457, 457, 457,
- 457, 457, 459, 459, 459, 459, 459, 459, 459, 459,
- 459, 768, 1256, 886, 459, 753, 459, 1008, 886, 1015,
- 459, 459, 459, 459, 459, 459, 729, 729, 729, 729,
- 729, 729, 729, 733, 733, 733, 733, 733, 733, 733,
-
- 756, 769, 459, 469, 469, 469, 469, 469, 469, 469,
- 469, 469, 1255, 1027, 756, 469, 1251, 975, 1250, 769,
- 757, 469, 469, 469, 469, 469, 469, 470, 470, 470,
- 470, 470, 470, 470, 757, 975, 769, 1247, 470, 1027,
- 756, 785, 975, 876, 470, 470, 470, 470, 470, 470,
- 521, 819, 521, 521, 521, 521, 521, 521, 521, 785,
- 757, 876, 1244, 521, 876, 819, 972, 967, 785, 521,
- 521, 521, 521, 521, 521, 522, 522, 522, 522, 522,
- 522, 522, 522, 1243, 972, 967, 1242, 522, 967, 522,
- 1238, 819, 972, 522, 522, 522, 522, 522, 522, 738,
-
- 738, 738, 738, 738, 738, 738, 740, 740, 740, 740,
- 740, 740, 740, 771, 777, 522, 524, 524, 524, 524,
- 524, 524, 524, 524, 1030, 1124, 1237, 1042, 524, 1046,
- 1058, 771, 777, 1124, 524, 524, 524, 524, 524, 524,
- 528, 528, 528, 528, 528, 528, 528, 528, 771, 1135,
- 1030, 777, 528, 1042, 1114, 1046, 1058, 1135, 528, 528,
+ 1, 1, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 14, 14, 674, 11, 11, 11, 674, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 12, 16, 16, 20, 23, 20,
+
+ 20, 31, 23, 408, 20, 24, 24, 25, 23, 20,
+ 31, 23, 25, 20, 21, 20, 90, 408, 90, 12,
+ 17, 17, 17, 17, 17, 17, 17, 17, 21, 22,
+ 89, 1270, 26, 89, 17, 21, 26, 34, 101, 22,
+ 97, 34, 22, 27, 101, 27, 22, 93, 26, 34,
+ 27, 27, 93, 27, 34, 1273, 34, 27, 129, 17,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 29, 29, 97, 18, 1274, 36, 129, 36, 18, 18,
+ 18, 18, 18, 18, 28, 29, 1278, 28, 28, 29,
+ 28, 36, 28, 29, 28, 29, 28, 30, 36, 28,
+
+ 33, 30, 29, 32, 150, 33, 33, 102, 33, 33,
+ 30, 30, 102, 38, 30, 32, 30, 32, 35, 32,
+ 98, 38, 32, 133, 35, 38, 35, 38, 35, 150,
+ 124, 217, 35, 133, 35, 35, 44, 44, 44, 44,
+ 44, 44, 44, 124, 217, 105, 98, 44, 105, 247,
+ 105, 98, 44, 44, 44, 44, 44, 44, 45, 45,
+ 45, 45, 45, 45, 45, 158, 246, 581, 246, 45,
+ 262, 262, 247, 581, 45, 45, 45, 45, 45, 45,
+ 46, 46, 46, 46, 46, 46, 46, 46, 668, 334,
+ 158, 668, 46, 78, 334, 269, 346, 46, 46, 46,
+
+ 46, 46, 46, 48, 48, 48, 48, 48, 48, 48,
+ 48, 50, 50, 50, 50, 50, 50, 50, 371, 78,
+ 269, 346, 50, 432, 432, 78, 1279, 50, 50, 50,
+ 50, 50, 50, 52, 52, 52, 52, 52, 52, 52,
+ 614, 614, 667, 371, 52, 665, 665, 667, 434, 52,
+ 52, 52, 52, 52, 52, 58, 58, 58, 58, 58,
+ 58, 58, 131, 261, 261, 261, 261, 261, 261, 261,
+ 350, 131, 148, 434, 148, 148, 148, 148, 148, 148,
+ 148, 441, 447, 1280, 350, 148, 279, 279, 279, 279,
+ 148, 148, 148, 148, 148, 148, 149, 149, 149, 149,
+
+ 149, 149, 149, 149, 461, 279, 441, 447, 149, 350,
+ 149, 1287, 461, 149, 149, 149, 149, 149, 149, 272,
+ 272, 272, 272, 272, 272, 272, 356, 356, 356, 356,
+ 356, 356, 356, 366, 681, 149, 151, 151, 151, 151,
+ 151, 151, 151, 151, 455, 518, 666, 366, 151, 558,
+ 622, 681, 666, 151, 151, 151, 151, 151, 151, 152,
+ 152, 152, 152, 152, 152, 152, 152, 152, 1291, 455,
+ 518, 152, 366, 625, 558, 622, 152, 152, 152, 152,
+ 152, 152, 153, 153, 153, 153, 153, 153, 153, 153,
+ 155, 155, 155, 155, 155, 155, 155, 155, 625, 686,
+
+ 686, 155, 561, 561, 561, 561, 155, 155, 155, 155,
+ 155, 155, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 367, 631, 1316, 157, 392, 157, 759, 304, 157,
+ 157, 157, 157, 157, 157, 367, 304, 360, 360, 360,
+ 360, 360, 360, 360, 759, 392, 405, 631, 304, 670,
+ 1319, 157, 255, 255, 255, 255, 255, 255, 255, 405,
+ 367, 392, 638, 255, 304, 675, 1322, 670, 255, 255,
+ 255, 255, 255, 255, 257, 257, 257, 257, 257, 257,
+ 257, 542, 673, 675, 673, 257, 1325, 638, 650, 542,
+ 257, 257, 257, 257, 257, 257, 258, 258, 258, 258,
+
+ 258, 258, 258, 258, 260, 260, 260, 260, 260, 260,
+ 260, 552, 677, 650, 677, 260, 696, 696, 1328, 552,
+ 260, 260, 260, 260, 260, 260, 263, 263, 263, 263,
+ 263, 263, 263, 263, 657, 705, 1331, 1335, 263, 1336,
+ 1337, 703, 657, 263, 263, 263, 263, 263, 263, 265,
+ 265, 265, 265, 265, 265, 265, 265, 268, 268, 268,
+ 268, 268, 268, 268, 268, 268, 703, 1338, 1339, 268,
+ 705, 268, 761, 450, 268, 268, 268, 268, 268, 268,
+ 431, 431, 431, 431, 431, 431, 431, 450, 679, 761,
+ 1343, 1344, 676, 451, 522, 679, 268, 273, 273, 273,
+
+ 273, 273, 273, 273, 273, 273, 676, 451, 522, 273,
+ 1350, 771, 450, 680, 273, 273, 273, 273, 273, 273,
+ 274, 274, 274, 274, 274, 274, 274, 680, 771, 771,
+ 744, 274, 451, 522, 481, 671, 274, 274, 274, 274,
+ 274, 274, 339, 481, 339, 671, 339, 339, 459, 459,
+ 459, 459, 459, 459, 459, 744, 339, 549, 339, 339,
+ 550, 339, 344, 483, 344, 344, 344, 344, 344, 344,
+ 344, 549, 483, 1351, 550, 344, 756, 1358, 782, 1359,
+ 344, 344, 344, 344, 344, 344, 345, 345, 345, 345,
+ 345, 345, 345, 345, 682, 782, 549, 1366, 345, 550,
+
+ 345, 756, 682, 345, 345, 345, 345, 345, 345, 463,
+ 463, 463, 463, 463, 463, 463, 535, 535, 535, 535,
+ 535, 535, 535, 553, 678, 345, 347, 347, 347, 347,
+ 347, 347, 347, 347, 800, 678, 1367, 553, 347, 1374,
+ 783, 768, 554, 347, 347, 347, 347, 347, 347, 351,
+ 351, 351, 351, 351, 351, 351, 554, 783, 768, 800,
+ 351, 768, 553, 760, 684, 351, 351, 351, 351, 351,
+ 351, 352, 352, 352, 352, 352, 352, 352, 352, 684,
+ 760, 554, 1375, 352, 803, 806, 812, 760, 352, 352,
+ 352, 352, 352, 352, 353, 353, 353, 353, 353, 353,
+
+ 353, 353, 355, 355, 355, 355, 355, 355, 355, 803,
+ 806, 812, 819, 355, 1379, 1382, 767, 685, 355, 355,
+ 355, 355, 355, 355, 359, 359, 359, 359, 359, 359,
+ 359, 359, 685, 767, 1383, 359, 1387, 819, 767, 769,
+ 359, 359, 359, 359, 359, 359, 361, 361, 361, 361,
+ 361, 361, 361, 361, 361, 1389, 769, 1408, 361, 769,
+ 774, 784, 779, 361, 361, 361, 361, 361, 361, 362,
+ 362, 362, 362, 362, 362, 362, 362, 774, 784, 779,
+ 362, 784, 774, 778, 779, 362, 362, 362, 362, 362,
+ 362, 368, 368, 368, 368, 368, 368, 368, 368, 368,
+
+ 778, 1409, 831, 368, 1419, 1420, 785, 778, 368, 368,
+ 368, 368, 368, 368, 370, 370, 370, 370, 370, 370,
+ 370, 370, 370, 785, 1424, 1425, 370, 831, 370, 582,
+ 687, 370, 370, 370, 370, 370, 370, 485, 582, 485,
+ 583, 633, 485, 485, 687, 634, 485, 485, 669, 583,
+ 683, 485, 695, 370, 391, 633, 1429, 669, 391, 634,
+ 683, 391, 695, 641, 391, 642, 391, 391, 391, 391,
+ 425, 425, 425, 425, 425, 425, 425, 641, 1432, 642,
+ 633, 425, 834, 786, 634, 688, 425, 425, 425, 425,
+ 425, 425, 427, 427, 427, 427, 427, 427, 427, 688,
+
+ 786, 1433, 641, 427, 642, 846, 887, 834, 427, 427,
+ 427, 427, 427, 427, 428, 428, 428, 428, 428, 428,
+ 428, 428, 430, 430, 430, 430, 430, 430, 430, 726,
+ 846, 887, 943, 430, 955, 1438, 790, 726, 430, 430,
+ 430, 430, 430, 430, 433, 433, 433, 433, 433, 433,
+ 433, 433, 737, 790, 1441, 1442, 433, 943, 433, 955,
+ 737, 433, 433, 433, 433, 433, 433, 540, 540, 540,
+ 540, 540, 540, 540, 544, 544, 544, 544, 544, 544,
+ 544, 762, 645, 433, 435, 435, 435, 435, 435, 435,
+ 435, 988, 1447, 991, 994, 435, 645, 861, 762, 691,
+
+ 435, 435, 435, 435, 435, 435, 436, 436, 436, 436,
+ 436, 436, 436, 691, 861, 762, 988, 436, 991, 994,
+ 1450, 645, 436, 436, 436, 436, 436, 436, 437, 437,
+ 437, 437, 437, 437, 437, 437, 440, 440, 440, 440,
+ 440, 440, 440, 440, 440, 694, 646, 1451, 440, 1456,
+ 440, 1459, 1460, 440, 440, 440, 440, 440, 440, 694,
+ 646, 653, 653, 653, 653, 653, 653, 653, 655, 655,
+ 655, 655, 655, 655, 655, 440, 446, 446, 446, 446,
+ 446, 446, 446, 446, 446, 646, 1468, 1497, 446, 1498,
+ 446, 1523, 1526, 446, 446, 446, 446, 446, 446, 659,
+
+ 659, 659, 659, 659, 659, 659, 719, 719, 719, 719,
+ 719, 719, 719, 747, 763, 446, 452, 452, 452, 452,
+ 452, 452, 452, 452, 452, 997, 1550, 747, 452, 1554,
+ 1003, 763, 862, 452, 452, 452, 452, 452, 452, 454,
+ 454, 454, 454, 454, 454, 454, 454, 454, 763, 862,
+ 997, 454, 747, 454, 862, 1003, 454, 454, 454, 454,
+ 454, 454, 724, 724, 724, 724, 724, 724, 724, 728,
+ 728, 728, 728, 728, 728, 728, 748, 764, 454, 464,
+ 464, 464, 464, 464, 464, 464, 464, 464, 1558, 1010,
+ 748, 464, 1562, 883, 764, 751, 464, 464, 464, 464,
+
+ 464, 464, 465, 465, 465, 465, 465, 465, 465, 751,
+ 883, 764, 1566, 465, 1010, 748, 792, 792, 465, 465,
+ 465, 465, 465, 465, 516, 752, 516, 516, 516, 516,
+ 516, 516, 516, 792, 751, 1586, 1022, 516, 1595, 752,
+ 974, 863, 516, 516, 516, 516, 516, 516, 517, 517,
+ 517, 517, 517, 517, 517, 517, 1266, 974, 863, 974,
+ 517, 1022, 517, 863, 752, 517, 517, 517, 517, 517,
+ 517, 733, 733, 733, 733, 733, 733, 733, 735, 735,
+ 735, 735, 735, 735, 735, 766, 772, 517, 519, 519,
+ 519, 519, 519, 519, 519, 519, 854, 1265, 1264, 1025,
+
+ 519, 1037, 766, 772, 854, 519, 519, 519, 519, 519,
+ 519, 523, 523, 523, 523, 523, 523, 523, 523, 766,
+ 1260, 1259, 772, 523, 1025, 1041, 1037, 1053, 523, 523,
+ 523, 523, 523, 523, 524, 524, 524, 524, 524, 524,
+ 524, 524, 525, 525, 525, 525, 525, 525, 525, 912,
+ 1041, 1256, 1053, 525, 1109, 1162, 1174, 912, 525, 525,
+ 525, 525, 525, 525, 526, 526, 526, 526, 526, 526,
+ 526, 526, 528, 528, 528, 528, 528, 528, 528, 1109,
+ 1162, 1174, 1203, 528, 1252, 1251, 864, 866, 528, 528,
528, 528, 528, 528, 529, 529, 529, 529, 529, 529,
- 529, 529, 530, 530, 530, 530, 530, 530, 530, 1147,
- 1114, 1234, 1233, 530, 1167, 1179, 1208, 1147, 1232, 530,
- 530, 530, 530, 530, 530, 531, 531, 531, 531, 531,
-
- 531, 531, 531, 533, 533, 533, 533, 533, 533, 533,
- 1167, 1179, 1208, 1211, 533, 1228, 1226, 970, 974, 977,
- 533, 533, 533, 533, 533, 533, 534, 534, 534, 534,
- 534, 534, 534, 534, 534, 970, 974, 977, 534, 1211,
- 970, 974, 977, 820, 534, 534, 534, 534, 534, 534,
- 535, 535, 535, 535, 535, 535, 535, 820, 1159, 1225,
- 1214, 535, 1222, 976, 978, 1221, 1159, 535, 535, 535,
- 535, 535, 535, 539, 539, 539, 539, 539, 539, 539,
- 539, 976, 978, 820, 539, 978, 1214, 979, 981, 976,
- 539, 539, 539, 539, 539, 539, 541, 541, 541, 541,
-
- 541, 541, 541, 541, 541, 979, 981, 979, 541, 1218,
- 983, 981, 984, 1215, 541, 541, 541, 541, 541, 541,
- 542, 542, 542, 542, 542, 542, 542, 542, 983, 1212,
- 984, 542, 1209, 1205, 985, 989, 1076, 542, 542, 542,
- 542, 542, 542, 550, 550, 550, 550, 550, 550, 550,
- 550, 550, 985, 989, 1076, 550, 1181, 1079, 1082, 1083,
- 1180, 550, 550, 550, 550, 550, 550, 551, 551, 551,
- 551, 551, 551, 551, 551, 1079, 1082, 1083, 551, 1079,
- 1082, 1084, 1083, 1087, 551, 551, 551, 551, 551, 551,
- 560, 560, 560, 560, 560, 560, 560, 560, 560, 1084,
-
- 1177, 1087, 560, 1217, 1220, 1088, 1087, 1173, 560, 560,
- 560, 560, 560, 560, 562, 562, 562, 562, 562, 562,
- 562, 562, 562, 1088, 1172, 1088, 562, 1169, 562, 1217,
- 1220, 1164, 562, 562, 562, 562, 562, 562, 744, 744,
- 744, 744, 744, 744, 744, 750, 750, 750, 750, 750,
- 750, 750, 872, 778, 562, 613, 613, 613, 613, 613,
- 613, 613, 1245, 1163, 1259, 1273, 613, 1319, 1092, 1160,
- 872, 778, 613, 613, 613, 613, 613, 613, 615, 615,
- 615, 615, 615, 615, 615, 778, 1092, 872, 1245, 615,
- 1259, 1273, 1092, 1319, 1152, 615, 615, 615, 615, 615,
-
- 615, 616, 616, 616, 616, 616, 616, 616, 616, 618,
- 618, 618, 618, 618, 618, 618, 1291, 1151, 1148, 1382,
- 618, 1432, 882, 1090, 1291, 1093, 618, 618, 618, 618,
- 618, 618, 620, 620, 620, 620, 620, 620, 620, 620,
- 882, 1090, 1090, 1093, 620, 1382, 1093, 1432, 1441, 882,
- 620, 620, 620, 620, 620, 620, 621, 621, 621, 621,
- 621, 621, 621, 621, 622, 622, 622, 622, 622, 622,
- 622, 1347, 1354, 1140, 1441, 622, 1139, 1136, 1129, 1347,
- 1354, 622, 622, 622, 622, 622, 622, 623, 623, 623,
- 623, 623, 623, 623, 623, 626, 626, 626, 626, 626,
-
- 626, 626, 626, 626, 770, 884, 827, 626, 782, 626,
- 786, 1182, 1186, 626, 626, 626, 626, 626, 626, 1362,
- 827, 1128, 770, 884, 1125, 1120, 782, 1362, 786, 1182,
- 1186, 775, 884, 792, 770, 626, 629, 629, 629, 629,
- 629, 629, 629, 629, 629, 782, 827, 786, 629, 775,
- 629, 792, 1370, 1182, 629, 629, 629, 629, 629, 629,
- 1370, 775, 1119, 1116, 792, 799, 799, 799, 799, 799,
- 799, 799, 793, 828, 831, 1450, 629, 635, 635, 635,
- 635, 635, 635, 635, 635, 635, 1183, 828, 831, 635,
- 793, 635, 832, 842, 843, 635, 635, 635, 635, 635,
-
- 635, 1450, 793, 1378, 1183, 1459, 832, 842, 843, 1184,
- 1115, 1378, 1112, 828, 831, 846, 1111, 635, 640, 640,
- 640, 640, 640, 640, 640, 640, 640, 1184, 1183, 846,
- 640, 1459, 832, 842, 843, 1189, 640, 640, 640, 640,
- 640, 640, 642, 642, 642, 642, 642, 642, 642, 642,
- 642, 1184, 1108, 1189, 642, 846, 642, 1105, 1189, 847,
- 642, 642, 642, 642, 642, 642, 840, 840, 840, 840,
- 840, 840, 840, 847, 855, 855, 855, 855, 855, 855,
- 855, 1102, 642, 652, 652, 652, 652, 652, 652, 652,
- 652, 652, 1423, 1098, 1526, 652, 1553, 1557, 1185, 847,
-
- 1423, 652, 652, 652, 652, 652, 652, 654, 654, 654,
- 654, 654, 654, 654, 654, 654, 1185, 1071, 1185, 654,
- 1526, 654, 1553, 1557, 1067, 654, 654, 654, 654, 654,
- 654, 857, 857, 857, 857, 857, 857, 857, 861, 861,
- 861, 861, 861, 861, 861, 878, 870, 654, 665, 665,
- 665, 665, 665, 665, 665, 665, 665, 1472, 1060, 1059,
- 665, 1056, 1561, 878, 870, 1472, 665, 665, 665, 665,
- 665, 665, 666, 666, 666, 666, 666, 666, 666, 870,
- 878, 1052, 1051, 666, 887, 875, 877, 885, 1561, 666,
- 666, 666, 666, 666, 666, 669, 669, 669, 669, 669,
-
- 669, 669, 887, 875, 877, 885, 669, 966, 1078, 951,
- 963, 881, 669, 669, 669, 669, 669, 669, 875, 877,
- 1565, 887, 885, 951, 1532, 966, 1078, 952, 963, 881,
- 669, 704, 1532, 704, 704, 704, 704, 704, 704, 704,
- 881, 952, 966, 963, 704, 1078, 1565, 964, 1048, 951,
- 704, 704, 704, 704, 704, 704, 910, 910, 910, 910,
- 910, 910, 910, 955, 956, 964, 968, 952, 704, 705,
- 705, 705, 705, 705, 705, 705, 705, 955, 956, 1044,
- 964, 705, 1190, 1298, 968, 968, 1043, 705, 705, 705,
- 705, 705, 705, 915, 915, 915, 915, 915, 915, 915,
-
- 1190, 1298, 968, 955, 956, 705, 706, 706, 706, 706,
- 706, 706, 706, 919, 919, 919, 919, 919, 919, 919,
- 924, 924, 924, 924, 924, 924, 924, 926, 926, 926,
- 926, 926, 926, 926, 930, 930, 930, 930, 930, 930,
- 930, 706, 707, 707, 707, 707, 707, 707, 707, 1040,
- 1036, 1035, 1032, 707, 1029, 1569, 1589, 1598, 1028, 707,
- 707, 707, 707, 707, 707, 709, 709, 709, 709, 709,
- 709, 709, 709, 711, 711, 711, 711, 711, 711, 711,
- 711, 1569, 1589, 1598, 1025, 711, 1021, 1020, 1017, 1016,
- 1013, 711, 711, 711, 711, 711, 711, 712, 712, 712,
-
- 712, 712, 712, 712, 712, 714, 714, 714, 714, 714,
- 714, 714, 1009, 1005, 1004, 1003, 714, 1000, 997, 1201,
- 1202, 1187, 714, 714, 714, 714, 714, 714, 715, 715,
- 715, 715, 715, 715, 715, 715, 715, 1201, 1202, 1187,
- 715, 1201, 994, 1202, 1299, 1010, 715, 715, 715, 715,
- 715, 715, 716, 716, 716, 716, 716, 716, 716, 1010,
- 1187, 991, 1299, 716, 990, 962, 1300, 961, 1301, 716,
- 716, 716, 716, 716, 716, 718, 718, 718, 718, 718,
- 718, 718, 718, 718, 1300, 1010, 1301, 718, 958, 1192,
- 1302, 1310, 1011, 718, 718, 718, 718, 718, 718, 719,
-
- 719, 719, 719, 719, 719, 719, 1011, 1192, 1302, 1310,
- 719, 954, 1307, 1302, 1310, 1192, 719, 719, 719, 719,
- 719, 719, 723, 723, 723, 723, 723, 723, 723, 723,
- 1307, 953, 1011, 723, 950, 945, 941, 1314, 1315, 723,
- 723, 723, 723, 723, 723, 725, 725, 725, 725, 725,
- 725, 725, 725, 725, 1307, 1314, 1315, 725, 933, 929,
- 1396, 1397, 922, 725, 725, 725, 725, 725, 725, 726,
- 726, 726, 726, 726, 726, 726, 726, 1315, 1396, 1397,
- 726, 1396, 1397, 1398, 1399, 1401, 726, 726, 726, 726,
- 726, 726, 734, 734, 734, 734, 734, 734, 734, 734,
-
- 734, 1398, 1399, 1401, 734, 918, 1399, 913, 1402, 908,
- 734, 734, 734, 734, 734, 734, 735, 735, 735, 735,
- 735, 735, 735, 735, 907, 1398, 1402, 735, 906, 903,
- 1402, 1403, 1404, 735, 735, 735, 735, 735, 735, 745,
- 745, 745, 745, 745, 745, 745, 745, 745, 900, 1403,
- 1404, 745, 896, 1403, 1406, 1409, 1404, 745, 745, 745,
- 745, 745, 745, 746, 746, 746, 746, 746, 746, 746,
- 746, 864, 1406, 1409, 746, 860, 1406, 1477, 1409, 1478,
- 746, 746, 746, 746, 746, 746, 758, 758, 758, 758,
- 758, 758, 758, 758, 758, 1477, 853, 1478, 758, 852,
-
- 849, 1488, 845, 1477, 758, 758, 758, 758, 758, 758,
- 760, 760, 760, 760, 760, 760, 760, 760, 760, 1488,
- 1488, 844, 760, 841, 760, 838, 837, 834, 760, 760,
- 760, 760, 760, 760, 936, 936, 936, 936, 936, 936,
- 936, 938, 938, 938, 938, 938, 938, 938, 1018, 969,
- 760, 794, 1019, 794, 794, 794, 794, 794, 794, 794,
- 830, 829, 1018, 826, 794, 825, 1019, 969, 1081, 794,
- 794, 794, 794, 794, 794, 794, 796, 796, 796, 796,
- 796, 796, 796, 969, 822, 818, 1081, 796, 1018, 1534,
- 1491, 1536, 1019, 796, 796, 796, 796, 796, 796, 798,
-
- 798, 798, 798, 798, 798, 798, 1081, 1534, 1491, 1536,
- 798, 1491, 1303, 1537, 1544, 1548, 798, 798, 798, 798,
- 798, 798, 800, 800, 800, 800, 800, 800, 800, 800,
- 1303, 1537, 1544, 1548, 800, 815, 1537, 1544, 814, 1303,
- 800, 800, 800, 800, 800, 800, 801, 801, 801, 801,
- 801, 801, 801, 801, 804, 804, 804, 804, 804, 804,
- 804, 804, 804, 813, 812, 809, 804, 806, 804, 803,
- 802, 763, 804, 804, 804, 804, 804, 804, 942, 942,
- 942, 942, 942, 942, 942, 949, 949, 949, 949, 949,
- 949, 949, 965, 971, 804, 807, 807, 807, 807, 807,
-
- 807, 807, 807, 807, 1073, 1074, 1022, 807, 762, 807,
- 965, 971, 1479, 807, 807, 807, 807, 807, 807, 759,
- 1022, 755, 1073, 1074, 754, 965, 965, 982, 971, 980,
- 1479, 1077, 751, 1073, 1074, 807, 810, 810, 810, 810,
- 810, 810, 810, 810, 810, 982, 1022, 980, 810, 1077,
- 810, 1479, 1023, 747, 810, 810, 810, 810, 810, 810,
- 980, 1033, 982, 1077, 743, 736, 1023, 1031, 1031, 1031,
- 1031, 1031, 1031, 1031, 1034, 1033, 810, 816, 816, 816,
- 816, 816, 816, 816, 816, 816, 1576, 1075, 1034, 816,
- 732, 816, 1023, 1037, 1038, 816, 816, 816, 816, 816,
-
- 816, 1033, 727, 722, 1576, 1075, 721, 1037, 1038, 720,
- 1541, 717, 713, 1049, 1034, 1050, 1075, 816, 821, 821,
- 821, 821, 821, 821, 821, 821, 821, 1049, 1541, 1050,
- 821, 703, 702, 1037, 1038, 698, 821, 821, 821, 821,
- 821, 821, 823, 823, 823, 823, 823, 823, 823, 823,
- 823, 1541, 697, 1049, 823, 1050, 823, 1085, 1196, 1053,
- 823, 823, 823, 823, 823, 823, 1047, 1047, 1047, 1047,
- 1047, 1047, 1047, 1053, 695, 1085, 1196, 694, 1054, 1410,
- 1197, 677, 823, 833, 833, 833, 833, 833, 833, 833,
- 833, 833, 1054, 1196, 1085, 833, 667, 1410, 1197, 1053,
-
- 663, 833, 833, 833, 833, 833, 833, 835, 835, 835,
- 835, 835, 835, 835, 835, 835, 1197, 1410, 1054, 835,
- 657, 835, 656, 653, 649, 835, 835, 835, 835, 835,
- 835, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1064, 1064,
- 1064, 1064, 1064, 1064, 1064, 1170, 1094, 835, 848, 848,
- 848, 848, 848, 848, 848, 848, 848, 648, 645, 1170,
- 848, 644, 641, 637, 1094, 1094, 848, 848, 848, 848,
- 848, 848, 850, 850, 850, 850, 850, 850, 850, 850,
- 850, 1094, 1094, 634, 850, 1170, 850, 1587, 1486, 1086,
- 850, 850, 850, 850, 850, 850, 1068, 1068, 1068, 1068,
-
- 1068, 1068, 1068, 633, 632, 1587, 1486, 1086, 1200, 1171,
- 1174, 631, 850, 862, 862, 862, 862, 862, 862, 862,
- 862, 862, 1086, 1171, 1174, 862, 1200, 1486, 1612, 1080,
- 1175, 862, 862, 862, 862, 862, 862, 863, 863, 863,
- 863, 863, 863, 863, 1175, 1200, 1612, 1080, 863, 1171,
- 1174, 1578, 628, 1579, 863, 863, 863, 863, 863, 863,
- 889, 1080, 889, 889, 889, 889, 889, 889, 889, 1578,
- 1175, 1579, 1578, 889, 1579, 1620, 1580, 1628, 889, 889,
- 889, 889, 889, 889, 889, 890, 890, 890, 890, 890,
- 890, 890, 625, 1620, 1580, 1628, 890, 1580, 1411, 1089,
-
- 1585, 1091, 890, 890, 890, 890, 890, 890, 891, 891,
- 891, 891, 891, 891, 891, 891, 1411, 1089, 1585, 1091,
- 891, 1585, 891, 624, 617, 1411, 891, 891, 891, 891,
- 891, 891, 1089, 1091, 1117, 1117, 1117, 1117, 1117, 1117,
- 1117, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 891, 893,
- 893, 893, 893, 893, 893, 893, 614, 612, 608, 602,
- 893, 601, 1476, 1605, 1607, 1608, 893, 893, 893, 893,
- 893, 893, 894, 894, 894, 894, 894, 894, 894, 894,
- 1476, 1605, 1607, 1608, 894, 1605, 600, 1607, 1608, 1476,
- 894, 894, 894, 894, 894, 894, 895, 895, 895, 895,
-
- 895, 895, 895, 895, 897, 897, 897, 897, 897, 897,
- 897, 599, 595, 594, 592, 897, 591, 590, 1633, 1634,
- 1622, 897, 897, 897, 897, 897, 897, 898, 898, 898,
- 898, 898, 898, 898, 898, 898, 1633, 1634, 1622, 898,
- 589, 585, 1634, 1635, 1229, 898, 898, 898, 898, 898,
- 898, 899, 899, 899, 899, 899, 899, 899, 1229, 1622,
- 584, 1635, 899, 583, 582, 1636, 1635, 1623, 899, 899,
- 899, 899, 899, 899, 901, 901, 901, 901, 901, 901,
- 901, 901, 901, 1636, 1229, 1623, 901, 581, 1636, 1638,
- 1640, 1230, 901, 901, 901, 901, 901, 901, 902, 902,
-
- 902, 902, 902, 902, 902, 1230, 1623, 1638, 1640, 902,
- 580, 579, 1638, 578, 1624, 902, 902, 902, 902, 902,
- 902, 904, 904, 904, 904, 904, 904, 904, 904, 904,
- 577, 1230, 1624, 904, 576, 575, 1645, 1647, 1235, 904,
- 904, 904, 904, 904, 904, 905, 905, 905, 905, 905,
- 905, 905, 1235, 1624, 1645, 1647, 905, 1645, 1649, 1647,
- 574, 573, 905, 905, 905, 905, 905, 905, 909, 909,
- 909, 909, 909, 909, 909, 909, 1649, 572, 1235, 909,
- 569, 1649, 1651, 1652, 1657, 909, 909, 909, 909, 909,
- 909, 911, 911, 911, 911, 911, 911, 911, 911, 911,
-
- 1651, 1652, 1657, 911, 568, 1651, 1653, 567, 565, 911,
- 911, 911, 911, 911, 911, 912, 912, 912, 912, 912,
- 912, 912, 912, 1657, 1653, 1652, 912, 564, 561, 1660,
- 556, 1664, 912, 912, 912, 912, 912, 912, 920, 920,
- 920, 920, 920, 920, 920, 920, 920, 1660, 1653, 1664,
- 920, 552, 1660, 1668, 1669, 548, 920, 920, 920, 920,
- 920, 920, 921, 921, 921, 921, 921, 921, 921, 921,
- 543, 1668, 1669, 921, 538, 537, 1668, 1669, 1674, 921,
- 921, 921, 921, 921, 921, 931, 931, 931, 931, 931,
- 931, 931, 931, 931, 536, 532, 1674, 931, 526, 1675,
-
- 1677, 1674, 525, 931, 931, 931, 931, 931, 931, 932,
- 932, 932, 932, 932, 932, 932, 932, 1675, 1677, 520,
- 932, 1675, 519, 1679, 1682, 1683, 932, 932, 932, 932,
- 932, 932, 943, 943, 943, 943, 943, 943, 943, 943,
- 943, 1679, 1682, 1683, 943, 1682, 1679, 1684, 1689, 518,
- 943, 943, 943, 943, 943, 943, 944, 944, 944, 944,
- 944, 944, 944, 944, 517, 1684, 1689, 944, 516, 515,
- 1694, 1689, 1698, 944, 944, 944, 944, 944, 944, 957,
- 957, 957, 957, 957, 957, 957, 957, 957, 1694, 1684,
- 1698, 957, 514, 513, 1700, 1698, 1703, 957, 957, 957,
-
- 957, 957, 957, 959, 959, 959, 959, 959, 959, 959,
- 959, 959, 1700, 512, 1703, 959, 511, 959, 510, 509,
- 508, 959, 959, 959, 959, 959, 959, 1126, 1126, 1126,
- 1126, 1126, 1126, 1126, 1131, 1131, 1131, 1131, 1131, 1131,
- 1131, 1710, 1712, 959, 986, 986, 986, 986, 986, 986,
- 986, 986, 986, 506, 503, 502, 501, 986, 500, 1710,
- 1712, 499, 986, 986, 986, 986, 986, 986, 986, 987,
- 987, 987, 987, 987, 987, 987, 987, 988, 988, 988,
- 988, 988, 988, 988, 988, 988, 1133, 1133, 1133, 1133,
- 1133, 1133, 1133, 1701, 1714, 988, 992, 992, 992, 992,
-
- 992, 992, 992, 992, 992, 498, 497, 495, 992, 494,
- 992, 1701, 1714, 493, 992, 992, 992, 992, 992, 992,
- 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1143, 1143, 1143,
- 1143, 1143, 1143, 1143, 1706, 1701, 992, 995, 995, 995,
- 995, 995, 995, 995, 995, 995, 492, 491, 489, 995,
- 487, 995, 1706, 485, 484, 995, 995, 995, 995, 995,
- 995, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1149, 1149,
- 1149, 1149, 1149, 1149, 1149, 1719, 1706, 995, 998, 998,
- 998, 998, 998, 998, 998, 998, 998, 483, 482, 481,
- 998, 479, 998, 1719, 478, 476, 998, 998, 998, 998,
-
- 998, 998, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1157,
- 1157, 1157, 1157, 1157, 1157, 1157, 1721, 1724, 998, 1001,
- 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 475, 474,
- 471, 1001, 467, 1001, 1721, 1724, 463, 1001, 1001, 1001,
- 1001, 1001, 1001, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
- 1168, 1168, 1168, 1168, 1168, 1168, 1168, 462, 461, 1001,
- 1006, 1006, 1006, 1006, 1006, 1006, 1006, 1006, 458, 454,
- 453, 1006, 450, 449, 448, 1191, 1194, 1006, 1006, 1006,
- 1006, 1006, 1006, 1007, 1007, 1007, 1007, 1007, 1007, 1007,
- 1007, 1007, 1188, 1191, 1194, 1007, 1543, 1007, 1198, 1236,
-
- 1308, 1007, 1007, 1007, 1007, 1007, 1007, 1194, 1191, 447,
- 1188, 444, 443, 1236, 1543, 434, 1198, 1709, 1308, 431,
- 429, 1188, 428, 1007, 1012, 1012, 1012, 1012, 1012, 1012,
- 1012, 1012, 1012, 1198, 1543, 1709, 1012, 1308, 1709, 1236,
- 1195, 1199, 1012, 1012, 1012, 1012, 1012, 1012, 1014, 1014,
- 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1193, 1195, 1199,
- 1014, 427, 1014, 426, 425, 1309, 1014, 1014, 1014, 1014,
- 1014, 1014, 1195, 1199, 424, 1193, 1223, 1223, 1223, 1223,
- 1223, 1223, 1223, 1309, 1239, 1311, 1193, 423, 1014, 1024,
- 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1239, 422,
-
- 1309, 1024, 421, 1311, 420, 1203, 419, 1024, 1024, 1024,
- 1024, 1024, 1024, 1026, 1026, 1026, 1026, 1026, 1026, 1026,
- 1026, 1026, 1311, 1203, 1239, 1026, 418, 1026, 1240, 417,
- 416, 1026, 1026, 1026, 1026, 1026, 1026, 1203, 414, 412,
- 411, 409, 1240, 1246, 1246, 1246, 1246, 1246, 1246, 1246,
- 408, 1248, 1313, 1026, 1039, 1039, 1039, 1039, 1039, 1039,
- 1039, 1039, 1039, 405, 404, 1248, 1039, 402, 1240, 400,
- 1313, 399, 1039, 1039, 1039, 1039, 1039, 1039, 1041, 1041,
- 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1313, 1249, 1252,
- 1041, 1248, 1041, 1253, 398, 393, 1041, 1041, 1041, 1041,
-
- 1041, 1041, 1249, 1252, 392, 391, 389, 1253, 1260, 1260,
- 1260, 1260, 1260, 1260, 1260, 388, 1262, 1395, 1041, 1055,
- 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1249, 1252,
- 1262, 1055, 387, 1253, 386, 1395, 384, 1055, 1055, 1055,
- 1055, 1055, 1055, 1057, 1057, 1057, 1057, 1057, 1057, 1057,
- 1057, 1057, 1395, 1263, 1266, 1057, 1262, 1057, 1267, 379,
- 378, 1057, 1057, 1057, 1057, 1057, 1057, 1263, 1266, 377,
- 374, 370, 1267, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- 368, 1276, 1489, 1057, 1069, 1069, 1069, 1069, 1069, 1069,
- 1069, 1069, 1069, 1263, 1266, 1276, 1069, 363, 1267, 362,
-
- 1489, 1277, 1069, 1069, 1069, 1069, 1069, 1069, 1070, 1070,
- 1070, 1070, 1070, 1070, 1070, 1277, 359, 1489, 354, 1070,
- 353, 1276, 1707, 345, 1713, 1070, 1070, 1070, 1070, 1070,
- 1070, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095,
- 1707, 1277, 1713, 343, 1095, 1707, 342, 1713, 337, 1095,
- 1095, 1095, 1095, 1095, 1095, 1095, 1096, 1096, 1096, 1096,
- 1096, 1096, 1096, 1096, 1097, 1097, 1097, 1097, 1097, 1097,
- 1097, 1097, 1097, 335, 1725, 1726, 1280, 1281, 1727, 1306,
- 333, 1337, 1097, 1099, 1099, 1099, 1099, 1099, 1099, 1099,
- 1280, 1281, 1725, 1726, 1099, 1337, 1727, 1306, 1306, 332,
-
- 1099, 1099, 1099, 1099, 1099, 1099, 1100, 1100, 1100, 1100,
- 1100, 1100, 1100, 1100, 1100, 1306, 1280, 1281, 1100, 331,
- 330, 1337, 329, 1338, 1100, 1100, 1100, 1100, 1100, 1100,
- 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1338, 328, 327,
- 325, 1101, 324, 323, 318, 315, 1687, 1101, 1101, 1101,
- 1101, 1101, 1101, 1103, 1103, 1103, 1103, 1103, 1103, 1103,
- 1103, 1103, 314, 1338, 1687, 1103, 313, 310, 303, 302,
- 1385, 1103, 1103, 1103, 1103, 1103, 1103, 1104, 1104, 1104,
- 1104, 1104, 1104, 1104, 1385, 1687, 300, 299, 1104, 298,
- 296, 294, 293, 1718, 1104, 1104, 1104, 1104, 1104, 1104,
-
- 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 292,
- 1385, 1718, 1106, 290, 286, 285, 283, 1386, 1106, 1106,
- 1106, 1106, 1106, 1106, 1107, 1107, 1107, 1107, 1107, 1107,
- 1107, 1386, 1718, 280, 276, 1107, 275, 272, 271, 269,
- 264, 1107, 1107, 1107, 1107, 1107, 1107, 1109, 1109, 1109,
- 1109, 1109, 1109, 1109, 1109, 1109, 261, 1386, 259, 1109,
- 258, 256, 253, 249, 1389, 1109, 1109, 1109, 1109, 1109,
- 1109, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1389, 245,
- 243, 241, 1110, 240, 238, 237, 236, 235, 1110, 1110,
- 1110, 1110, 1110, 1110, 1113, 1113, 1113, 1113, 1113, 1113,
-
- 1113, 1113, 1113, 234, 1389, 233, 1113, 232, 1113, 230,
- 228, 226, 1113, 1113, 1113, 1113, 1113, 1113, 1287, 1287,
- 1287, 1287, 1287, 1287, 1287, 1289, 1289, 1289, 1289, 1289,
- 1289, 1289, 1312, 225, 1113, 1118, 1118, 1118, 1118, 1118,
- 1118, 1118, 1118, 1118, 223, 221, 220, 1118, 218, 215,
- 1312, 1312, 214, 1118, 1118, 1118, 1118, 1118, 1118, 1127,
- 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1312, 213,
- 211, 1127, 209, 208, 205, 204, 202, 1127, 1127, 1127,
- 1127, 1127, 1127, 1138, 1138, 1138, 1138, 1138, 1138, 1138,
- 1138, 1138, 201, 200, 199, 1138, 198, 197, 196, 195,
-
- 194, 1138, 1138, 1138, 1138, 1138, 1138, 1150, 1150, 1150,
- 1150, 1150, 1150, 1150, 1150, 1150, 193, 192, 191, 1150,
- 190, 189, 188, 187, 186, 1150, 1150, 1150, 1150, 1150,
- 1150, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162,
- 185, 183, 182, 1162, 179, 178, 177, 176, 175, 1162,
- 1162, 1162, 1162, 1162, 1162, 1176, 1176, 1176, 1176, 1176,
- 1176, 1176, 1176, 1176, 174, 173, 172, 1176, 170, 167,
- 166, 165, 164, 1176, 1176, 1176, 1176, 1176, 1176, 1178,
- 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 161, 159,
- 150, 1178, 149, 1178, 1475, 1535, 1390, 1178, 1178, 1178,
-
- 1178, 1178, 1178, 1293, 1293, 1293, 1293, 1293, 1293, 1293,
- 1390, 1650, 1475, 1535, 148, 1546, 1304, 1316, 147, 1178,
- 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1650,
- 146, 1475, 1535, 1546, 1304, 1316, 1390, 1427, 1204, 1206,
- 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1304, 1316, 1650,
- 1206, 1427, 1546, 145, 144, 1400, 1206, 1206, 1206, 1206,
- 1206, 1206, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207,
- 1207, 1305, 1317, 1400, 1207, 142, 1207, 1427, 140, 139,
- 1207, 1207, 1207, 1207, 1207, 1207, 137, 1400, 135, 1305,
- 1317, 1345, 1345, 1345, 1345, 1345, 1345, 1345, 133, 132,
-
- 1305, 1317, 1207, 1210, 1210, 1210, 1210, 1210, 1210, 1210,
- 1210, 1210, 131, 130, 128, 1210, 127, 1210, 126, 125,
- 124, 1210, 1210, 1210, 1210, 1210, 1210, 1350, 1350, 1350,
- 1350, 1350, 1350, 1350, 1352, 1352, 1352, 1352, 1352, 1352,
- 1352, 123, 121, 1210, 1213, 1213, 1213, 1213, 1213, 1213,
- 1213, 1213, 1213, 119, 118, 117, 1213, 116, 1213, 115,
- 114, 113, 1213, 1213, 1213, 1213, 1213, 1213, 1358, 1358,
- 1358, 1358, 1358, 1358, 1358, 1360, 1360, 1360, 1360, 1360,
- 1360, 1360, 112, 111, 1213, 1216, 1216, 1216, 1216, 1216,
- 1216, 1216, 1216, 1216, 109, 108, 101, 1216, 100, 1216,
-
- 99, 97, 96, 1216, 1216, 1216, 1216, 1216, 1216, 1366,
- 1366, 1366, 1366, 1366, 1366, 1366, 1368, 1368, 1368, 1368,
- 1368, 1368, 1368, 93, 92, 1216, 1219, 1219, 1219, 1219,
- 1219, 1219, 1219, 1219, 1219, 91, 90, 89, 1219, 88,
- 1219, 87, 86, 85, 1219, 1219, 1219, 1219, 1219, 1219,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1376, 1376, 1376,
- 1376, 1376, 1376, 1376, 1428, 1539, 1219, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 84, 82, 1428, 1224,
- 81, 80, 79, 1539, 78, 1224, 1224, 1224, 1224, 1224,
- 1224, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231,
-
- 77, 1539, 76, 1231, 1428, 75, 74, 73, 72, 1231,
- 1231, 1231, 1231, 1231, 1231, 1241, 1241, 1241, 1241, 1241,
- 1241, 1241, 1241, 1241, 71, 70, 69, 1241, 67, 66,
- 65, 51, 43, 1241, 1241, 1241, 1241, 1241, 1241, 1254,
- 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 42, 40,
- 18, 1254, 11, 8, 3, 0, 0, 1254, 1254, 1254,
- 1254, 1254, 1254, 1268, 1268, 1268, 1268, 1268, 1268, 1268,
- 1268, 1268, 0, 0, 0, 1268, 0, 0, 0, 0,
- 0, 1268, 1268, 1268, 1268, 1268, 1268, 1282, 1282, 1282,
- 1282, 1282, 1282, 1282, 1282, 1282, 0, 0, 0, 1282,
-
- 0, 0, 0, 0, 0, 1282, 1282, 1282, 1282, 1282,
- 1282, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294,
- 0, 0, 0, 1294, 0, 0, 0, 0, 0, 1294,
- 1294, 1294, 1294, 1294, 1294, 1318, 1318, 1318, 1318, 1318,
- 1318, 1318, 1318, 1318, 0, 0, 0, 1318, 0, 1318,
- 0, 0, 0, 1318, 1318, 1318, 1318, 1318, 1318, 1383,
- 1383, 1383, 1383, 1383, 1383, 1383, 1421, 1421, 1421, 1421,
- 1421, 1421, 1421, 1435, 1540, 1318, 1322, 1322, 1322, 1322,
- 1322, 1322, 1322, 1322, 1322, 0, 0, 1435, 1322, 0,
- 0, 0, 1540, 0, 1322, 1322, 1322, 1322, 1322, 1322,
-
- 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 0,
- 1540, 0, 1325, 1435, 0, 0, 0, 0, 1325, 1325,
- 1325, 1325, 1325, 1325, 1328, 1328, 1328, 1328, 1328, 1328,
- 1328, 1328, 1328, 0, 0, 0, 1328, 0, 0, 0,
- 0, 0, 1328, 1328, 1328, 1328, 1328, 1328, 1331, 1331,
- 1331, 1331, 1331, 1331, 1331, 1331, 1331, 0, 0, 0,
- 1331, 0, 0, 0, 0, 0, 1331, 1331, 1331, 1331,
- 1331, 1331, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334,
- 1334, 0, 0, 0, 1334, 0, 0, 0, 0, 0,
- 1334, 1334, 1334, 1334, 1334, 1334, 1339, 1339, 1339, 1339,
-
- 1339, 1339, 1339, 1339, 1339, 0, 0, 0, 1339, 0,
- 0, 0, 1407, 0, 1339, 1339, 1339, 1339, 1339, 1339,
- 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1391, 1405,
- 1407, 1408, 1391, 0, 1436, 0, 0, 0, 1391, 1391,
- 1391, 1391, 1391, 1391, 1407, 1490, 0, 1405, 1436, 1408,
- 1433, 1433, 1433, 1433, 1433, 1433, 1433, 0, 1405, 0,
- 0, 1408, 1444, 1490, 1405, 1412, 1412, 1412, 1412, 1412,
- 1412, 1412, 1412, 1412, 1436, 1490, 1444, 1412, 0, 0,
- 0, 0, 1445, 1412, 1412, 1412, 1412, 1412, 1412, 1442,
- 1442, 1442, 1442, 1442, 1442, 1442, 1445, 1453, 1454, 0,
-
- 0, 0, 1444, 1451, 1451, 1451, 1451, 1451, 1451, 1451,
- 1462, 1453, 1454, 1460, 1460, 1460, 1460, 1460, 1460, 1460,
- 1463, 0, 1445, 0, 1462, 1468, 1468, 1468, 1468, 1468,
- 1468, 1468, 0, 1480, 1463, 1485, 1481, 1453, 1454, 1470,
- 1470, 1470, 1470, 1470, 1470, 1470, 1482, 1483, 1484, 0,
- 1462, 1480, 1487, 1485, 1481, 1500, 0, 1501, 1542, 1547,
- 1463, 1603, 1480, 1481, 1482, 1483, 1484, 1485, 0, 1500,
- 1487, 1501, 0, 1482, 1483, 1484, 1542, 1547, 0, 1603,
- 0, 1487, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 0,
- 0, 0, 0, 1603, 1542, 1500, 1547, 1501, 1510, 1510,
-
- 1510, 1510, 1510, 1510, 1510, 1514, 1514, 1514, 1514, 1514,
- 1514, 1514, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1522,
- 1522, 1522, 1522, 1522, 1522, 1522, 1527, 1527, 1527, 1527,
- 1527, 1527, 1527, 1529, 1530, 1538, 1545, 1549, 1551, 1551,
- 1551, 1551, 1551, 1551, 1551, 0, 0, 1529, 1530, 0,
- 0, 0, 0, 1538, 1545, 1549, 0, 0, 0, 0,
- 0, 0, 1538, 1545, 1549, 1554, 1554, 1554, 1554, 1554,
- 1554, 1554, 0, 1529, 1530, 1558, 1558, 1558, 1558, 1558,
- 1558, 1558, 1562, 1562, 1562, 1562, 1562, 1562, 1562, 1566,
- 1566, 1566, 1566, 1566, 1566, 1566, 1570, 1570, 1570, 1570,
-
- 1570, 1570, 1570, 1573, 1573, 1573, 1573, 1573, 1573, 1573,
- 1577, 1581, 0, 1582, 1583, 1586, 1588, 1584, 1590, 1590,
- 1590, 1590, 1590, 1590, 1590, 1601, 1609, 0, 1577, 1581,
- 1581, 1582, 1583, 1586, 1588, 1584, 0, 0, 0, 0,
- 0, 0, 1586, 1601, 1609, 1577, 1602, 1581, 1604, 1606,
- 1582, 1583, 1584, 1588, 1599, 1599, 1599, 1599, 1599, 1599,
- 1599, 1610, 1601, 1609, 1602, 1611, 1604, 1606, 1621, 1625,
- 0, 1626, 1627, 1602, 1629, 1630, 1637, 1639, 0, 1610,
- 1604, 1606, 1641, 1611, 0, 0, 1621, 1625, 1610, 1626,
- 1627, 1642, 1629, 1630, 1637, 1639, 1639, 1611, 1625, 0,
-
- 1641, 1643, 1626, 1637, 1644, 1621, 1630, 1627, 0, 1642,
- 1646, 1629, 1648, 1639, 1639, 1654, 1641, 1641, 0, 1643,
- 1655, 0, 1644, 1665, 1656, 1658, 1642, 0, 1646, 0,
- 1648, 1659, 1661, 1654, 0, 1662, 1643, 1663, 1655, 1644,
- 0, 1665, 1656, 1658, 1648, 1646, 1656, 1655, 0, 1659,
- 1661, 1666, 1654, 1662, 1658, 1663, 1663, 1667, 1656, 1656,
- 1665, 1670, 1671, 1672, 1673, 0, 1659, 1676, 1661, 1666,
- 1662, 1678, 1680, 1663, 0, 1667, 1681, 0, 1685, 1670,
- 1671, 1672, 1673, 1666, 0, 1676, 1686, 0, 1670, 1678,
- 1680, 1690, 1671, 0, 1681, 1667, 1685, 1673, 1672, 1676,
-
- 1688, 0, 1678, 1691, 1686, 1680, 1692, 1693, 0, 1690,
- 1685, 1681, 1696, 1695, 1697, 1699, 0, 0, 1688, 1686,
- 1686, 1691, 1702, 0, 1692, 1693, 1690, 1704, 1708, 1688,
- 1696, 1695, 1697, 1699, 1693, 1691, 1705, 1711, 1716, 0,
- 1702, 1696, 1699, 1692, 1695, 1704, 1708, 1715, 1720, 1717,
- 1722, 0, 1697, 0, 1705, 1711, 1716, 1702, 0, 0,
- 0, 0, 0, 1708, 1704, 1715, 1720, 1717, 1722, 0,
- 0, 0, 1705, 0, 1711, 1716, 1717, 1723, 0, 0,
- 1723, 1723, 0, 1715, 0, 1720, 0, 1722, 0, 0,
- 0, 0, 0, 0, 0, 1723, 1729, 0, 0, 0,
-
- 0, 1729, 1729, 1729, 1730, 0, 1730, 1730, 1730, 1730,
- 1730, 1730, 1730, 1731, 0, 1731, 1732, 1732, 1732, 1733,
- 1733, 1733, 1734, 1734, 1734, 1735, 1735, 1735, 1736, 1736,
- 1736, 1737, 1737, 1737, 1738, 1738, 1738, 1739, 1739, 1739,
- 1740, 1740, 1740, 1741, 0, 1741, 1742, 1742, 1742, 1743,
- 1743, 1743, 1744, 1744, 1744, 1745, 1745, 1745, 1746, 0,
- 1746, 1747, 1747, 1747, 1748, 1748, 0, 0, 1748, 1749,
- 1749, 1749, 1750, 1750, 1750, 1751, 1751, 1751, 1752, 1752,
- 1752, 1753, 1753, 1753, 1754, 1754, 1754, 1755, 1755, 1755,
- 1756, 1756, 1756, 1757, 1757, 1757, 1758, 1758, 0, 0,
-
- 1758, 1759, 1759, 1759, 1760, 1760, 1760, 1761, 0, 1761,
- 1762, 1762, 1762, 1763, 1763, 1763, 1764, 0, 1764, 1765,
- 1765, 1765, 1766, 1766, 1766, 1767, 1767, 1767, 1768, 1768,
- 1768, 1769, 1769, 1769, 1770, 0, 1770, 1771, 0, 1771,
- 1772, 1772, 1772, 1773, 1773, 1773, 1774, 0, 1774, 1775,
- 1775, 0, 0, 1775, 1776, 1776, 0, 0, 1776, 1777,
- 1777, 1777, 1778, 1778, 1778, 1779, 1779, 0, 1779, 1780,
- 1780, 1780, 1781, 1781, 1781, 1782, 1782, 1782, 1783, 1783,
- 1783, 1784, 1784, 1784, 1785, 1785, 1785, 1786, 1786, 1786,
- 1787, 1787, 0, 0, 1787, 1788, 1788, 1788, 1789, 1789,
-
- 1789, 1790, 1790, 0, 1790, 1791, 1791, 0, 0, 1791,
- 1792, 1792, 0, 1792, 1793, 1793, 1794, 1794, 0, 0,
- 1794, 1795, 1795, 1795, 1796, 1796, 1796, 1797, 1797, 0,
- 1797, 1798, 0, 1798, 1799, 0, 1799, 1800, 1800, 1800,
- 1801, 1801, 1801, 1802, 0, 1802, 1803, 1803, 1803, 1804,
- 1804, 1804, 1805, 1805, 1805, 1806, 1806, 1806, 1807, 1807,
- 1807, 1808, 1808, 1808, 1809, 0, 1809, 1810, 0, 1810,
- 1811, 1811, 1811, 1812, 1812, 1812, 1813, 0, 1813, 1814,
- 0, 1814, 1815, 0, 1815, 1816, 1816, 1816, 1817, 1817,
- 1817, 1818, 0, 1818, 1819, 0, 0, 1819, 1820, 1820,
-
- 0, 1820, 1821, 1821, 0, 0, 1821, 1822, 1822, 0,
- 1822, 1823, 1823, 1824, 1824, 0, 0, 1824, 1825, 1825,
- 1825, 1826, 1826, 1826, 1827, 1827, 0, 1827, 1828, 1828,
- 1828, 0, 1828, 1828, 1829, 1829, 1829, 1830, 1830, 1830,
- 1831, 1831, 1831, 1832, 1832, 1832, 1833, 1833, 1833, 1834,
- 1834, 1834, 1835, 1835, 1835, 1836, 1836, 1836, 1837, 1837,
- 0, 0, 1837, 1838, 1838, 1838, 1839, 1839, 1839, 1840,
- 1840, 0, 1840, 1841, 1841, 0, 0, 1841, 1842, 1842,
- 0, 1842, 1843, 1843, 1844, 1844, 0, 0, 1844, 1845,
- 1845, 1845, 1846, 1846, 1846, 1847, 1847, 0, 1847, 1848,
-
- 0, 0, 1848, 1849, 1849, 0, 1849, 1850, 1850, 0,
- 0, 1850, 1851, 1851, 0, 1851, 1852, 1852, 1853, 1853,
- 0, 0, 1853, 1854, 1854, 1854, 1855, 1855, 1855, 1856,
- 1856, 0, 1856, 1857, 0, 1857, 1858, 0, 1858, 1859,
- 0, 1859, 1860, 1860, 1860, 1861, 1861, 1861, 1862, 0,
- 1862, 1863, 1863, 1863, 0, 1863, 1863, 1864, 1864, 1864,
- 1865, 1865, 1865, 1866, 1866, 1866, 1867, 1867, 1867, 1868,
- 1868, 1868, 1869, 1869, 1869, 1870, 1870, 1870, 1871, 0,
- 1871, 1872, 0, 1872, 1873, 1873, 1873, 1874, 1874, 1874,
- 1875, 0, 1875, 1876, 0, 1876, 1877, 0, 1877, 1878,
-
- 1878, 1878, 1879, 1879, 1879, 1880, 0, 1880, 1881, 0,
- 1881, 1882, 0, 1882, 1883, 0, 1883, 1884, 1884, 1884,
- 1885, 1885, 1885, 1886, 0, 1886, 1887, 0, 1887, 1888,
- 0, 0, 1888, 1889, 1889, 0, 1889, 1890, 1890, 0,
- 0, 1890, 1891, 1891, 0, 1891, 1892, 1892, 1893, 1893,
- 0, 0, 1893, 1894, 1894, 1894, 1895, 1895, 1895, 1896,
- 1896, 0, 1896, 1897, 1897, 1897, 0, 1897, 1897, 1898,
- 1898, 1898, 1899, 1899, 1899, 1900, 1900, 1900, 1901, 1901,
- 1901, 1902, 1902, 1902, 1903, 1903, 1903, 1904, 1904, 1904,
- 1905, 1905, 1905, 1906, 1906, 0, 0, 1906, 1907, 1907,
-
- 1907, 1908, 1908, 1908, 1909, 1909, 0, 1909, 1910, 1910,
- 0, 0, 1910, 1911, 1911, 0, 1911, 1912, 1912, 1913,
- 1913, 0, 0, 1913, 1914, 1914, 1914, 1915, 1915, 1915,
- 1916, 1916, 0, 1916, 1917, 0, 0, 1917, 1918, 1918,
- 0, 1918, 1919, 1919, 0, 0, 1919, 1920, 1920, 0,
- 1920, 1921, 1921, 1922, 1922, 0, 0, 1922, 1923, 1923,
- 1923, 1924, 1924, 1924, 1925, 1925, 0, 1925, 1926, 0,
- 1926, 1927, 0, 0, 1927, 1928, 1928, 0, 1928, 1929,
- 1929, 0, 0, 1929, 1930, 1930, 0, 1930, 1931, 1931,
- 1932, 1932, 0, 0, 1932, 1933, 1933, 1933, 1934, 1934,
-
- 1934, 1935, 1935, 0, 1935, 1936, 0, 1936, 1937, 0,
- 1937, 1938, 0, 1938, 1939, 1939, 1939, 1940, 1940, 1940,
- 1941, 0, 1941, 1942, 1942, 1942, 0, 1942, 1942, 1943,
- 1943, 1943, 1944, 1944, 1944, 1945, 1945, 1945, 1946, 1946,
- 1946, 1947, 1947, 1947, 1948, 1948, 1948, 1949, 1949, 1949,
- 1950, 1950, 1950, 1951, 1951, 1951, 1952, 1952, 1952, 1953,
- 0, 1953, 1954, 0, 1954, 1955, 1955, 1955, 1956, 1956,
- 1956, 1957, 1957, 1957, 1958, 0, 1958, 1959, 0, 1959,
- 1960, 0, 1960, 1961, 1961, 1961, 1962, 1962, 1962, 1963,
- 1963, 1963, 1964, 0, 1964, 1965, 0, 1965, 1966, 0,
-
- 1966, 1967, 0, 1967, 1968, 1968, 1968, 1969, 1969, 1969,
- 1970, 1970, 1970, 1971, 0, 1971, 1972, 0, 1972, 1973,
- 0, 1973, 1974, 0, 1974, 1975, 1975, 1975, 1976, 1976,
- 1976, 1977, 1977, 1977, 1978, 0, 1978, 1979, 0, 1979,
- 1980, 0, 0, 1980, 1981, 1981, 0, 1981, 1982, 1982,
- 0, 0, 1982, 1983, 1983, 0, 1983, 1984, 1984, 1985,
- 1985, 0, 0, 1985, 1986, 1986, 1986, 1987, 1987, 1987,
- 1988, 1988, 0, 1988, 1989, 1989, 1989, 0, 1989, 1989,
- 1990, 1990, 1990, 1991, 1991, 1991, 1992, 1992, 1992, 1993,
- 1993, 1993, 1994, 1994, 1994, 1995, 1995, 1995, 1996, 1996,
-
- 1996, 1997, 1997, 1997, 1998, 0, 1998, 1999, 1999, 1999,
- 2000, 2000, 0, 0, 2000, 2001, 2001, 2001, 2002, 2002,
- 2002, 2003, 2003, 0, 2003, 2004, 2004, 0, 0, 2004,
- 2005, 2005, 0, 2005, 2006, 2006, 2007, 2007, 0, 0,
- 2007, 2008, 2008, 2008, 2009, 2009, 2009, 2010, 2010, 0,
- 2010, 2011, 0, 0, 2011, 2012, 2012, 0, 2012, 2013,
- 2013, 0, 0, 2013, 2014, 2014, 0, 2014, 2015, 2015,
- 2016, 2016, 0, 0, 2016, 2017, 2017, 2017, 2018, 2018,
- 2018, 2019, 2019, 0, 2019, 2020, 0, 2020, 2021, 0,
- 0, 2021, 2022, 2022, 0, 2022, 2023, 2023, 0, 0,
-
- 2023, 2024, 2024, 0, 2024, 2025, 2025, 2026, 2026, 0,
- 0, 2026, 2027, 2027, 2027, 2028, 2028, 2028, 2029, 2029,
- 0, 2029, 2030, 0, 2030, 2031, 0, 0, 2031, 2032,
- 2032, 0, 2032, 2033, 2033, 0, 0, 2033, 2034, 2034,
- 0, 2034, 2035, 2035, 2036, 2036, 0, 0, 2036, 2037,
- 2037, 2037, 2038, 2038, 2038, 2039, 2039, 0, 2039, 2040,
- 0, 2040, 2041, 0, 2041, 2042, 0, 2042, 2043, 2043,
- 2043, 2044, 0, 2044, 2045, 2045, 2045, 2046, 0, 2046,
- 2047, 2047, 2047, 0, 2047, 2047, 2048, 0, 2048, 2049,
- 2049, 2049, 2050, 0, 2050, 2051, 2051, 2051, 2052, 0,
-
- 2052, 2053, 2053, 2053, 2054, 0, 2054, 2055, 2055, 2055,
- 2056, 0, 2056, 2057, 2057, 2057, 2058, 0, 2058, 2059,
- 2059, 2059, 2060, 2060, 0, 0, 2060, 2061, 2061, 2061,
- 2062, 2062, 2062, 2063, 2063, 2063, 2064, 2064, 0, 2064,
- 2065, 2065, 2065, 2066, 0, 2066, 2067, 2067, 2067, 2068,
- 2068, 2068, 2069, 0, 2069, 2070, 0, 2070, 2071, 2071,
- 2071, 2072, 2072, 2072, 2073, 0, 2073, 2074, 0, 2074,
- 2075, 0, 2075, 2076, 2076, 2076, 2077, 2077, 2077, 2078,
- 0, 2078, 2079, 0, 2079, 2080, 0, 2080, 2081, 2081,
- 2081, 2082, 2082, 2082, 2083, 0, 2083, 2084, 0, 2084,
-
- 2085, 0, 2085, 2086, 2086, 2086, 2087, 2087, 2087, 2088,
- 0, 2088, 2089, 0, 0, 2089, 2090, 2090, 0, 2090,
- 2091, 2091, 0, 0, 2091, 2092, 2092, 0, 2092, 2093,
- 2093, 2094, 2094, 0, 0, 2094, 2095, 2095, 2095, 2096,
- 0, 2096, 2097, 2097, 0, 2097, 2098, 2098, 2098, 0,
- 2098, 2098, 2099, 2099, 2099, 2100, 2100, 2100, 2101, 0,
- 2101, 2102, 0, 2102, 2103, 0, 2103, 2104, 0, 2104,
- 2105, 0, 2105, 2106, 0, 2106, 2107, 0, 2107, 2108,
- 2108, 2108, 2109, 2109, 2109, 2110, 0, 2110, 2111, 2111,
- 0, 0, 2111, 2112, 2112, 0, 2112, 2113, 2113, 2114,
-
- 0, 2114, 2115, 0, 0, 2115, 2116, 2116, 0, 2116,
- 2117, 2117, 0, 0, 2117, 2118, 2118, 0, 2118, 2119,
- 2119, 2120, 0, 2120, 2121, 0, 2121, 2122, 0, 0,
- 2122, 2123, 2123, 0, 2123, 2124, 2124, 0, 0, 2124,
- 2125, 2125, 0, 2125, 2126, 2126, 2127, 0, 2127, 2128,
- 0, 2128, 2129, 0, 0, 2129, 2130, 2130, 0, 2130,
- 2131, 2131, 0, 0, 2131, 2132, 2132, 0, 2132, 2133,
- 2133, 2134, 0, 2134, 2135, 0, 2135, 2136, 0, 0,
- 2136, 2137, 2137, 0, 2137, 2138, 2138, 0, 0, 2138,
- 2139, 2139, 0, 2139, 2140, 2140, 2141, 0, 2141, 2142,
-
- 0, 2142, 2143, 0, 2143, 2144, 0, 2144, 2145, 2145,
- 2145, 2146, 0, 2146, 2147, 2147, 2147, 0, 2147, 2147,
- 2148, 0, 2148, 2149, 0, 2149, 2150, 0, 2150, 2151,
- 0, 2151, 2152, 0, 2152, 2153, 0, 2153, 2154, 0,
- 2154, 2155, 2155, 0, 0, 2155, 2156, 2156, 0, 2156,
- 2157, 2157, 2158, 0, 2158, 2159, 0, 2159, 2160, 0,
- 2160, 2161, 0, 2161, 2162, 0, 2162, 2163, 0, 2163,
- 2164, 0, 2164, 2165, 0, 2165, 2166, 0, 2166, 2167,
- 0, 2167, 2168, 0, 0, 2168, 2169, 2169, 0, 0,
- 2169, 2170, 0, 2170, 2171, 0, 2171, 2172, 0, 2172,
-
- 2173, 0, 0, 2173, 2174, 0, 0, 2174, 2175, 0,
- 0, 2175, 2176, 0, 0, 2176, 2177, 0, 0, 2177,
- 2178, 0, 2178, 2179, 0, 2179, 2180, 0, 0, 2180,
- 2181, 0, 2181, 2182, 0, 2182, 2183, 0, 2183, 2184,
- 0, 2184, 2185, 0, 2185, 2186, 0, 0, 2186, 2187,
- 0, 2187, 2188, 0, 2188, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728,
-
- 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728
+
+ 529, 529, 529, 864, 866, 1250, 529, 1203, 864, 866,
+ 814, 529, 529, 529, 529, 529, 529, 530, 530, 530,
+ 530, 530, 530, 530, 814, 1246, 1206, 1245, 530, 1242,
+ 868, 869, 1239, 530, 530, 530, 530, 530, 530, 534,
+ 534, 534, 534, 534, 534, 534, 534, 868, 869, 814,
+ 534, 1206, 868, 869, 871, 534, 534, 534, 534, 534,
+ 534, 536, 536, 536, 536, 536, 536, 536, 536, 536,
+ 1238, 871, 1209, 536, 871, 874, 1237, 881, 536, 536,
+ 536, 536, 536, 536, 537, 537, 537, 537, 537, 537,
+ 537, 537, 874, 874, 881, 537, 1233, 1209, 875, 881,
+
+ 537, 537, 537, 537, 537, 537, 545, 545, 545, 545,
+ 545, 545, 545, 545, 545, 875, 1232, 1229, 545, 1212,
+ 965, 962, 875, 545, 545, 545, 545, 545, 545, 546,
+ 546, 546, 546, 546, 546, 546, 546, 965, 962, 1215,
+ 546, 962, 965, 968, 1212, 546, 546, 546, 546, 546,
+ 546, 555, 555, 555, 555, 555, 555, 555, 555, 555,
+ 968, 968, 1240, 555, 1215, 1228, 970, 969, 555, 555,
+ 555, 555, 555, 555, 557, 557, 557, 557, 557, 557,
+ 557, 557, 557, 970, 969, 1227, 557, 1240, 557, 969,
+ 970, 557, 557, 557, 557, 557, 557, 739, 739, 739,
+
+ 739, 739, 739, 739, 745, 745, 745, 745, 745, 745,
+ 745, 867, 773, 557, 608, 608, 608, 608, 608, 608,
+ 608, 1254, 1223, 1268, 1221, 608, 1314, 972, 867, 773,
+ 608, 608, 608, 608, 608, 608, 610, 610, 610, 610,
+ 610, 610, 610, 773, 972, 867, 1254, 610, 1268, 972,
+ 1377, 1314, 610, 610, 610, 610, 610, 610, 611, 611,
+ 611, 611, 611, 611, 611, 611, 613, 613, 613, 613,
+ 613, 613, 613, 923, 1427, 1377, 1436, 613, 1445, 878,
+ 976, 923, 613, 613, 613, 613, 613, 613, 615, 615,
+ 615, 615, 615, 615, 615, 615, 878, 976, 1220, 1427,
+
+ 615, 1436, 976, 1445, 878, 615, 615, 615, 615, 615,
+ 615, 616, 616, 616, 616, 616, 616, 616, 616, 617,
+ 617, 617, 617, 617, 617, 617, 935, 1217, 1216, 1213,
+ 617, 1210, 1207, 1204, 935, 617, 617, 617, 617, 617,
+ 617, 618, 618, 618, 618, 618, 618, 618, 618, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 765, 775,
+ 776, 621, 777, 621, 973, 978, 621, 621, 621, 621,
+ 621, 621, 1061, 1200, 1176, 765, 775, 776, 1175, 777,
+ 1061, 973, 978, 770, 973, 775, 776, 765, 621, 624,
+ 624, 624, 624, 624, 624, 624, 624, 624, 777, 780,
+
+ 770, 624, 781, 624, 979, 1119, 624, 624, 624, 624,
+ 624, 624, 770, 1119, 1172, 1130, 780, 1454, 1168, 781,
+ 1167, 979, 787, 1130, 1164, 780, 815, 788, 624, 630,
+ 630, 630, 630, 630, 630, 630, 630, 630, 781, 787,
+ 815, 630, 1454, 630, 788, 1142, 630, 630, 630, 630,
+ 630, 630, 787, 1142, 1521, 1159, 788, 794, 794, 794,
+ 794, 794, 794, 794, 822, 815, 823, 873, 630, 635,
+ 635, 635, 635, 635, 635, 635, 635, 635, 822, 1521,
+ 823, 635, 1158, 1548, 873, 1155, 635, 635, 635, 635,
+ 635, 635, 637, 637, 637, 637, 637, 637, 637, 637,
+
+ 637, 873, 826, 822, 637, 823, 637, 827, 1548, 637,
+ 637, 637, 637, 637, 637, 1147, 826, 1552, 1146, 1143,
+ 1556, 827, 835, 835, 835, 835, 835, 835, 835, 837,
+ 980, 637, 647, 647, 647, 647, 647, 647, 647, 647,
+ 647, 826, 1552, 837, 647, 1556, 827, 980, 1135, 647,
+ 647, 647, 647, 647, 647, 649, 649, 649, 649, 649,
+ 649, 649, 649, 649, 876, 838, 841, 649, 837, 649,
+ 842, 1134, 649, 649, 649, 649, 649, 649, 1131, 838,
+ 841, 876, 1124, 1560, 842, 850, 850, 850, 850, 850,
+ 850, 850, 876, 865, 649, 660, 660, 660, 660, 660,
+
+ 660, 660, 660, 660, 838, 841, 1123, 660, 1560, 842,
+ 865, 882, 660, 660, 660, 660, 660, 660, 661, 661,
+ 661, 661, 661, 661, 661, 865, 1120, 1115, 882, 661,
+ 1114, 984, 1071, 1079, 661, 661, 661, 661, 661, 661,
+ 664, 664, 664, 664, 664, 664, 664, 882, 984, 1071,
+ 1079, 664, 870, 872, 958, 880, 664, 664, 664, 664,
+ 664, 664, 852, 852, 852, 852, 852, 852, 852, 870,
+ 872, 958, 880, 946, 664, 699, 947, 699, 699, 699,
+ 699, 699, 699, 699, 870, 872, 958, 946, 699, 880,
+ 947, 1083, 1074, 699, 699, 699, 699, 699, 699, 700,
+
+ 700, 700, 700, 700, 700, 700, 700, 1111, 1083, 1074,
+ 1083, 700, 946, 1074, 1110, 947, 700, 700, 700, 700,
+ 700, 700, 701, 701, 701, 701, 701, 701, 701, 856,
+ 856, 856, 856, 856, 856, 856, 961, 959, 877, 905,
+ 905, 905, 905, 905, 905, 905, 910, 910, 910, 910,
+ 910, 910, 910, 961, 959, 877, 701, 702, 702, 702,
+ 702, 702, 702, 702, 877, 1107, 1106, 1103, 702, 959,
+ 961, 1564, 1584, 702, 702, 702, 702, 702, 702, 704,
+ 704, 704, 704, 704, 704, 704, 704, 706, 706, 706,
+ 706, 706, 706, 706, 706, 1154, 1564, 1584, 1100, 706,
+
+ 1593, 1097, 1093, 1154, 706, 706, 706, 706, 706, 706,
+ 707, 707, 707, 707, 707, 707, 707, 707, 709, 709,
+ 709, 709, 709, 709, 709, 1593, 1066, 1062, 1055, 709,
+ 1054, 1051, 1077, 1078, 709, 709, 709, 709, 709, 709,
+ 710, 710, 710, 710, 710, 710, 710, 710, 710, 1077,
+ 1078, 1047, 710, 1077, 1082, 1078, 950, 710, 710, 710,
+ 710, 710, 710, 711, 711, 711, 711, 711, 711, 711,
+ 950, 1082, 1046, 1043, 711, 1039, 1082, 1087, 1038, 711,
+ 711, 711, 711, 711, 711, 713, 713, 713, 713, 713,
+ 713, 713, 713, 713, 1087, 950, 1035, 713, 1031, 1085,
+
+ 1087, 951, 713, 713, 713, 713, 713, 713, 714, 714,
+ 714, 714, 714, 714, 714, 951, 1085, 1085, 1030, 714,
+ 1027, 1177, 1088, 1024, 714, 714, 714, 714, 714, 714,
+ 718, 718, 718, 718, 718, 718, 718, 718, 1177, 1088,
+ 951, 718, 1088, 1023, 1178, 1020, 718, 718, 718, 718,
+ 718, 718, 720, 720, 720, 720, 720, 720, 720, 720,
+ 720, 1178, 1177, 1016, 720, 1015, 1179, 1181, 1012, 720,
+ 720, 720, 720, 720, 720, 721, 721, 721, 721, 721,
+ 721, 721, 721, 1179, 1181, 1178, 721, 1011, 1008, 1180,
+ 1004, 721, 721, 721, 721, 721, 721, 729, 729, 729,
+
+ 729, 729, 729, 729, 729, 729, 1180, 1179, 1180, 729,
+ 1000, 1184, 1185, 1182, 729, 729, 729, 729, 729, 729,
+ 730, 730, 730, 730, 730, 730, 730, 730, 1184, 1185,
+ 1182, 730, 999, 1184, 998, 1196, 730, 730, 730, 730,
+ 730, 730, 740, 740, 740, 740, 740, 740, 740, 740,
+ 740, 1182, 1196, 995, 740, 992, 1196, 1197, 1293, 740,
+ 740, 740, 740, 740, 740, 741, 741, 741, 741, 741,
+ 741, 741, 741, 989, 1197, 1293, 741, 986, 985, 1197,
+ 1294, 741, 741, 741, 741, 741, 741, 753, 753, 753,
+ 753, 753, 753, 753, 753, 753, 957, 1294, 956, 753,
+
+ 953, 949, 948, 975, 753, 753, 753, 753, 753, 753,
+ 755, 755, 755, 755, 755, 755, 755, 755, 755, 879,
+ 975, 1005, 755, 945, 755, 940, 936, 755, 755, 755,
+ 755, 755, 755, 975, 967, 1005, 879, 914, 914, 914,
+ 914, 914, 914, 914, 1076, 879, 928, 963, 1006, 755,
+ 789, 967, 789, 789, 789, 789, 789, 789, 789, 967,
+ 1005, 1076, 1006, 789, 963, 963, 1295, 789, 789, 789,
+ 789, 789, 789, 789, 791, 791, 791, 791, 791, 791,
+ 791, 1076, 963, 1295, 924, 791, 971, 1006, 1296, 1309,
+ 791, 791, 791, 791, 791, 791, 793, 793, 793, 793,
+
+ 793, 793, 793, 971, 917, 1296, 1309, 793, 913, 1187,
+ 1297, 971, 793, 793, 793, 793, 793, 793, 795, 795,
+ 795, 795, 795, 795, 795, 795, 1187, 1297, 908, 903,
+ 795, 902, 1297, 901, 1187, 795, 795, 795, 795, 795,
+ 795, 796, 796, 796, 796, 796, 796, 796, 796, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799, 898, 895,
+ 891, 799, 859, 799, 855, 848, 799, 799, 799, 799,
+ 799, 799, 919, 919, 919, 919, 919, 919, 919, 921,
+ 921, 921, 921, 921, 921, 921, 847, 1396, 799, 802,
+ 802, 802, 802, 802, 802, 802, 802, 802, 844, 840,
+
+ 839, 802, 836, 802, 1396, 833, 802, 802, 802, 802,
+ 802, 802, 925, 925, 925, 925, 925, 925, 925, 931,
+ 931, 931, 931, 931, 931, 931, 832, 1473, 802, 805,
+ 805, 805, 805, 805, 805, 805, 805, 805, 829, 825,
+ 824, 805, 821, 805, 1473, 820, 805, 805, 805, 805,
+ 805, 805, 933, 933, 933, 933, 933, 933, 933, 937,
+ 937, 937, 937, 937, 937, 937, 1013, 960, 805, 811,
+ 811, 811, 811, 811, 811, 811, 811, 811, 817, 813,
+ 1013, 811, 810, 811, 960, 964, 811, 811, 811, 811,
+ 811, 811, 944, 944, 944, 944, 944, 944, 944, 960,
+
+ 960, 809, 964, 808, 807, 1013, 1014, 966, 811, 816,
+ 816, 816, 816, 816, 816, 816, 816, 816, 964, 804,
+ 1014, 816, 801, 798, 966, 977, 816, 816, 816, 816,
+ 816, 816, 818, 818, 818, 818, 818, 818, 818, 818,
+ 818, 966, 977, 1017, 818, 1014, 818, 1018, 1286, 818,
+ 818, 818, 818, 818, 818, 797, 1286, 1017, 758, 977,
+ 757, 1018, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1028,
+ 754, 818, 828, 828, 828, 828, 828, 828, 828, 828,
+ 828, 750, 1017, 1028, 828, 749, 1018, 1072, 746, 828,
+ 828, 828, 828, 828, 828, 830, 830, 830, 830, 830,
+
+ 830, 830, 830, 830, 1072, 1029, 1032, 830, 1028, 830,
+ 1033, 742, 830, 830, 830, 830, 830, 830, 1072, 1029,
+ 1032, 738, 731, 727, 1033, 1042, 1042, 1042, 1042, 1042,
+ 1042, 1042, 1044, 1302, 830, 843, 843, 843, 843, 843,
+ 843, 843, 843, 843, 1029, 1032, 1044, 843, 722, 1033,
+ 1302, 717, 843, 843, 843, 843, 843, 843, 845, 845,
+ 845, 845, 845, 845, 845, 845, 845, 1068, 1045, 1048,
+ 845, 1044, 845, 1049, 1302, 845, 845, 845, 845, 845,
+ 845, 716, 1045, 1048, 1068, 715, 712, 1049, 1057, 1057,
+ 1057, 1057, 1057, 1057, 1057, 1068, 708, 845, 857, 857,
+
+ 857, 857, 857, 857, 857, 857, 857, 1045, 1048, 698,
+ 857, 697, 1049, 1075, 1165, 857, 857, 857, 857, 857,
+ 857, 858, 858, 858, 858, 858, 858, 858, 1165, 693,
+ 1075, 692, 858, 690, 689, 1305, 672, 858, 858, 858,
+ 858, 858, 858, 884, 1075, 884, 884, 884, 884, 884,
+ 884, 884, 1305, 1165, 662, 658, 884, 1305, 1393, 1310,
+ 884, 884, 884, 884, 884, 884, 884, 885, 885, 885,
+ 885, 885, 885, 885, 1342, 1393, 1310, 652, 885, 651,
+ 648, 1394, 1342, 885, 885, 885, 885, 885, 885, 886,
+ 886, 886, 886, 886, 886, 886, 886, 1310, 1394, 1393,
+
+ 644, 886, 1394, 886, 643, 640, 886, 886, 886, 886,
+ 886, 886, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1063,
+ 1063, 1063, 1063, 1063, 1063, 1063, 1073, 1081, 886, 888,
+ 888, 888, 888, 888, 888, 888, 639, 636, 632, 629,
+ 888, 628, 627, 1073, 1081, 888, 888, 888, 888, 888,
+ 888, 889, 889, 889, 889, 889, 889, 889, 889, 1081,
+ 626, 623, 1073, 889, 620, 619, 612, 609, 889, 889,
+ 889, 889, 889, 889, 890, 890, 890, 890, 890, 890,
+ 890, 890, 892, 892, 892, 892, 892, 892, 892, 1349,
+ 607, 603, 597, 892, 596, 595, 1397, 1349, 892, 892,
+
+ 892, 892, 892, 892, 893, 893, 893, 893, 893, 893,
+ 893, 893, 893, 1397, 594, 590, 893, 1397, 1404, 1391,
+ 1166, 893, 893, 893, 893, 893, 893, 894, 894, 894,
+ 894, 894, 894, 894, 1166, 1404, 1391, 589, 894, 1391,
+ 1404, 1398, 587, 894, 894, 894, 894, 894, 894, 896,
+ 896, 896, 896, 896, 896, 896, 896, 896, 1398, 1166,
+ 586, 896, 1398, 1399, 1392, 1169, 896, 896, 896, 896,
+ 896, 896, 897, 897, 897, 897, 897, 897, 897, 1169,
+ 1399, 1392, 585, 897, 1392, 584, 1399, 580, 897, 897,
+ 897, 897, 897, 897, 899, 899, 899, 899, 899, 899,
+
+ 899, 899, 899, 579, 1169, 578, 899, 577, 1401, 1474,
+ 1170, 899, 899, 899, 899, 899, 899, 900, 900, 900,
+ 900, 900, 900, 900, 1170, 1401, 1474, 576, 900, 1401,
+ 575, 1486, 574, 900, 900, 900, 900, 900, 900, 904,
+ 904, 904, 904, 904, 904, 904, 904, 1474, 1486, 1170,
+ 904, 1486, 573, 1529, 1481, 904, 904, 904, 904, 904,
+ 904, 906, 906, 906, 906, 906, 906, 906, 906, 906,
+ 1529, 1481, 572, 906, 571, 570, 1483, 569, 906, 906,
+ 906, 906, 906, 906, 907, 907, 907, 907, 907, 907,
+ 907, 907, 1481, 1483, 1483, 907, 568, 567, 1531, 1532,
+
+ 907, 907, 907, 907, 907, 907, 915, 915, 915, 915,
+ 915, 915, 915, 915, 915, 1531, 1532, 564, 915, 563,
+ 1536, 1532, 1539, 915, 915, 915, 915, 915, 915, 916,
+ 916, 916, 916, 916, 916, 916, 916, 1536, 562, 1539,
+ 916, 560, 559, 556, 1539, 916, 916, 916, 916, 916,
+ 916, 926, 926, 926, 926, 926, 926, 926, 926, 926,
+ 1536, 551, 547, 926, 543, 1543, 1571, 1573, 926, 926,
+ 926, 926, 926, 926, 927, 927, 927, 927, 927, 927,
+ 927, 927, 1543, 1571, 1573, 927, 538, 1573, 1582, 1574,
+ 927, 927, 927, 927, 927, 927, 938, 938, 938, 938,
+
+ 938, 938, 938, 938, 938, 1582, 1574, 533, 938, 1574,
+ 1607, 1575, 1580, 938, 938, 938, 938, 938, 938, 939,
+ 939, 939, 939, 939, 939, 939, 939, 1607, 1575, 1580,
+ 939, 1575, 1580, 1600, 1602, 939, 939, 939, 939, 939,
+ 939, 952, 952, 952, 952, 952, 952, 952, 952, 952,
+ 1600, 1602, 532, 952, 1600, 531, 1602, 527, 952, 952,
+ 952, 952, 952, 952, 954, 954, 954, 954, 954, 954,
+ 954, 954, 954, 1069, 1070, 521, 954, 1080, 954, 1224,
+ 1089, 954, 954, 954, 954, 954, 954, 1357, 1365, 520,
+ 1069, 1070, 1373, 1224, 1080, 1357, 1365, 1089, 1089, 1615,
+
+ 1373, 1069, 1070, 954, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 1080, 1089, 1089, 1615, 981, 1224, 515,
+ 514, 981, 981, 981, 981, 981, 981, 981, 982, 982,
+ 982, 982, 982, 982, 982, 982, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 513, 1084, 1189, 1086, 512,
+ 1623, 511, 1195, 983, 987, 987, 987, 987, 987, 987,
+ 987, 987, 987, 1084, 1189, 1086, 987, 1623, 987, 1195,
+ 1191, 987, 987, 987, 987, 987, 987, 1189, 1084, 1086,
+ 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1191, 1195, 510,
+ 1628, 509, 1635, 987, 990, 990, 990, 990, 990, 990,
+
+ 990, 990, 990, 508, 1191, 507, 990, 1628, 990, 1635,
+ 506, 990, 990, 990, 990, 990, 990, 1117, 1117, 1117,
+ 1117, 1117, 1117, 1117, 1121, 1121, 1121, 1121, 1121, 1121,
+ 1121, 505, 1659, 990, 993, 993, 993, 993, 993, 993,
+ 993, 993, 993, 504, 503, 501, 993, 498, 993, 1659,
+ 497, 993, 993, 993, 993, 993, 993, 1126, 1126, 1126,
+ 1126, 1126, 1126, 1126, 1128, 1128, 1128, 1128, 1128, 1128,
+ 1128, 496, 1672, 993, 996, 996, 996, 996, 996, 996,
+ 996, 996, 996, 495, 494, 493, 996, 492, 996, 1672,
+ 490, 996, 996, 996, 996, 996, 996, 1132, 1132, 1132,
+
+ 1132, 1132, 1132, 1132, 1138, 1138, 1138, 1138, 1138, 1138,
+ 1138, 1192, 1225, 996, 1001, 1001, 1001, 1001, 1001, 1001,
+ 1001, 1001, 489, 488, 487, 1001, 1225, 486, 1192, 484,
+ 1001, 1001, 1001, 1001, 1001, 1001, 1002, 1002, 1002, 1002,
+ 1002, 1002, 1002, 1002, 1002, 482, 1192, 480, 1002, 479,
+ 1002, 1225, 478, 1002, 1002, 1002, 1002, 1002, 1002, 1140,
+ 1140, 1140, 1140, 1140, 1140, 1140, 1144, 1144, 1144, 1144,
+ 1144, 1144, 1144, 1230, 1193, 1002, 1007, 1007, 1007, 1007,
+ 1007, 1007, 1007, 1007, 1007, 477, 476, 1230, 1007, 474,
+ 473, 1193, 1603, 1007, 1007, 1007, 1007, 1007, 1007, 1009,
+
+ 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1193, 1603,
+ 471, 1009, 1230, 1009, 1603, 470, 1009, 1009, 1009, 1009,
+ 1009, 1009, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1152,
+ 1152, 1152, 1152, 1152, 1152, 1152, 1231, 1301, 1009, 1019,
+ 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 469, 466,
+ 1231, 1019, 462, 458, 1301, 1301, 1019, 1019, 1019, 1019,
+ 1019, 1019, 1021, 1021, 1021, 1021, 1021, 1021, 1021, 1021,
+ 1021, 457, 1301, 456, 1021, 1231, 1021, 453, 449, 1021,
+ 1021, 1021, 1021, 1021, 1021, 1156, 1156, 1156, 1156, 1156,
+ 1156, 1156, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1234,
+
+ 1303, 1021, 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,
+ 1034, 448, 445, 1234, 1034, 444, 443, 1303, 1186, 1034,
+ 1034, 1034, 1034, 1034, 1034, 1036, 1036, 1036, 1036, 1036,
+ 1036, 1036, 1036, 1036, 1183, 1186, 1303, 1036, 1234, 1036,
+ 1418, 1467, 1036, 1036, 1036, 1036, 1036, 1036, 1418, 1467,
+ 1186, 1183, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1640,
+ 1235, 1678, 1183, 1617, 1036, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1235, 442, 1640, 1050, 1678, 1640,
+ 1617, 1190, 1050, 1050, 1050, 1050, 1050, 1050, 1052, 1052,
+ 1052, 1052, 1052, 1052, 1052, 1052, 1052, 1188, 1190, 1235,
+
+ 1052, 1617, 1052, 1527, 439, 1052, 1052, 1052, 1052, 1052,
+ 1052, 1527, 1190, 438, 1188, 1241, 1241, 1241, 1241, 1241,
+ 1241, 1241, 1405, 429, 1243, 1188, 1304, 1052, 1064, 1064,
+ 1064, 1064, 1064, 1064, 1064, 1064, 1064, 426, 1243, 1405,
+ 1064, 424, 423, 1304, 1244, 1064, 1064, 1064, 1064, 1064,
+ 1064, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1244, 1405,
+ 1304, 422, 1065, 1243, 421, 1629, 420, 1065, 1065, 1065,
+ 1065, 1065, 1065, 1090, 1090, 1090, 1090, 1090, 1090, 1090,
+ 1090, 1090, 1629, 1244, 419, 418, 1090, 1629, 417, 416,
+ 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1091, 1091, 1091,
+
+ 1091, 1091, 1091, 1091, 1091, 1092, 1092, 1092, 1092, 1092,
+ 1092, 1092, 1092, 1092, 415, 1642, 1247, 1248, 414, 1257,
+ 1308, 1258, 1092, 1094, 1094, 1094, 1094, 1094, 1094, 1094,
+ 1247, 1248, 1642, 1257, 1094, 1258, 1642, 1308, 413, 1094,
+ 1094, 1094, 1094, 1094, 1094, 1095, 1095, 1095, 1095, 1095,
+ 1095, 1095, 1095, 1095, 1308, 1247, 1248, 1095, 1257, 1630,
+ 1258, 1261, 1095, 1095, 1095, 1095, 1095, 1095, 1096, 1096,
+ 1096, 1096, 1096, 1096, 1096, 1261, 1630, 412, 411, 1096,
+ 409, 1630, 1631, 407, 1096, 1096, 1096, 1096, 1096, 1096,
+ 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1631,
+
+ 1261, 406, 1098, 404, 1631, 1633, 1262, 1098, 1098, 1098,
+ 1098, 1098, 1098, 1099, 1099, 1099, 1099, 1099, 1099, 1099,
+ 1262, 403, 1633, 400, 1099, 399, 397, 1633, 395, 1099,
+ 1099, 1099, 1099, 1099, 1099, 1101, 1101, 1101, 1101, 1101,
+ 1101, 1101, 1101, 1101, 394, 1262, 393, 1101, 388, 1644,
+ 1647, 1271, 1101, 1101, 1101, 1101, 1101, 1101, 1102, 1102,
+ 1102, 1102, 1102, 1102, 1102, 1271, 1644, 1647, 387, 1102,
+ 386, 1644, 1618, 384, 1102, 1102, 1102, 1102, 1102, 1102,
+ 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1104, 1618,
+ 1271, 1647, 1104, 383, 1646, 1648, 1689, 1104, 1104, 1104,
+
+ 1104, 1104, 1104, 1105, 1105, 1105, 1105, 1105, 1105, 1105,
+ 1618, 1646, 1648, 1689, 1105, 382, 1646, 1194, 1198, 1105,
+ 1105, 1105, 1105, 1105, 1105, 1108, 1108, 1108, 1108, 1108,
+ 1108, 1108, 1108, 1108, 1194, 1198, 1648, 1108, 381, 1108,
+ 379, 374, 1108, 1108, 1108, 1108, 1108, 1108, 1194, 1198,
+ 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1269, 1269, 1269,
+ 1269, 1269, 1269, 1269, 1108, 1113, 1113, 1113, 1113, 1113,
+ 1113, 1113, 1113, 1113, 373, 372, 369, 1113, 365, 363,
+ 1655, 1663, 1113, 1113, 1113, 1113, 1113, 1113, 1122, 1122,
+ 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1655, 1663, 358,
+
+ 1122, 357, 1655, 1663, 1664, 1122, 1122, 1122, 1122, 1122,
+ 1122, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133,
+ 354, 1664, 349, 1133, 348, 340, 1664, 1669, 1133, 1133,
+ 1133, 1133, 1133, 1133, 1145, 1145, 1145, 1145, 1145, 1145,
+ 1145, 1145, 1145, 338, 1669, 337, 1145, 332, 330, 1669,
+ 1670, 1145, 1145, 1145, 1145, 1145, 1145, 1157, 1157, 1157,
+ 1157, 1157, 1157, 1157, 1157, 1157, 328, 1670, 327, 1157,
+ 326, 1670, 1674, 1677, 1157, 1157, 1157, 1157, 1157, 1157,
+ 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 1674,
+ 1677, 325, 1171, 1677, 1674, 324, 323, 1171, 1171, 1171,
+
+ 1171, 1171, 1171, 1173, 1173, 1173, 1173, 1173, 1173, 1173,
+ 1173, 1173, 1298, 1272, 1275, 1173, 1276, 1173, 322, 320,
+ 1173, 1173, 1173, 1173, 1173, 1173, 319, 1272, 1275, 1298,
+ 1276, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1298, 1299,
+ 1306, 1311, 1173, 1199, 1199, 1199, 1199, 1199, 1199, 1199,
+ 1199, 1199, 1272, 1275, 318, 1276, 1299, 1306, 1311, 1332,
+ 1199, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1201, 1299,
+ 313, 1311, 1201, 1332, 310, 1695, 1306, 1201, 1201, 1201,
+ 1201, 1201, 1201, 1202, 1202, 1202, 1202, 1202, 1202, 1202,
+ 1202, 1202, 1695, 309, 308, 1202, 305, 1202, 1332, 298,
+
+ 1202, 1202, 1202, 1202, 1202, 1202, 1284, 1284, 1284, 1284,
+ 1284, 1284, 1284, 1288, 1288, 1288, 1288, 1288, 1288, 1288,
+ 1333, 1300, 1202, 1205, 1205, 1205, 1205, 1205, 1205, 1205,
+ 1205, 1205, 297, 1312, 1333, 1205, 1470, 1205, 1300, 1307,
+ 1205, 1205, 1205, 1205, 1205, 1205, 295, 294, 293, 1300,
+ 1312, 291, 289, 1470, 288, 287, 1307, 1307, 285, 1333,
+ 281, 1312, 1205, 1208, 1208, 1208, 1208, 1208, 1208, 1208,
+ 1208, 1208, 1470, 280, 1307, 1208, 278, 1208, 275, 271,
+ 1208, 1208, 1208, 1208, 1208, 1208, 1340, 1340, 1340, 1340,
+ 1340, 1340, 1340, 1345, 1345, 1345, 1345, 1345, 1345, 1345,
+
+ 270, 1698, 1208, 1211, 1211, 1211, 1211, 1211, 1211, 1211,
+ 1211, 1211, 267, 266, 264, 1211, 259, 1211, 1698, 256,
+ 1211, 1211, 1211, 1211, 1211, 1211, 1347, 1347, 1347, 1347,
+ 1347, 1347, 1347, 1353, 1353, 1353, 1353, 1353, 1353, 1353,
+ 254, 1705, 1211, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1214, 1214, 253, 251, 248, 1214, 244, 1214, 1705, 240,
+ 1214, 1214, 1214, 1214, 1214, 1214, 1355, 1355, 1355, 1355,
+ 1355, 1355, 1355, 1361, 1361, 1361, 1361, 1361, 1361, 1361,
+ 1380, 1390, 1214, 1219, 1219, 1219, 1219, 1219, 1219, 1219,
+ 1219, 1219, 238, 236, 1380, 1219, 235, 233, 1390, 1679,
+
+ 1219, 1219, 1219, 1219, 1219, 1219, 1226, 1226, 1226, 1226,
+ 1226, 1226, 1226, 1226, 1226, 1390, 1679, 232, 1226, 1380,
+ 231, 1684, 1693, 1226, 1226, 1226, 1226, 1226, 1226, 1236,
+ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1684, 1693,
+ 1679, 1236, 230, 1684, 1693, 1696, 1236, 1236, 1236, 1236,
+ 1236, 1236, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 229, 1696, 228, 1249, 227, 225, 1701, 1702, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1263, 1263, 1263, 1263, 1263,
+ 1263, 1263, 1263, 1263, 1701, 1702, 1696, 1263, 223, 221,
+ 1702, 220, 1263, 1263, 1263, 1263, 1263, 1263, 1277, 1277,
+
+ 1277, 1277, 1277, 1277, 1277, 1277, 1277, 218, 1701, 216,
+ 1277, 215, 213, 1707, 1704, 1277, 1277, 1277, 1277, 1277,
+ 1277, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289, 1289,
+ 1707, 1704, 210, 1289, 1704, 209, 1709, 1708, 1289, 1289,
+ 1289, 1289, 1289, 1289, 1313, 1313, 1313, 1313, 1313, 1313,
+ 1313, 1313, 1313, 1709, 1708, 208, 1313, 206, 1313, 1708,
+ 204, 1313, 1313, 1313, 1313, 1313, 1313, 1363, 1363, 1363,
+ 1363, 1363, 1363, 1363, 1369, 1369, 1369, 1369, 1369, 1369,
+ 1369, 1381, 1484, 1313, 1317, 1317, 1317, 1317, 1317, 1317,
+ 1317, 1317, 1317, 203, 200, 1381, 1317, 199, 197, 1484,
+
+ 1714, 1317, 1317, 1317, 1317, 1317, 1317, 1320, 1320, 1320,
+ 1320, 1320, 1320, 1320, 1320, 1320, 1484, 1714, 196, 1320,
+ 1381, 195, 1716, 1719, 1320, 1320, 1320, 1320, 1320, 1320,
+ 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1323, 1716,
+ 1719, 194, 1323, 193, 192, 1720, 1721, 1323, 1323, 1323,
+ 1323, 1323, 1323, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1720, 1721, 191, 1326, 190, 189, 1722, 188,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1329, 1329, 1329, 1329,
+ 1329, 1329, 1329, 1329, 1329, 1722, 187, 186, 1329, 185,
+ 184, 183, 182, 1329, 1329, 1329, 1329, 1329, 1329, 1334,
+
+ 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 181, 180,
+ 178, 1334, 177, 174, 173, 172, 1334, 1334, 1334, 1334,
+ 1334, 1334, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1378,
+ 1378, 1378, 1378, 1378, 1378, 1378, 1384, 1385, 1395, 1400,
+ 1402, 1403, 1406, 1416, 1416, 1416, 1416, 1416, 1416, 1416,
+ 1384, 1385, 1422, 171, 170, 1395, 1400, 1402, 1403, 1406,
+ 169, 168, 167, 165, 162, 161, 1422, 1400, 1406, 1395,
+ 1403, 1402, 1423, 1400, 1430, 1384, 1385, 1386, 1386, 1386,
+ 1386, 1386, 1386, 1386, 1386, 1386, 1423, 160, 1430, 1386,
+ 159, 1422, 156, 154, 1386, 1386, 1386, 1386, 1386, 1386,
+
+ 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 145,
+ 144, 1423, 1407, 1430, 143, 142, 1431, 1407, 1407, 1407,
+ 1407, 1407, 1407, 1428, 1428, 1428, 1428, 1428, 1428, 1428,
+ 1431, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1439, 1440,
+ 1446, 1446, 1446, 1446, 1446, 1446, 1446, 1448, 1449, 141,
+ 140, 139, 1439, 1440, 137, 1431, 1457, 1458, 135, 134,
+ 132, 1448, 1449, 1455, 1455, 1455, 1455, 1455, 1455, 1455,
+ 1457, 1458, 130, 128, 127, 126, 125, 1439, 1440, 1463,
+ 1463, 1463, 1463, 1463, 1463, 1463, 1448, 1449, 1465, 1465,
+ 1465, 1465, 1465, 1465, 1465, 1457, 1458, 1471, 1475, 1472,
+
+ 1480, 1476, 1477, 1478, 1479, 1482, 123, 122, 1485, 121,
+ 120, 119, 118, 116, 1471, 1475, 1472, 1480, 1476, 1477,
+ 1478, 1479, 1482, 1471, 1472, 1485, 1475, 1476, 1477, 1478,
+ 1479, 1480, 1495, 1482, 1496, 114, 113, 1485, 1501, 1501,
+ 1501, 1501, 1501, 1501, 1501, 112, 1495, 111, 1496, 1505,
+ 1505, 1505, 1505, 1505, 1505, 1505, 1509, 1509, 1509, 1509,
+ 1509, 1509, 1509, 1513, 1513, 1513, 1513, 1513, 1513, 1513,
+ 110, 1495, 109, 1496, 1517, 1517, 1517, 1517, 1517, 1517,
+ 1517, 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1524, 1525,
+ 1530, 1533, 1540, 1544, 1534, 1535, 1537, 1538, 1572, 1541,
+
+ 108, 107, 1524, 1525, 1542, 1579, 1598, 1530, 1533, 1540,
+ 1544, 1534, 1535, 1537, 1538, 1572, 1541, 1533, 1540, 1544,
+ 106, 1542, 1579, 1598, 104, 103, 1530, 1524, 1525, 1534,
+ 1535, 1537, 1572, 96, 1538, 1541, 95, 1598, 94, 1579,
+ 1542, 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1549, 1549,
+ 1549, 1549, 1549, 1549, 1549, 1553, 1553, 1553, 1553, 1553,
+ 1553, 1553, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1561,
+ 1561, 1561, 1561, 1561, 1561, 1561, 1565, 1565, 1565, 1565,
+ 1565, 1565, 1565, 1568, 1568, 1568, 1568, 1568, 1568, 1568,
+ 1576, 92, 1577, 1578, 1581, 1583, 1585, 1585, 1585, 1585,
+
+ 1585, 1585, 1585, 91, 1596, 1599, 1597, 1576, 1576, 1577,
+ 1578, 1581, 1583, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
+ 1581, 1596, 1599, 1597, 1601, 1576, 1604, 1605, 1577, 1578,
+ 1606, 1583, 1597, 1616, 1619, 1620, 1599, 1621, 88, 1622,
+ 1596, 1601, 1624, 1604, 1605, 87, 86, 1606, 1632, 1625,
+ 1616, 1619, 1620, 1605, 1621, 1601, 1622, 85, 1634, 1624,
+ 1643, 1606, 1604, 1620, 1636, 1632, 1625, 1621, 1637, 1616,
+ 1638, 1639, 1619, 1622, 1632, 1634, 1634, 1643, 1624, 1625,
+ 84, 1636, 1641, 1645, 1650, 1637, 1649, 1638, 1639, 1652,
+ 1651, 1643, 1654, 1634, 1634, 1656, 83, 1636, 1636, 1641,
+
+ 1645, 1650, 1637, 1649, 1638, 1639, 1652, 1651, 1653, 1654,
+ 1650, 1651, 1656, 82, 1657, 1658, 1641, 1660, 1661, 81,
+ 1645, 1662, 1649, 1651, 1651, 1653, 1654, 1652, 1665, 1667,
+ 1656, 1657, 1658, 1658, 1660, 1661, 1653, 80, 1662, 1666,
+ 1668, 79, 1671, 1675, 1673, 1665, 1667, 1676, 1657, 1661,
+ 1658, 77, 1680, 1660, 1665, 76, 1666, 1668, 1662, 1671,
+ 1675, 1673, 1681, 1667, 1676, 1682, 75, 1685, 1666, 1680,
+ 1683, 1686, 1668, 1671, 1673, 1675, 1687, 74, 73, 1681,
+ 1688, 1676, 1682, 1680, 1685, 72, 71, 1683, 1686, 70,
+ 1690, 1691, 1692, 1687, 1681, 1681, 1694, 1688, 1683, 1697,
+
+ 1699, 1685, 1686, 1682, 1700, 69, 1688, 1690, 1691, 1692,
+ 1703, 1706, 1687, 1694, 1710, 1711, 1697, 1699, 1713, 1691,
+ 1690, 1700, 1694, 1715, 1712, 1717, 68, 1703, 1706, 1692,
+ 67, 1710, 1711, 1697, 66, 1713, 1699, 65, 64, 1700,
+ 1715, 1712, 1717, 62, 1703, 61, 60, 1706, 47, 1710,
+ 1712, 1711, 40, 39, 1718, 37, 1713, 1718, 1718, 1715,
+ 15, 1717, 13, 10, 7, 3, 0, 0, 0, 0,
+ 0, 1718, 1724, 0, 1724, 1725, 0, 1725, 1725, 1725,
+ 1725, 1725, 1725, 1726, 0, 1726, 1727, 1727, 1727, 1728,
+ 1728, 1728, 1729, 1729, 1729, 1730, 1730, 1730, 1731, 1731,
+
+ 1731, 1732, 1732, 1732, 1733, 1733, 1733, 1734, 1734, 1734,
+ 1735, 1735, 1735, 1736, 0, 1736, 1737, 1737, 1737, 1738,
+ 1738, 1738, 1739, 1739, 1739, 1740, 1740, 1740, 1741, 0,
+ 1741, 1742, 1742, 1742, 1743, 1743, 0, 0, 1743, 1744,
+ 1744, 1744, 1745, 1745, 1745, 1746, 1746, 1746, 1747, 1747,
+ 1747, 1748, 1748, 1748, 1749, 1749, 1749, 1750, 1750, 1750,
+ 1751, 1751, 1751, 1752, 1752, 1752, 1753, 1753, 0, 0,
+ 1753, 1754, 1754, 1754, 1755, 1755, 1755, 1756, 0, 1756,
+ 1757, 1757, 1757, 1758, 1758, 1758, 1759, 0, 1759, 1760,
+ 1760, 1760, 1761, 1761, 1761, 1762, 1762, 1762, 1763, 1763,
+
+ 1763, 1764, 1764, 1764, 1765, 0, 1765, 1766, 0, 1766,
+ 1767, 1767, 1767, 1768, 1768, 1768, 1769, 0, 1769, 1770,
+ 1770, 0, 0, 1770, 1771, 1771, 0, 0, 1771, 1772,
+ 1772, 1772, 1773, 1773, 1773, 1774, 1774, 0, 1774, 1775,
+ 1775, 1775, 1776, 1776, 1776, 1777, 1777, 1777, 1778, 1778,
+ 1778, 1779, 1779, 1779, 1780, 1780, 1780, 1781, 1781, 1781,
+ 1782, 1782, 0, 0, 1782, 1783, 1783, 1783, 1784, 1784,
+ 1784, 1785, 1785, 0, 1785, 1786, 1786, 0, 0, 1786,
+ 1787, 1787, 0, 1787, 1788, 1788, 1789, 1789, 0, 0,
+ 1789, 1790, 1790, 1790, 1791, 1791, 1791, 1792, 1792, 0,
+
+ 1792, 1793, 0, 1793, 1794, 0, 1794, 1795, 1795, 1795,
+ 1796, 1796, 1796, 1797, 0, 1797, 1798, 1798, 1798, 1799,
+ 1799, 1799, 1800, 1800, 1800, 1801, 1801, 1801, 1802, 1802,
+ 1802, 1803, 1803, 1803, 1804, 0, 1804, 1805, 0, 1805,
+ 1806, 1806, 1806, 1807, 1807, 1807, 1808, 0, 1808, 1809,
+ 0, 1809, 1810, 0, 1810, 1811, 1811, 1811, 1812, 1812,
+ 1812, 1813, 0, 1813, 1814, 0, 0, 1814, 1815, 1815,
+ 0, 1815, 1816, 1816, 0, 0, 1816, 1817, 1817, 0,
+ 1817, 1818, 1818, 1819, 1819, 0, 0, 1819, 1820, 1820,
+ 1820, 1821, 1821, 1821, 1822, 1822, 0, 1822, 1823, 1823,
+
+ 1823, 0, 1823, 1823, 1824, 1824, 1824, 1825, 1825, 1825,
+ 1826, 1826, 1826, 1827, 1827, 1827, 1828, 1828, 1828, 1829,
+ 1829, 1829, 1830, 1830, 1830, 1831, 1831, 1831, 1832, 1832,
+ 0, 0, 1832, 1833, 1833, 1833, 1834, 1834, 1834, 1835,
+ 1835, 0, 1835, 1836, 1836, 0, 0, 1836, 1837, 1837,
+ 0, 1837, 1838, 1838, 1839, 1839, 0, 0, 1839, 1840,
+ 1840, 1840, 1841, 1841, 1841, 1842, 1842, 0, 1842, 1843,
+ 0, 0, 1843, 1844, 1844, 0, 1844, 1845, 1845, 0,
+ 0, 1845, 1846, 1846, 0, 1846, 1847, 1847, 1848, 1848,
+ 0, 0, 1848, 1849, 1849, 1849, 1850, 1850, 1850, 1851,
+
+ 1851, 0, 1851, 1852, 0, 1852, 1853, 0, 1853, 1854,
+ 0, 1854, 1855, 1855, 1855, 1856, 1856, 1856, 1857, 0,
+ 1857, 1858, 1858, 1858, 0, 1858, 1858, 1859, 1859, 1859,
+ 1860, 1860, 1860, 1861, 1861, 1861, 1862, 1862, 1862, 1863,
+ 1863, 1863, 1864, 1864, 1864, 1865, 1865, 1865, 1866, 0,
+ 1866, 1867, 0, 1867, 1868, 1868, 1868, 1869, 1869, 1869,
+ 1870, 0, 1870, 1871, 0, 1871, 1872, 0, 1872, 1873,
+ 1873, 1873, 1874, 1874, 1874, 1875, 0, 1875, 1876, 0,
+ 1876, 1877, 0, 1877, 1878, 0, 1878, 1879, 1879, 1879,
+ 1880, 1880, 1880, 1881, 0, 1881, 1882, 0, 1882, 1883,
+
+ 0, 0, 1883, 1884, 1884, 0, 1884, 1885, 1885, 0,
+ 0, 1885, 1886, 1886, 0, 1886, 1887, 1887, 1888, 1888,
+ 0, 0, 1888, 1889, 1889, 1889, 1890, 1890, 1890, 1891,
+ 1891, 0, 1891, 1892, 1892, 1892, 0, 1892, 1892, 1893,
+ 1893, 1893, 1894, 1894, 1894, 1895, 1895, 1895, 1896, 1896,
+ 1896, 1897, 1897, 1897, 1898, 1898, 1898, 1899, 1899, 1899,
+ 1900, 1900, 1900, 1901, 1901, 0, 0, 1901, 1902, 1902,
+ 1902, 1903, 1903, 1903, 1904, 1904, 0, 1904, 1905, 1905,
+ 0, 0, 1905, 1906, 1906, 0, 1906, 1907, 1907, 1908,
+ 1908, 0, 0, 1908, 1909, 1909, 1909, 1910, 1910, 1910,
+
+ 1911, 1911, 0, 1911, 1912, 0, 0, 1912, 1913, 1913,
+ 0, 1913, 1914, 1914, 0, 0, 1914, 1915, 1915, 0,
+ 1915, 1916, 1916, 1917, 1917, 0, 0, 1917, 1918, 1918,
+ 1918, 1919, 1919, 1919, 1920, 1920, 0, 1920, 1921, 0,
+ 1921, 1922, 0, 0, 1922, 1923, 1923, 0, 1923, 1924,
+ 1924, 0, 0, 1924, 1925, 1925, 0, 1925, 1926, 1926,
+ 1927, 1927, 0, 0, 1927, 1928, 1928, 1928, 1929, 1929,
+ 1929, 1930, 1930, 0, 1930, 1931, 0, 1931, 1932, 0,
+ 1932, 1933, 0, 1933, 1934, 1934, 1934, 1935, 1935, 1935,
+ 1936, 0, 1936, 1937, 1937, 1937, 0, 1937, 1937, 1938,
+
+ 1938, 1938, 1939, 1939, 1939, 1940, 1940, 1940, 1941, 1941,
+ 1941, 1942, 1942, 1942, 1943, 1943, 1943, 1944, 1944, 1944,
+ 1945, 1945, 1945, 1946, 1946, 1946, 1947, 1947, 1947, 1948,
+ 0, 1948, 1949, 0, 1949, 1950, 1950, 1950, 1951, 1951,
+ 1951, 1952, 1952, 1952, 1953, 0, 1953, 1954, 0, 1954,
+ 1955, 0, 1955, 1956, 1956, 1956, 1957, 1957, 1957, 1958,
+ 1958, 1958, 1959, 0, 1959, 1960, 0, 1960, 1961, 0,
+ 1961, 1962, 0, 1962, 1963, 1963, 1963, 1964, 1964, 1964,
+ 1965, 1965, 1965, 1966, 0, 1966, 1967, 0, 1967, 1968,
+ 0, 1968, 1969, 0, 1969, 1970, 1970, 1970, 1971, 1971,
+
+ 1971, 1972, 1972, 1972, 1973, 0, 1973, 1974, 0, 1974,
+ 1975, 0, 0, 1975, 1976, 1976, 0, 1976, 1977, 1977,
+ 0, 0, 1977, 1978, 1978, 0, 1978, 1979, 1979, 1980,
+ 1980, 0, 0, 1980, 1981, 1981, 1981, 1982, 1982, 1982,
+ 1983, 1983, 0, 1983, 1984, 1984, 1984, 0, 1984, 1984,
+ 1985, 1985, 1985, 1986, 1986, 1986, 1987, 1987, 1987, 1988,
+ 1988, 1988, 1989, 1989, 1989, 1990, 1990, 1990, 1991, 1991,
+ 1991, 1992, 1992, 1992, 1993, 0, 1993, 1994, 1994, 1994,
+ 1995, 1995, 0, 0, 1995, 1996, 1996, 1996, 1997, 1997,
+ 1997, 1998, 1998, 0, 1998, 1999, 1999, 0, 0, 1999,
+
+ 2000, 2000, 0, 2000, 2001, 2001, 2002, 2002, 0, 0,
+ 2002, 2003, 2003, 2003, 2004, 2004, 2004, 2005, 2005, 0,
+ 2005, 2006, 0, 0, 2006, 2007, 2007, 0, 2007, 2008,
+ 2008, 0, 0, 2008, 2009, 2009, 0, 2009, 2010, 2010,
+ 2011, 2011, 0, 0, 2011, 2012, 2012, 2012, 2013, 2013,
+ 2013, 2014, 2014, 0, 2014, 2015, 0, 2015, 2016, 0,
+ 0, 2016, 2017, 2017, 0, 2017, 2018, 2018, 0, 0,
+ 2018, 2019, 2019, 0, 2019, 2020, 2020, 2021, 2021, 0,
+ 0, 2021, 2022, 2022, 2022, 2023, 2023, 2023, 2024, 2024,
+ 0, 2024, 2025, 0, 2025, 2026, 0, 0, 2026, 2027,
+
+ 2027, 0, 2027, 2028, 2028, 0, 0, 2028, 2029, 2029,
+ 0, 2029, 2030, 2030, 2031, 2031, 0, 0, 2031, 2032,
+ 2032, 2032, 2033, 2033, 2033, 2034, 2034, 0, 2034, 2035,
+ 0, 2035, 2036, 0, 2036, 2037, 0, 2037, 2038, 2038,
+ 2038, 2039, 0, 2039, 2040, 2040, 2040, 2041, 0, 2041,
+ 2042, 2042, 2042, 0, 2042, 2042, 2043, 0, 2043, 2044,
+ 2044, 2044, 2045, 0, 2045, 2046, 2046, 2046, 2047, 0,
+ 2047, 2048, 2048, 2048, 2049, 0, 2049, 2050, 2050, 2050,
+ 2051, 0, 2051, 2052, 2052, 2052, 2053, 0, 2053, 2054,
+ 2054, 2054, 2055, 2055, 0, 0, 2055, 2056, 2056, 2056,
+
+ 2057, 2057, 2057, 2058, 2058, 2058, 2059, 2059, 0, 2059,
+ 2060, 2060, 2060, 2061, 0, 2061, 2062, 2062, 2062, 2063,
+ 2063, 2063, 2064, 0, 2064, 2065, 0, 2065, 2066, 2066,
+ 2066, 2067, 2067, 2067, 2068, 0, 2068, 2069, 0, 2069,
+ 2070, 0, 2070, 2071, 2071, 2071, 2072, 2072, 2072, 2073,
+ 0, 2073, 2074, 0, 2074, 2075, 0, 2075, 2076, 2076,
+ 2076, 2077, 2077, 2077, 2078, 0, 2078, 2079, 0, 2079,
+ 2080, 0, 2080, 2081, 2081, 2081, 2082, 2082, 2082, 2083,
+ 0, 2083, 2084, 0, 0, 2084, 2085, 2085, 0, 2085,
+ 2086, 2086, 0, 0, 2086, 2087, 2087, 0, 2087, 2088,
+
+ 2088, 2089, 2089, 0, 0, 2089, 2090, 2090, 2090, 2091,
+ 0, 2091, 2092, 2092, 0, 2092, 2093, 2093, 2093, 0,
+ 2093, 2093, 2094, 2094, 2094, 2095, 2095, 2095, 2096, 0,
+ 2096, 2097, 0, 2097, 2098, 0, 2098, 2099, 0, 2099,
+ 2100, 0, 2100, 2101, 0, 2101, 2102, 0, 2102, 2103,
+ 2103, 2103, 2104, 2104, 2104, 2105, 0, 2105, 2106, 2106,
+ 0, 0, 2106, 2107, 2107, 0, 2107, 2108, 2108, 2109,
+ 0, 2109, 2110, 0, 0, 2110, 2111, 2111, 0, 2111,
+ 2112, 2112, 0, 0, 2112, 2113, 2113, 0, 2113, 2114,
+ 2114, 2115, 0, 2115, 2116, 0, 2116, 2117, 0, 0,
+
+ 2117, 2118, 2118, 0, 2118, 2119, 2119, 0, 0, 2119,
+ 2120, 2120, 0, 2120, 2121, 2121, 2122, 0, 2122, 2123,
+ 0, 2123, 2124, 0, 0, 2124, 2125, 2125, 0, 2125,
+ 2126, 2126, 0, 0, 2126, 2127, 2127, 0, 2127, 2128,
+ 2128, 2129, 0, 2129, 2130, 0, 2130, 2131, 0, 0,
+ 2131, 2132, 2132, 0, 2132, 2133, 2133, 0, 0, 2133,
+ 2134, 2134, 0, 2134, 2135, 2135, 2136, 0, 2136, 2137,
+ 0, 2137, 2138, 0, 2138, 2139, 0, 2139, 2140, 2140,
+ 2140, 2141, 0, 2141, 2142, 2142, 2142, 0, 2142, 2142,
+ 2143, 0, 2143, 2144, 0, 2144, 2145, 0, 2145, 2146,
+
+ 0, 2146, 2147, 0, 2147, 2148, 0, 2148, 2149, 0,
+ 2149, 2150, 2150, 0, 0, 2150, 2151, 2151, 0, 2151,
+ 2152, 2152, 2153, 0, 2153, 2154, 0, 2154, 2155, 0,
+ 2155, 2156, 0, 2156, 2157, 0, 2157, 2158, 0, 2158,
+ 2159, 0, 2159, 2160, 0, 2160, 2161, 0, 2161, 2162,
+ 0, 2162, 2163, 0, 0, 2163, 2164, 2164, 0, 0,
+ 2164, 2165, 0, 2165, 2166, 0, 2166, 2167, 0, 2167,
+ 2168, 0, 0, 2168, 2169, 0, 0, 2169, 2170, 0,
+ 0, 2170, 2171, 0, 0, 2171, 2172, 0, 0, 2172,
+ 2173, 0, 2173, 2174, 0, 2174, 2175, 0, 0, 2175,
+
+ 2176, 0, 2176, 2177, 0, 2177, 2178, 0, 2178, 2179,
+ 0, 2179, 2180, 0, 2180, 2181, 0, 0, 2181, 2182,
+ 0, 2182, 2183, 0, 2183, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723,
+ 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723
} ;
/* The intent behind this definition is that it'll catch
@@ -2996,7 +2944,7 @@ static inline int xdtoi(int);
*/
DIAG_OFF_FLEX
-#line 3000 "scanner.c"
+#line 2948 "scanner.c"
#define INITIAL 0
@@ -3231,7 +3179,7 @@ YY_DECL
#line 254 "scanner.l"
-#line 3235 "scanner.c"
+#line 3183 "scanner.c"
yylval = yylval_param;
@@ -3286,13 +3234,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 1729 )
+ if ( yy_current_state >= 1724 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_current_state != 1728 );
+ while ( yy_current_state != 1723 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
@@ -3565,705 +3513,690 @@ return PROTO;
case 51:
YY_RULE_SETUP
#line 314 "scanner.l"
-{
-#ifdef NO_PROTOCHAIN
- bpf_error(yyextra, "%s not supported", yytext);
-#else
- return PROTOCHAIN;
-#endif
- }
+return PROTOCHAIN;
YY_BREAK
case 52:
YY_RULE_SETUP
-#line 322 "scanner.l"
+#line 316 "scanner.l"
return GATEWAY;
YY_BREAK
case 53:
YY_RULE_SETUP
-#line 324 "scanner.l"
+#line 318 "scanner.l"
return TYPE;
YY_BREAK
case 54:
YY_RULE_SETUP
-#line 325 "scanner.l"
+#line 319 "scanner.l"
return SUBTYPE;
YY_BREAK
case 55:
YY_RULE_SETUP
-#line 326 "scanner.l"
+#line 320 "scanner.l"
return DIR;
YY_BREAK
case 56:
YY_RULE_SETUP
-#line 327 "scanner.l"
+#line 321 "scanner.l"
return ADDR1;
YY_BREAK
case 57:
YY_RULE_SETUP
-#line 328 "scanner.l"
+#line 322 "scanner.l"
return ADDR2;
YY_BREAK
case 58:
YY_RULE_SETUP
-#line 329 "scanner.l"
+#line 323 "scanner.l"
return ADDR3;
YY_BREAK
case 59:
YY_RULE_SETUP
-#line 330 "scanner.l"
+#line 324 "scanner.l"
return ADDR4;
YY_BREAK
case 60:
YY_RULE_SETUP
-#line 331 "scanner.l"
+#line 325 "scanner.l"
return RA;
YY_BREAK
case 61:
YY_RULE_SETUP
-#line 332 "scanner.l"
+#line 326 "scanner.l"
return TA;
YY_BREAK
case 62:
YY_RULE_SETUP
-#line 334 "scanner.l"
+#line 328 "scanner.l"
return LESS;
YY_BREAK
case 63:
YY_RULE_SETUP
-#line 335 "scanner.l"
+#line 329 "scanner.l"
return GREATER;
YY_BREAK
case 64:
YY_RULE_SETUP
-#line 336 "scanner.l"
+#line 330 "scanner.l"
return CBYTE;
YY_BREAK
case 65:
YY_RULE_SETUP
-#line 337 "scanner.l"
+#line 331 "scanner.l"
return TK_BROADCAST;
YY_BREAK
case 66:
YY_RULE_SETUP
-#line 338 "scanner.l"
+#line 332 "scanner.l"
return TK_MULTICAST;
YY_BREAK
case 67:
YY_RULE_SETUP
-#line 340 "scanner.l"
+#line 334 "scanner.l"
return AND;
YY_BREAK
case 68:
YY_RULE_SETUP
-#line 341 "scanner.l"
+#line 335 "scanner.l"
return OR;
YY_BREAK
case 69:
YY_RULE_SETUP
-#line 342 "scanner.l"
+#line 336 "scanner.l"
return '!';
YY_BREAK
case 70:
YY_RULE_SETUP
-#line 344 "scanner.l"
+#line 338 "scanner.l"
return LEN;
YY_BREAK
case 71:
YY_RULE_SETUP
-#line 345 "scanner.l"
+#line 339 "scanner.l"
return INBOUND;
YY_BREAK
case 72:
YY_RULE_SETUP
-#line 346 "scanner.l"
+#line 340 "scanner.l"
return OUTBOUND;
YY_BREAK
case 73:
YY_RULE_SETUP
-#line 348 "scanner.l"
+#line 342 "scanner.l"
return VLAN;
YY_BREAK
case 74:
YY_RULE_SETUP
-#line 349 "scanner.l"
+#line 343 "scanner.l"
return MPLS;
YY_BREAK
case 75:
YY_RULE_SETUP
-#line 350 "scanner.l"
+#line 344 "scanner.l"
return PPPOED;
YY_BREAK
case 76:
YY_RULE_SETUP
-#line 351 "scanner.l"
+#line 345 "scanner.l"
return PPPOES;
YY_BREAK
case 77:
YY_RULE_SETUP
-#line 352 "scanner.l"
+#line 346 "scanner.l"
return GENEVE;
YY_BREAK
case 78:
YY_RULE_SETUP
-#line 354 "scanner.l"
+#line 348 "scanner.l"
return LANE;
YY_BREAK
case 79:
YY_RULE_SETUP
-#line 355 "scanner.l"
+#line 349 "scanner.l"
return LLC;
YY_BREAK
case 80:
YY_RULE_SETUP
-#line 356 "scanner.l"
+#line 350 "scanner.l"
return METAC;
YY_BREAK
case 81:
YY_RULE_SETUP
-#line 357 "scanner.l"
+#line 351 "scanner.l"
return BCC;
YY_BREAK
case 82:
YY_RULE_SETUP
-#line 358 "scanner.l"
+#line 352 "scanner.l"
return OAM;
YY_BREAK
case 83:
YY_RULE_SETUP
-#line 359 "scanner.l"
+#line 353 "scanner.l"
return OAMF4;
YY_BREAK
case 84:
YY_RULE_SETUP
-#line 360 "scanner.l"
+#line 354 "scanner.l"
return OAMF4EC;
YY_BREAK
case 85:
YY_RULE_SETUP
-#line 361 "scanner.l"
+#line 355 "scanner.l"
return OAMF4SC;
YY_BREAK
case 86:
YY_RULE_SETUP
-#line 362 "scanner.l"
+#line 356 "scanner.l"
return SC;
YY_BREAK
case 87:
YY_RULE_SETUP
-#line 363 "scanner.l"
+#line 357 "scanner.l"
return ILMIC;
YY_BREAK
case 88:
YY_RULE_SETUP
-#line 364 "scanner.l"
+#line 358 "scanner.l"
return VPI;
YY_BREAK
case 89:
YY_RULE_SETUP
-#line 365 "scanner.l"
+#line 359 "scanner.l"
return VCI;
YY_BREAK
case 90:
YY_RULE_SETUP
-#line 366 "scanner.l"
+#line 360 "scanner.l"
return CONNECTMSG;
YY_BREAK
case 91:
YY_RULE_SETUP
-#line 367 "scanner.l"
+#line 361 "scanner.l"
return METACONNECT;
YY_BREAK
case 92:
YY_RULE_SETUP
-#line 369 "scanner.l"
+#line 363 "scanner.l"
return PF_IFNAME;
YY_BREAK
case 93:
YY_RULE_SETUP
-#line 370 "scanner.l"
+#line 364 "scanner.l"
return PF_RSET;
YY_BREAK
case 94:
YY_RULE_SETUP
-#line 371 "scanner.l"
+#line 365 "scanner.l"
return PF_RNR;
YY_BREAK
case 95:
YY_RULE_SETUP
-#line 372 "scanner.l"
+#line 366 "scanner.l"
return PF_SRNR;
YY_BREAK
case 96:
YY_RULE_SETUP
-#line 373 "scanner.l"
+#line 367 "scanner.l"
return PF_REASON;
YY_BREAK
case 97:
YY_RULE_SETUP
-#line 374 "scanner.l"
+#line 368 "scanner.l"
return PF_ACTION;
YY_BREAK
case 98:
YY_RULE_SETUP
-#line 376 "scanner.l"
+#line 370 "scanner.l"
return FISU;
YY_BREAK
case 99:
YY_RULE_SETUP
-#line 377 "scanner.l"
+#line 371 "scanner.l"
return LSSU;
YY_BREAK
case 100:
YY_RULE_SETUP
-#line 378 "scanner.l"
+#line 372 "scanner.l"
return LSSU;
YY_BREAK
case 101:
YY_RULE_SETUP
-#line 379 "scanner.l"
+#line 373 "scanner.l"
return MSU;
YY_BREAK
case 102:
YY_RULE_SETUP
-#line 380 "scanner.l"
+#line 374 "scanner.l"
return HFISU;
YY_BREAK
case 103:
YY_RULE_SETUP
-#line 381 "scanner.l"
+#line 375 "scanner.l"
return HLSSU;
YY_BREAK
case 104:
YY_RULE_SETUP
-#line 382 "scanner.l"
+#line 376 "scanner.l"
return HMSU;
YY_BREAK
case 105:
YY_RULE_SETUP
-#line 383 "scanner.l"
+#line 377 "scanner.l"
return SIO;
YY_BREAK
case 106:
YY_RULE_SETUP
-#line 384 "scanner.l"
+#line 378 "scanner.l"
return OPC;
YY_BREAK
case 107:
YY_RULE_SETUP
-#line 385 "scanner.l"
+#line 379 "scanner.l"
return DPC;
YY_BREAK
case 108:
YY_RULE_SETUP
-#line 386 "scanner.l"
+#line 380 "scanner.l"
return SLS;
YY_BREAK
case 109:
YY_RULE_SETUP
-#line 387 "scanner.l"
+#line 381 "scanner.l"
return HSIO;
YY_BREAK
case 110:
YY_RULE_SETUP
-#line 388 "scanner.l"
+#line 382 "scanner.l"
return HOPC;
YY_BREAK
case 111:
YY_RULE_SETUP
-#line 389 "scanner.l"
+#line 383 "scanner.l"
return HDPC;
YY_BREAK
case 112:
YY_RULE_SETUP
-#line 390 "scanner.l"
+#line 384 "scanner.l"
return HSLS;
YY_BREAK
case 113:
/* rule 113 can match eol */
YY_RULE_SETUP
-#line 392 "scanner.l"
+#line 386 "scanner.l"
;
YY_BREAK
case 114:
YY_RULE_SETUP
-#line 393 "scanner.l"
+#line 387 "scanner.l"
return yytext[0];
YY_BREAK
case 115:
YY_RULE_SETUP
-#line 394 "scanner.l"
+#line 388 "scanner.l"
return GEQ;
YY_BREAK
case 116:
YY_RULE_SETUP
-#line 395 "scanner.l"
+#line 389 "scanner.l"
return LEQ;
YY_BREAK
case 117:
YY_RULE_SETUP
-#line 396 "scanner.l"
+#line 390 "scanner.l"
return NEQ;
YY_BREAK
case 118:
YY_RULE_SETUP
-#line 397 "scanner.l"
+#line 391 "scanner.l"
return '=';
YY_BREAK
case 119:
YY_RULE_SETUP
-#line 398 "scanner.l"
+#line 392 "scanner.l"
return LSH;
YY_BREAK
case 120:
YY_RULE_SETUP
-#line 399 "scanner.l"
+#line 393 "scanner.l"
return RSH;
YY_BREAK
case 121:
YY_RULE_SETUP
-#line 400 "scanner.l"
-{ yylval->e = pcap_ether_aton(((char *)yytext)+1);
- if (yylval->e == NULL)
- bpf_error(yyextra, "malloc");
- return AID; }
+#line 394 "scanner.l"
+{ yylval->s = sdup(yyextra, yytext); return AID; }
YY_BREAK
case 122:
YY_RULE_SETUP
-#line 404 "scanner.l"
-{ yylval->e = pcap_ether_aton((char *)yytext);
- if (yylval->e == NULL)
- bpf_error(yyextra, "malloc");
- return EID; }
+#line 395 "scanner.l"
+{ yylval->s = sdup(yyextra, yytext); return EID; }
YY_BREAK
case 123:
YY_RULE_SETUP
-#line 408 "scanner.l"
+#line 396 "scanner.l"
{ yylval->i = stoi((char *)yytext); return NUM; }
YY_BREAK
case 124:
YY_RULE_SETUP
-#line 409 "scanner.l"
+#line 397 "scanner.l"
{
yylval->s = sdup(yyextra, (char *)yytext); return HID; }
YY_BREAK
case 125:
YY_RULE_SETUP
-#line 411 "scanner.l"
+#line 399 "scanner.l"
{
#ifdef INET6
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(yytext, NULL, &hints, &res))
- bpf_error(yyextra, "bogus IPv6 address %s", yytext);
- else {
+ if (getaddrinfo(yytext, NULL, &hints, &res)) {
+ bpf_set_error(yyextra, "bogus IPv6 address %s", yytext);
+ yylval->s = NULL;
+ } else {
freeaddrinfo(res);
- yylval->s = sdup(yyextra, (char *)yytext); return HID6;
+ yylval->s = sdup(yyextra, (char *)yytext);
}
#else
- bpf_error(yyextra, "IPv6 address %s not supported", yytext);
+ bpf_set_error(yyextra, "IPv6 address %s not supported", yytext);
+ yylval->s = NULL;
#endif /*INET6*/
+ return HID6;
}
YY_BREAK
case 126:
YY_RULE_SETUP
-#line 427 "scanner.l"
-{ bpf_error(yyextra, "bogus ethernet address %s", yytext); }
+#line 418 "scanner.l"
+{ bpf_set_error(yyextra, "bogus ethernet address %s", yytext); yylval->s = NULL; return EID; }
YY_BREAK
case 127:
YY_RULE_SETUP
-#line 428 "scanner.l"
+#line 419 "scanner.l"
{ yylval->i = 0; return NUM; }
YY_BREAK
case 128:
YY_RULE_SETUP
-#line 429 "scanner.l"
+#line 420 "scanner.l"
{ yylval->i = 1; return NUM; }
YY_BREAK
case 129:
YY_RULE_SETUP
-#line 430 "scanner.l"
+#line 421 "scanner.l"
{ yylval->i = 0; return NUM; }
YY_BREAK
case 130:
YY_RULE_SETUP
-#line 431 "scanner.l"
+#line 422 "scanner.l"
{ yylval->i = 3; return NUM; }
YY_BREAK
case 131:
YY_RULE_SETUP
-#line 432 "scanner.l"
+#line 423 "scanner.l"
{ yylval->i = 4; return NUM; }
YY_BREAK
case 132:
YY_RULE_SETUP
-#line 433 "scanner.l"
+#line 424 "scanner.l"
{ yylval->i = 5; return NUM; }
YY_BREAK
case 133:
YY_RULE_SETUP
-#line 434 "scanner.l"
+#line 425 "scanner.l"
{ yylval->i = 8; return NUM; }
YY_BREAK
case 134:
YY_RULE_SETUP
-#line 435 "scanner.l"
+#line 426 "scanner.l"
{ yylval->i = 9; return NUM; }
YY_BREAK
case 135:
YY_RULE_SETUP
-#line 436 "scanner.l"
+#line 427 "scanner.l"
{ yylval->i = 10; return NUM; }
YY_BREAK
case 136:
YY_RULE_SETUP
-#line 437 "scanner.l"
+#line 428 "scanner.l"
{ yylval->i = 11; return NUM; }
YY_BREAK
case 137:
YY_RULE_SETUP
-#line 438 "scanner.l"
+#line 429 "scanner.l"
{ yylval->i = 12; return NUM; }
YY_BREAK
case 138:
YY_RULE_SETUP
-#line 439 "scanner.l"
+#line 430 "scanner.l"
{ yylval->i = 13; return NUM; }
YY_BREAK
case 139:
YY_RULE_SETUP
-#line 440 "scanner.l"
+#line 431 "scanner.l"
{ yylval->i = 14; return NUM; }
YY_BREAK
case 140:
YY_RULE_SETUP
-#line 441 "scanner.l"
+#line 432 "scanner.l"
{ yylval->i = 15; return NUM; }
YY_BREAK
case 141:
YY_RULE_SETUP
-#line 442 "scanner.l"
+#line 433 "scanner.l"
{ yylval->i = 16; return NUM; }
YY_BREAK
case 142:
YY_RULE_SETUP
-#line 443 "scanner.l"
+#line 434 "scanner.l"
{ yylval->i = 17; return NUM; }
YY_BREAK
case 143:
YY_RULE_SETUP
-#line 444 "scanner.l"
+#line 435 "scanner.l"
{ yylval->i = 18; return NUM; }
YY_BREAK
case 144:
YY_RULE_SETUP
-#line 446 "scanner.l"
+#line 437 "scanner.l"
{ yylval->i = 0; return NUM; }
YY_BREAK
case 145:
YY_RULE_SETUP
-#line 447 "scanner.l"
+#line 438 "scanner.l"
{ yylval->i = 1; return NUM; }
YY_BREAK
case 146:
YY_RULE_SETUP
-#line 449 "scanner.l"
+#line 440 "scanner.l"
{ yylval->i = 128; return NUM; }
YY_BREAK
case 147:
YY_RULE_SETUP
-#line 450 "scanner.l"
+#line 441 "scanner.l"
{ yylval->i = 129; return NUM; }
YY_BREAK
case 148:
YY_RULE_SETUP
-#line 451 "scanner.l"
+#line 442 "scanner.l"
{ yylval->i = 130; return NUM; }
YY_BREAK
case 149:
YY_RULE_SETUP
-#line 452 "scanner.l"
+#line 443 "scanner.l"
{ yylval->i = 131; return NUM; }
YY_BREAK
case 150:
YY_RULE_SETUP
-#line 453 "scanner.l"
+#line 444 "scanner.l"
{ yylval->i = 132; return NUM; }
YY_BREAK
case 151:
YY_RULE_SETUP
-#line 454 "scanner.l"
+#line 445 "scanner.l"
{ yylval->i = 133; return NUM; }
YY_BREAK
case 152:
YY_RULE_SETUP
-#line 455 "scanner.l"
+#line 446 "scanner.l"
{ yylval->i = 134; return NUM; }
YY_BREAK
case 153:
YY_RULE_SETUP
-#line 456 "scanner.l"
+#line 447 "scanner.l"
{ yylval->i = 135; return NUM; }
YY_BREAK
case 154:
YY_RULE_SETUP
-#line 457 "scanner.l"
+#line 448 "scanner.l"
{ yylval->i = 136; return NUM; }
YY_BREAK
case 155:
YY_RULE_SETUP
-#line 458 "scanner.l"
+#line 449 "scanner.l"
{ yylval->i = 137; return NUM; }
YY_BREAK
case 156:
YY_RULE_SETUP
-#line 459 "scanner.l"
+#line 450 "scanner.l"
{ yylval->i = 138; return NUM; }
YY_BREAK
case 157:
YY_RULE_SETUP
-#line 460 "scanner.l"
+#line 451 "scanner.l"
{ yylval->i = 139; return NUM; }
YY_BREAK
case 158:
YY_RULE_SETUP
-#line 461 "scanner.l"
+#line 452 "scanner.l"
{ yylval->i = 140; return NUM; }
YY_BREAK
case 159:
YY_RULE_SETUP
-#line 462 "scanner.l"
+#line 453 "scanner.l"
{ yylval->i = 141; return NUM; }
YY_BREAK
case 160:
YY_RULE_SETUP
-#line 463 "scanner.l"
+#line 454 "scanner.l"
{ yylval->i = 142; return NUM; }
YY_BREAK
case 161:
YY_RULE_SETUP
-#line 464 "scanner.l"
+#line 455 "scanner.l"
{ yylval->i = 143; return NUM; }
YY_BREAK
case 162:
YY_RULE_SETUP
-#line 465 "scanner.l"
+#line 456 "scanner.l"
{ yylval->i = 144; return NUM; }
YY_BREAK
case 163:
YY_RULE_SETUP
-#line 466 "scanner.l"
+#line 457 "scanner.l"
{ yylval->i = 145; return NUM; }
YY_BREAK
case 164:
YY_RULE_SETUP
-#line 467 "scanner.l"
+#line 458 "scanner.l"
{ yylval->i = 146; return NUM; }
YY_BREAK
case 165:
YY_RULE_SETUP
-#line 468 "scanner.l"
+#line 459 "scanner.l"
{ yylval->i = 147; return NUM; }
YY_BREAK
case 166:
YY_RULE_SETUP
-#line 469 "scanner.l"
+#line 460 "scanner.l"
{ yylval->i = 148; return NUM; }
YY_BREAK
case 167:
YY_RULE_SETUP
-#line 470 "scanner.l"
+#line 461 "scanner.l"
{ yylval->i = 149; return NUM; }
YY_BREAK
case 168:
YY_RULE_SETUP
-#line 471 "scanner.l"
+#line 462 "scanner.l"
{ yylval->i = 151; return NUM; }
YY_BREAK
case 169:
YY_RULE_SETUP
-#line 472 "scanner.l"
+#line 463 "scanner.l"
{ yylval->i = 152; return NUM; }
YY_BREAK
case 170:
YY_RULE_SETUP
-#line 473 "scanner.l"
+#line 464 "scanner.l"
{ yylval->i = 153; return NUM; }
YY_BREAK
case 171:
YY_RULE_SETUP
-#line 475 "scanner.l"
+#line 466 "scanner.l"
{ yylval->i = 13; return NUM; }
YY_BREAK
case 172:
YY_RULE_SETUP
-#line 476 "scanner.l"
+#line 467 "scanner.l"
{ yylval->i = 0x01; return NUM; }
YY_BREAK
case 173:
YY_RULE_SETUP
-#line 477 "scanner.l"
+#line 468 "scanner.l"
{ yylval->i = 0x02; return NUM; }
YY_BREAK
case 174:
YY_RULE_SETUP
-#line 478 "scanner.l"
+#line 469 "scanner.l"
{ yylval->i = 0x04; return NUM; }
YY_BREAK
case 175:
YY_RULE_SETUP
-#line 479 "scanner.l"
+#line 470 "scanner.l"
{ yylval->i = 0x08; return NUM; }
YY_BREAK
case 176:
YY_RULE_SETUP
-#line 480 "scanner.l"
+#line 471 "scanner.l"
{ yylval->i = 0x10; return NUM; }
YY_BREAK
case 177:
YY_RULE_SETUP
-#line 481 "scanner.l"
+#line 472 "scanner.l"
{ yylval->i = 0x20; return NUM; }
YY_BREAK
case 178:
YY_RULE_SETUP
-#line 482 "scanner.l"
+#line 473 "scanner.l"
{ yylval->i = 0x40; return NUM; }
YY_BREAK
case 179:
YY_RULE_SETUP
-#line 483 "scanner.l"
+#line 474 "scanner.l"
{ yylval->i = 0x80; return NUM; }
YY_BREAK
case 180:
YY_RULE_SETUP
-#line 484 "scanner.l"
+#line 475 "scanner.l"
{
yylval->s = sdup(yyextra, (char *)yytext); return ID; }
YY_BREAK
case 181:
YY_RULE_SETUP
-#line 486 "scanner.l"
+#line 477 "scanner.l"
{ yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
YY_BREAK
case 182:
YY_RULE_SETUP
-#line 487 "scanner.l"
-{
- bpf_error(yyextra, "illegal token: %s", yytext); }
+#line 478 "scanner.l"
+{ return LEX_ERROR; }
YY_BREAK
case 183:
YY_RULE_SETUP
-#line 489 "scanner.l"
-{ bpf_error(yyextra, "illegal char '%c'", *yytext); }
- YY_BREAK
-case 184:
-YY_RULE_SETUP
-#line 490 "scanner.l"
+#line 479 "scanner.l"
ECHO;
YY_BREAK
-#line 4267 "scanner.c"
+#line 4200 "scanner.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -4558,7 +4491,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 1729 )
+ if ( yy_current_state >= 1724 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -4587,11 +4520,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 1729 )
+ if ( yy_current_state >= 1724 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 1728);
+ yy_is_jam = (yy_current_state == 1723);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state;
@@ -5390,7 +5323,7 @@ void pcap_free (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
-#line 490 "scanner.l"
+#line 479 "scanner.l"
diff --git a/freebsd/contrib/libpcap/scanner.h b/freebsd/contrib/libpcap/scanner.h
index 48ed6ee4..9403558e 100644
--- a/freebsd/contrib/libpcap/scanner.h
+++ b/freebsd/contrib/libpcap/scanner.h
@@ -376,7 +376,7 @@ extern int pcap_lex \
#undef YY_DECL
#endif
-#line 490 "scanner.l"
+#line 479 "scanner.l"
#line 383 "scanner.h"
diff --git a/freebsd/contrib/libpcap/scanner.l b/freebsd/contrib/libpcap/scanner.l
index e0890b43..effcf815 100644
--- a/freebsd/contrib/libpcap/scanner.l
+++ b/freebsd/contrib/libpcap/scanner.l
@@ -311,13 +311,7 @@ mask return NETMASK;
port return PORT;
portrange return PORTRANGE;
proto return PROTO;
-protochain {
-#ifdef NO_PROTOCHAIN
- bpf_error(yyextra, "%s not supported", yytext);
-#else
- return PROTOCHAIN;
-#endif
- }
+protochain return PROTOCHAIN;
gateway return GATEWAY;
@@ -397,14 +391,8 @@ hsls return HSLS;
"==" return '=';
"<<" return LSH;
">>" return RSH;
-${B} { yylval->e = pcap_ether_aton(((char *)yytext)+1);
- if (yylval->e == NULL)
- bpf_error(yyextra, "malloc");
- return AID; }
-{MAC} { yylval->e = pcap_ether_aton((char *)yytext);
- if (yylval->e == NULL)
- bpf_error(yyextra, "malloc");
- return EID; }
+${B} { yylval->s = sdup(yyextra, yytext); return AID; }
+{MAC} { yylval->s = sdup(yyextra, yytext); return EID; }
{N} { yylval->i = stoi((char *)yytext); return NUM; }
({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
yylval->s = sdup(yyextra, (char *)yytext); return HID; }
@@ -414,17 +402,20 @@ ${B} { yylval->e = pcap_ether_aton(((char *)yytext)+1);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(yytext, NULL, &hints, &res))
- bpf_error(yyextra, "bogus IPv6 address %s", yytext);
- else {
+ if (getaddrinfo(yytext, NULL, &hints, &res)) {
+ bpf_set_error(yyextra, "bogus IPv6 address %s", yytext);
+ yylval->s = NULL;
+ } else {
freeaddrinfo(res);
- yylval->s = sdup(yyextra, (char *)yytext); return HID6;
+ yylval->s = sdup(yyextra, (char *)yytext);
}
#else
- bpf_error(yyextra, "IPv6 address %s not supported", yytext);
+ bpf_set_error(yyextra, "IPv6 address %s not supported", yytext);
+ yylval->s = NULL;
#endif /*INET6*/
+ return HID6;
}
-{B}:+({B}:+)+ { bpf_error(yyextra, "bogus ethernet address %s", yytext); }
+{B}:+({B}:+)+ { bpf_set_error(yyextra, "bogus ethernet address %s", yytext); yylval->s = NULL; return EID; }
icmptype { yylval->i = 0; return NUM; }
icmpcode { yylval->i = 1; return NUM; }
icmp-echoreply { yylval->i = 0; return NUM; }
@@ -484,9 +475,7 @@ tcp-cwr { yylval->i = 0x80; return NUM; }
[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
yylval->s = sdup(yyextra, (char *)yytext); return ID; }
"\\"[^ !()\n\t]+ { yylval->s = sdup(yyextra, (char *)yytext + 1); return ID; }
-[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ {
- bpf_error(yyextra, "illegal token: %s", yytext); }
-. { bpf_error(yyextra, "illegal char '%c'", *yytext); }
+. { return LEX_ERROR; }
%%
/*
diff --git a/freebsd/contrib/libpcap/sf-pcap.c b/freebsd/contrib/libpcap/sf-pcap.c
index c9ac143d..86d404df 100644
--- a/freebsd/contrib/libpcap/sf-pcap.c
+++ b/freebsd/contrib/libpcap/sf-pcap.c
@@ -45,6 +45,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h> /* for INT_MAX */
#include "pcap-int.h"
@@ -111,6 +112,20 @@
static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
+#ifdef _WIN32
+/*
+ * This isn't exported on Windows, because it would only work if both
+ * libpcap and the code using it were using the same C runtime; otherwise they
+ * would be using different definitions of a FILE structure.
+ *
+ * Instead we define this as a macro in pcap/pcap.h that wraps the hopen
+ * version that we do export, passing it a raw OS HANDLE, as defined by the
+ * Win32 / Win64 ABI, obtained from the _fileno() and _get_osfhandle()
+ * functions of the appropriate CRT.
+ */
+static pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *f);
+#endif /* _WIN32 */
+
/*
* Private data for reading pcap savefiles.
*/
@@ -137,9 +152,10 @@ struct pcap_sf {
* relevant information from the header.
*/
pcap_t *
-pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
+pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
int *err)
{
+ bpf_u_int32 magic_int;
struct pcap_file_header hdr;
size_t amt_read;
pcap_t *p;
@@ -156,11 +172,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
* number for a pcap savefile, or for a byte-swapped pcap
* savefile.
*/
- if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
- magic != NSEC_TCPDUMP_MAGIC) {
- magic = SWAPLONG(magic);
- if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
- magic != NSEC_TCPDUMP_MAGIC)
+ memcpy(&magic_int, magic, sizeof(magic_int));
+ if (magic_int != TCPDUMP_MAGIC &&
+ magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
+ magic_int != NSEC_TCPDUMP_MAGIC) {
+ magic_int = SWAPLONG(magic_int);
+ if (magic_int != TCPDUMP_MAGIC &&
+ magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
+ magic_int != NSEC_TCPDUMP_MAGIC)
return (NULL); /* nope */
swapped = 1;
}
@@ -169,7 +188,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
* They are. Put the magic number in the header, and read
* the rest of the header.
*/
- hdr.magic = magic;
+ hdr.magic = magic_int;
amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
sizeof(hdr) - sizeof(hdr.magic), fp);
if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
@@ -178,9 +197,8 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
errno, "error reading dump file");
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %lu file header bytes, only got %lu",
- (unsigned long)sizeof(hdr),
- (unsigned long)amt_read);
+ "truncated dump file; tried to read %" PRIsize " file header bytes, only got %" PRIsize,
+ sizeof(hdr), amt_read);
}
*err = 1;
return (NULL);
@@ -234,20 +252,9 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
p->version_major = hdr.version_major;
p->version_minor = hdr.version_minor;
p->tzoff = hdr.thiszone;
- p->snapshot = hdr.snaplen;
- if (p->snapshot <= 0) {
- /*
- * Bogus snapshot length; use the maximum for this
- * link-layer type as a fallback.
- *
- * XXX - the only reason why snapshot is signed is
- * that pcap_snapshot() returns an int, not an
- * unsigned int.
- */
- p->snapshot = max_snaplen_for_dlt(hdr.linktype);
- }
p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
+ p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen);
p->next_packet_op = pcap_next_packet;
@@ -262,7 +269,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
switch (precision) {
case PCAP_TSTAMP_PRECISION_MICRO:
- if (magic == NSEC_TCPDUMP_MAGIC) {
+ if (magic_int == NSEC_TCPDUMP_MAGIC) {
/*
* The file has nanoseconds, the user
* wants microseconds; scale the
@@ -279,7 +286,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
break;
case PCAP_TSTAMP_PRECISION_NANO:
- if (magic == NSEC_TCPDUMP_MAGIC) {
+ if (magic_int == NSEC_TCPDUMP_MAGIC) {
/*
* The file has nanoseconds, the
* user wants nanoseconds; nothing to do.
@@ -333,7 +340,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
break;
}
- if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
+ if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) {
/*
* XXX - the patch that's in some versions of libpcap
* changes the packet header but not the magic number,
@@ -373,8 +380,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
* length will be misleading if you use it to figure
* out why a capture doesn't have all the packet data,
* but there's not much we can do to avoid that.
+ *
+ * But don't grow the snapshot length past the
+ * maximum value of an int.
*/
- p->snapshot += 14;
+ if (p->snapshot <= INT_MAX - 14)
+ p->snapshot += 14;
+ else
+ p->snapshot = INT_MAX;
}
} else
ps->hdrsize = sizeof(struct pcap_sf_pkthdr);
@@ -452,9 +465,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
} else {
if (amt_read != 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %lu header bytes, only got %lu",
- (unsigned long)ps->hdrsize,
- (unsigned long)amt_read);
+ "truncated dump file; tried to read %" PRIsize " header bytes, only got %" PRIsize,
+ ps->hdrsize, amt_read);
return (-1);
}
/* EOF */
@@ -613,8 +625,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* the read finished.
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %u captured bytes, only got %lu",
- p->snapshot, (unsigned long)amt_read);
+ "truncated dump file; tried to read %u captured bytes, only got %" PRIsize,
+ p->snapshot, amt_read);
}
return (-1);
}
@@ -637,8 +649,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
"error reading dump file");
} else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %u captured bytes, only got %lu",
- hdr->caplen, (unsigned long)bytes_read);
+ "truncated dump file; tried to read %u captured bytes, only got %" PRIsize,
+ hdr->caplen, bytes_read);
}
return (-1);
}
@@ -651,6 +663,9 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
*/
hdr->caplen = p->snapshot;
} else {
+ /*
+ * The packet is within the snapshot length for this file.
+ */
if (hdr->caplen > p->bufsize) {
/*
* Grow the buffer to the next power of 2, or
@@ -686,8 +701,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
"error reading dump file");
} else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %u captured bytes, only got %lu",
- hdr->caplen, (unsigned long)amt_read);
+ "truncated dump file; tried to read %u captured bytes, only got %" PRIsize,
+ hdr->caplen, amt_read);
}
return (-1);
}
@@ -819,9 +834,42 @@ pcap_dump_open(pcap_t *p, const char *fname)
return (pcap_setup_dump(p, linktype, f, fname));
}
+#ifdef _WIN32
+/*
+ * Initialize so that sf_write() will output to a stream wrapping the given raw
+ * OS file HANDLE.
+ */
+pcap_dumper_t *
+pcap_dump_hopen(pcap_t *p, intptr_t osfd)
+{
+ int fd;
+ FILE *file;
+
+ fd = _open_osfhandle(osfd, _O_APPEND);
+ if (fd < 0) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "_open_osfhandle");
+ return NULL;
+ }
+
+ file = _fdopen(fd, "wb");
+ if (file == NULL) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "_fdopen");
+ _close(fd);
+ return NULL;
+ }
+
+ return pcap_dump_fopen(p, file);
+}
+#endif /* _WIN32 */
+
/*
* Initialize so that sf_write() will output to the given stream.
*/
+#ifdef _WIN32
+static
+#endif /* _WIN32 */
pcap_dumper_t *
pcap_dump_fopen(pcap_t *p, FILE *f)
{
@@ -864,11 +912,19 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
return (pcap_setup_dump(p, linktype, stdout, "standard output"));
/*
+ * "a" will cause the file *not* to be truncated if it exists
+ * but will cause it to be created if it doesn't. It will
+ * also cause all writes to be done at the end of the file,
+ * but will allow reads to be done anywhere in the file. This
+ * is what we need, because we need to read from the beginning
+ * of the file to see if it already has a header and packets
+ * or if it doesn't.
+ *
* "b" is supported as of C90, so *all* UN*Xes should support it,
* even though it does nothing. It's required on Windows, as the
* file is a binary file and must be read in binary mode.
*/
- f = fopen(fname, "rb+");
+ f = fopen(fname, "ab+");
if (f == NULL) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", fname);
@@ -877,18 +933,33 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
/*
* Try to read a pcap header.
+ *
+ * We do not assume that the file will be positioned at the
+ * beginning immediately after we've opened it - we seek to
+ * the beginning. ISO C says it's implementation-defined
+ * whether the file position indicator is at the beginning
+ * or the end of the file after an append-mode open, and
+ * it wasn't obvious from the Single UNIX Specification
+ * or the Microsoft documentation how that works on SUS-
+ * compliant systems or on Windows.
*/
+ if (fseek(f, 0, SEEK_SET) == -1) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Can't seek to the beginning of %s", fname);
+ (void)fclose(f);
+ return (NULL);
+ }
amt_read = fread(&ph, 1, sizeof (ph), f);
if (amt_read != sizeof (ph)) {
if (ferror(f)) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
} else if (feof(f) && amt_read > 0) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: truncated pcap file header", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
}
}
@@ -924,7 +995,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: different time stamp precision, cannot append to file", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
}
break;
@@ -933,7 +1004,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: different time stamp precision, cannot append to file", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
}
break;
@@ -942,7 +1013,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
case SWAPLONG(NSEC_TCPDUMP_MAGIC):
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: different byte order, cannot append to file", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
case KUZNETZOV_TCPDUMP_MAGIC:
@@ -951,13 +1022,13 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: not a pcap file to which we can append", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
default:
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: not a pcap file", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
}
@@ -969,19 +1040,19 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: version is %u.%u, cannot append to file", fname,
ph.version_major, ph.version_minor);
- fclose(f);
+ (void)fclose(f);
return (NULL);
}
if ((bpf_u_int32)linktype != ph.linktype) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: different linktype, cannot append to file", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
}
if ((bpf_u_int32)p->snapshot != ph.snaplen) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: different snaplen, cannot append to file", fname);
- fclose(f);
+ (void)fclose(f);
return (NULL);
}
} else {
@@ -998,10 +1069,14 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
/*
* Start writing at the end of the file.
+ *
+ * XXX - this shouldn't be necessary, given that we're opening
+ * the file in append mode, and ISO C specifies that all writes
+ * are done at the end of the file in that mode.
*/
if (fseek(f, 0, SEEK_END) == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
- errno, "Can't seek to end of %s", fname);
+ errno, "Can't seek to the end of %s", fname);
(void)fclose(f);
return (NULL);
}
diff --git a/freebsd/contrib/libpcap/sf-pcap.h b/freebsd/contrib/libpcap/sf-pcap.h
index e9c7eafa..bc7150f4 100644
--- a/freebsd/contrib/libpcap/sf-pcap.h
+++ b/freebsd/contrib/libpcap/sf-pcap.h
@@ -31,7 +31,7 @@
#ifndef sf_pcap_h
#define sf_pcap_h
-extern pcap_t *pcap_check_header(bpf_u_int32 magic, FILE *fp,
+extern pcap_t *pcap_check_header(const uint8_t *magic, FILE *fp,
u_int precision, char *errbuf, int *err);
#endif
diff --git a/freebsd/contrib/libpcap/sf-pcapng.c b/freebsd/contrib/libpcap/sf-pcapng.c
index f5719042..bfc43241 100644
--- a/freebsd/contrib/libpcap/sf-pcapng.c
+++ b/freebsd/contrib/libpcap/sf-pcapng.c
@@ -87,7 +87,7 @@ struct option_header {
* Section Header Block.
*/
#define BT_SHB 0x0A0D0D0A
-
+#define BT_SHB_INSANE_MAX 1024U*1024U*1U /* 1MB should be enough */
struct section_header_block {
bpf_u_int32 byte_order_magic;
u_short major_version;
@@ -199,9 +199,9 @@ typedef enum {
* Per-interface information.
*/
struct pcap_ng_if {
- u_int tsresol; /* time stamp resolution */
+ uint64_t tsresol; /* time stamp resolution */
tstamp_scale_type_t scale_type; /* how to scale */
- u_int scale_factor; /* time stamp scale factor for power-of-10 tsresol */
+ uint64_t scale_factor; /* time stamp scale factor for power-of-10 tsresol */
uint64_t tsoffset; /* time stamp offset */
};
@@ -225,7 +225,7 @@ struct pcap_ng_if {
* so we impose a limit regardless of the size of a pointer.
*/
struct pcap_ng_sf {
- u_int user_tsresol; /* time stamp resolution requested by the user */
+ uint64_t user_tsresol; /* time stamp resolution requested by the user */
u_int max_blocksize; /* don't grow buffer size past this */
bpf_u_int32 ifcount; /* number of interfaces seen in this capture */
bpf_u_int32 ifaces_size; /* size of array below */
@@ -233,16 +233,21 @@ struct pcap_ng_sf {
};
/*
- * Maximum block size for a given maximum snapshot length; we calculate
- * this based
- *
- * We define it as the size of an EPB with a max_snaplen-sized
- * packet and 128KB of options.
+ * The maximum block size we start with; we use an arbitrary value of
+ * 16 MiB.
+ */
+#define INITIAL_MAX_BLOCKSIZE (16*1024*1024)
+
+/*
+ * Maximum block size for a given maximum snapshot length; we define it
+ * as the size of an EPB with a max_snaplen-sized packet and 128KB of
+ * options.
*/
-#define MAX_BLOCKSIZE(max_snaplen) (sizeof (struct block_header) + \
- sizeof (struct enhanced_packet_block) + \
- (max_snaplen) + 131072 + \
- sizeof (struct block_trailer))
+#define MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen) \
+ (sizeof (struct block_header) + \
+ sizeof (struct enhanced_packet_block) + \
+ (max_snaplen) + 131072 + \
+ sizeof (struct block_trailer))
static void pcap_ng_cleanup(pcap_t *p);
static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
@@ -263,9 +268,8 @@ read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof,
if (amt_read == 0 && !fail_on_eof)
return (0); /* EOF */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %lu bytes, only got %lu",
- (unsigned long)bytes_to_read,
- (unsigned long)amt_read);
+ "truncated pcapng dump file; tried to read %" PRIsize " bytes, only got %" PRIsize,
+ bytes_to_read, amt_read);
}
return (-1);
}
@@ -278,6 +282,7 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
struct pcap_ng_sf *ps;
int status;
struct block_header bhdr;
+ struct block_trailer *btrlr;
u_char *bdata;
size_t data_remaining;
@@ -293,29 +298,28 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
}
/*
- * Is this block "too big"?
- *
- * We choose 16MB as "too big", for now, so that we handle
- * "reasonably" large buffers but don't chew up all the
- * memory if we read a malformed file.
- */
- if (bhdr.total_length > 16*1024*1024) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "pcapng block size %u > maximum %u",
- bhdr.total_length, 16*1024*1024);
- return (-1);
- }
-
- /*
* Is this block "too small" - i.e., is it shorter than a block
* header plus a block trailer?
*/
if (bhdr.total_length < sizeof(struct block_header) +
sizeof(struct block_trailer)) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "block in pcapng dump file has a length of %u < %lu",
+ "block in pcapng dump file has a length of %u < %" PRIsize,
bhdr.total_length,
- (unsigned long)(sizeof(struct block_header) + sizeof(struct block_trailer)));
+ sizeof(struct block_header) + sizeof(struct block_trailer));
+ return (-1);
+ }
+
+ /*
+ * Is the block total length a multiple of 4?
+ */
+ if ((bhdr.total_length % 4) != 0) {
+ /*
+ * No. Report that as an error.
+ */
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "block in pcapng dump file has a length of %u that is not a multiple of 4" PRIsize,
+ bhdr.total_length);
return (-1);
}
@@ -324,12 +328,13 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
*/
if (p->bufsize < bhdr.total_length) {
/*
- * No - make it big enough, unless it's too big.
+ * No - make it big enough, unless it's too big, in
+ * which case we fail.
*/
void *bigger_buffer;
if (bhdr.total_length > ps->max_blocksize) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "block is larger than maximum block size %u",
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "pcapng block size %u > maximum %u", bhdr.total_length,
ps->max_blocksize);
return (-1);
}
@@ -352,6 +357,26 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
return (-1);
/*
+ * Get the block size from the trailer.
+ */
+ btrlr = (struct block_trailer *)(bdata + data_remaining - sizeof (struct block_trailer));
+ if (p->swapped)
+ btrlr->total_length = SWAPLONG(btrlr->total_length);
+
+ /*
+ * Is the total length from the trailer the same as the total
+ * length from the header?
+ */
+ if (bhdr.total_length != btrlr->total_length) {
+ /*
+ * No.
+ */
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "block total length in header and trailer don't match");
+ return (-1);
+ }
+
+ /*
* Initialize the cursor.
*/
cursor->data = bdata;
@@ -433,13 +458,13 @@ get_optvalue_from_block_data(struct block_cursor *cursor,
}
static int
-process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
+process_idb_options(pcap_t *p, struct block_cursor *cursor, uint64_t *tsresol,
uint64_t *tsoffset, int *is_binary, char *errbuf)
{
struct option_header *opthdr;
void *optvalue;
int saw_tsresol, saw_tsoffset;
- u_char tsresol_opt;
+ uint8_t tsresol_opt;
u_int i;
saw_tsresol = 0;
@@ -497,31 +522,42 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
/*
* Resolution is negative power of 2.
*/
+ uint8_t tsresol_shift = (tsresol_opt & 0x7F);
+
+ if (tsresol_shift > 63) {
+ /*
+ * Resolution is too high; 2^-{res}
+ * won't fit in a 64-bit value.
+ */
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block if_tsresol option resolution 2^-%u is too high",
+ tsresol_shift);
+ return (-1);
+ }
*is_binary = 1;
- *tsresol = 1 << (tsresol_opt & 0x7F);
+ *tsresol = ((uint64_t)1) << tsresol_shift;
} else {
/*
* Resolution is negative power of 10.
*/
- *is_binary = 0;
- *tsresol = 1;
- for (i = 0; i < tsresol_opt; i++)
- *tsresol *= 10;
- }
- if (*tsresol == 0) {
- /*
- * Resolution is too high.
- */
- if (tsresol_opt & 0x80) {
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Interface Description Block if_tsresol option resolution 2^-%u is too high",
- tsresol_opt & 0x7F);
- } else {
+ if (tsresol_opt > 19) {
+ /*
+ * Resolution is too high; 2^-{res}
+ * won't fit in a 64-bit value (the
+ * largest power of 10 that fits
+ * in a 64-bit value is 10^19, as
+ * the largest 64-bit unsigned
+ * value is ~1.8*10^19).
+ */
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Interface Description Block if_tsresol option resolution 10^-%u is too high",
tsresol_opt);
+ return (-1);
}
- return (-1);
+ *is_binary = 0;
+ *tsresol = 1;
+ for (i = 0; i < tsresol_opt; i++)
+ *tsresol *= 10;
}
break;
@@ -556,7 +592,7 @@ static int
add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
{
struct pcap_ng_sf *ps;
- u_int tsresol;
+ uint64_t tsresol;
uint64_t tsoffset;
int is_binary;
@@ -727,9 +763,10 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
* relevant information from the header.
*/
pcap_t *
-pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
- int *err)
+pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision,
+ char *errbuf, int *err)
{
+ bpf_u_int32 magic_int;
size_t amt_read;
bpf_u_int32 total_length;
bpf_u_int32 byte_order_magic;
@@ -751,7 +788,8 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
* Check whether the first 4 bytes of the file are the block
* type for a pcapng savefile.
*/
- if (magic != BT_SHB) {
+ memcpy(&magic_int, magic, sizeof(magic_int));
+ if (magic_int != BT_SHB) {
/*
* XXX - check whether this looks like what the block
* type would be after being munged by mapping between
@@ -820,11 +858,14 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
/*
* Check the sanity of the total length.
*/
- if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)) {
+ if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer) ||
+ (total_length > BT_SHB_INSANE_MAX)) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "Section Header Block in pcapng dump file has a length of %u < %lu",
+ "Section Header Block in pcapng dump file has invalid length %" PRIsize " < _%u_ < %u (BT_SHB_INSANE_MAX)",
+ sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer),
total_length,
- (unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
+ BT_SHB_INSANE_MAX);
+
*err = 1;
return (NULL);
}
@@ -876,10 +917,10 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
* leaving room for some options.
*
* If we find a bigger block, we reallocate the buffer, up to
- * the maximum size. We start out with a maximum size based
- * on a maximum snapshot length of MAXIMUM_SNAPLEN; if we see
- * any link-layer header types with a larger maximum snapshot
- * length, we boost the maximum.
+ * the maximum size. We start out with a maximum size of
+ * INITIAL_MAX_BLOCKSIZE; if we see any link-layer header types
+ * with a maximum snapshot that results in a larger maximum
+ * block length, we boost the maximum.
*/
p->bufsize = 2048;
if (p->bufsize < total_length)
@@ -891,7 +932,7 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
*err = 1;
return (NULL);
}
- ps->max_blocksize = MAX_BLOCKSIZE(MAXIMUM_SNAPLEN);
+ ps->max_blocksize = INITIAL_MAX_BLOCKSIZE;
/*
* Copy the stuff we've read to the buffer, and read the rest
@@ -899,12 +940,12 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
*/
bhdrp = (struct block_header *)p->buffer;
shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header));
- bhdrp->block_type = magic;
+ bhdrp->block_type = magic_int;
bhdrp->total_length = total_length;
shbp->byte_order_magic = byte_order_magic;
if (read_bytes(fp,
- (u_char *)p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
- total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
+ (u_char *)p->buffer + (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)),
+ total_length - (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)),
1, errbuf) == -1)
goto fail;
@@ -1001,19 +1042,8 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
done:
p->tzoff = 0; /* XXX - not used in pcap */
- p->snapshot = idbp->snaplen;
- if (p->snapshot <= 0) {
- /*
- * Bogus snapshot length; use the maximum for this
- * link-layer type as a fallback.
- *
- * XXX - the only reason why snapshot is signed is
- * that pcap_snapshot() returns an int, not an
- * unsigned int.
- */
- p->snapshot = max_snaplen_for_dlt(idbp->linktype);
- }
p->linktype = linktype_to_dlt(idbp->linktype);
+ p->snapshot = pcap_adjust_snapshot(p->linktype, idbp->snaplen);
p->linktype_ext = 0;
/*
@@ -1021,8 +1051,8 @@ done:
* snapshot length for this DLT_ is bigger than the current
* maximum block size, increase the maximum.
*/
- if (MAX_BLOCKSIZE(max_snaplen_for_dlt(p->linktype)) > ps->max_blocksize)
- ps->max_blocksize = MAX_BLOCKSIZE(max_snaplen_for_dlt(p->linktype));
+ if (MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype)) > ps->max_blocksize)
+ ps->max_blocksize = MAX_BLOCKSIZE_FOR_SNAPLEN(max_snaplen_for_dlt(p->linktype));
p->next_packet_op = pcap_ng_next_packet;
p->cleanup_op = pcap_ng_cleanup;
@@ -1208,7 +1238,13 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
idbp->linktype);
return (-1);
}
- if ((bpf_u_int32)p->snapshot != idbp->snaplen) {
+
+ /*
+ * Check against the *adjusted* value of this IDB's
+ * snapshot length.
+ */
+ if ((bpf_u_int32)p->snapshot !=
+ pcap_adjust_snapshot(p->linktype, idbp->snaplen)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"an interface has a snapshot length %u different from the type of the first interface",
idbp->snaplen);
diff --git a/freebsd/contrib/libpcap/sf-pcapng.h b/freebsd/contrib/libpcap/sf-pcapng.h
index d99b0d4e..835082a5 100644
--- a/freebsd/contrib/libpcap/sf-pcapng.h
+++ b/freebsd/contrib/libpcap/sf-pcapng.h
@@ -26,7 +26,7 @@
#ifndef sf_pcapng_h
#define sf_pcapng_h
-extern pcap_t *pcap_ng_check_header(bpf_u_int32 magic, FILE *fp,
+extern pcap_t *pcap_ng_check_header(const uint8_t *magic, FILE *fp,
u_int precision, char *errbuf, int *err);
#endif
diff --git a/freebsd/contrib/tcpdump/addrtoname.c b/freebsd/contrib/tcpdump/addrtoname.c
index e182b22a..50516cdd 100644
--- a/freebsd/contrib/tcpdump/addrtoname.c
+++ b/freebsd/contrib/tcpdump/addrtoname.c
@@ -131,7 +131,7 @@ win32_gethostbyaddr(const char *addr, int len, int type)
hname, sizeof(hname), NULL, 0, 0)) {
return NULL;
} else {
- strcpy(host.h_name, hname);
+ strlcpy(host.h_name, hname, NI_MAXHOST);
return &host;
}
break;
@@ -1253,10 +1253,7 @@ dnaddr_string(netdissect_options *ndo, u_short dnaddr)
tp->addr = dnaddr;
tp->nxt = newhnamemem(ndo);
- if (ndo->ndo_nflag)
- tp->name = dnnum_string(ndo, dnaddr);
- else
- tp->name = dnname_string(ndo, dnaddr);
+ tp->name = dnnum_string(ndo, dnaddr);
return(tp->name);
}
diff --git a/freebsd/contrib/tcpdump/netdissect.h b/freebsd/contrib/tcpdump/netdissect.h
index 105c490a..20b5ef63 100644
--- a/freebsd/contrib/tcpdump/netdissect.h
+++ b/freebsd/contrib/tcpdump/netdissect.h
@@ -514,6 +514,7 @@ extern void hsrp_print(netdissect_options *, const u_char *, u_int);
extern void http_print(netdissect_options *, const u_char *, u_int);
extern void icmp6_print(netdissect_options *, const u_char *, u_int, const u_char *, int);
extern void icmp_print(netdissect_options *, const u_char *, u_int, const u_char *, int);
+extern u_int ieee802_11_radio_print(netdissect_options *, const u_char *, u_int, u_int);
extern void igmp_print(netdissect_options *, const u_char *, u_int);
extern void igrp_print(netdissect_options *, const u_char *, u_int);
extern void ip6_print(netdissect_options *, const u_char *, u_int);
@@ -641,7 +642,6 @@ extern int nextproto6_cksum(netdissect_options *, const struct ip6_hdr *, const
extern int mask2plen(uint32_t);
extern int mask62plen(const u_char *);
-extern const char *dnname_string(netdissect_options *, u_short);
extern const char *dnnum_string(netdissect_options *, u_short);
extern char *smb_errstr(int, int);
diff --git a/freebsd/contrib/tcpdump/print-802_11.c b/freebsd/contrib/tcpdump/print-802_11.c
index ff2ac02a..de3eb31c 100644
--- a/freebsd/contrib/tcpdump/print-802_11.c
+++ b/freebsd/contrib/tcpdump/print-802_11.c
@@ -2064,6 +2064,10 @@ ieee802_11_print(netdissect_options *ndo,
hdrlen = roundup2(hdrlen, 4);
if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
+ if (caplen < hdrlen + 1) {
+ ND_PRINT((ndo, "%s", tstr));
+ return hdrlen;
+ }
meshdrlen = extract_mesh_header_length(p+hdrlen);
hdrlen += meshdrlen;
} else
@@ -3077,7 +3081,7 @@ print_in_radiotap_namespace(netdissect_options *ndo,
return 0;
}
-static u_int
+u_int
ieee802_11_radio_print(netdissect_options *ndo,
const u_char *p, u_int length, u_int caplen)
{
@@ -3107,6 +3111,15 @@ ieee802_11_radio_print(netdissect_options *ndo,
hdr = (const struct ieee80211_radiotap_header *)p;
len = EXTRACT_LE_16BITS(&hdr->it_len);
+ if (len < sizeof(*hdr)) {
+ /*
+ * The length is the length of the entire header, so
+ * it must be as large as the fixed-length part of
+ * the header.
+ */
+ ND_PRINT((ndo, "%s", tstr));
+ return caplen;
+ }
/*
* If we don't have the entire radiotap header, just give up.
diff --git a/freebsd/contrib/tcpdump/print-aoe.c b/freebsd/contrib/tcpdump/print-aoe.c
index de51a3da..85f78986 100644
--- a/freebsd/contrib/tcpdump/print-aoe.c
+++ b/freebsd/contrib/tcpdump/print-aoe.c
@@ -331,6 +331,7 @@ aoev1_reserve_print(netdissect_options *ndo,
goto invalid;
/* addresses */
for (i = 0; i < nmacs; i++) {
+ ND_TCHECK2(*cp, ETHER_ADDR_LEN);
ND_PRINT((ndo, "\n\tEthernet Address %u: %s", i, etheraddr_string(ndo, cp)));
cp += ETHER_ADDR_LEN;
}
@@ -356,6 +357,7 @@ aoev1_print(netdissect_options *ndo,
if (len < AOEV1_COMMON_HDR_LEN)
goto invalid;
/* Flags */
+ ND_TCHECK2(*cp, 1);
flags = *cp & 0x0F;
ND_PRINT((ndo, ", Flags: [%s]", bittok2str(aoev1_flag_str, "none", flags)));
cp += 1;
diff --git a/freebsd/contrib/tcpdump/print-babel.c b/freebsd/contrib/tcpdump/print-babel.c
index de549fd4..279291f6 100644
--- a/freebsd/contrib/tcpdump/print-babel.c
+++ b/freebsd/contrib/tcpdump/print-babel.c
@@ -358,6 +358,8 @@ babel_print_v2(netdissect_options *ndo,
goto invalid;
bodylen = EXTRACT_16BITS(cp + 2);
ND_PRINT((ndo, " (%u)", bodylen));
+ if (4U + bodylen > length)
+ goto invalid;
/* Process the TLVs in the body */
i = 0;
@@ -486,7 +488,7 @@ babel_print_v2(netdissect_options *ndo,
case MESSAGE_UPDATE: {
if (!ndo->ndo_vflag) {
ND_PRINT((ndo, " update"));
- if(len < 1)
+ if(len < 10)
ND_PRINT((ndo, "/truncated"));
else
ND_PRINT((ndo, "%s%s%s",
diff --git a/freebsd/contrib/tcpdump/print-bfd.c b/freebsd/contrib/tcpdump/print-bfd.c
index bec521c1..c71b0d29 100644
--- a/freebsd/contrib/tcpdump/print-bfd.c
+++ b/freebsd/contrib/tcpdump/print-bfd.c
@@ -21,7 +21,10 @@
/* \summary: Bidirectional Forwarding Detection (BFD) printer */
-/* specification: RFC 5880 (for version 1) and RFC 5881 */
+/*
+ * specification: draft-ietf-bfd-base-01 for version 0,
+ * RFC 5880 for version 1, and RFC 5881
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -35,12 +38,12 @@
#include "udp.h"
/*
- * Control packet, BFDv0, draft-katz-ward-bfd-01.txt
+ * Control packet, BFDv0, draft-ietf-bfd-base-01
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |Vers | Diag |H|D|P|F| Rsvd | Detect Mult | Length |
+ * |Vers | Diag |H|D|P|F|C|A|Rsv| Detect Mult | Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | My Discriminator |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -132,12 +135,6 @@ enum auth_length {
#define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5)
#define BFD_EXTRACT_DIAG(x) ((x)&0x1f)
-static const struct tok bfd_port_values[] = {
- { BFD_CONTROL_PORT, "Control" },
- { BFD_ECHO_PORT, "Echo" },
- { 0, NULL }
-};
-
static const struct tok bfd_diag_values[] = {
{ 0, "No Diagnostic" },
{ 1, "Control Detection Time Expired" },
@@ -151,20 +148,20 @@ static const struct tok bfd_diag_values[] = {
{ 0, NULL }
};
+#define BFD_FLAG_AUTH 0x04
+
static const struct tok bfd_v0_flag_values[] = {
{ 0x80, "I Hear You" },
{ 0x40, "Demand" },
{ 0x20, "Poll" },
{ 0x10, "Final" },
- { 0x08, "Reserved" },
- { 0x04, "Reserved" },
+ { 0x08, "Control Plane Independent" },
+ { BFD_FLAG_AUTH, "Authentication Present" },
{ 0x02, "Reserved" },
{ 0x01, "Reserved" },
{ 0, NULL }
};
-#define BFD_FLAG_AUTH 0x04
-
static const struct tok bfd_v1_flag_values[] = {
{ 0x20, "Poll" },
{ 0x10, "Final" },
@@ -298,106 +295,124 @@ void
bfd_print(netdissect_options *ndo, register const u_char *pptr,
register u_int len, register u_int port)
{
- const struct bfd_header_t *bfd_header;
- uint8_t version = 0;
-
- bfd_header = (const struct bfd_header_t *)pptr;
if (port == BFD_CONTROL_PORT) {
+ /*
+ * Control packet.
+ */
+ const struct bfd_header_t *bfd_header;
+ uint8_t version_diag;
+ uint8_t version = 0;
+ uint8_t flags;
+
+ bfd_header = (const struct bfd_header_t *)pptr;
ND_TCHECK(*bfd_header);
- version = BFD_EXTRACT_VERSION(bfd_header->version_diag);
- } else if (port == BFD_ECHO_PORT) {
- /* Echo is BFD v1 only */
- version = 1;
- }
- switch ((port << 8) | version) {
+ version_diag = bfd_header->version_diag;
+ version = BFD_EXTRACT_VERSION(version_diag);
+ flags = bfd_header->flags;
+
+ switch (version) {
+
+ /* BFDv0 */
+ case 0:
+ if (ndo->ndo_vflag < 1)
+ {
+ ND_PRINT((ndo, "BFDv0, Control, Flags: [%s], length: %u",
+ bittok2str(bfd_v0_flag_values, "none", flags),
+ len));
+ return;
+ }
+
+ ND_PRINT((ndo, "BFDv0, length: %u\n\tControl, Flags: [%s], Diagnostic: %s (0x%02x)",
+ len,
+ bittok2str(bfd_v0_flag_values, "none", flags),
+ tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)),
+ BFD_EXTRACT_DIAG(version_diag)));
+
+ ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
+ bfd_header->detect_time_multiplier,
+ bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
+ bfd_header->length));
- /* BFDv0 */
- case (BFD_CONTROL_PORT << 8):
- if (ndo->ndo_vflag < 1)
- {
- ND_PRINT((ndo, "BFDv%u, %s, Flags: [%s], length: %u",
- version,
- tok2str(bfd_port_values, "unknown (%u)", port),
- bittok2str(bfd_v0_flag_values, "none", bfd_header->flags),
- len));
- return;
- }
- ND_PRINT((ndo, "BFDv%u, length: %u\n\t%s, Flags: [%s], Diagnostic: %s (0x%02x)",
- version,
- len,
- tok2str(bfd_port_values, "unknown (%u)", port),
- bittok2str(bfd_v0_flag_values, "none", bfd_header->flags),
- tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)),
- BFD_EXTRACT_DIAG(bfd_header->version_diag)));
-
- ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
- bfd_header->detect_time_multiplier,
- bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
- bfd_header->length));
-
-
- ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)));
- ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)));
- ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000));
- ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000));
- ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000));
- break;
-
- /* BFDv1 */
- case (BFD_CONTROL_PORT << 8 | 1):
- if (ndo->ndo_vflag < 1)
- {
- ND_PRINT((ndo, "BFDv%u, %s, State %s, Flags: [%s], length: %u",
+ ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)));
+ ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)));
+ ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000));
+ ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000));
+ ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000));
+
+ if (flags & BFD_FLAG_AUTH) {
+ if (auth_print(ndo, pptr))
+ goto trunc;
+ }
+ break;
+
+ /* BFDv1 */
+ case 1:
+ if (ndo->ndo_vflag < 1)
+ {
+ ND_PRINT((ndo, "BFDv1, Control, State %s, Flags: [%s], length: %u",
+ tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6),
+ bittok2str(bfd_v1_flag_values, "none", flags & 0x3f),
+ len));
+ return;
+ }
+
+ ND_PRINT((ndo, "BFDv1, length: %u\n\tControl, State %s, Flags: [%s], Diagnostic: %s (0x%02x)",
+ len,
+ tok2str(bfd_v1_state_values, "unknown (%u)", (flags & 0xc0) >> 6),
+ bittok2str(bfd_v1_flag_values, "none", flags & 0x3f),
+ tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(version_diag)),
+ BFD_EXTRACT_DIAG(version_diag)));
+
+ ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
+ bfd_header->detect_time_multiplier,
+ bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
+ bfd_header->length));
+
+
+ ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)));
+ ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)));
+ ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000));
+ ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000));
+ ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000));
+
+ if (flags & BFD_FLAG_AUTH) {
+ if (auth_print(ndo, pptr))
+ goto trunc;
+ }
+ break;
+
+ default:
+ ND_PRINT((ndo, "BFDv%u, Control, length: %u",
version,
- tok2str(bfd_port_values, "unknown (%u)", port),
- tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6),
- bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f),
len));
- return;
+ if (ndo->ndo_vflag >= 1) {
+ if(!print_unknown_data(ndo, pptr,"\n\t",len))
+ return;
+ }
+ break;
}
-
- ND_PRINT((ndo, "BFDv%u, length: %u\n\t%s, State %s, Flags: [%s], Diagnostic: %s (0x%02x)",
- version,
- len,
- tok2str(bfd_port_values, "unknown (%u)", port),
- tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6),
- bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f),
- tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)),
- BFD_EXTRACT_DIAG(bfd_header->version_diag)));
-
- ND_PRINT((ndo, "\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
- bfd_header->detect_time_multiplier,
- bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
- bfd_header->length));
-
-
- ND_PRINT((ndo, "\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)));
- ND_PRINT((ndo, ", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)));
- ND_PRINT((ndo, "\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000));
- ND_PRINT((ndo, "\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000));
- ND_PRINT((ndo, "\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000));
-
- if (bfd_header->flags & BFD_FLAG_AUTH) {
- if (auth_print(ndo, pptr))
- goto trunc;
+ } else if (port == BFD_ECHO_PORT) {
+ /*
+ * Echo packet.
+ */
+ ND_PRINT((ndo, "BFD, Echo, length: %u",
+ len));
+ if (ndo->ndo_vflag >= 1) {
+ if(!print_unknown_data(ndo, pptr,"\n\t",len))
+ return;
}
- break;
-
- /* BFDv0 */
- case (BFD_ECHO_PORT << 8): /* not yet supported - fall through */
- /* BFDv1 */
- case (BFD_ECHO_PORT << 8 | 1):
-
- default:
- ND_PRINT((ndo, "BFD, %s, length: %u",
- tok2str(bfd_port_values, "unknown (%u)", port),
+ } else {
+ /*
+ * Unknown packet type.
+ */
+ ND_PRINT((ndo, "BFD, unknown (%u), length: %u",
+ port,
len));
if (ndo->ndo_vflag >= 1) {
if(!print_unknown_data(ndo, pptr,"\n\t",len))
return;
}
- break;
}
return;
diff --git a/freebsd/contrib/tcpdump/print-bgp.c b/freebsd/contrib/tcpdump/print-bgp.c
index 3d1e2f4d..148b7a0c 100644
--- a/freebsd/contrib/tcpdump/print-bgp.c
+++ b/freebsd/contrib/tcpdump/print-bgp.c
@@ -53,6 +53,8 @@
#include "af.h"
#include "l2vpn.h"
+static const char tstr[] = "[|BGP]";
+
struct bgp {
uint8_t bgp_marker[16];
uint16_t bgp_len;
@@ -1019,7 +1021,7 @@ trunc:
*/
#define UPDATE_BUF_BUFLEN(buf, buflen, stringlen) \
if (stringlen<0) \
- buflen=0; \
+ buflen=0; \
else if ((u_int)stringlen>buflen) \
buflen=0; \
else { \
@@ -1365,7 +1367,7 @@ trunc:
static int
bgp_attr_print(netdissect_options *ndo,
- u_int atype, const u_char *pptr, u_int len)
+ u_int atype, const u_char *pptr, u_int len, const unsigned attr_set_level)
{
int i;
uint16_t af;
@@ -1488,7 +1490,7 @@ bgp_attr_print(netdissect_options *ndo,
}
ND_TCHECK2(tptr[0], 8);
ND_PRINT((ndo, " AS #%s, origin %s",
- as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
+ as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
ipaddr_string(ndo, tptr + 4)));
break;
case BGPTYPE_COMMUNITIES:
@@ -1704,10 +1706,12 @@ bgp_attr_print(netdissect_options *ndo,
bgp_vpn_rd_print(ndo, tptr),
isonsap_string(ndo, tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)));
/* rfc986 mapped IPv4 address ? */
- if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601)
+ if (tlen == BGP_VPN_RD_LEN + 4 + sizeof(struct in_addr)
+ && EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601)
ND_PRINT((ndo, " = %s", ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN+4)));
/* rfc1888 mapped IPv6 address ? */
- else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000)
+ else if (tlen == BGP_VPN_RD_LEN + 3 + sizeof(struct in6_addr)
+ && EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000)
ND_PRINT((ndo, " = %s", ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN+3)));
tptr += tlen;
tlen = 0;
@@ -2286,8 +2290,16 @@ bgp_attr_print(netdissect_options *ndo,
ND_PRINT((ndo, "+%x", aflags & 0xf));
ND_PRINT((ndo, "]: "));
}
- /* FIXME check for recursion */
- if (!bgp_attr_print(ndo, atype, tptr, alen))
+ /* The protocol encoding per se allows ATTR_SET to be nested as many times
+ * as the message can accommodate. This printer used to be able to recurse
+ * into ATTR_SET contents until the stack exhaustion, but now there is a
+ * limit on that (if live protocol exchange goes that many levels deep,
+ * something is probably wrong anyway). Feel free to refine this value if
+ * you can find the spec with respective normative text.
+ */
+ if (attr_set_level == 10)
+ ND_PRINT((ndo, "(too many nested levels, not recursing)"));
+ else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1))
return 0;
tptr += alen;
len -= alen;
@@ -2348,6 +2360,8 @@ bgp_capabilities_print(netdissect_options *ndo,
ND_TCHECK2(opt[i+2], cap_len);
switch (cap_type) {
case BGP_CAPCODE_MP:
+ /* AFI (16 bits), Reserved (8 bits), SAFI (8 bits) */
+ ND_TCHECK_8BITS(opt + i + 5);
ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u)",
tok2str(af_values, "Unknown",
EXTRACT_16BITS(opt+i+2)),
@@ -2357,12 +2371,15 @@ bgp_capabilities_print(netdissect_options *ndo,
opt[i+5]));
break;
case BGP_CAPCODE_RESTART:
+ /* Restart Flags (4 bits), Restart Time in seconds (12 bits) */
+ ND_TCHECK_16BITS(opt + i + 2);
ND_PRINT((ndo, "\n\t\tRestart Flags: [%s], Restart Time %us",
((opt[i+2])&0x80) ? "R" : "none",
EXTRACT_16BITS(opt+i+2)&0xfff));
tcap_len-=2;
cap_offset=4;
while(tcap_len>=4) {
+ ND_TCHECK_8BITS(opt + i + cap_offset + 3);
ND_PRINT((ndo, "\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
tok2str(af_values,"Unknown",
EXTRACT_16BITS(opt+i+cap_offset)),
@@ -2426,7 +2443,7 @@ bgp_capabilities_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static void
@@ -2489,7 +2506,7 @@ bgp_open_print(netdissect_options *ndo,
}
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static void
@@ -2589,7 +2606,7 @@ bgp_update_print(netdissect_options *ndo,
goto trunc;
if (length < alen)
goto trunc;
- if (!bgp_attr_print(ndo, atype, p, alen))
+ if (!bgp_attr_print(ndo, atype, p, alen, 0))
goto trunc;
p += alen;
len -= alen;
@@ -2626,7 +2643,7 @@ bgp_update_print(netdissect_options *ndo,
}
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static void
@@ -2707,7 +2724,7 @@ bgp_notification_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static void
@@ -2741,7 +2758,7 @@ bgp_route_refresh_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
static int
@@ -2781,7 +2798,7 @@ bgp_header_print(netdissect_options *ndo,
}
return 1;
trunc:
- ND_PRINT((ndo, "[|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
return 0;
}
@@ -2830,7 +2847,7 @@ bgp_print(netdissect_options *ndo,
memcpy(&bgp, p, BGP_SIZE);
if (start != p)
- ND_PRINT((ndo, " [|BGP]"));
+ ND_PRINT((ndo, " %s", tstr));
hlen = ntohs(bgp.bgp_len);
if (hlen < BGP_SIZE) {
@@ -2856,7 +2873,7 @@ bgp_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo, " [|BGP]"));
+ ND_PRINT((ndo, "%s", tstr));
}
/*
diff --git a/freebsd/contrib/tcpdump/print-bootp.c b/freebsd/contrib/tcpdump/print-bootp.c
index c9f687ff..3166ca10 100644
--- a/freebsd/contrib/tcpdump/print-bootp.c
+++ b/freebsd/contrib/tcpdump/print-bootp.c
@@ -364,7 +364,7 @@ bootp_print(netdissect_options *ndo,
if (*bp->bp_sname) {
ND_PRINT((ndo, "\n\t sname \""));
if (fn_printztn(ndo, bp->bp_sname, (u_int)sizeof bp->bp_sname,
- ndo->ndo_snapend)) {
+ ndo->ndo_snapend) == 0) {
ND_PRINT((ndo, "\""));
ND_PRINT((ndo, "%s", tstr + 1));
return;
@@ -375,7 +375,7 @@ bootp_print(netdissect_options *ndo,
if (*bp->bp_file) {
ND_PRINT((ndo, "\n\t file \""));
if (fn_printztn(ndo, bp->bp_file, (u_int)sizeof bp->bp_file,
- ndo->ndo_snapend)) {
+ ndo->ndo_snapend) == 0) {
ND_PRINT((ndo, "\""));
ND_PRINT((ndo, "%s", tstr + 1));
return;
@@ -384,7 +384,7 @@ bootp_print(netdissect_options *ndo,
}
/* Decode the vendor buffer */
- ND_TCHECK(bp->bp_vend[0]);
+ ND_TCHECK2(bp->bp_vend[0], 4);
if (memcmp((const char *)bp->bp_vend, vm_rfc1048,
sizeof(uint32_t)) == 0)
rfc1048_print(ndo, bp->bp_vend);
@@ -394,6 +394,7 @@ bootp_print(netdissect_options *ndo,
else {
uint32_t ul;
+ ND_TCHECK_32BITS(&bp->bp_vend);
ul = EXTRACT_32BITS(&bp->bp_vend);
if (ul != 0)
ND_PRINT((ndo, "\n\t Vendor-#0x%x", ul));
diff --git a/freebsd/contrib/tcpdump/print-dccp.c b/freebsd/contrib/tcpdump/print-dccp.c
index 7ad86094..3ba151d6 100644
--- a/freebsd/contrib/tcpdump/print-dccp.c
+++ b/freebsd/contrib/tcpdump/print-dccp.c
@@ -536,7 +536,8 @@ static const struct tok dccp_option_values[] = {
{ 0, NULL }
};
-static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen)
+static int
+dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen)
{
uint8_t optlen, i;
@@ -629,16 +630,54 @@ static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_in
}
break;
case 41:
- if (optlen == 4)
+ /*
+ * 13.1. Timestamp Option
+ *
+ * +--------+--------+--------+--------+--------+--------+
+ * |00101001|00000110| Timestamp Value |
+ * +--------+--------+--------+--------+--------+--------+
+ * Type=41 Length=6
+ */
+ if (optlen == 6)
ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
else
- ND_PRINT((ndo, " optlen != 4"));
+ ND_PRINT((ndo, " [optlen != 6]"));
break;
case 42:
- if (optlen == 4)
+ /*
+ * 13.3. Timestamp Echo Option
+ *
+ * +--------+--------+--------+--------+--------+--------+
+ * |00101010|00000110| Timestamp Echo |
+ * +--------+--------+--------+--------+--------+--------+
+ * Type=42 Len=6
+ *
+ * +--------+--------+------- ... -------+--------+--------+
+ * |00101010|00001000| Timestamp Echo | Elapsed Time |
+ * +--------+--------+------- ... -------+--------+--------+
+ * Type=42 Len=8 (4 bytes)
+ *
+ * +--------+--------+------- ... -------+------- ... -------+
+ * |00101010|00001010| Timestamp Echo | Elapsed Time |
+ * +--------+--------+------- ... -------+------- ... -------+
+ * Type=42 Len=10 (4 bytes) (4 bytes)
+ */
+ switch (optlen) {
+ case 6:
ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
- else
- ND_PRINT((ndo, " optlen != 4"));
+ break;
+ case 8:
+ ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
+ ND_PRINT((ndo, " (elapsed time %u)", EXTRACT_16BITS(option + 6)));
+ break;
+ case 10:
+ ND_PRINT((ndo, " %u", EXTRACT_32BITS(option + 2)));
+ ND_PRINT((ndo, " (elapsed time %u)", EXTRACT_32BITS(option + 6)));
+ break;
+ default:
+ ND_PRINT((ndo, " [optlen != 6 or 8 or 10]"));
+ break;
+ }
break;
case 43:
if (optlen == 6)
@@ -646,7 +685,7 @@ static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_in
else if (optlen == 4)
ND_PRINT((ndo, " %u", EXTRACT_16BITS(option + 2)));
else
- ND_PRINT((ndo, " optlen != 4 or 6"));
+ ND_PRINT((ndo, " [optlen != 4 or 6]"));
break;
case 44:
if (optlen > 2) {
diff --git a/freebsd/contrib/tcpdump/print-decnet.c b/freebsd/contrib/tcpdump/print-decnet.c
index af50492b..3531337e 100644
--- a/freebsd/contrib/tcpdump/print-decnet.c
+++ b/freebsd/contrib/tcpdump/print-decnet.c
@@ -36,10 +36,6 @@
struct mbuf;
struct rtentry;
-#ifdef HAVE_NETDNET_DNETDB_H
-#include <netdnet/dnetdb.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -81,12 +77,6 @@ typedef union etheraddress etheraddr; /* Ethernet address */
#define AREASHIFT 10 /* bit-offset for area field */
#define NODEMASK 01777 /* mask for node address field */
-#define DN_MAXADDL 20 /* max size of DECnet address */
-struct dn_naddr {
- uint16_t a_len; /* length of address */
- uint8_t a_addr[DN_MAXADDL]; /* address as bytes */
-};
-
/*
* Define long and short header formats.
*/
@@ -498,10 +488,6 @@ static int print_elist(const char *, u_int);
static int print_nsp(netdissect_options *, const u_char *, u_int);
static void print_reason(netdissect_options *, int);
-#ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA
-extern char *dnet_htoa(struct dn_naddr *);
-#endif
-
void
decnet_print(netdissect_options *ndo,
register const u_char *ap, register u_int length,
@@ -1258,25 +1244,6 @@ dnnum_string(netdissect_options *ndo, u_short dnaddr)
snprintf(str, siz, "%d.%d", area, node);
return(str);
}
-
-const char *
-dnname_string(netdissect_options *ndo, u_short dnaddr)
-{
-#ifdef HAVE_DNET_HTOA
- struct dn_naddr dna;
- char *dnname;
-
- dna.a_len = sizeof(short);
- memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short));
- dnname = dnet_htoa(&dna);
- if(dnname != NULL)
- return (strdup(dnname));
- else
- return(dnnum_string(ndo, dnaddr));
-#else
- return(dnnum_string(ndo, dnaddr)); /* punt */
-#endif
-}
#ifdef __rtems__
#include "rtems-bsd-tcpdump-print-decnet-data.h"
#endif /* __rtems__ */
diff --git a/freebsd/contrib/tcpdump/print-domain.c b/freebsd/contrib/tcpdump/print-domain.c
index 52348a17..68e494ce 100644
--- a/freebsd/contrib/tcpdump/print-domain.c
+++ b/freebsd/contrib/tcpdump/print-domain.c
@@ -588,6 +588,13 @@ ns_print(netdissect_options *ndo,
register const u_char *cp;
uint16_t b2;
+ if(length < sizeof(*np)) {
+ ND_PRINT((ndo, "domain"));
+ ND_PRINT((ndo, " [length %u < %zu]", length, sizeof(*np)));
+ ND_PRINT((ndo, " (invalid)"));
+ return;
+ }
+
np = (const HEADER *)bp;
ND_TCHECK(*np);
/* get the byte-order right */
diff --git a/freebsd/contrib/tcpdump/print-dvmrp.c b/freebsd/contrib/tcpdump/print-dvmrp.c
index bf391603..f4454f97 100644
--- a/freebsd/contrib/tcpdump/print-dvmrp.c
+++ b/freebsd/contrib/tcpdump/print-dvmrp.c
@@ -38,6 +38,8 @@
#include "addrtoname.h"
/*
+ * See: RFC 1075 and draft-ietf-idmr-dvmrp-v3
+ *
* DVMRP message types and flag values shamelessly stolen from
* mrouted/dvmrp.h.
*/
@@ -64,19 +66,18 @@
static int print_probe(netdissect_options *, const u_char *, const u_char *, u_int);
static int print_report(netdissect_options *, const u_char *, const u_char *, u_int);
static int print_neighbors(netdissect_options *, const u_char *, const u_char *, u_int);
-static int print_neighbors2(netdissect_options *, const u_char *, const u_char *, u_int);
+static int print_neighbors2(netdissect_options *, const u_char *, const u_char *, u_int, uint8_t, uint8_t);
static int print_prune(netdissect_options *, const u_char *);
static int print_graft(netdissect_options *, const u_char *);
static int print_graft_ack(netdissect_options *, const u_char *);
-static uint32_t target_level;
-
void
dvmrp_print(netdissect_options *ndo,
register const u_char *bp, register u_int len)
{
register const u_char *ep;
register u_char type;
+ uint8_t major_version, minor_version;
ep = (const u_char *)ndo->ndo_snapend;
if (bp >= ep)
@@ -124,15 +125,15 @@ dvmrp_print(netdissect_options *ndo,
case DVMRP_NEIGHBORS2:
ND_PRINT((ndo, " Neighbors2"));
/*
- * extract version and capabilities from IGMP group
- * address field
+ * extract version from IGMP group address field
*/
bp -= 4;
ND_TCHECK2(bp[0], 4);
- target_level = (bp[0] << 24) | (bp[1] << 16) |
- (bp[2] << 8) | bp[3];
+ major_version = *(bp + 3);
+ minor_version = *(bp + 2);
bp += 4;
- if (print_neighbors2(ndo, bp, ep, len) < 0)
+ if (print_neighbors2(ndo, bp, ep, len, major_version,
+ minor_version) < 0)
goto trunc;
break;
@@ -236,7 +237,7 @@ print_probe(netdissect_options *ndo,
ND_PRINT((ndo, " [|}"));
return (0);
}
- genid = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3];
+ genid = EXTRACT_32BITS(bp);
bp += 4;
len -= 4;
ND_PRINT((ndo, ndo->ndo_vflag > 1 ? "\n\t" : " "));
@@ -289,15 +290,14 @@ trunc:
static int
print_neighbors2(netdissect_options *ndo,
register const u_char *bp, register const u_char *ep,
- register u_int len)
+ register u_int len, uint8_t major_version,
+ uint8_t minor_version)
{
const u_char *laddr;
register u_char metric, thresh, flags;
register int ncount;
- ND_PRINT((ndo, " (v %d.%d):",
- (int)target_level & 0xff,
- (int)(target_level >> 8) & 0xff));
+ ND_PRINT((ndo, " (v %d.%d):", major_version, minor_version));
while (len > 0 && bp < ep) {
ND_TCHECK2(bp[0], 8);
diff --git a/freebsd/contrib/tcpdump/print-eigrp.c b/freebsd/contrib/tcpdump/print-eigrp.c
index 2b1ea588..f28955e0 100644
--- a/freebsd/contrib/tcpdump/print-eigrp.c
+++ b/freebsd/contrib/tcpdump/print-eigrp.c
@@ -359,6 +359,7 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
}
byte_length = (bit_length + 7) / 8; /* variable length encoding */
memset(prefix, 0, 4);
+ ND_TCHECK2(tlv_ptr.eigrp_tlv_ip_int->destination, byte_length);
memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length);
ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ",
@@ -393,6 +394,7 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
}
byte_length = (bit_length + 7) / 8; /* variable length encoding */
memset(prefix, 0, 4);
+ ND_TCHECK2(tlv_ptr.eigrp_tlv_ip_ext->destination, byte_length);
memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length);
ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ",
diff --git a/freebsd/contrib/tcpdump/print-esp.c b/freebsd/contrib/tcpdump/print-esp.c
index a7961716..ef15b590 100644
--- a/freebsd/contrib/tcpdump/print-esp.c
+++ b/freebsd/contrib/tcpdump/print-esp.c
@@ -197,8 +197,8 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
const u_char *iv;
unsigned int len;
EVP_CIPHER_CTX *ctx;
- unsigned int block_size, output_buffer_size;
- u_char *output_buffer;
+ unsigned int block_size, buffer_size;
+ u_char *input_buffer, *output_buffer;
/* initiator arg is any non-zero value */
if(initiator) initiator=1;
@@ -233,19 +233,39 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
(*ndo->ndo_warning)(ndo, "espkey init failed");
set_cipher_parameters(ctx, NULL, NULL, iv, 0);
/*
- * Allocate a buffer for the decrypted data.
- * The output buffer must be separate from the input buffer, and
- * its size must be a multiple of the cipher block size.
+ * Allocate buffers for the encrypted and decrypted data.
+ * Both buffers' sizes must be a multiple of the cipher block
+ * size, and the output buffer must be separate from the input
+ * buffer.
*/
block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
- output_buffer_size = len + (block_size - len % block_size);
- output_buffer = (u_char *)malloc(output_buffer_size);
+ buffer_size = len + (block_size - len % block_size);
+
+ /*
+ * Attempt to allocate the input buffer.
+ */
+ input_buffer = (u_char *)malloc(buffer_size);
+ if (input_buffer == NULL) {
+ EVP_CIPHER_CTX_free(ctx);
+ (*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer");
+ }
+ /*
+ * Copy the input data to the encrypted data buffer, and pad it
+ * with zeroes.
+ */
+ memcpy(input_buffer, buf, len);
+ memset(input_buffer + len, 0, buffer_size - len);
+
+ /*
+ * Attempt to allocate the output buffer.
+ */
+ output_buffer = (u_char *)malloc(buffer_size);
if (output_buffer == NULL) {
- (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ free(input_buffer);
EVP_CIPHER_CTX_free(ctx);
- return 0;
+ (*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer");
}
- EVP_Cipher(ctx, output_buffer, buf, len);
+ EVP_Cipher(ctx, output_buffer, input_buffer, len);
EVP_CIPHER_CTX_free(ctx);
/*
@@ -253,6 +273,7 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
* but changing this would require a more complicated fix.
*/
memcpy(__DECONST(u_char *, buf), output_buffer, len);
+ free(input_buffer);
free(output_buffer);
ndo->ndo_packetp = buf;
@@ -293,7 +314,6 @@ static u_int hexdigit(netdissect_options *ndo, char hex)
return (hex - 'a' + 10);
else {
(*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
- return 0;
}
}
@@ -404,7 +424,7 @@ espprint_decode_encalgo(netdissect_options *ndo,
USES_APPLE_RST
/*
- * for the moment, ignore the auth algorith, just hard code the authenticator
+ * for the moment, ignore the auth algorithm, just hard code the authenticator
* length. Need to research how openssl looks up HMAC stuff.
*/
static int
@@ -527,7 +547,6 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
if (secretfile == NULL) {
(*ndo->ndo_error)(ndo, "print_esp: can't open %s: %s\n",
filename, strerror(errno));
- return;
}
while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
@@ -557,6 +576,10 @@ static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
uint32_t spino;
spistr = strsep(&spikey, "@");
+ if (spistr == NULL) {
+ (*ndo->ndo_warning)(ndo, "print_esp: failed to find the @ token");
+ return;
+ }
spino = strtoul(spistr, &foo, 0);
if (spistr == foo || !spikey) {
@@ -669,8 +692,8 @@ esp_print(netdissect_options *ndo,
const u_char *ivoff;
const u_char *p;
EVP_CIPHER_CTX *ctx;
- unsigned int block_size, output_buffer_size;
- u_char *output_buffer;
+ unsigned int block_size, buffer_size;
+ u_char *input_buffer, *output_buffer;
#endif
esp = (const struct newesp *)bp;
@@ -786,21 +809,41 @@ esp_print(netdissect_options *ndo,
len = ep - (p + ivlen);
/*
- * Allocate a buffer for the decrypted data.
- * The output buffer must be separate from the
- * input buffer, and its size must be a multiple
- * of the cipher block size.
+ * Allocate buffers for the encrypted and decrypted
+ * data. Both buffers' sizes must be a multiple of
+ * the cipher block size, and the output buffer must
+ * be separate from the input buffer.
*/
block_size = (unsigned int)EVP_CIPHER_CTX_block_size(ctx);
- output_buffer_size = len + (block_size - len % block_size);
- output_buffer = (u_char *)malloc(output_buffer_size);
+ buffer_size = len + (block_size - len % block_size);
+
+ /*
+ * Attempt to allocate the input buffer.
+ */
+ input_buffer = (u_char *)malloc(buffer_size);
+ if (input_buffer == NULL) {
+ EVP_CIPHER_CTX_free(ctx);
+ (*ndo->ndo_error)(ndo, "can't allocate memory for encrypted data buffer");
+ }
+ /*
+ * Copy the input data to the encrypted data buffer,
+ * and pad it with zeroes.
+ */
+ memcpy(input_buffer, p + ivlen, len);
+ memset(input_buffer + len, 0, buffer_size - len);
+
+ /*
+ * Attempt to allocate the output buffer.
+ */
+ output_buffer = (u_char *)malloc(buffer_size);
if (output_buffer == NULL) {
- (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer");
+ free(input_buffer);
EVP_CIPHER_CTX_free(ctx);
- return -1;
+ (*ndo->ndo_error)(ndo, "can't allocate memory for decryption buffer");
}
- EVP_Cipher(ctx, output_buffer, p + ivlen, len);
+ EVP_Cipher(ctx, output_buffer, input_buffer, len);
+ free(input_buffer);
EVP_CIPHER_CTX_free(ctx);
/*
* XXX - of course this is wrong, because buf is a
diff --git a/freebsd/contrib/tcpdump/print-fr.c b/freebsd/contrib/tcpdump/print-fr.c
index 1b9f0c71..59a50c9f 100644
--- a/freebsd/contrib/tcpdump/print-fr.c
+++ b/freebsd/contrib/tcpdump/print-fr.c
@@ -463,6 +463,10 @@ mfr_print(netdissect_options *ndo,
*/
ND_TCHECK2(*p, 4); /* minimum frame header length */
+ if (length < 4) {
+ ND_PRINT((ndo, "Message too short (%u bytes)", length));
+ return length;
+ }
if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) {
ND_PRINT((ndo, "FRF.16 Control, Flags [%s], %s, length %u",
@@ -499,6 +503,11 @@ mfr_print(netdissect_options *ndo,
switch (ie_type) {
case MFR_CTRL_IE_MAGIC_NUM:
+ /* FRF.16.1 Section 3.4.3 Magic Number Information Element */
+ if (ie_len != 4) {
+ ND_PRINT((ndo, "(invalid length)"));
+ break;
+ }
ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(tptr)));
break;
diff --git a/freebsd/contrib/tcpdump/print-hncp.c b/freebsd/contrib/tcpdump/print-hncp.c
index 26224249..cd564cc2 100644
--- a/freebsd/contrib/tcpdump/print-hncp.c
+++ b/freebsd/contrib/tcpdump/print-hncp.c
@@ -74,8 +74,8 @@ hncp_print(netdissect_options *ndo,
#define HNCP_EXTERNAL_CONNECTION 33
#define HNCP_DELEGATED_PREFIX 34
#define HNCP_PREFIX_POLICY 43
-#define HNCP_DHCPV4_DATA 37
-#define HNCP_DHCPV6_DATA 38
+#define HNCP_DHCPV4_DATA 37 /* This is correct, see RFC 7788 Errata ID 5113. */
+#define HNCP_DHCPV6_DATA 38 /* idem */
#define HNCP_ASSIGNED_PREFIX 35
#define HNCP_NODE_ADDRESS 36
#define HNCP_DNS_DELEGATED_ZONE 39
@@ -164,13 +164,13 @@ is_ipv4_mapped_address(const u_char *addr)
static const char *
format_nid(const u_char *data)
{
- static char buf[4][11+5];
+ static char buf[4][sizeof("01:01:01:01")];
#ifdef __rtems__
__section(".rtemsrwset.bsd_prog_tcpdump.content")
#endif /* __rtems__ */
static int i = 0;
i = (i + 1) % 4;
- snprintf(buf[i], 16, "%02x:%02x:%02x:%02x",
+ snprintf(buf[i], sizeof(buf[i]), "%02x:%02x:%02x:%02x",
data[0], data[1], data[2], data[3]);
return buf[i];
}
@@ -178,13 +178,13 @@ format_nid(const u_char *data)
static const char *
format_256(const u_char *data)
{
- static char buf[4][64+5];
+ static char buf[4][sizeof("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")];
#ifdef __rtems__
__section(".rtemsrwset.bsd_prog_tcpdump.content")
#endif /* __rtems__ */
static int i = 0;
i = (i + 1) % 4;
- snprintf(buf[i], 28, "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
+ snprintf(buf[i], sizeof(buf[i]), "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
EXTRACT_64BITS(data),
EXTRACT_64BITS(data + 8),
EXTRACT_64BITS(data + 16),
@@ -244,6 +244,8 @@ print_prefix(netdissect_options *ndo, const u_char *prefix, u_int max_length)
plenbytes += 1 + IPV4_MAPPED_HEADING_LEN;
} else {
plenbytes = decode_prefix6(ndo, prefix, max_length, buf, sizeof(buf));
+ if (plenbytes < 0)
+ return plenbytes;
}
ND_PRINT((ndo, "%s", buf));
diff --git a/freebsd/contrib/tcpdump/print-icmp.c b/freebsd/contrib/tcpdump/print-icmp.c
index ce22ce81..4c2cc50e 100644
--- a/freebsd/contrib/tcpdump/print-icmp.c
+++ b/freebsd/contrib/tcpdump/print-icmp.c
@@ -406,7 +406,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
default:
(void)snprintf(buf, sizeof(buf),
- "%s protocol %d port %d unreachable",
+ "%s protocol %u port %u unreachable",
ipaddr_string(ndo, &oip->ip_dst),
oip->ip_p, dport);
break;
@@ -512,7 +512,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
break;
default:
- (void)snprintf(buf, sizeof(buf), "time exceeded-#%d",
+ (void)snprintf(buf, sizeof(buf), "time exceeded-#%u",
dp->icmp_code);
break;
}
@@ -521,11 +521,11 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
case ICMP_PARAMPROB:
if (dp->icmp_code)
(void)snprintf(buf, sizeof(buf),
- "parameter problem - code %d", dp->icmp_code);
+ "parameter problem - code %u", dp->icmp_code);
else {
ND_TCHECK(dp->icmp_pptr);
(void)snprintf(buf, sizeof(buf),
- "parameter problem - octet %d", dp->icmp_pptr);
+ "parameter problem - octet %u", dp->icmp_pptr);
}
break;
@@ -563,13 +563,15 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
}
ND_PRINT((ndo, "ICMP %s, length %u", str, plen));
if (ndo->ndo_vflag && !fragmented) { /* don't attempt checksumming if this is a frag */
- uint16_t sum, icmp_sum;
-
if (ND_TTEST2(*bp, plen)) {
+ uint16_t sum;
+
vec[0].ptr = (const uint8_t *)(const void *)dp;
vec[0].len = plen;
sum = in_cksum(vec, 1);
if (sum != 0) {
+ uint16_t icmp_sum;
+ ND_TCHECK_16BITS(&dp->icmp_cksum);
icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum);
ND_PRINT((ndo, " (wrong icmp cksum %x (->%x)!)",
icmp_sum,
diff --git a/freebsd/contrib/tcpdump/print-icmp6.c b/freebsd/contrib/tcpdump/print-icmp6.c
index 33f36ddd..f66d4f86 100644
--- a/freebsd/contrib/tcpdump/print-icmp6.c
+++ b/freebsd/contrib/tcpdump/print-icmp6.c
@@ -47,6 +47,10 @@
#include "udp.h"
#include "ah.h"
+static const char icmp6_tstr[] = " [|icmp6]";
+static const char rpl_tstr[] = " [|rpl]";
+static const char mldv2_tstr[] = " [|mldv2]";
+
/* NetBSD: icmp6.h,v 1.13 2000/08/03 16:30:37 itojun Exp */
/* $KAME: icmp6.h,v 1.22 2000/08/03 15:25:16 jinmei Exp $ */
@@ -689,10 +693,11 @@ rpl_dio_printopt(netdissect_options *ndo,
}
opt = (const struct rpl_dio_genoption *)(((const char *)opt) + optlen);
length -= optlen;
+ ND_TCHECK(opt->rpl_dio_len);
}
return;
trunc:
- ND_PRINT((ndo," [|truncated]"));
+ ND_PRINT((ndo, "%s", rpl_tstr));
return;
}
@@ -721,7 +726,7 @@ rpl_dio_print(netdissect_options *ndo,
}
return;
trunc:
- ND_PRINT((ndo," [|truncated]"));
+ ND_PRINT((ndo, "%s", rpl_tstr));
return;
}
@@ -762,7 +767,7 @@ rpl_dao_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo," [|truncated]"));
+ ND_PRINT((ndo, "%s", rpl_tstr));
return;
tooshort:
@@ -806,7 +811,7 @@ rpl_daoack_print(netdissect_options *ndo,
return;
trunc:
- ND_PRINT((ndo," [|dao-truncated]"));
+ ND_PRINT((ndo, "%s", rpl_tstr));
return;
tooshort:
@@ -865,7 +870,7 @@ rpl_print(netdissect_options *ndo,
#if 0
trunc:
- ND_PRINT((ndo," [|truncated]"));
+ ND_PRINT((ndo, "%s", rpl_tstr));
return;
#endif
@@ -1040,7 +1045,7 @@ icmp6_print(netdissect_options *ndo,
p = (const struct nd_router_advert *)dp;
ND_TCHECK(p->nd_ra_retransmit);
ND_PRINT((ndo,"\n\thop limit %u, Flags [%s]" \
- ", pref %s, router lifetime %us, reachable time %us, retrans time %us",
+ ", pref %s, router lifetime %us, reachable time %ums, retrans timer %ums",
(u_int)p->nd_ra_curhoplimit,
bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)),
get_rtpref(p->nd_ra_flags_reserved),
@@ -1163,7 +1168,7 @@ icmp6_print(netdissect_options *ndo,
ND_PRINT((ndo,", length %u", length));
return;
trunc:
- ND_PRINT((ndo, "[|icmp6]"));
+ ND_PRINT((ndo, "%s", icmp6_tstr));
}
static const struct udphdr *
@@ -1387,8 +1392,8 @@ icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid)
}
return;
- trunc:
- ND_PRINT((ndo, "[ndp opt]"));
+trunc:
+ ND_PRINT((ndo, "%s", icmp6_tstr));
return;
#undef ECHECK
}
@@ -1463,7 +1468,7 @@ mldv2_report_print(netdissect_options *ndo, const u_char *bp, u_int len)
}
return;
trunc:
- ND_PRINT((ndo,"[|icmp6]"));
+ ND_PRINT((ndo, "%s", mldv2_tstr));
return;
}
@@ -1529,7 +1534,7 @@ mldv2_query_print(netdissect_options *ndo, const u_char *bp, u_int len)
ND_PRINT((ndo,"]"));
return;
trunc:
- ND_PRINT((ndo,"[|icmp6]"));
+ ND_PRINT((ndo, "%s", mldv2_tstr));
return;
}
@@ -1816,7 +1821,7 @@ icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp,
return;
trunc:
- ND_PRINT((ndo, "[|icmp6]"));
+ ND_PRINT((ndo, "%s", icmp6_tstr));
}
static void
@@ -1951,7 +1956,7 @@ icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep)
return;
trunc:
- ND_PRINT((ndo,"[|icmp6]"));
+ ND_PRINT((ndo, "%s", icmp6_tstr));
}
/*
diff --git a/freebsd/contrib/tcpdump/print-ipnet.c b/freebsd/contrib/tcpdump/print-ipnet.c
index cf9d2aeb..b3365d84 100644
--- a/freebsd/contrib/tcpdump/print-ipnet.c
+++ b/freebsd/contrib/tcpdump/print-ipnet.c
@@ -13,16 +13,19 @@
#include <netdissect-stdinc.h>
#include "netdissect.h"
+#include "extract.h"
+
+static const char tstr[] = "[|ipnet]";
typedef struct ipnet_hdr {
- uint8_t iph_version;
- uint8_t iph_family;
- uint16_t iph_htype;
- uint32_t iph_pktlen;
- uint32_t iph_ifindex;
- uint32_t iph_grifindex;
- uint32_t iph_zsrc;
- uint32_t iph_zdst;
+ nd_uint8_t iph_version;
+ nd_uint8_t iph_family;
+ nd_uint16_t iph_htype;
+ nd_uint32_t iph_pktlen;
+ nd_uint32_t iph_ifindex;
+ nd_uint32_t iph_grifindex;
+ nd_uint32_t iph_zsrc;
+ nd_uint32_t iph_zdst;
} ipnet_hdr_t;
#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */
@@ -42,21 +45,26 @@ ipnet_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length)
const ipnet_hdr_t *hdr;
hdr = (const ipnet_hdr_t *)bp;
- ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst));
+ ND_TCHECK(*hdr);
+ ND_PRINT((ndo, "%d > %d", EXTRACT_32BITS(hdr->iph_zsrc),
+ EXTRACT_32BITS(hdr->iph_zdst)));
if (!ndo->ndo_qflag) {
ND_PRINT((ndo,", family %s (%d)",
tok2str(ipnet_values, "Unknown",
- hdr->iph_family),
- hdr->iph_family));
+ EXTRACT_8BITS(&hdr->iph_family)),
+ EXTRACT_8BITS(&hdr->iph_family)));
} else {
ND_PRINT((ndo,", %s",
tok2str(ipnet_values,
"Unknown Ethertype (0x%04x)",
- hdr->iph_family)));
+ EXTRACT_8BITS(&hdr->iph_family))));
}
ND_PRINT((ndo, ", length %u: ", length));
+ return;
+trunc:
+ ND_PRINT((ndo, " %s", tstr));
}
static void
@@ -64,10 +72,8 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
{
const ipnet_hdr_t *hdr;
- if (caplen < sizeof(ipnet_hdr_t)) {
- ND_PRINT((ndo, "[|ipnet]"));
- return;
- }
+ if (caplen < sizeof(ipnet_hdr_t))
+ goto trunc;
if (ndo->ndo_eflag)
ipnet_hdr_print(ndo, p, length);
@@ -77,7 +83,8 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
hdr = (const ipnet_hdr_t *)p;
p += sizeof(ipnet_hdr_t);
- switch (hdr->iph_family) {
+ ND_TCHECK2(hdr->iph_family, 1);
+ switch (EXTRACT_8BITS(&hdr->iph_family)) {
case IPH_AF_INET:
ip_print(ndo, p, length);
@@ -96,6 +103,9 @@ ipnet_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
ND_DEFAULTPRINT(p, caplen);
break;
}
+ return;
+trunc:
+ ND_PRINT((ndo, " %s", tstr));
}
/*
diff --git a/freebsd/contrib/tcpdump/print-isakmp.c b/freebsd/contrib/tcpdump/print-isakmp.c
index bcb1caf7..7d82336c 100644
--- a/freebsd/contrib/tcpdump/print-isakmp.c
+++ b/freebsd/contrib/tcpdump/print-isakmp.c
@@ -1779,6 +1779,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
}
case IPSECDOI_NTYPE_REPLAY_STATUS:
ND_PRINT((ndo," status=("));
+ ND_TCHECK_32BITS(cp);
ND_PRINT((ndo,"replay detection %sabled",
EXTRACT_32BITS(cp) ? "en" : "dis"));
ND_PRINT((ndo,")"));
diff --git a/freebsd/contrib/tcpdump/print-juniper.c b/freebsd/contrib/tcpdump/print-juniper.c
index db252a9d..ae7cd522 100644
--- a/freebsd/contrib/tcpdump/print-juniper.c
+++ b/freebsd/contrib/tcpdump/print-juniper.c
@@ -1360,6 +1360,11 @@ juniper_parse_header(netdissect_options *ndo,
lp->s,
l2info->cookie_len));
+ if (l2info->cookie_len > 8) {
+ ND_PRINT((ndo, " (invalid)"));
+ return 0;
+ }
+
if (l2info->cookie_len > 0) {
ND_TCHECK2(p[0], l2info->cookie_len);
if (ndo->ndo_eflag)
diff --git a/freebsd/contrib/tcpdump/print-l2tp.c b/freebsd/contrib/tcpdump/print-l2tp.c
index f2100fa7..66560495 100644
--- a/freebsd/contrib/tcpdump/print-l2tp.c
+++ b/freebsd/contrib/tcpdump/print-l2tp.c
@@ -29,6 +29,8 @@
/* \summary: Layer Two Tunneling Protocol (L2TP) printer */
+/* specification: RFC 2661 */
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -149,7 +151,7 @@ static const struct tok l2tp_msgtype2str[] = {
#define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */
#define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */
#define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */
-#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code */
+#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code - RFC 3145 */
static const struct tok l2tp_avp2str[] = {
{ L2TP_AVP_MSGTYPE, "MSGTYPE" },
@@ -288,15 +290,15 @@ print_octets(netdissect_options *ndo, const u_char *dat, u_int length)
}
static void
-print_16bits_val(netdissect_options *ndo, const uint16_t *dat)
+print_16bits_val(netdissect_options *ndo, const uint8_t *dat)
{
ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat)));
}
static void
-print_32bits_val(netdissect_options *ndo, const uint32_t *dat)
+print_32bits_val(netdissect_options *ndo, const uint8_t *dat)
{
- ND_PRINT((ndo, "%lu", (u_long)EXTRACT_32BITS(dat)));
+ ND_PRINT((ndo, "%u", EXTRACT_32BITS(dat)));
}
/***********************************/
@@ -305,28 +307,24 @@ print_32bits_val(netdissect_options *ndo, const uint32_t *dat)
static void
l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint16_t *ptr = (const uint16_t *)dat;
-
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
- EXTRACT_16BITS(ptr))));
+ EXTRACT_16BITS(dat))));
}
static void
l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint16_t *ptr = (const uint16_t *)dat;
-
/* Result Code */
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr)));
- ptr++;
+ ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat)));
+ dat += 2;
length -= 2;
/* Error Code (opt) */
@@ -336,19 +334,19 @@ l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
ND_PRINT((ndo, " AVP too short"));
return;
}
- ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr)));
- ptr++;
+ ND_PRINT((ndo, "/%u", EXTRACT_16BITS(dat)));
+ dat += 2;
length -= 2;
/* Error Message (opt) */
if (length == 0)
return;
ND_PRINT((ndo, " "));
- print_string(ndo, (const u_char *)ptr, length);
+ print_string(ndo, dat, length);
}
static void
-l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length)
+l2tp_proto_ver_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
@@ -361,16 +359,14 @@ l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length)
static void
l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint32_t *ptr = (const uint32_t *)dat;
-
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) {
+ if (EXTRACT_32BITS(dat) & L2TP_FRAMING_CAP_ASYNC_MASK) {
ND_PRINT((ndo, "A"));
}
- if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_SYNC_MASK) {
+ if (EXTRACT_32BITS(dat) & L2TP_FRAMING_CAP_SYNC_MASK) {
ND_PRINT((ndo, "S"));
}
}
@@ -378,16 +374,14 @@ l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
static void
l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint32_t *ptr = (const uint32_t *)dat;
-
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) {
+ if (EXTRACT_32BITS(dat) & L2TP_BEARER_CAP_ANALOG_MASK) {
ND_PRINT((ndo, "A"));
}
- if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_DIGITAL_MASK) {
+ if (EXTRACT_32BITS(dat) & L2TP_BEARER_CAP_DIGITAL_MASK) {
ND_PRINT((ndo, "D"));
}
}
@@ -399,8 +393,8 @@ l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
ND_PRINT((ndo, "AVP too short"));
return;
}
- print_16bits_val(ndo, (const uint16_t *)dat);
- ND_PRINT((ndo, ", %02x", dat[2]));
+ print_16bits_val(ndo, dat);
+ ND_PRINT((ndo, ", %02x", EXTRACT_8BITS(dat + 2)));
dat += 3;
length -= 3;
if (length != 0) {
@@ -412,16 +406,14 @@ l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
static void
l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint32_t *ptr = (const uint32_t *)dat;
-
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) {
+ if (EXTRACT_32BITS(dat) & L2TP_BEARER_TYPE_ANALOG_MASK) {
ND_PRINT((ndo, "A"));
}
- if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_DIGITAL_MASK) {
+ if (EXTRACT_32BITS(dat) & L2TP_BEARER_TYPE_DIGITAL_MASK) {
ND_PRINT((ndo, "D"));
}
}
@@ -429,16 +421,14 @@ l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
static void
l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint32_t *ptr = (const uint32_t *)dat;
-
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
+ if (EXTRACT_32BITS(dat) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
ND_PRINT((ndo, "A"));
}
- if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_SYNC_MASK) {
+ if (EXTRACT_32BITS(dat) & L2TP_FRAMING_TYPE_SYNC_MASK) {
ND_PRINT((ndo, "S"));
}
}
@@ -452,125 +442,109 @@ l2tp_packet_proc_delay_print(netdissect_options *ndo)
static void
l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint16_t *ptr = (const uint16_t *)dat;
-
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str,
- "AuthType-#%u", EXTRACT_16BITS(ptr))));
+ "AuthType-#%u", EXTRACT_16BITS(dat))));
}
static void
l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint16_t *ptr = (const uint16_t *)dat;
-
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK));
+ ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat) & L2TP_PROXY_AUTH_ID_MASK));
}
static void
l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint16_t *ptr = (const uint16_t *)dat;
- uint16_t val_h, val_l;
+ uint32_t val;
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- ptr++; /* skip "Reserved" */
+ dat += 2; /* skip "Reserved" */
length -= 2;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l));
+ val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
+ ND_PRINT((ndo, "CRCErr=%u ", val));
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l));
+ val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
+ ND_PRINT((ndo, "FrameErr=%u ", val));
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l));
+ val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
+ ND_PRINT((ndo, "HardOver=%u ", val));
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l));
+ val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
+ ND_PRINT((ndo, "BufOver=%u ", val));
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l));
+ val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
+ ND_PRINT((ndo, "Timeout=%u ", val));
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
- ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l));
+ val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
+ ND_PRINT((ndo, "AlignErr=%u ", val));
}
static void
l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint16_t *ptr = (const uint16_t *)dat;
- uint16_t val_h, val_l;
+ uint32_t val;
if (length < 2) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- ptr++; /* skip "Reserved" */
+ dat += 2; /* skip "Reserved" */
length -= 2;
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2;
- ND_PRINT((ndo, "send=%08x ", (val_h<<16) + val_l));
+ val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
+ ND_PRINT((ndo, "send=%08x ", val));
if (length < 4) {
ND_PRINT((ndo, "AVP too short"));
return;
}
- val_h = EXTRACT_16BITS(ptr); ptr++;
- val_l = EXTRACT_16BITS(ptr); ptr++;
- ND_PRINT((ndo, "recv=%08x ", (val_h<<16) + val_l));
+ val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
+ ND_PRINT((ndo, "recv=%08x ", val));
}
static void
l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
- const uint16_t *ptr = (const uint16_t *)dat;
-
if (length < 5) {
ND_PRINT((ndo, "AVP too short"));
return;
@@ -585,32 +559,27 @@ l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int lengt
length -= 2;
/* Direction */
ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str,
- "Direction-#%u", EXTRACT_8BITS(ptr))));
- ptr++;
+ "Direction-#%u", EXTRACT_8BITS(dat))));
+ dat++;
length--;
if (length != 0) {
ND_PRINT((ndo, " "));
- print_string(ndo, (const u_char *)ptr, length);
+ print_string(ndo, (const u_char *)dat, length);
}
}
-static void
-l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
+static u_int
+l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length)
{
u_int len;
- const uint16_t *ptr = (const uint16_t *)dat;
uint16_t attr_type;
int hidden = FALSE;
- if (length <= 0) {
- return;
- }
-
ND_PRINT((ndo, " "));
- ND_TCHECK(*ptr); /* Flags & Length */
- len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK;
+ ND_TCHECK_16BITS(dat); /* Flags & Length */
+ len = EXTRACT_16BITS(dat) & L2TP_AVP_HDR_LEN_MASK;
/* If it is not long enough to contain the header, we'll give up. */
if (len < 6)
@@ -623,7 +592,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
/* If it goes past the end of the remaining length of the captured
data, we'll give up. */
- ND_TCHECK2(*ptr, len);
+ ND_TCHECK2(*dat, len);
/*
* After this point, we don't need to check whether we go past
@@ -631,26 +600,26 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
* check whether we go past the end of the AVP.
*/
- if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
+ if (EXTRACT_16BITS(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) {
ND_PRINT((ndo, "*"));
}
- if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
+ if (EXTRACT_16BITS(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) {
hidden = TRUE;
ND_PRINT((ndo, "?"));
}
- ptr++;
+ dat += 2;
- if (EXTRACT_16BITS(ptr)) {
+ if (EXTRACT_16BITS(dat)) {
/* Vendor Specific Attribute */
- ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(ptr))); ptr++;
- ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(ptr))); ptr++;
+ ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(dat))); dat += 2;
+ ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(dat))); dat += 2;
ND_PRINT((ndo, "("));
- print_octets(ndo, (const u_char *)ptr, len-6);
+ print_octets(ndo, dat, len-6);
ND_PRINT((ndo, ")"));
} else {
/* IETF-defined Attributes */
- ptr++;
- attr_type = EXTRACT_16BITS(ptr); ptr++;
+ dat += 2;
+ attr_type = EXTRACT_16BITS(dat); dat += 2;
ND_PRINT((ndo, "%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type)));
ND_PRINT((ndo, "("));
if (hidden) {
@@ -658,26 +627,26 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
} else {
switch (attr_type) {
case L2TP_AVP_MSGTYPE:
- l2tp_msgtype_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_msgtype_print(ndo, dat, len-6);
break;
case L2TP_AVP_RESULT_CODE:
- l2tp_result_code_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_result_code_print(ndo, dat, len-6);
break;
case L2TP_AVP_PROTO_VER:
- l2tp_proto_ver_print(ndo, ptr, len-6);
+ l2tp_proto_ver_print(ndo, dat, len-6);
break;
case L2TP_AVP_FRAMING_CAP:
- l2tp_framing_cap_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_framing_cap_print(ndo, dat, len-6);
break;
case L2TP_AVP_BEARER_CAP:
- l2tp_bearer_cap_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_bearer_cap_print(ndo, dat, len-6);
break;
case L2TP_AVP_TIE_BREAKER:
if (len-6 < 8) {
ND_PRINT((ndo, "AVP too short"));
break;
}
- print_octets(ndo, (const u_char *)ptr, 8);
+ print_octets(ndo, dat, 8);
break;
case L2TP_AVP_FIRM_VER:
case L2TP_AVP_ASSND_TUN_ID:
@@ -687,7 +656,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
ND_PRINT((ndo, "AVP too short"));
break;
}
- print_16bits_val(ndo, ptr);
+ print_16bits_val(ndo, dat);
break;
case L2TP_AVP_HOST_NAME:
case L2TP_AVP_VENDOR_NAME:
@@ -696,7 +665,7 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
case L2TP_AVP_SUB_ADDRESS:
case L2TP_AVP_PROXY_AUTH_NAME:
case L2TP_AVP_PRIVATE_GRP_ID:
- print_string(ndo, (const u_char *)ptr, len-6);
+ print_string(ndo, dat, len-6);
break;
case L2TP_AVP_CHALLENGE:
case L2TP_AVP_INI_RECV_LCP:
@@ -705,17 +674,17 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
case L2TP_AVP_PROXY_AUTH_CHAL:
case L2TP_AVP_PROXY_AUTH_RESP:
case L2TP_AVP_RANDOM_VECTOR:
- print_octets(ndo, (const u_char *)ptr, len-6);
+ print_octets(ndo, dat, len-6);
break;
case L2TP_AVP_Q931_CC:
- l2tp_q931_cc_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_q931_cc_print(ndo, dat, len-6);
break;
case L2TP_AVP_CHALLENGE_RESP:
if (len-6 < 16) {
ND_PRINT((ndo, "AVP too short"));
break;
}
- print_octets(ndo, (const u_char *)ptr, 16);
+ print_octets(ndo, dat, 16);
break;
case L2TP_AVP_CALL_SER_NUM:
case L2TP_AVP_MINIMUM_BPS:
@@ -727,33 +696,33 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
ND_PRINT((ndo, "AVP too short"));
break;
}
- print_32bits_val(ndo, (const uint32_t *)ptr);
+ print_32bits_val(ndo, dat);
break;
case L2TP_AVP_BEARER_TYPE:
- l2tp_bearer_type_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_bearer_type_print(ndo, dat, len-6);
break;
case L2TP_AVP_FRAMING_TYPE:
- l2tp_framing_type_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_framing_type_print(ndo, dat, len-6);
break;
case L2TP_AVP_PACKET_PROC_DELAY:
l2tp_packet_proc_delay_print(ndo);
break;
case L2TP_AVP_PROXY_AUTH_TYPE:
- l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_proxy_auth_type_print(ndo, dat, len-6);
break;
case L2TP_AVP_PROXY_AUTH_ID:
- l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_proxy_auth_id_print(ndo, dat, len-6);
break;
case L2TP_AVP_CALL_ERRORS:
- l2tp_call_errors_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_call_errors_print(ndo, dat, len-6);
break;
case L2TP_AVP_ACCM:
- l2tp_accm_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_accm_print(ndo, dat, len-6);
break;
case L2TP_AVP_SEQ_REQUIRED:
break; /* No Attribute Value */
case L2TP_AVP_PPP_DISCON_CC:
- l2tp_ppp_discon_cc_print(ndo, (const u_char *)ptr, len-6);
+ l2tp_ppp_discon_cc_print(ndo, dat, len-6);
break;
default:
break;
@@ -762,11 +731,11 @@ l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length)
ND_PRINT((ndo, ")"));
}
- l2tp_avp_print(ndo, dat+len, length-len);
- return;
+ return (len);
trunc:
ND_PRINT((ndo, "|..."));
+ return (0);
}
@@ -871,7 +840,22 @@ l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length)
if (length - cnt == 0) {
ND_PRINT((ndo, " ZLB"));
} else {
- l2tp_avp_print(ndo, ptr, length - cnt);
+ /*
+ * Print AVPs.
+ */
+ while (length - cnt != 0) {
+ u_int avp_length;
+
+ avp_length = l2tp_avp_print(ndo, ptr, length - cnt);
+ if (avp_length == 0) {
+ /*
+ * Truncated.
+ */
+ break;
+ }
+ cnt += avp_length;
+ ptr += avp_length;
+ }
}
} else {
ND_PRINT((ndo, " {"));
diff --git a/freebsd/contrib/tcpdump/print-ldp.c b/freebsd/contrib/tcpdump/print-ldp.c
index b0975868..016915eb 100644
--- a/freebsd/contrib/tcpdump/print-ldp.c
+++ b/freebsd/contrib/tcpdump/print-ldp.c
@@ -35,6 +35,8 @@
#include "l2vpn.h"
#include "af.h"
+static const char tstr[] = " [|LDP]";
+
/*
* ldp common header
*
@@ -216,7 +218,7 @@ static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = {
{ 0, NULL}
};
-static int ldp_pdu_print(netdissect_options *, register const u_char *);
+static u_int ldp_pdu_print(netdissect_options *, register const u_char *);
/*
* ldp tlv header
@@ -441,19 +443,24 @@ ldp_tlv_print(netdissect_options *ndo,
switch(vc_info_tlv_type) {
case LDP_FEC_MARTINI_IFPARM_MTU:
+ ND_TCHECK_16BITS(tptr + 2);
ND_PRINT((ndo, ": %u", EXTRACT_16BITS(tptr+2)));
break;
case LDP_FEC_MARTINI_IFPARM_DESC:
ND_PRINT((ndo, ": "));
- for (idx = 2; idx < vc_info_tlv_len; idx++)
+ for (idx = 2; idx < vc_info_tlv_len; idx++) {
+ ND_TCHECK_8BITS(tptr + idx);
safeputchar(ndo, *(tptr + idx));
+ }
break;
case LDP_FEC_MARTINI_IFPARM_VCCV:
+ ND_TCHECK_8BITS(tptr + 2);
ND_PRINT((ndo, "\n\t\t Control Channels (0x%02x) = [%s]",
*(tptr+2),
bittok2str(ldp_fec_martini_ifparm_vccv_cc_values, "none", *(tptr+2))));
+ ND_TCHECK_8BITS(tptr + 3);
ND_PRINT((ndo, "\n\t\t CV Types (0x%02x) = [%s]",
*(tptr+3),
bittok2str(ldp_fec_martini_ifparm_vccv_cv_values, "none", *(tptr+3))));
@@ -492,7 +499,7 @@ ldp_tlv_print(netdissect_options *ndo,
break;
case LDP_TLV_FT_SESSION:
- TLV_TCHECK(8);
+ TLV_TCHECK(12);
ft_flags = EXTRACT_16BITS(tptr);
ND_PRINT((ndo, "\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
ft_flags&0x8000 ? "" : "No ",
@@ -500,6 +507,7 @@ ldp_tlv_print(netdissect_options *ndo,
ft_flags&0x4 ? "" : "No ",
ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
ft_flags&0x1 ? "" : "Don't "));
+ /* 16 bits (FT Flags) + 16 bits (Reserved) */
tptr+=4;
ui = EXTRACT_32BITS(tptr);
if (ui)
@@ -540,7 +548,7 @@ ldp_tlv_print(netdissect_options *ndo,
return(tlv_len+4); /* Type & Length fields not included */
trunc:
- ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
+ ND_PRINT((ndo, "%s", tstr));
return 0;
badtlv:
@@ -552,17 +560,23 @@ void
ldp_print(netdissect_options *ndo,
register const u_char *pptr, register u_int len)
{
- int processed;
+ u_int processed;
while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) {
processed = ldp_pdu_print(ndo, pptr);
if (processed == 0)
return;
+ if (len < processed) {
+ ND_PRINT((ndo, " [remaining length %u < %u]", len, processed));
+ ND_PRINT((ndo, "%s", istr));
+ break;
+
+ }
len -= processed;
pptr += processed;
}
}
-static int
+static u_int
ldp_pdu_print(netdissect_options *ndo,
register const u_char *pptr)
{
@@ -692,7 +706,7 @@ ldp_pdu_print(netdissect_options *ndo,
}
return pdu_len+4;
trunc:
- ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
+ ND_PRINT((ndo, "%s", tstr));
return 0;
}
diff --git a/freebsd/contrib/tcpdump/print-lmp.c b/freebsd/contrib/tcpdump/print-lmp.c
index 031fdb96..bf73909f 100644
--- a/freebsd/contrib/tcpdump/print-lmp.c
+++ b/freebsd/contrib/tcpdump/print-lmp.c
@@ -37,6 +37,8 @@
#include "addrtoname.h"
#include "gmpls.h"
+static const char tstr[] = " [|LMP]";
+
/*
* LMP common header
*
@@ -373,8 +375,9 @@ lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
} bw;
while (total_subobj_len > 0 && hexdump == FALSE ) {
- subobj_type = EXTRACT_8BITS(obj_tptr+offset);
- subobj_len = EXTRACT_8BITS(obj_tptr+offset+1);
+ ND_TCHECK_16BITS(obj_tptr + offset);
+ subobj_type = EXTRACT_8BITS(obj_tptr + offset);
+ subobj_len = EXTRACT_8BITS(obj_tptr + offset + 1);
ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u",
tok2str(lmp_data_link_subobj,
"Unknown",
@@ -395,24 +398,29 @@ lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
}
switch(subobj_type) {
case INT_SWITCHING_TYPE_SUBOBJ:
+ ND_TCHECK_8BITS(obj_tptr + offset + 2);
ND_PRINT((ndo, "\n\t Switching Type: %s (%u)",
tok2str(gmpls_switch_cap_values,
"Unknown",
- EXTRACT_8BITS(obj_tptr+offset+2)),
- EXTRACT_8BITS(obj_tptr+offset+2)));
+ EXTRACT_8BITS(obj_tptr + offset + 2)),
+ EXTRACT_8BITS(obj_tptr + offset + 2)));
+ ND_TCHECK_8BITS(obj_tptr + offset + 3);
ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)",
tok2str(gmpls_encoding_values,
"Unknown",
- EXTRACT_8BITS(obj_tptr+offset+3)),
- EXTRACT_8BITS(obj_tptr+offset+3)));
+ EXTRACT_8BITS(obj_tptr + offset + 3)),
+ EXTRACT_8BITS(obj_tptr + offset + 3)));
+ ND_TCHECK_32BITS(obj_tptr + offset + 4);
bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps",
bw.f*8/1000000));
+ ND_TCHECK_32BITS(obj_tptr + offset + 8);
bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps",
bw.f*8/1000000));
break;
case WAVELENGTH_SUBOBJ:
+ ND_TCHECK_32BITS(obj_tptr + offset + 4);
ND_PRINT((ndo, "\n\t Wavelength: %u",
EXTRACT_32BITS(obj_tptr+offset+4)));
break;
@@ -425,6 +433,8 @@ lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr,
offset+=subobj_len;
}
return (hexdump);
+trunc:
+ return -1;
}
void
@@ -435,7 +445,7 @@ lmp_print(netdissect_options *ndo,
const struct lmp_object_header *lmp_obj_header;
const u_char *tptr,*obj_tptr;
u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
- int hexdump;
+ int hexdump, ret;
u_int offset;
u_int link_type;
@@ -737,7 +747,10 @@ lmp_print(netdissect_options *ndo,
ipaddr_string(ndo, obj_tptr+8),
EXTRACT_32BITS(obj_tptr+8)));
- if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
+ ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12);
+ if (ret == -1)
+ goto trunc;
+ if (ret == TRUE)
hexdump=TRUE;
break;
@@ -757,7 +770,10 @@ lmp_print(netdissect_options *ndo,
ip6addr_string(ndo, obj_tptr+20),
EXTRACT_32BITS(obj_tptr+20)));
- if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36))
+ ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36);
+ if (ret == -1)
+ goto trunc;
+ if (ret == TRUE)
hexdump=TRUE;
break;
@@ -777,7 +793,10 @@ lmp_print(netdissect_options *ndo,
EXTRACT_32BITS(obj_tptr+8),
EXTRACT_32BITS(obj_tptr+8)));
- if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
+ ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12);
+ if (ret == -1)
+ goto trunc;
+ if (ret == TRUE)
hexdump=TRUE;
break;
@@ -1018,7 +1037,7 @@ lmp_print(netdissect_options *ndo,
EXTRACT_8BITS(obj_tptr))));
ND_PRINT((ndo, "\n\t UNI Version: %u",
- EXTRACT_8BITS(obj_tptr+1)));
+ EXTRACT_8BITS(obj_tptr + 1)));
break;
@@ -1040,28 +1059,28 @@ lmp_print(netdissect_options *ndo,
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
"Unknown",
- EXTRACT_8BITS(obj_tptr+1)),
- EXTRACT_8BITS(obj_tptr+1)));
+ EXTRACT_8BITS(obj_tptr + 1)),
+ EXTRACT_8BITS(obj_tptr + 1)));
break;
case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET:
ND_PRINT((ndo, "\n\t Signal Type: %s (%u)",
tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
"Unknown",
- EXTRACT_8BITS(obj_tptr+1)),
- EXTRACT_8BITS(obj_tptr+1)));
+ EXTRACT_8BITS(obj_tptr + 1)),
+ EXTRACT_8BITS(obj_tptr + 1)));
break;
}
ND_PRINT((ndo, "\n\t Transparency: %s",
bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
"none",
- EXTRACT_8BITS(obj_tptr+2))));
+ EXTRACT_8BITS(obj_tptr + 2))));
ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s",
bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
"none",
- EXTRACT_8BITS(obj_tptr+3))));
+ EXTRACT_8BITS(obj_tptr + 3))));
ND_PRINT((ndo, "\n\t Minimum NCC: %u",
EXTRACT_16BITS(obj_tptr+4)));
@@ -1097,7 +1116,7 @@ lmp_print(netdissect_options *ndo,
bittok2str(
lmp_obj_service_config_nsa_tcm_flag_values,
"none",
- EXTRACT_8BITS(obj_tptr+7))));
+ EXTRACT_8BITS(obj_tptr + 7))));
break;
@@ -1111,7 +1130,7 @@ lmp_print(netdissect_options *ndo,
bittok2str(
lmp_obj_service_config_nsa_network_diversity_flag_values,
"none",
- EXTRACT_8BITS(obj_tptr+3))));
+ EXTRACT_8BITS(obj_tptr + 3))));
break;
default:
@@ -1135,7 +1154,7 @@ lmp_print(netdissect_options *ndo,
}
return;
trunc:
- ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
+ ND_PRINT((ndo, "%s", tstr));
}
/*
* Local Variables:
diff --git a/freebsd/contrib/tcpdump/print-nfs.c b/freebsd/contrib/tcpdump/print-nfs.c
index 97748dce..11579827 100644
--- a/freebsd/contrib/tcpdump/print-nfs.c
+++ b/freebsd/contrib/tcpdump/print-nfs.c
@@ -1574,8 +1574,8 @@ interp_reply(netdissect_options *ndo,
tok2str(nfsv3_writemodes,
NULL, EXTRACT_32BITS(&dp[1]))));
}
- return;
}
+ return;
} else {
if (parseattrstat(ndo, dp, ndo->ndo_vflag, v3) != 0)
return;
@@ -1661,8 +1661,8 @@ interp_reply(netdissect_options *ndo,
ND_PRINT((ndo, " dir:"));
if (!(dp = parse_wcc_data(ndo, dp, ndo->ndo_vflag)))
break;
- return;
}
+ return;
} else {
if (parsestatus(ndo, dp, &er) != NULL)
return;
diff --git a/freebsd/contrib/tcpdump/print-openflow.c b/freebsd/contrib/tcpdump/print-openflow.c
index 7f8c907e..977403c4 100644
--- a/freebsd/contrib/tcpdump/print-openflow.c
+++ b/freebsd/contrib/tcpdump/print-openflow.c
@@ -138,13 +138,11 @@ trunc:
/* Print a TCP segment worth of OpenFlow messages presuming the segment begins
* on a message boundary. */
void
-openflow_print(netdissect_options *ndo, const u_char *cp, const u_int len)
+openflow_print(netdissect_options *ndo, const u_char *cp, const u_int len _U_)
{
- const u_char *ep = cp + len;
-
ND_PRINT((ndo, ": OpenFlow"));
- while (cp < ep)
- cp = of_header_body_print(ndo, cp, ep);
+ while (cp < ndo->ndo_snapend)
+ cp = of_header_body_print(ndo, cp, ndo->ndo_snapend);
}
#ifdef __rtems__
#include "rtems-bsd-tcpdump-print-openflow-data.h"
diff --git a/freebsd/contrib/tcpdump/print-ospf.c b/freebsd/contrib/tcpdump/print-ospf.c
index 9343de12..0d3a9dd6 100644
--- a/freebsd/contrib/tcpdump/print-ospf.c
+++ b/freebsd/contrib/tcpdump/print-ospf.c
@@ -712,7 +712,7 @@ ospf_print_lsa(netdissect_options *ndo,
while ((const u_char *)lp < ls_end) {
register uint32_t ul;
- ND_TCHECK(*lp);
+ ND_TCHECK_32BITS(lp);
ul = EXTRACT_32BITS(lp);
topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d",
@@ -729,7 +729,7 @@ ospf_print_lsa(netdissect_options *ndo,
while ((const u_char *)lp < ls_end) {
register uint32_t ul;
- ND_TCHECK(*lp);
+ ND_TCHECK_32BITS(lp);
ul = EXTRACT_32BITS(lp);
topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d",
diff --git a/freebsd/contrib/tcpdump/print-ospf6.c b/freebsd/contrib/tcpdump/print-ospf6.c
index 333ac774..41c833de 100644
--- a/freebsd/contrib/tcpdump/print-ospf6.c
+++ b/freebsd/contrib/tcpdump/print-ospf6.c
@@ -395,8 +395,7 @@ ospf6_print_lshdr(netdissect_options *ndo,
{
if ((const u_char *)(lshp + 1) > dataend)
goto trunc;
- ND_TCHECK(lshp->ls_type);
- ND_TCHECK(lshp->ls_seq);
+ ND_TCHECK(lshp->ls_length); /* last field of struct lsa6_hdr */
ND_PRINT((ndo, "\n\t Advertising Router %s, seq 0x%08x, age %us, length %u",
ipaddr_string(ndo, &lshp->ls_router),
diff --git a/freebsd/contrib/tcpdump/print-pflog.c b/freebsd/contrib/tcpdump/print-pflog.c
index 78c3295c..b7706353 100644
--- a/freebsd/contrib/tcpdump/print-pflog.c
+++ b/freebsd/contrib/tcpdump/print-pflog.c
@@ -103,8 +103,12 @@ pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
else
ND_PRINT((ndo, "rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr));
- ND_PRINT((ndo, "%s: %s %s on %s: ",
- tok2str(pf_reasons, "unkn(%u)", hdr->reason),
+ ND_PRINT((ndo, "%s", tok2str(pf_reasons, "unkn(%u)", hdr->reason)));
+
+ if (hdr->uid != UID_MAX)
+ ND_PRINT((ndo, " [uid %u]", (unsigned)hdr->uid));
+
+ ND_PRINT((ndo, ": %s %s on %s: ",
tok2str(pf_actions, "unkn(%u)", hdr->action),
tok2str(pf_directions, "unkn(%u)", hdr->dir),
hdr->ifname));
diff --git a/freebsd/contrib/tcpdump/print-ppi.c b/freebsd/contrib/tcpdump/print-ppi.c
index d1faa7f2..b717c0bb 100644
--- a/freebsd/contrib/tcpdump/print-ppi.c
+++ b/freebsd/contrib/tcpdump/print-ppi.c
@@ -74,6 +74,7 @@ ppi_print(netdissect_options *ndo,
}
hdr = (const ppi_header_t *)p;
+ ND_TCHECK_16BITS(&hdr->ppi_len);
len = EXTRACT_LE_16BITS(&hdr->ppi_len);
if (caplen < len) {
/*
@@ -87,6 +88,7 @@ ppi_print(netdissect_options *ndo,
ND_PRINT((ndo, "[|ppi]"));
return (len);
}
+ ND_TCHECK_32BITS(&hdr->ppi_dlt);
dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt);
if (ndo->ndo_eflag)
@@ -110,6 +112,8 @@ ppi_print(netdissect_options *ndo,
hdrlen = 0;
}
return (len + hdrlen);
+trunc:
+ return (caplen);
}
/*
diff --git a/freebsd/contrib/tcpdump/print-rsvp.c b/freebsd/contrib/tcpdump/print-rsvp.c
index 102757d0..fbb5329a 100644
--- a/freebsd/contrib/tcpdump/print-rsvp.c
+++ b/freebsd/contrib/tcpdump/print-rsvp.c
@@ -505,6 +505,7 @@ rsvp_intserv_print(netdissect_options *ndo,
if (obj_tlen < 4)
return 0;
+ ND_TCHECK_8BITS(tptr);
parameter_id = *(tptr);
ND_TCHECK2(*(tptr + 2), 2);
parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */
@@ -1560,6 +1561,7 @@ rsvp_obj_print(netdissect_options *ndo,
case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */
switch(rsvp_obj_ctype) {
case RSVP_CTYPE_1:
+ ND_TCHECK_32BITS(obj_tptr);
ND_PRINT((ndo, "%s CT: %u",
ident,
EXTRACT_32BITS(obj_tptr) & 0x7));
diff --git a/freebsd/contrib/tcpdump/print-rx.c b/freebsd/contrib/tcpdump/print-rx.c
index e7e369bf..ee1f17b4 100644
--- a/freebsd/contrib/tcpdump/print-rx.c
+++ b/freebsd/contrib/tcpdump/print-rx.c
@@ -700,7 +700,7 @@ rx_cache_insert(netdissect_options *ndo,
UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t));
UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t));
rxent->dport = dport;
- rxent->serviceId = EXTRACT_32BITS(&rxh->serviceId);
+ rxent->serviceId = EXTRACT_16BITS(&rxh->serviceId);
rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
}
@@ -731,7 +731,7 @@ rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,
if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) &&
rxent->client.s_addr == clip &&
rxent->server.s_addr == sip &&
- rxent->serviceId == EXTRACT_32BITS(&rxh->serviceId) &&
+ rxent->serviceId == EXTRACT_16BITS(&rxh->serviceId) &&
rxent->dport == sport) {
/* We got a match! */
@@ -1025,6 +1025,7 @@ fs_print(netdissect_options *ndo,
}
if (j == 0)
ND_PRINT((ndo, " <none!>"));
+ break;
}
case 65537: /* Fetch data 64 */
FIDOUT();
@@ -1285,6 +1286,7 @@ cb_print(netdissect_options *ndo,
bp += sizeof(int32_t);
tok2str(cb_types, "type %d", t);
}
+ break;
}
case 214: {
ND_PRINT((ndo, " afsuuid"));
@@ -1746,6 +1748,7 @@ vldb_reply_print(netdissect_options *ndo,
INTOUT();
ND_PRINT((ndo, " nextindex"));
INTOUT();
+ /*FALLTHROUGH*/
case 503: /* Get entry by id */
case 504: /* Get entry by name */
{ unsigned long nservers, j;
@@ -1795,6 +1798,7 @@ vldb_reply_print(netdissect_options *ndo,
INTOUT();
ND_PRINT((ndo, " nextindex"));
INTOUT();
+ /*FALLTHROUGH*/
case 518: /* Get entry by ID N */
case 519: /* Get entry by name N */
{ unsigned long nservers, j;
diff --git a/freebsd/contrib/tcpdump/print-sflow.c b/freebsd/contrib/tcpdump/print-sflow.c
index b2131164..4313f78a 100644
--- a/freebsd/contrib/tcpdump/print-sflow.c
+++ b/freebsd/contrib/tcpdump/print-sflow.c
@@ -887,6 +887,14 @@ sflow_print(netdissect_options *ndo,
tptr = pptr;
tlen = len;
sflow_datagram = (const struct sflow_datagram_t *)pptr;
+ if (len < sizeof(struct sflow_datagram_t)) {
+ ND_TCHECK(sflow_datagram->version);
+ ND_PRINT((ndo, "sFlowv%u", EXTRACT_32BITS(sflow_datagram->version)));
+ ND_PRINT((ndo, " [length %u < %zu]",
+ len, sizeof(struct sflow_datagram_t)));
+ ND_PRINT((ndo, " (invalid)"));
+ return;
+ }
ND_TCHECK(*sflow_datagram);
/*
@@ -922,6 +930,8 @@ sflow_print(netdissect_options *ndo,
/* skip Common header */
tptr += sizeof(const struct sflow_datagram_t);
+
+ if(tlen <= sizeof(const struct sflow_datagram_t)) goto trunc;
tlen -= sizeof(const struct sflow_datagram_t);
while (nsamples > 0 && tlen > 0) {
diff --git a/freebsd/contrib/tcpdump/print-sl.c b/freebsd/contrib/tcpdump/print-sl.c
index faaa5ba7..609f0950 100644
--- a/freebsd/contrib/tcpdump/print-sl.c
+++ b/freebsd/contrib/tcpdump/print-sl.c
@@ -58,8 +58,8 @@ static const char tstr[] = "[|slip]";
static u_int lastlen[2][256];
static u_int lastconn = 255;
-static void sliplink_print(netdissect_options *, const u_char *, const struct ip *, u_int);
-static void compressed_sl_print(netdissect_options *, const u_char *, const struct ip *, u_int, int);
+static int sliplink_print(netdissect_options *, const u_char *, const struct ip *, u_int);
+static int compressed_sl_print(netdissect_options *, const u_char *, const struct ip *, u_int, int);
u_int
sl_if_print(netdissect_options *ndo,
@@ -80,7 +80,10 @@ sl_if_print(netdissect_options *ndo,
ip = (const struct ip *)(p + SLIP_HDRLEN);
if (ndo->ndo_eflag)
- sliplink_print(ndo, p, ip, length);
+ if (sliplink_print(ndo, p, ip, length) == -1) {
+ ND_PRINT((ndo, "%s", tstr));
+ return (caplen + SLIP_HDRLEN);
+ }
if (caplen < 1 || length < 1) {
ND_PRINT((ndo, "%s", tstr));
@@ -128,7 +131,7 @@ sl_bsdos_if_print(netdissect_options *ndo,
return (SLIP_HDRLEN);
}
-static void
+static int
sliplink_print(netdissect_options *ndo,
register const u_char *p, register const struct ip *ip,
register u_int length)
@@ -159,7 +162,7 @@ sliplink_print(netdissect_options *ndo,
for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i)
ND_PRINT((ndo, "%02x.", p[i]));
ND_PRINT((ndo, "%02x: ", p[SLX_CHDR + CHDR_LEN - 1]));
- return;
+ return 0;
}
switch (p[SLX_CHDR] & 0xf0) {
@@ -177,9 +180,11 @@ sliplink_print(netdissect_options *ndo,
ND_PRINT((ndo, "utcp %d: ", lastconn));
if (dir == -1) {
/* Direction is bogus, don't use it */
- return;
+ return 0;
}
+ ND_TCHECK(*ip);
hlen = IP_HL(ip);
+ ND_TCHECK(*((const struct tcphdr *)&((const int *)ip)[hlen]));
hlen += TH_OFF((const struct tcphdr *)&((const int *)ip)[hlen]);
lastlen[dir][lastconn] = length - (hlen << 2);
break;
@@ -187,15 +192,19 @@ sliplink_print(netdissect_options *ndo,
default:
if (dir == -1) {
/* Direction is bogus, don't use it */
- return;
+ return 0;
}
if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
- compressed_sl_print(ndo, &p[SLX_CHDR], ip,
- length, dir);
+ if (compressed_sl_print(ndo, &p[SLX_CHDR], ip,
+ length, dir) == -1)
+ goto trunc;
ND_PRINT((ndo, ": "));
} else
ND_PRINT((ndo, "slip-%d!: ", p[SLX_CHDR]));
}
+ return 0;
+trunc:
+ return -1;
}
static const u_char *
@@ -229,7 +238,7 @@ print_sl_winchange(netdissect_options *ndo,
return (cp);
}
-static void
+static int
compressed_sl_print(netdissect_options *ndo,
const u_char *chdr, const struct ip *ip,
u_int length, int dir)
@@ -275,10 +284,15 @@ compressed_sl_print(netdissect_options *ndo,
* 'cp - chdr' is the length of the compressed header.
* 'length - hlen' is the amount of data in the packet.
*/
+ ND_TCHECK(*ip);
hlen = IP_HL(ip);
+ ND_TCHECK(*((const struct tcphdr *)&((const int32_t *)ip)[hlen]));
hlen += TH_OFF((const struct tcphdr *)&((const int32_t *)ip)[hlen]);
lastlen[dir][lastconn] = length - (hlen << 2);
ND_PRINT((ndo, " %d (%ld)", lastlen[dir][lastconn], (long)(cp - chdr)));
+ return 0;
+trunc:
+ return -1;
}
#ifdef __rtems__
#include "rtems-bsd-tcpdump-print-sl-data.h"
diff --git a/freebsd/contrib/tcpdump/print-sll.c b/freebsd/contrib/tcpdump/print-sll.c
index 51eeb293..e30381db 100644
--- a/freebsd/contrib/tcpdump/print-sll.c
+++ b/freebsd/contrib/tcpdump/print-sll.c
@@ -204,6 +204,7 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
u_int caplen = h->caplen;
u_int length = h->len;
register const struct sll_header *sllp;
+ u_short hatype;
u_short ether_type;
int llc_hdrlen;
u_int hdrlen;
@@ -231,6 +232,16 @@ sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char
p += SLL_HDR_LEN;
hdrlen = SLL_HDR_LEN;
+ hatype = EXTRACT_16BITS(&sllp->sll_hatype);
+ switch (hatype) {
+
+ case 803:
+ /*
+ * This is an packet with a radiotap header;
+ * just dissect the payload as such.
+ */
+ return (SLL_HDR_LEN + ieee802_11_radio_print(ndo, p, length, caplen));
+ }
ether_type = EXTRACT_16BITS(&sllp->sll_protocol);
recurse:
diff --git a/freebsd/contrib/tcpdump/print-smb.c b/freebsd/contrib/tcpdump/print-smb.c
index 72a42b26..efd028c9 100644
--- a/freebsd/contrib/tcpdump/print-smb.c
+++ b/freebsd/contrib/tcpdump/print-smb.c
@@ -383,16 +383,21 @@ print_trans(netdissect_options *ndo,
ND_PRINT((ndo, "smb_bcc=%u\n", bcc));
if (bcc > 0) {
smb_fdata(ndo, data1 + 2, f2, maxbuf - (paramlen + datalen), unicodestr);
-
- if (strcmp((const char *)(data1 + 2), "\\MAILSLOT\\BROWSE") == 0) {
+#define MAILSLOT_BROWSE_STR "\\MAILSLOT\\BROWSE"
+ ND_TCHECK2(*(data1 + 2), strlen(MAILSLOT_BROWSE_STR) + 1);
+ if (strcmp((const char *)(data1 + 2), MAILSLOT_BROWSE_STR) == 0) {
print_browse(ndo, param, paramlen, data, datalen);
return;
}
+#undef MAILSLOT_BROWSE_STR
- if (strcmp((const char *)(data1 + 2), "\\PIPE\\LANMAN") == 0) {
+#define PIPE_LANMAN_STR "\\PIPE\\LANMAN"
+ ND_TCHECK2(*(data1 + 2), strlen(PIPE_LANMAN_STR) + 1);
+ if (strcmp((const char *)(data1 + 2), PIPE_LANMAN_STR) == 0) {
print_ipc(ndo, param, paramlen, data, datalen);
return;
}
+#undef PIPE_LANMAN_STR
if (paramlen)
smb_fdata(ndo, param, f3, min(param + paramlen, maxbuf), unicodestr);
@@ -952,7 +957,9 @@ nbt_tcp_print(netdissect_options *ndo,
if (caplen < 4)
goto trunc;
maxbuf = data + caplen;
+ ND_TCHECK_8BITS(data);
type = data[0];
+ ND_TCHECK_16BITS(data + 2);
nbt_len = EXTRACT_16BITS(data + 2);
length -= 4;
caplen -= 4;
diff --git a/freebsd/contrib/tcpdump/print-tcp.c b/freebsd/contrib/tcpdump/print-tcp.c
index a772db6a..2c62fb6a 100644
--- a/freebsd/contrib/tcpdump/print-tcp.c
+++ b/freebsd/contrib/tcpdump/print-tcp.c
@@ -273,11 +273,11 @@ tcp_print(netdissect_options *ndo,
if (rev) {
UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst);
UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src);
- tha.port = dport << 16 | sport;
+ tha.port = ((u_int)dport) << 16 | sport;
} else {
UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst);
UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src);
- tha.port = sport << 16 | dport;
+ tha.port = ((u_int)sport) << 16 | dport;
}
for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
@@ -324,11 +324,11 @@ tcp_print(netdissect_options *ndo,
if (rev) {
UNALIGNED_MEMCPY(&tha.src, &ip->ip_dst, sizeof ip->ip_dst);
UNALIGNED_MEMCPY(&tha.dst, &ip->ip_src, sizeof ip->ip_src);
- tha.port = dport << 16 | sport;
+ tha.port = ((u_int)dport) << 16 | sport;
} else {
UNALIGNED_MEMCPY(&tha.dst, &ip->ip_dst, sizeof ip->ip_dst);
UNALIGNED_MEMCPY(&tha.src, &ip->ip_src, sizeof ip->ip_src);
- tha.port = sport << 16 | dport;
+ tha.port = ((u_int)sport) << 16 | dport;
}
for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
@@ -720,6 +720,12 @@ tcp_print(netdissect_options *ndo,
rtsp_print(ndo, bp, length);
} else if (length > 2 &&
(IS_SRC_OR_DST_PORT(NAMESERVER_PORT))) {
+ /* domain_print() assumes it does not have to prepend a space before its
+ * own output to separate it from the output of the calling function. This
+ * works well with udp_print(), but requires a small prop here.
+ */
+ ND_PRINT((ndo, " "));
+
/*
* TCP DNS query has 2byte length at the head.
* XXX packet could be unaligned, it can go strange
diff --git a/freebsd/contrib/tcpdump/print-udp.c b/freebsd/contrib/tcpdump/print-udp.c
index d14a38de..fbb1bab2 100644
--- a/freebsd/contrib/tcpdump/print-udp.c
+++ b/freebsd/contrib/tcpdump/print-udp.c
@@ -427,7 +427,9 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length,
if (ndo->ndo_packettype) {
register const struct sunrpc_msg *rp;
+#ifndef __rtems__
enum sunrpc_msg_type direction;
+#endif /* __rtems__ */
switch (ndo->ndo_packettype) {
@@ -443,8 +445,8 @@ udp_print(netdissect_options *ndo, register const u_char *bp, u_int length,
case PT_RPC:
rp = (const struct sunrpc_msg *)(up + 1);
- direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
#ifndef __rtems__
+ direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
if (direction == SUNRPC_CALL)
sunrpcrequest_print(ndo, (const u_char *)rp, length,
(const u_char *)ip);
diff --git a/freebsd/contrib/tcpdump/print-vrrp.c b/freebsd/contrib/tcpdump/print-vrrp.c
index 4465415e..5dd28e58 100644
--- a/freebsd/contrib/tcpdump/print-vrrp.c
+++ b/freebsd/contrib/tcpdump/print-vrrp.c
@@ -148,17 +148,21 @@ vrrp_print(netdissect_options *ndo,
vec[0].ptr = bp;
vec[0].len = len;
- if (in_cksum(vec, 1))
+ if (in_cksum(vec, 1)) {
+ ND_TCHECK_16BITS(&bp[6]);
ND_PRINT((ndo, ", (bad vrrp cksum %x)",
EXTRACT_16BITS(&bp[6])));
+ }
}
if (version == 3 && ND_TTEST2(bp[0], len)) {
uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp,
len, len, IPPROTO_VRRP);
- if (cksum)
+ if (cksum) {
+ ND_TCHECK_16BITS(&bp[6]);
ND_PRINT((ndo, ", (bad vrrp cksum %x)",
EXTRACT_16BITS(&bp[6])));
+ }
}
ND_PRINT((ndo, ", addrs"));
diff --git a/freebsd/contrib/tcpdump/print-vtp.c b/freebsd/contrib/tcpdump/print-vtp.c
index 8f8d236b..ca38d32b 100644
--- a/freebsd/contrib/tcpdump/print-vtp.c
+++ b/freebsd/contrib/tcpdump/print-vtp.c
@@ -247,7 +247,7 @@ vtp_print (netdissect_options *ndo,
*/
tptr += 4;
- while (tptr < (pptr+length)) {
+ while ((unsigned)(tptr - pptr) < length) {
ND_TCHECK_8BITS(tptr);
len = *tptr;
diff --git a/freebsd/contrib/tcpdump/print-wb.c b/freebsd/contrib/tcpdump/print-wb.c
index aeab01c3..4256d33d 100644
--- a/freebsd/contrib/tcpdump/print-wb.c
+++ b/freebsd/contrib/tcpdump/print-wb.c
@@ -209,7 +209,7 @@ wb_id(netdissect_options *ndo,
len -= sizeof(*io) * nid;
io = (const struct id_off *)(id + 1);
cp = (const char *)(io + nid);
- if (ND_TTEST2(cp, len)) {
+ if (ND_TTEST2(*cp, len)) {
ND_PRINT((ndo, "\""));
fn_print(ndo, (const u_char *)cp, (const u_char *)cp + len);
ND_PRINT((ndo, "\""));
diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h
index bb4ed207..c5ab7dd8 100644
--- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h
+++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-namespace.h
@@ -65,6 +65,7 @@
#define ieee802_11_if_print _bsd_tcpdump_ieee802_11_if_print
#define ieee802_11_radio_avs_if_print _bsd_tcpdump_ieee802_11_radio_avs_if_print
#define ieee802_11_radio_if_print _bsd_tcpdump_ieee802_11_radio_if_print
+#define ieee802_11_radio_print _bsd_tcpdump_ieee802_11_radio_print
#define prism_if_print _bsd_tcpdump_prism_if_print
/* print-802_15_4.c */
#define ieee802_15_4_if_print _bsd_tcpdump_ieee802_15_4_if_print
@@ -138,7 +139,6 @@
#define dccp_print _bsd_tcpdump_dccp_print
/* print-decnet.c */
#define decnet_print _bsd_tcpdump_decnet_print
-#define dnname_string _bsd_tcpdump_dnname_string
#define dnnum_string _bsd_tcpdump_dnnum_string
/* print-dhcp6.c */
#define dhcp6_print _bsd_tcpdump_dhcp6_print
diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-dvmrp-data.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-dvmrp-data.h
index 1ea6e8ee..10124f59 100644
--- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-dvmrp-data.h
+++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-dvmrp-data.h
@@ -2,4 +2,3 @@
#include <rtems/linkersets.h>
#include "rtems-bsd-tcpdump-data.h"
/* print-dvmrp.c */
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static uint32_t target_level);
diff --git a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-pim-data.h b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-pim-data.h
index c19c1b5d..8d20800c 100644
--- a/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-pim-data.h
+++ b/freebsd/contrib/tcpdump/rtems-bsd-tcpdump-print-pim-data.h
@@ -2,4 +2,3 @@
#include <rtems/linkersets.h>
#include "rtems-bsd-tcpdump-data.h"
/* print-pim.c */
-RTEMS_LINKER_RWSET_CONTENT(bsd_prog_tcpdump, static int pimv2_addr_len);
diff --git a/freebsd/contrib/tcpdump/signature.c b/freebsd/contrib/tcpdump/signature.c
index 861f59cd..cc8936f9 100644
--- a/freebsd/contrib/tcpdump/signature.c
+++ b/freebsd/contrib/tcpdump/signature.c
@@ -136,7 +136,7 @@ signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen,
/*
* Do we have all the packet data to be checked?
*/
- if (!ND_TTEST2(pptr, plen)) {
+ if (!ND_TTEST2(*pptr, plen)) {
/* No. */
return (CANT_CHECK_SIGNATURE);
}
@@ -144,7 +144,7 @@ signature_verify(netdissect_options *ndo, const u_char *pptr, u_int plen,
/*
* Do we have the entire signature to check?
*/
- if (!ND_TTEST2(sig_ptr, sizeof(sig))) {
+ if (!ND_TTEST2(*sig_ptr, sizeof(sig))) {
/* No. */
return (CANT_CHECK_SIGNATURE);
}
diff --git a/freebsd/contrib/tcpdump/smbutil.c b/freebsd/contrib/tcpdump/smbutil.c
index 5ed188b6..31ee99c4 100644
--- a/freebsd/contrib/tcpdump/smbutil.c
+++ b/freebsd/contrib/tcpdump/smbutil.c
@@ -484,12 +484,13 @@ smb_fdata1(netdissect_options *ndo,
case 'P':
{
- int l = atoi(fmt + 1);
+ int l = atoi(fmt + 1);
+ if(l <= 0) goto trunc; /* actually error in fmt string */
ND_TCHECK2(buf[0], l);
buf += l;
fmt++;
while (isdigit((unsigned char)*fmt))
- fmt++;
+ fmt++;
break;
}
case 'r':
@@ -803,17 +804,33 @@ smb_fdata(netdissect_options *ndo,
int unicodestr)
{
static int depth = 0;
+ const u_char *buf_start = buf;
char s[128];
char *p;
while (*fmt) {
switch (*fmt) {
case '*':
+ /*
+ * List of multiple instances of something described by the
+ * remainder of the string (which may itself include a list
+ * of multiple instances of something, so we recurse).
+ */
fmt++;
while (buf < maxbuf) {
const u_char *buf2;
depth++;
- buf2 = smb_fdata(ndo, buf, fmt, maxbuf, unicodestr);
+ /*
+ * In order to avoid stack exhaustion recurse at most 10
+ * levels; that "should not happen", as no SMB structure
+ * should be nested *that* deeply, and we thus shouldn't
+ * have format strings with that level of nesting.
+ */
+ if (depth == 10) {
+ ND_PRINT((ndo, "(too many nested levels, not recursing)"));
+ buf2 = buf;
+ } else
+ buf2 = smb_fdata(ndo, buf, fmt, maxbuf, unicodestr);
depth--;
if (buf2 == NULL)
return(NULL);
@@ -824,22 +841,35 @@ smb_fdata(netdissect_options *ndo,
return(buf);
case '|':
+ /*
+ * Just do a bounds check.
+ */
fmt++;
if (buf >= maxbuf)
return(buf);
break;
case '%':
+ /*
+ * XXX - unused?
+ */
fmt++;
buf = maxbuf;
break;
case '#':
+ /*
+ * Done?
+ */
fmt++;
return(buf);
break;
case '[':
+ /*
+ * Format of an item, enclosed in square brackets; dissect
+ * the item with smb_fdata1().
+ */
fmt++;
if (buf >= maxbuf)
return(buf);
@@ -853,11 +883,15 @@ smb_fdata(netdissect_options *ndo,
s[p - fmt] = '\0';
fmt = p + 1;
buf = smb_fdata1(ndo, buf, s, maxbuf, unicodestr);
- if (buf == NULL)
+ if(buf < buf_start || buf == NULL) {
return(NULL);
+ }
break;
default:
+ /*
+ * Not a formatting character, so just print it.
+ */
ND_PRINT((ndo, "%c", *fmt));
fmt++;
break;
diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c
index 3b68ed51..b1e7f0d1 100644
--- a/freebsd/contrib/tcpdump/tcpdump.c
+++ b/freebsd/contrib/tcpdump/tcpdump.c
@@ -125,10 +125,6 @@ The Regents of the University of California. All rights reserved.\n";
#endif /* HAVE_CAP_NG_H */
#endif /* HAVE_LIBCAP_NG */
-#ifdef __FreeBSD__
-#include <sys/sysctl.h>
-#endif /* __FreeBSD__ */
-
#include "netdissect.h"
#include "interface.h"
#include "addrtoname.h"
@@ -652,11 +648,10 @@ droproot(const char *username, const char *chroot_dir)
#ifdef HAVE_LIBCAP_NG
{
int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG);
- if (ret < 0) {
- fprintf(stderr, "error : ret %d\n", ret);
- } else {
+ if (ret < 0)
+ error("capng_change_id(): return %d\n", ret);
+ else
fprintf(stderr, "dropped privs to %s\n", username);
- }
}
#else
#ifndef __rtems__
@@ -747,13 +742,15 @@ static char *
get_next_file(FILE *VFile, char *ptr)
{
char *ret;
+ size_t len;
ret = fgets(ptr, PATH_MAX, VFile);
if (!ret)
return NULL;
- if (ptr[strlen(ptr) - 1] == '\n')
- ptr[strlen(ptr) - 1] = '\0';
+ len = strlen (ptr);
+ if (len > 0 && ptr[len - 1] == '\n')
+ ptr[len - 1] = '\0';
return ret;
}
@@ -1099,6 +1096,10 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf)
if (status < 0)
error("%s: Can't set time stamp type: %s",
device, pcap_statustostr(status));
+ else if (status > 0)
+ warning("When trying to set timestamp type '%s' on %s: %s",
+ pcap_tstamp_type_val_to_name(jflag), device,
+ pcap_statustostr(status));
}
#endif
status = pcap_activate(pc);
@@ -1120,30 +1121,6 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf)
} else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0')
error("%s: %s\n(%s)", device,
pcap_statustostr(status), cp);
-#ifdef __FreeBSD__
- else if (status == PCAP_ERROR_RFMON_NOTSUP &&
- strncmp(device, "wlan", 4) == 0) {
- char parent[8], newdev[8];
- char sysctl[32];
- size_t s = sizeof(parent);
-
- snprintf(sysctl, sizeof(sysctl),
- "net.wlan.%d.%%parent", atoi(device + 4));
- sysctlbyname(sysctl, parent, &s, NULL, 0);
- strlcpy(newdev, device, sizeof(newdev));
- /* Suggest a new wlan device. */
- /* FIXME: incrementing the index this way is not going to work well
- * when the index is 9 or greater but the only consequence in this
- * specific case would be an error message that looks a bit odd.
- */
- newdev[strlen(newdev)-1]++;
- error("%s is not a monitor mode VAP\n"
- "To create a new monitor mode VAP use:\n"
- " ifconfig %s create wlandev %s wlanmode monitor\n"
- "and use %s as the tcpdump interface",
- device, newdev, parent, newdev);
- }
-#endif
else
error("%s: %s", device,
pcap_statustostr(status));
diff --git a/freebsd/contrib/tcpdump/util-print.c b/freebsd/contrib/tcpdump/util-print.c
index ef1454a1..49bcfe6c 100644
--- a/freebsd/contrib/tcpdump/util-print.c
+++ b/freebsd/contrib/tcpdump/util-print.c
@@ -126,10 +126,21 @@ fn_print(netdissect_options *ndo,
/*
* Print out a null-terminated filename (or other ascii string) from
- * a fixed-length buffer.
- * If ep is NULL, assume no truncation check is needed.
+ * a fixed-length field in the packet buffer, or from what remains of
+ * the packet.
+ *
+ * n is the length of the fixed-length field, or the number of bytes
+ * remaining in the packet based on its on-the-network length.
+ *
+ * If ep is non-null, it should point just past the last captured byte
+ * of the packet, e.g. ndo->ndo_snapend. If ep is NULL, we assume no
+ * truncation check, other than the checks of the field length/remaining
+ * packet data length, is needed.
+ *
* Return the number of bytes of string processed, including the
- * terminating null, if not truncated. Return 0 if truncated.
+ * terminating null, if not truncated; as the terminating null is
+ * included in the count, and as there must be a terminating null,
+ * this will always be non-zero. Return 0 if truncated.
*/
u_int
fn_printztn(netdissect_options *ndo,
@@ -143,7 +154,8 @@ fn_printztn(netdissect_options *ndo,
if (n == 0 || (ep != NULL && s >= ep)) {
/*
* Truncated. This includes "no null before we
- * got to the end of the fixed-length buffer".
+ * got to the end of the fixed-length buffer or
+ * the end of the packet".
*
* XXX - BOOTP says "null-terminated", which
* means the maximum length of the string, in
diff --git a/freebsd/lib/libc/net/nslexer.c b/freebsd/lib/libc/net/nslexer.c
index d3cc82ce..c278240a 100644
--- a/freebsd/lib/libc/net/nslexer.c
+++ b/freebsd/lib/libc/net/nslexer.c
@@ -765,7 +765,7 @@ YY_DECL
char *yy_cp, *yy_bp;
int yy_act;
-#line 61 "nslexer.l"
+#line 62 "nslexer.l"
#line 772 "nslexer.c"
@@ -827,16 +827,12 @@ yy_match:
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 69 );
+ while ( yy_current_state != 58 );
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
yy_find_action:
yy_act = yy_accept[yy_current_state];
- if ( yy_act == 0 )
- { /* have to back up */
- yy_cp = (yy_last_accepting_cpos);
- yy_current_state = (yy_last_accepting_state);
- yy_act = yy_accept[yy_current_state];
- }
YY_DO_BEFORE_ACTION;
@@ -863,59 +859,59 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
-#line 63 "nslexer.l"
+#line 64 "nslexer.l"
; /* skip whitespace */
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 65 "nslexer.l"
+#line 66 "nslexer.l"
; /* skip comments */
YY_BREAK
case 3:
/* rule 3 can match eol */
YY_RULE_SETUP
-#line 67 "nslexer.l"
+#line 68 "nslexer.l"
; /* allow continuation */
YY_BREAK
case 4:
/* rule 4 can match eol */
YY_RULE_SETUP
-#line 69 "nslexer.l"
+#line 70 "nslexer.l"
return NL;
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 71 "nslexer.l"
+#line 72 "nslexer.l"
return SUCCESS;
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 72 "nslexer.l"
+#line 73 "nslexer.l"
return UNAVAIL;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 73 "nslexer.l"
+#line 74 "nslexer.l"
return NOTFOUND;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 74 "nslexer.l"
+#line 75 "nslexer.l"
return TRYAGAIN;
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 76 "nslexer.l"
+#line 77 "nslexer.l"
return RETURN;
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 77 "nslexer.l"
+#line 78 "nslexer.l"
return CONTINUE;
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 79 "nslexer.l"
+#line 80 "nslexer.l"
{
char *p;
int i;
@@ -935,15 +931,15 @@ YY_RULE_SETUP
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 96 "nslexer.l"
+#line 97 "nslexer.l"
return _nsyytext[0];
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 98 "nslexer.l"
+#line 99 "nslexer.l"
ECHO;
YY_BREAK
-#line 947 "nslexer.c"
+#line 943 "nslexer.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1010,7 +1006,8 @@ case YY_STATE_EOF(INITIAL):
else
{
- yy_cp = (yy_c_buf_p);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
goto yy_find_action;
}
}
@@ -1484,7 +1481,7 @@ static void _nsyy_load_buffer_state (void)
b->yy_bs_column = 0;
}
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+ b->yy_is_interactive = 0;
errno = oerrno;
}
@@ -1908,7 +1905,7 @@ void _nsyyfree (void * ptr )
#define YYTABLES_NAME "yytables"
-#line 98 "nslexer.l"
+#line 99 "nslexer.l"
diff --git a/freebsd/lib/libc/net/nsparser.c b/freebsd/lib/libc/net/nsparser.c
index d574ad2a..2f74c0b0 100644
--- a/freebsd/lib/libc/net/nsparser.c
+++ b/freebsd/lib/libc/net/nsparser.c
@@ -5,7 +5,7 @@
#define YYBYACC 1
#define YYMAJOR 1
#define YYMINOR 9
-#define YYPATCH 20170201
+#define YYPATCH 20170430
#define YYEMPTY (-1)
#define yyclearin (yychar = YYEMPTY)
diff --git a/freebsd/lib/libc/resolv/res_findzonecut.c b/freebsd/lib/libc/resolv/res_findzonecut.c
index 8cf8c554..bd607f94 100644
--- a/freebsd/lib/libc/resolv/res_findzonecut.c
+++ b/freebsd/lib/libc/resolv/res_findzonecut.c
@@ -631,7 +631,7 @@ save_a(res_state statp, ns_msg *msg, ns_sect sect,
arr->addr.sin6.sin6_len = sizeof(arr->addr.sin6);
#endif
memcpy(&arr->addr.sin6.sin6_addr, ns_rr_rdata(rr), 16);
- arr->addr.sin.sin_port = htons(NAMESERVER_PORT);
+ arr->addr.sin6.sin6_port = htons(NAMESERVER_PORT);
nsrr->flags |= RR_NS_HAVE_V6;
break;
default:
diff --git a/freebsd/sbin/dhclient/bpf.c b/freebsd/sbin/dhclient/bpf.c
index e1bfacdc..55a8586f 100644
--- a/freebsd/sbin/dhclient/bpf.c
+++ b/freebsd/sbin/dhclient/bpf.c
@@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$");
#include <netinet/udp.h>
#include <netinet/if_ether.h>
+#include <capsicum_helpers.h>
+
#define BPF_FORMAT "/dev/bpf%d"
/*
@@ -166,7 +168,7 @@ if_register_send(struct interface_info *info)
error("Cannot lock bpf");
cap_rights_init(&rights, CAP_WRITE);
- if (cap_rights_limit(info->wfdesc, &rights) < 0 && errno != ENOSYS)
+ if (caph_rights_limit(info->wfdesc, &rights) < 0)
error("Can't limit bpf descriptor: %m");
/*
@@ -272,9 +274,9 @@ if_register_receive(struct interface_info *info)
error("Cannot lock bpf");
cap_rights_init(&rights, CAP_IOCTL, CAP_EVENT, CAP_READ);
- if (cap_rights_limit(info->rfdesc, &rights) < 0 && errno != ENOSYS)
+ if (caph_rights_limit(info->rfdesc, &rights) < 0)
error("Can't limit bpf descriptor: %m");
- if (cap_ioctls_limit(info->rfdesc, cmds, 2) < 0 && errno != ENOSYS)
+ if (caph_ioctls_limit(info->rfdesc, cmds, 2) < 0)
error("Can't limit ioctls for bpf descriptor: %m");
}
diff --git a/freebsd/sbin/dhclient/dhclient.c b/freebsd/sbin/dhclient/dhclient.c
index 0e654e9b..f088489a 100644
--- a/freebsd/sbin/dhclient/dhclient.c
+++ b/freebsd/sbin/dhclient/dhclient.c
@@ -514,7 +514,7 @@ main(int argc, char *argv[])
close(pipe_fd[0]);
privfd = pipe_fd[1];
cap_rights_init(&rights, CAP_READ, CAP_WRITE);
- if (cap_rights_limit(privfd, &rights) < 0 && errno != ENOSYS)
+ if (caph_rights_limit(privfd, &rights) < 0)
error("can't limit private descriptor: %m");
if ((fd = open(path_dhclient_db, O_RDONLY|O_EXLOCK|O_CREAT, 0)) == -1)
@@ -528,7 +528,7 @@ main(int argc, char *argv[])
if (shutdown(routefd, SHUT_WR) < 0)
error("can't shutdown route socket: %m");
cap_rights_init(&rights, CAP_EVENT, CAP_READ);
- if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS)
+ if (caph_rights_limit(routefd, &rights) < 0)
error("can't limit route socket: %m");
endpwent();
@@ -1776,7 +1776,7 @@ make_request(struct interface_info *ip, struct client_lease * lease)
}
/* set unique client identifier */
- char client_ident[sizeof(struct hardware)];
+ char client_ident[sizeof(ip->hw_address.haddr) + 1];
if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
ip->hw_address.hlen : sizeof(client_ident)-1;
@@ -1930,12 +1930,10 @@ rewrite_client_leases(void)
error("can't create %s: %m", path_dhclient_db);
cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_FSYNC,
CAP_FTRUNCATE, CAP_SEEK, CAP_WRITE);
- if (cap_rights_limit(fileno(leaseFile), &rights) < 0 &&
- errno != ENOSYS) {
+ if (caph_rights_limit(fileno(leaseFile), &rights) < 0) {
error("can't limit lease descriptor: %m");
}
- if (cap_fcntls_limit(fileno(leaseFile), CAP_FCNTL_GETFL) < 0 &&
- errno != ENOSYS) {
+ if (caph_fcntls_limit(fileno(leaseFile), CAP_FCNTL_GETFL) < 0) {
error("can't limit lease descriptor fcntls: %m");
}
} else {
@@ -2463,20 +2461,24 @@ go_daemon(void)
cap_rights_init(&rights);
- if (pidfile != NULL)
+ if (pidfile != NULL) {
pidfile_write(pidfile);
+ if (caph_rights_limit(pidfile_fileno(pidfile), &rights) < 0)
+ error("can't limit pidfile descriptor: %m");
+ }
+
if (nullfd != -1) {
close(nullfd);
nullfd = -1;
}
- if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS)
+ if (caph_rights_limit(STDIN_FILENO, &rights) < 0)
error("can't limit stdin: %m");
cap_rights_init(&rights, CAP_WRITE);
- if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
+ if (caph_rights_limit(STDOUT_FILENO, &rights) < 0)
error("can't limit stdout: %m");
- if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
+ if (caph_rights_limit(STDERR_FILENO, &rights) < 0)
error("can't limit stderr: %m");
}
diff --git a/freebsd/sbin/ifconfig/ifconfig.c b/freebsd/sbin/ifconfig/ifconfig.c
index 2ce85e27..2b54d6a3 100644
--- a/freebsd/sbin/ifconfig/ifconfig.c
+++ b/freebsd/sbin/ifconfig/ifconfig.c
@@ -155,8 +155,16 @@ static struct module_map_entry {
const char *kldname;
} module_map[] = {
{
+ .ifname = "tun",
+ .kldname = "if_tuntap",
+ },
+ {
+ .ifname = "tap",
+ .kldname = "if_tuntap",
+ },
+ {
.ifname = "vmnet",
- .kldname = "if_tap",
+ .kldname = "if_tuntap",
},
{
.ifname = "ipsec",
diff --git a/freebsd/sbin/ifconfig/iflagg.c b/freebsd/sbin/ifconfig/iflagg.c
index 4952196a..c328cf3b 100644
--- a/freebsd/sbin/ifconfig/iflagg.c
+++ b/freebsd/sbin/ifconfig/iflagg.c
@@ -126,10 +126,13 @@ setlaggrr_limit(const char *val, int d, int s, const struct afswtch *afp)
bzero(&ro, sizeof(ro));
strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
- ro.ro_bkt = (int)strtol(val, NULL, 10);
+ ro.ro_opts = LAGG_OPT_RR_LIMIT;
+ ro.ro_bkt = (uint32_t)strtoul(val, NULL, 10);
+ if (ro.ro_bkt == 0)
+ errx(1, "Invalid round-robin stride: %s", val);
if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
- err(1, "SIOCSLAGG");
+ err(1, "SIOCSLAGGOPTS");
}
static void
diff --git a/freebsd/sbin/ifconfig/ifmedia.c b/freebsd/sbin/ifconfig/ifmedia.c
index ac2af8b6..02893547 100644
--- a/freebsd/sbin/ifconfig/ifmedia.c
+++ b/freebsd/sbin/ifconfig/ifmedia.c
@@ -89,6 +89,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -137,18 +138,20 @@ static void
media_status(int s)
{
struct ifmediareq ifmr;
+ struct ifdownreason ifdr;
int *media_list, i;
- int xmedia = 1;
+ bool no_carrier, xmedia;
(void) memset(&ifmr, 0, sizeof(ifmr));
(void) strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+ xmedia = true;
/*
* Check if interface supports extended media types.
*/
if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0)
- xmedia = 0;
- if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+ xmedia = false;
+ if (!xmedia && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
/*
* Interface doesn't support SIOC{G,S}IFMEDIA.
*/
@@ -185,6 +188,7 @@ media_status(int s)
putchar('\n');
if (ifmr.ifm_status & IFM_AVALID) {
+ no_carrier = false;
printf("\tstatus: ");
switch (IFM_TYPE(ifmr.ifm_active)) {
case IFM_ETHER:
@@ -192,7 +196,7 @@ media_status(int s)
if (ifmr.ifm_status & IFM_ACTIVE)
printf("active");
else
- printf("no carrier");
+ no_carrier = true;
break;
case IFM_IEEE80211:
@@ -203,9 +207,27 @@ media_status(int s)
else
printf("running");
} else
- printf("no carrier");
+ no_carrier = true;
break;
}
+ if (no_carrier) {
+ printf("no carrier");
+ memset(&ifdr, 0, sizeof(ifdr));
+ strlcpy(ifdr.ifdr_name, name, sizeof(ifdr.ifdr_name));
+ if (ioctl(s, SIOCGIFDOWNREASON, (caddr_t)&ifdr) == 0) {
+ switch (ifdr.ifdr_reason) {
+ case IFDR_REASON_MSG:
+ printf(" (%s)", ifdr.ifdr_msg);
+ break;
+ case IFDR_REASON_VENDOR:
+ printf(" (vendor code %d)",
+ ifdr.ifdr_vendor);
+ break;
+ default:
+ break;
+ }
+ }
+ }
putchar('\n');
}
diff --git a/freebsd/sbin/ifconfig/sfp.c b/freebsd/sbin/ifconfig/sfp.c
index 0aa3300d..6444736f 100644
--- a/freebsd/sbin/ifconfig/sfp.c
+++ b/freebsd/sbin/ifconfig/sfp.c
@@ -88,7 +88,7 @@ struct _nv {
const char *find_value(struct _nv *x, int value);
const char *find_zero_bit(struct _nv *x, int value, int sz);
-/* SFF-8024 Rev. 4.1 Table 4-3: Connector Types */
+/* SFF-8024 Rev. 4.6 Table 4-3: Connector Types */
static struct _nv conn[] = {
{ 0x00, "Unknown" },
{ 0x01, "SC" },
@@ -96,18 +96,23 @@ static struct _nv conn[] = {
{ 0x03, "Fibre Channel Style 2 copper" },
{ 0x04, "BNC/TNC" },
{ 0x05, "Fibre Channel coaxial" },
- { 0x06, "FiberJack" },
+ { 0x06, "Fiber Jack" },
{ 0x07, "LC" },
{ 0x08, "MT-RJ" },
{ 0x09, "MU" },
{ 0x0A, "SG" },
{ 0x0B, "Optical pigtail" },
- { 0x0C, "MPO Parallel Optic" },
+ { 0x0C, "MPO 1x12 Parallel Optic" },
+ { 0x0D, "MPO 2x16 Parallel Optic" },
{ 0x20, "HSSDC II" },
{ 0x21, "Copper pigtail" },
{ 0x22, "RJ45" },
{ 0x23, "No separable connector" },
{ 0x24, "MXC 2x16" },
+ { 0x25, "CS optical connector" },
+ { 0x26, "Mini CS optical connector" },
+ { 0x27, "MPO 2x12 Parallel Optic" },
+ { 0x28, "MPO 1x16 Parallel Optic" },
{ 0, NULL }
};
@@ -203,9 +208,61 @@ static struct _nv eth_1040g[] = {
};
#define SFF_8636_EXT_COMPLIANCE 0x80
-/* SFF-8024 Rev. 4.2 table 4-4: Extended Specification Compliance */
+/* SFF-8024 Rev. 4.6 table 4-4: Extended Specification Compliance */
static struct _nv eth_extended_comp[] = {
{ 0xFF, "Reserved" },
+ { 0x55, "128GFC LW" },
+ { 0x54, "128GFC SW" },
+ { 0x53, "128GFC EA" },
+ { 0x52, "64GFC LW" },
+ { 0x51, "64GFC SW" },
+ { 0x50, "64GFC EA" },
+ { 0x4F, "Reserved" },
+ { 0x4E, "Reserved" },
+ { 0x4D, "Reserved" },
+ { 0x4C, "Reserved" },
+ { 0x4B, "Reserved" },
+ { 0x4A, "Reserved" },
+ { 0x49, "Reserved" },
+ { 0x48, "Reserved" },
+ { 0x47, "Reserved" },
+ { 0x46, "200GBASE-LR4" },
+ { 0x45, "50GBASE-LR" },
+ { 0x44, "200G 1550nm PSM4" },
+ { 0x43, "200GBASE-FR4" },
+ { 0x42, "50GBASE-FR or 200GBASE-DR4" },
+ { 0x41, "50GBASE-SR/100GBASE-SR2/200GBASE-SR4" },
+ { 0x40, "50GBASE-CR/100GBASE-CR2/200GBASE-CR4" },
+ { 0x3F, "Reserved" },
+ { 0x3E, "Reserved" },
+ { 0x3D, "Reserved" },
+ { 0x3C, "Reserved" },
+ { 0x3B, "Reserved" },
+ { 0x3A, "Reserved" },
+ { 0x39, "Reserved" },
+ { 0x38, "Reserved" },
+ { 0x37, "Reserved" },
+ { 0x36, "Reserved" },
+ { 0x35, "Reserved" },
+ { 0x34, "Reserved" },
+ { 0x33, "50GAUI/100GAUI-2/200GAUI-4 AOC (BER <2.6e-4)" },
+ { 0x32, "50GAUI/100GAUI-2/200GAUI-4 ACC (BER <2.6e-4)" },
+ { 0x31, "50GAUI/100GAUI-2/200GAUI-4 AOC (BER <1e-6)" },
+ { 0x30, "50GAUI/100GAUI-2/200GAUI-4 ACC (BER <1e-6)" },
+ { 0x2F, "Reserved" },
+ { 0x2E, "Reserved" },
+ { 0x2D, "Reserved" },
+ { 0x2C, "Reserved" },
+ { 0x2B, "Reserved" },
+ { 0x2A, "Reserved" },
+ { 0x29, "Reserved" },
+ { 0x28, "Reserved" },
+ { 0x27, "100G-LR" },
+ { 0x26, "100G-FR" },
+ { 0x25, "100GBASE-DR" },
+ { 0x24, "4WDM-40 MSA" },
+ { 0x23, "4WDM-20 MSA" },
+ { 0x22, "4WDM-10 MSA" },
{ 0x21, "100G PAM4 BiDi" },
{ 0x20, "100G SWDM4" },
{ 0x1F, "40G SWDM4" },
@@ -226,8 +283,8 @@ static struct _nv eth_extended_comp[] = {
{ 0x10, "40GBASE-ER4" },
{ 0x0F, "Reserved" },
{ 0x0E, "Reserved" },
- { 0x0D, "25GBASE-CR CA-N" },
- { 0x0C, "25GBASE-CR CA-S" },
+ { 0x0D, "25GBASE-CR CA-25G-N" },
+ { 0x0C, "25GBASE-CR CA-25G-S" },
{ 0x0B, "100GBASE-CR4 or 25GBASE-CR CA-L" },
{ 0x0A, "Reserved" },
{ 0x09, "Obsolete" },
diff --git a/freebsd/sbin/nvmecontrol/comnd.c b/freebsd/sbin/nvmecontrol/comnd.c
index a4fa686f..06af943d 100644
--- a/freebsd/sbin/nvmecontrol/comnd.c
+++ b/freebsd/sbin/nvmecontrol/comnd.c
@@ -207,7 +207,7 @@ arg_parse(int argc, char * const * argv, const struct cmd *f)
if (lopts == NULL)
err(1, "option memory");
#ifndef __rtems__
- p = shortopts = malloc((2 * n + 2) * sizeof(char));
+ p = shortopts = malloc((n + 3) * sizeof(char));
#else /* __rtems__ */
p = shortopts = malloc((2 * n + 3) * sizeof(char));
#endif /* __rtems__ */
diff --git a/freebsd/sbin/nvmecontrol/identify.c b/freebsd/sbin/nvmecontrol/identify.c
index e494fb59..452494ef 100644
--- a/freebsd/sbin/nvmecontrol/identify.c
+++ b/freebsd/sbin/nvmecontrol/identify.c
@@ -67,6 +67,7 @@ static struct options {
void
print_namespace(struct nvme_namespace_data *nsdata)
{
+ char cbuf[UINT128_DIG + 1];
uint32_t i;
uint32_t lbaf, lbads, ms, rp;
uint8_t thin_prov, ptype;
@@ -78,15 +79,12 @@ print_namespace(struct nvme_namespace_data *nsdata)
flbas_fmt = (nsdata->flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT) &
NVME_NS_DATA_FLBAS_FORMAT_MASK;
- printf("Size (in LBAs): %lld (%lldM)\n",
- (long long)nsdata->nsze,
- (long long)nsdata->nsze / 1024 / 1024);
- printf("Capacity (in LBAs): %lld (%lldM)\n",
- (long long)nsdata->ncap,
- (long long)nsdata->ncap / 1024 / 1024);
- printf("Utilization (in LBAs): %lld (%lldM)\n",
- (long long)nsdata->nuse,
- (long long)nsdata->nuse / 1024 / 1024);
+ printf("Size: %lld blocks\n",
+ (long long)nsdata->nsze);
+ printf("Capacity: %lld blocks\n",
+ (long long)nsdata->ncap);
+ printf("Utilization: %lld blocks\n",
+ (long long)nsdata->nuse);
printf("Thin Provisioning: %s\n",
thin_prov ? "Supported" : "Not Supported");
printf("Number of LBA Formats: %d\n", nsdata->nlbaf+1);
@@ -153,7 +151,22 @@ print_namespace(struct nvme_namespace_data *nsdata)
NVME_NS_DATA_DLFEAT_DWZ_MASK ? ", Write Zero" : "",
(nsdata->dlfeat >> NVME_NS_DATA_DLFEAT_GCRC_SHIFT) &
NVME_NS_DATA_DLFEAT_GCRC_MASK ? ", Guard CRC" : "");
- printf("Optimal I/O Boundary (LBAs): %u\n", nsdata->noiob);
+ printf("Optimal I/O Boundary: %u blocks\n", nsdata->noiob);
+ printf("NVM Capacity: %s bytes\n",
+ uint128_to_str(to128(nsdata->nvmcap), cbuf, sizeof(cbuf)));
+ if ((nsdata->nsfeat >> NVME_NS_DATA_NSFEAT_NPVALID_SHIFT) &
+ NVME_NS_DATA_NSFEAT_NPVALID_MASK) {
+ printf("Preferred Write Granularity: %u blocks",
+ nsdata->npwg + 1);
+ printf("Preferred Write Alignment: %u blocks",
+ nsdata->npwa + 1);
+ printf("Preferred Deallocate Granul: %u blocks",
+ nsdata->npdg + 1);
+ printf("Preferred Deallocate Align: %u blocks",
+ nsdata->npda + 1);
+ printf("Optimal Write Size: %u blocks",
+ nsdata->nows + 1);
+ }
printf("Globally Unique Identifier: ");
for (i = 0; i < sizeof(nsdata->nguid); i++)
printf("%02x", nsdata->nguid[i]);
diff --git a/freebsd/sbin/nvmecontrol/identify_ext.c b/freebsd/sbin/nvmecontrol/identify_ext.c
index 44e0011b..bb0a0d51 100644
--- a/freebsd/sbin/nvmecontrol/identify_ext.c
+++ b/freebsd/sbin/nvmecontrol/identify_ext.c
@@ -126,7 +126,7 @@ nvme_print_controller(struct nvme_controller_data *cdata)
if (cdata->mdts == 0)
printf("Unlimited\n");
else
- printf("%ld\n", PAGE_SIZE * (1L << cdata->mdts));
+ printf("%ld bytes\n", PAGE_SIZE * (1L << cdata->mdts));
printf("Controller ID: 0x%04x\n", cdata->ctrlr_id);
printf("Version: %d.%d.%d\n",
(cdata->ver >> 16) & 0xffff, (cdata->ver >> 8) & 0xff,
@@ -189,6 +189,18 @@ nvme_print_controller(struct nvme_controller_data *cdata)
ns_smart ? "Yes" : "No");
printf("Error Log Page Entries: %d\n", cdata->elpe+1);
printf("Number of Power States: %d\n", cdata->npss+1);
+ if (cdata->ver >= 0x010200) {
+ printf("Total NVM Capacity: %s bytes\n",
+ uint128_to_str(to128(cdata->untncap.tnvmcap),
+ cbuf, sizeof(cbuf)));
+ printf("Unallocated NVM Capacity: %s bytes\n",
+ uint128_to_str(to128(cdata->untncap.unvmcap),
+ cbuf, sizeof(cbuf)));
+ }
+ printf("Host Buffer Preferred Size: %llu bytes\n",
+ (long long unsigned)cdata->hmpre * 4096);
+ printf("Host Buffer Minimum Size: %llu bytes\n",
+ (long long unsigned)cdata->hmmin * 4096);
printf("\n");
printf("NVM Command Set Attributes\n");
@@ -240,13 +252,6 @@ nvme_print_controller(struct nvme_controller_data *cdata)
(t == NVME_CTRLR_DATA_VWC_ALL_NO) ? ", no flush all" :
(t == NVME_CTRLR_DATA_VWC_ALL_YES) ? ", flush all" : "");
- if (nsmgmt) {
- printf("\n");
- printf("Namespace Drive Attributes\n");
- printf("==========================\n");
- printf("NVM total cap: %s\n",
- uint128_to_str(to128(cdata->untncap.tnvmcap), cbuf, sizeof(cbuf)));
- printf("NVM unallocated cap: %s\n",
- uint128_to_str(to128(cdata->untncap.unvmcap), cbuf, sizeof(cbuf)));
- }
+ if (cdata->ver >= 0x010201)
+ printf("\nNVM Subsystem Name: %.256s\n", cdata->subnqn);
}
diff --git a/freebsd/sbin/nvmecontrol/logpage.c b/freebsd/sbin/nvmecontrol/logpage.c
index 8ab50bea..6765efdd 100644
--- a/freebsd/sbin/nvmecontrol/logpage.c
+++ b/freebsd/sbin/nvmecontrol/logpage.c
@@ -1,3 +1,5 @@
+#include <machine/rtems-bsd-user-space.h>
+
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
diff --git a/freebsd/sbin/nvmecontrol/modules/wdc/wdc.c b/freebsd/sbin/nvmecontrol/modules/wdc/wdc.c
index 3cd5cdb7..81546676 100644
--- a/freebsd/sbin/nvmecontrol/modules/wdc/wdc.c
+++ b/freebsd/sbin/nvmecontrol/modules/wdc/wdc.c
@@ -1,8 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
/*-
- * Copyright (c) 2017 Netflix, Inc
- * All rights reserved.
+ * Copyright (c) 2017 Netflix, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/freebsd/sbin/nvmecontrol/nc_util.c b/freebsd/sbin/nvmecontrol/nc_util.c
index f2818871..3a349c6d 100644
--- a/freebsd/sbin/nvmecontrol/nc_util.c
+++ b/freebsd/sbin/nvmecontrol/nc_util.c
@@ -1,8 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
/*-
- * Copyright (c) 2017 Netflix, Inc
- * All rights reserved.
+ * Copyright (c) 2017 Netflix, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/freebsd/sbin/nvmecontrol/ns.c b/freebsd/sbin/nvmecontrol/ns.c
index 841c1a87..f01d3213 100644
--- a/freebsd/sbin/nvmecontrol/ns.c
+++ b/freebsd/sbin/nvmecontrol/ns.c
@@ -3,7 +3,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2017 Netflix, Inc
+ * Copyright (c) 2017 Netflix, Inc.
* Copyright (C) 2018-2019 Alexander Motin <mav@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
diff --git a/freebsd/sbin/nvmecontrol/nvmecontrol_ext.h b/freebsd/sbin/nvmecontrol/nvmecontrol_ext.h
index 43042dfa..d60fcd4d 100644
--- a/freebsd/sbin/nvmecontrol/nvmecontrol_ext.h
+++ b/freebsd/sbin/nvmecontrol/nvmecontrol_ext.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (C) 2018 Netflix
+ * Copyright (C) 2018 Netflix, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/freebsd/sbin/nvmecontrol/power.c b/freebsd/sbin/nvmecontrol/power.c
index 9f6eeda4..2194d9f6 100644
--- a/freebsd/sbin/nvmecontrol/power.c
+++ b/freebsd/sbin/nvmecontrol/power.c
@@ -1,8 +1,7 @@
#include <machine/rtems-bsd-user-space.h>
/*-
- * Copyright (c) 2016 Netflix, Inc
- * All rights reserved.
+ * Copyright (c) 2016 Netflix, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/freebsd/sbin/pfctl/parse.c b/freebsd/sbin/pfctl/parse.c
index 83002a82..daf408de 100644
--- a/freebsd/sbin/pfctl/parse.c
+++ b/freebsd/sbin/pfctl/parse.c
@@ -5,7 +5,7 @@
#define YYBYACC 1
#define YYMAJOR 1
#define YYMINOR 9
-#define YYPATCH 20170201
+#define YYPATCH 20170430
#define YYEMPTY (-1)
#define yyclearin (yychar = YYEMPTY)
@@ -2765,6 +2765,8 @@ process_tabledef(char *name, struct table_opts *opts)
{
struct pfr_buffer ab;
struct node_tinit *ti;
+ unsigned long maxcount;
+ size_t s = sizeof(maxcount);
bzero(&ab, sizeof(ab));
ab.pfrb_type = PFRB_ADDRS;
@@ -2792,8 +2794,19 @@ process_tabledef(char *name, struct table_opts *opts)
if (!(pf->opts & PF_OPT_NOACTION) &&
pfctl_define_table(name, opts->flags, opts->init_addr,
pf->anchor->name, &ab, pf->anchor->ruleset.tticket)) {
- yyerror("cannot define table %s: %s", name,
- pfr_strerror(errno));
+
+ if (sysctlbyname("net.pf.request_maxcount", &maxcount, &s,
+ NULL, 0) == -1)
+ maxcount = 65535;
+
+ if (ab.pfrb_size > maxcount)
+ yyerror("cannot define table %s: too many elements.\n"
+ "Consider increasing net.pf.request_maxcount.",
+ name);
+ else
+ yyerror("cannot define table %s: %s", name,
+ pfr_strerror(errno));
+
goto _error;
}
pf->tdirty = 1;
@@ -3795,8 +3808,10 @@ top:
return (0);
if (next == quotec || c == ' ' || c == '\t')
c = next;
- else if (next == '\n')
+ else if (next == '\n') {
+ file->lineno++;
continue;
+ }
else
lungetc(next);
} else if (c == quotec) {
@@ -4382,7 +4397,7 @@ rt_tableid_max(void)
return (RT_TABLEID_MAX);
#endif
}
-#line 4388 "parse.c"
+#line 4401 "parse.c"
#if YYDEBUG
#include <stdio.h> /* needed for printf */
@@ -9167,7 +9182,7 @@ case 420:
yyval.v.host = calloc(1, sizeof(struct node_host));
if (yyval.v.host == NULL)
err(1, "route_host: calloc");
- yyval.v.host->ifname = yystack.l_mark[0].v.string;
+ yyval.v.host->ifname = strdup(yystack.l_mark[0].v.string);
set_ipmask(yyval.v.host, 128);
yyval.v.host->next = NULL;
yyval.v.host->tail = yyval.v.host;
@@ -9180,7 +9195,7 @@ case 421:
yyval.v.host = yystack.l_mark[-1].v.host;
for (n = yystack.l_mark[-1].v.host; n != NULL; n = n->next)
- n->ifname = yystack.l_mark[-2].v.string;
+ n->ifname = strdup(yystack.l_mark[-2].v.string);
}
break;
case 422:
@@ -9350,7 +9365,7 @@ case 447:
#line 4575 "parse.y"
{ yyval.v.i = PF_OP_GT; }
break;
-#line 9356 "parse.c"
+#line 9369 "parse.c"
}
yystack.s_mark -= yym;
yystate = *yystack.s_mark;
diff --git a/freebsd/sbin/ping6/ping6.c b/freebsd/sbin/ping6/ping6.c
index 122f6d0e..db3ab05a 100644
--- a/freebsd/sbin/ping6/ping6.c
+++ b/freebsd/sbin/ping6/ping6.c
@@ -1089,8 +1089,8 @@ main(int argc, char *argv[])
err(1, "caph_enter_casper");
cap_rights_init(&rights_stdin);
- if (cap_rights_limit(STDIN_FILENO, &rights_stdin) < 0)
- err(1, "cap_rights_limit stdin");
+ if (caph_rights_limit(STDIN_FILENO, &rights_stdin) < 0)
+ err(1, "caph_rights_limit stdin");
if (caph_limit_stdout() < 0)
err(1, "caph_limit_stdout");
if (caph_limit_stderr() < 0)
@@ -1098,10 +1098,10 @@ main(int argc, char *argv[])
cap_rights_init(&rights_srecv, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT);
if (caph_rights_limit(srecv, &rights_srecv) < 0)
- err(1, "cap_rights_limit srecv");
+ err(1, "caph_rights_limit srecv");
cap_rights_init(&rights_ssend, CAP_SEND, CAP_SETSOCKOPT);
if (caph_rights_limit(ssend, &rights_ssend) < 0)
- err(1, "cap_rights_limit ssend");
+ err(1, "caph_rights_limit ssend");
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
if (sockbufsize) {
@@ -1153,10 +1153,10 @@ main(int argc, char *argv[])
cap_rights_clear(&rights_srecv, CAP_SETSOCKOPT);
if (caph_rights_limit(srecv, &rights_srecv) < 0)
- err(1, "cap_rights_limit srecv setsockopt");
+ err(1, "caph_rights_limit srecv setsockopt");
cap_rights_clear(&rights_ssend, CAP_SETSOCKOPT);
if (caph_rights_limit(ssend, &rights_ssend) < 0)
- err(1, "cap_rights_limit ssend setsockopt");
+ err(1, "caph_rights_limit ssend setsockopt");
printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()),
(unsigned long)(pingerlen() - 8));
diff --git a/freebsd/sys/arm/freescale/imx/imx_gpio.c b/freebsd/sys/arm/freescale/imx/imx_gpio.c
index 983e4d74..f5b476d7 100644
--- a/freebsd/sys/arm/freescale/imx/imx_gpio.c
+++ b/freebsd/sys/arm/freescale/imx/imx_gpio.c
@@ -870,6 +870,15 @@ imx51_gpio_detach(device_t dev)
return(0);
}
+static phandle_t
+imx51_gpio_get_node(device_t bus, device_t dev)
+{
+ /*
+ * Share controller node with gpiobus device
+ */
+ return ofw_bus_get_node(bus);
+}
+
static device_method_t imx51_gpio_methods[] = {
DEVMETHOD(device_probe, imx51_gpio_probe),
DEVMETHOD(device_attach, imx51_gpio_attach),
@@ -887,6 +896,9 @@ static device_method_t imx51_gpio_methods[] = {
DEVMETHOD(pic_pre_ithread, gpio_pic_pre_ithread),
#endif
+ /* OFW methods */
+ DEVMETHOD(ofw_bus_get_node, imx51_gpio_get_node),
+
/* GPIO protocol */
DEVMETHOD(gpio_get_bus, imx51_gpio_get_bus),
DEVMETHOD(gpio_pin_max, imx51_gpio_pin_max),
diff --git a/freebsd/sys/arm/ti/ti_sdhci.c b/freebsd/sys/arm/ti/ti_sdhci.c
index a2be1f19..e3502099 100644
--- a/freebsd/sys/arm/ti/ti_sdhci.c
+++ b/freebsd/sys/arm/ti/ti_sdhci.c
@@ -483,15 +483,16 @@ ti_sdhci_hw_init(device_t dev)
/*
* The attach() routine has examined fdt data and set flags in
* slot.host.caps to reflect what voltages we can handle. Set those
- * values in the CAPA register. The manual says that these values can
- * only be set once, and that they survive a reset so unless u-boot didn't
- * set this register this code is a no-op.
+ * values in the CAPA register. Empirical testing shows that the
+ * values in this register can be overwritten at any time, but the
+ * manual says that these values should only be set once, "before
+ * initialization" whatever that means, and that they survive a reset.
*/
regval = ti_mmchs_read_4(sc, MMCHS_SD_CAPA);
if (sc->slot.host.caps & MMC_OCR_LOW_VOLTAGE)
regval |= MMCHS_SD_CAPA_VS18;
- if (sc->slot.host.caps & (MMC_OCR_320_330 | MMC_OCR_330_340))
- regval |= MMCHS_SD_CAPA_VS33;
+ if (sc->slot.host.caps & (MMC_OCR_290_300 | MMC_OCR_300_310))
+ regval |= MMCHS_SD_CAPA_VS30;
ti_mmchs_write_4(sc, MMCHS_SD_CAPA, regval);
/* Set initial host configuration (1-bit, std speed, pwr off). */
@@ -525,20 +526,16 @@ ti_sdhci_attach(device_t dev)
}
/*
- * The hardware can inherently do dual-voltage (1p8v, 3p3v) on the first
+ * The hardware can inherently do dual-voltage (1p8v, 3p0v) on the first
* device, and only 1p8v on other devices unless an external transceiver
* is used. The only way we could know about a transceiver is fdt data.
* Note that we have to do this before calling ti_sdhci_hw_init() so
- * that it can set the right values in the CAPA register, which can only
- * be done once and never reset.
+ * that it can set the right values in the CAPA register.
*/
- if (OF_hasprop(node, "ti,dual-volt")) {
- sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340;
- } else if (OF_hasprop(node, "no-1-8-v")) {
- sc->slot.host.caps |= MMC_OCR_320_330 | MMC_OCR_330_340;
- } else
- sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE;
-
+ sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE;
+ if (sc->mmchs_clk_id == MMC1_CLK || OF_hasprop(node, "ti,dual-volt")) {
+ sc->slot.host.caps |= MMC_OCR_290_300 | MMC_OCR_300_310;
+ }
/*
* Set the offset from the device's memory start to the MMCHS registers.
diff --git a/freebsd/sys/cam/cam_periph.h b/freebsd/sys/cam/cam_periph.h
index b087b872..d5dcfed0 100644
--- a/freebsd/sys/cam/cam_periph.h
+++ b/freebsd/sys/cam/cam_periph.h
@@ -132,6 +132,8 @@ struct cam_periph {
#define CAM_PERIPH_RUN_TASK 0x40
#define CAM_PERIPH_FREE 0x80
#define CAM_PERIPH_ANNOUNCED 0x100
+#define CAM_PERIPH_RECOVERY_WAIT 0x200
+#define CAM_PERIPH_RECOVERY_WAIT_FAILED 0x400
uint32_t scheduled_priority;
uint32_t immediate_priority;
int periph_allocating;
diff --git a/freebsd/sys/cam/scsi/scsi_all.c b/freebsd/sys/cam/scsi/scsi_all.c
index 99d82fee..b547fbbd 100644
--- a/freebsd/sys/cam/scsi/scsi_all.c
+++ b/freebsd/sys/cam/scsi/scsi_all.c
@@ -1115,7 +1115,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x04, 0x08, SS_FATAL | EBUSY,
"Logical unit not ready, long write in progress") },
/* DTLPWROMAEBKVF */
- { SST(0x04, 0x09, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x09, SS_FATAL | EBUSY,
"Logical unit not ready, self-test in progress") },
/* DTLPWROMAEBKVF */
{ SST(0x04, 0x0A, SS_WAIT | ENXIO,
@@ -1133,37 +1133,37 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x04, 0x0E, SS_RDEF, /* XXX TBD */
"Logical unit not ready, security session in progress") },
/* DT WROM B */
- { SST(0x04, 0x10, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x10, SS_FATAL | ENODEV,
"Logical unit not ready, auxiliary memory not accessible") },
/* DT WRO AEB VF */
- { SST(0x04, 0x11, SS_WAIT | EBUSY,
+ { SST(0x04, 0x11, SS_WAIT | ENXIO,
"Logical unit not ready, notify (enable spinup) required") },
/* M V */
- { SST(0x04, 0x12, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x12, SS_FATAL | ENXIO,
"Logical unit not ready, offline") },
/* DT R MAEBKV */
- { SST(0x04, 0x13, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x13, SS_WAIT | EBUSY,
"Logical unit not ready, SA creation in progress") },
/* D B */
- { SST(0x04, 0x14, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x14, SS_WAIT | ENOSPC,
"Logical unit not ready, space allocation in progress") },
/* M */
- { SST(0x04, 0x15, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x15, SS_FATAL | ENXIO,
"Logical unit not ready, robotics disabled") },
/* M */
- { SST(0x04, 0x16, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x16, SS_FATAL | ENXIO,
"Logical unit not ready, configuration required") },
/* M */
- { SST(0x04, 0x17, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x17, SS_FATAL | ENXIO,
"Logical unit not ready, calibration required") },
/* M */
- { SST(0x04, 0x18, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x18, SS_FATAL | ENXIO,
"Logical unit not ready, a door is open") },
/* M */
- { SST(0x04, 0x19, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x19, SS_FATAL | ENODEV,
"Logical unit not ready, operating in sequential mode") },
/* DT B */
- { SST(0x04, 0x1A, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x1A, SS_WAIT | EBUSY,
"Logical unit not ready, START/STOP UNIT command in progress") },
/* D B */
{ SST(0x04, 0x1B, SS_WAIT | EBUSY,
@@ -1172,7 +1172,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x04, 0x1C, SS_START | SSQ_DECREMENT_COUNT | ENXIO,
"Logical unit not ready, additional power use not yet granted") },
/* D */
- { SST(0x04, 0x1D, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x1D, SS_WAIT | EBUSY,
"Logical unit not ready, configuration in progress") },
/* D */
{ SST(0x04, 0x1E, SS_FATAL | ENXIO,
@@ -1181,14 +1181,20 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x04, 0x1F, SS_FATAL | ENXIO,
"Logical unit not ready, microcode download required") },
/* DTLPWROMAEBKVF */
- { SST(0x04, 0x20, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x20, SS_FATAL | ENXIO,
"Logical unit not ready, logical unit reset required") },
/* DTLPWROMAEBKVF */
- { SST(0x04, 0x21, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x21, SS_FATAL | ENXIO,
"Logical unit not ready, hard reset required") },
/* DTLPWROMAEBKVF */
- { SST(0x04, 0x22, SS_RDEF, /* XXX TBD */
+ { SST(0x04, 0x22, SS_FATAL | ENXIO,
"Logical unit not ready, power cycle required") },
+ /* D */
+ { SST(0x04, 0x23, SS_FATAL | ENXIO,
+ "Logical unit not ready, affiliation required") },
+ /* D */
+ { SST(0x04, 0x24, SS_FATAL | EBUSY,
+ "Depopulation in progress") },
/* DTL WROMAEBKVF */
{ SST(0x05, 0x00, SS_RDEF,
"Logical unit does not respond to selection") },
@@ -3387,7 +3393,7 @@ scsi_error_action(struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data,
if (!scsi_extract_sense_ccb((union ccb *)csio,
&error_code, &sense_key, &asc, &ascq)) {
- action = SS_RETRY | SSQ_DECREMENT_COUNT | SSQ_PRINT_SENSE | EIO;
+ action = SS_RDEF;
} else if ((error_code == SSD_DEFERRED_ERROR)
|| (error_code == SSD_DESC_DEFERRED_ERROR)) {
/*
diff --git a/freebsd/sys/dev/dwc/if_dwc.c b/freebsd/sys/dev/dwc/if_dwc.c
index 895fdfe5..7e249414 100644
--- a/freebsd/sys/dev/dwc/if_dwc.c
+++ b/freebsd/sys/dev/dwc/if_dwc.c
@@ -1239,16 +1239,13 @@ dwc_reset(device_t dev)
if (OF_hasprop(node, "snps,reset-active-low"))
pin_value = GPIO_PIN_HIGH;
- if (flags & GPIO_ACTIVE_LOW)
- pin_value = !pin_value;
-
GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT);
GPIO_PIN_SET(gpio, pin, pin_value);
- DELAY(delay_prop[0]);
+ DELAY(delay_prop[0] * 5);
GPIO_PIN_SET(gpio, pin, !pin_value);
- DELAY(delay_prop[1]);
+ DELAY(delay_prop[1] * 5);
GPIO_PIN_SET(gpio, pin, pin_value);
- DELAY(delay_prop[2]);
+ DELAY(delay_prop[2] * 5);
#endif /* __rtems__ */
return (0);
diff --git a/freebsd/sys/dev/e1000/e1000_api.c b/freebsd/sys/dev/e1000/e1000_api.c
index c351901c..21b11bc2 100644
--- a/freebsd/sys/dev/e1000/e1000_api.c
+++ b/freebsd/sys/dev/e1000/e1000_api.c
@@ -321,6 +321,7 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_PCH_ICP_I219_V8:
case E1000_DEV_ID_PCH_ICP_I219_LM9:
case E1000_DEV_ID_PCH_ICP_I219_V9:
+ case E1000_DEV_ID_PCH_ICP_I219_V10:
mac->type = e1000_pch_cnp;
break;
case E1000_DEV_ID_82575EB_COPPER:
diff --git a/freebsd/sys/dev/e1000/e1000_hw.h b/freebsd/sys/dev/e1000/e1000_hw.h
index 7e4e7f1a..6c0b5203 100644
--- a/freebsd/sys/dev/e1000/e1000_hw.h
+++ b/freebsd/sys/dev/e1000/e1000_hw.h
@@ -155,6 +155,7 @@ struct e1000_hw;
#define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0
#define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1
#define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2
+#define E1000_DEV_ID_PCH_ICP_I219_V10 0x0D4F
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c
index 32eb4afe..9b52c35a 100644
--- a/freebsd/sys/dev/e1000/if_em.c
+++ b/freebsd/sys/dev/e1000/if_em.c
@@ -176,6 +176,7 @@ static pci_vendor_info_t em_vendor_info_array[] =
PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V8, "Intel(R) PRO/1000 Network Connection"),
PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_LM9, "Intel(R) PRO/1000 Network Connection"),
PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V9, "Intel(R) PRO/1000 Network Connection"),
+ PVID(0x8086, E1000_DEV_ID_PCH_ICP_I219_V10, "Intel(R) PRO/1000 Network Connection"),
/* required last entry */
PVID_END
};
@@ -1397,10 +1398,8 @@ em_intr(void *arg)
IFDI_INTR_DISABLE(ctx);
/* Link status change */
- if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- adapter->hw.mac.get_link_status = 1;
- iflib_admin_intr_deferred(ctx);
- }
+ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))
+ em_handle_link(ctx);
if (reg_icr & E1000_ICR_RXO)
adapter->rx_overruns++;
@@ -1483,22 +1482,24 @@ em_msix_link(void *arg)
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
em_handle_link(adapter->ctx);
- } else {
- E1000_WRITE_REG(&adapter->hw, E1000_IMS,
- EM_MSIX_LINK | E1000_IMS_LSC);
- if (adapter->hw.mac.type >= igb_mac_min)
- E1000_WRITE_REG(&adapter->hw, E1000_EIMS, adapter->link_mask);
+ } else if (adapter->hw.mac.type == e1000_82574) {
+ /* Only re-arm 82574 if em_if_update_admin_status() won't. */
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK |
+ E1000_IMS_LSC);
}
- /*
- * Because we must read the ICR for this interrupt
- * it may clear other causes using autoclear, for
- * this reason we simply create a soft interrupt
- * for all these vectors.
- */
- if (reg_icr && adapter->hw.mac.type < igb_mac_min) {
- E1000_WRITE_REG(&adapter->hw,
- E1000_ICS, adapter->ims);
+ if (adapter->hw.mac.type == e1000_82574) {
+ /*
+ * Because we must read the ICR for this interrupt it may
+ * clear other causes using autoclear, for this reason we
+ * simply create a soft interrupt for all these vectors.
+ */
+ if (reg_icr)
+ E1000_WRITE_REG(&adapter->hw, E1000_ICS, adapter->ims);
+ } else {
+ /* Re-arm unconditionally */
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS, E1000_IMS_LSC);
+ E1000_WRITE_REG(&adapter->hw, E1000_EIMS, adapter->link_mask);
}
return (FILTER_HANDLED);
@@ -1514,7 +1515,6 @@ em_handle_link(void *context)
iflib_admin_intr_deferred(ctx);
}
-
/*********************************************************************
*
* Media Ioctl callback
@@ -1831,14 +1831,15 @@ em_if_update_admin_status(if_ctx_t ctx)
em_update_stats_counters(adapter);
/* Reset LAA into RAR[0] on 82571 */
- if ((adapter->hw.mac.type == e1000_82571) &&
- e1000_get_laa_state_82571(&adapter->hw))
- e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+ if (hw->mac.type == e1000_82571 && e1000_get_laa_state_82571(hw))
+ e1000_rar_set(hw, hw->mac.addr, 0);
- if (adapter->hw.mac.type < em_mac_min)
+ if (hw->mac.type < em_mac_min)
lem_smartspeed(adapter);
-
- E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK | E1000_IMS_LSC);
+ else if (hw->mac.type == e1000_82574 &&
+ adapter->intr_type == IFLIB_INTR_MSIX)
+ E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK |
+ E1000_IMS_LSC);
}
static void
@@ -3905,6 +3906,7 @@ em_disable_aspm(struct adapter *adapter)
static void
em_update_stats_counters(struct adapter *adapter)
{
+ u64 prev_xoffrxc = adapter->stats.xoffrxc;
if(adapter->hw.phy.media_type == e1000_media_type_copper ||
(E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
@@ -3928,7 +3930,8 @@ em_update_stats_counters(struct adapter *adapter)
** For watchdog management we need to know if we have been
** paused during the last interval, so capture that here.
*/
- adapter->shared->isc_pause_frames = adapter->stats.xoffrxc;
+ if (adapter->stats.xoffrxc != prev_xoffrxc)
+ adapter->shared->isc_pause_frames = 1;
adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC);
adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC);
adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64);
diff --git a/freebsd/sys/dev/gpio/gpiobus.c b/freebsd/sys/dev/gpio/gpiobus.c
index d256ee4a..25daf717 100644
--- a/freebsd/sys/dev/gpio/gpiobus.c
+++ b/freebsd/sys/dev/gpio/gpiobus.c
@@ -80,6 +80,18 @@ static int gpiobus_pin_get(device_t, device_t, uint32_t, unsigned int*);
static int gpiobus_pin_toggle(device_t, device_t, uint32_t);
/*
+ * gpiobus_pin flags
+ * The flags in struct gpiobus_pin are not related to the flags used by the
+ * low-level controller driver in struct gpio_pin. Currently, only pins
+ * acquired via FDT data have gpiobus_pin.flags set, sourced from the flags in
+ * the FDT properties. In theory, these flags are defined per-platform. In
+ * practice they are always the flags from the dt-bindings/gpio/gpio.h file.
+ * The only one of those flags we currently support is for handling active-low
+ * pins, so we just define that flag here instead of including a GPL'd header.
+ */
+#define GPIO_ACTIVE_LOW 1
+
+/*
* XXX -> Move me to better place - gpio_subr.c?
* Also, this function must be changed when interrupt configuration
* data will be moved into struct resource.
@@ -137,6 +149,114 @@ gpio_check_flags(uint32_t caps, uint32_t flags)
return (0);
}
+int
+gpio_pin_get_by_bus_pinnum(device_t busdev, uint32_t pinnum, gpio_pin_t *ppin)
+{
+ gpio_pin_t pin;
+ int err;
+
+ err = gpiobus_acquire_pin(busdev, pinnum);
+ if (err != 0)
+ return (EBUSY);
+
+ pin = malloc(sizeof(*pin), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ pin->dev = device_get_parent(busdev);
+ pin->pin = pinnum;
+ pin->flags = 0;
+
+ *ppin = pin;
+ return (0);
+}
+
+int
+gpio_pin_get_by_child_index(device_t childdev, uint32_t idx, gpio_pin_t *ppin)
+{
+ struct gpiobus_ivar *devi;
+
+ devi = GPIOBUS_IVAR(childdev);
+ if (idx >= devi->npins)
+ return (EINVAL);
+
+ return (gpio_pin_get_by_bus_pinnum(device_get_parent(childdev),
+ devi->pins[idx], ppin));
+}
+
+int
+gpio_pin_getcaps(gpio_pin_t pin, uint32_t *caps)
+{
+
+ KASSERT(pin != NULL, ("GPIO pin is NULL."));
+ KASSERT(pin->dev != NULL, ("GPIO pin device is NULL."));
+ return (GPIO_PIN_GETCAPS(pin->dev, pin->pin, caps));
+}
+
+int
+gpio_pin_is_active(gpio_pin_t pin, bool *active)
+{
+ int rv;
+ uint32_t tmp;
+
+ KASSERT(pin != NULL, ("GPIO pin is NULL."));
+ KASSERT(pin->dev != NULL, ("GPIO pin device is NULL."));
+ rv = GPIO_PIN_GET(pin->dev, pin->pin, &tmp);
+ if (rv != 0) {
+ return (rv);
+ }
+
+ if (pin->flags & GPIO_ACTIVE_LOW)
+ *active = tmp == 0;
+ else
+ *active = tmp != 0;
+ return (0);
+}
+
+void
+gpio_pin_release(gpio_pin_t gpio)
+{
+ device_t busdev;
+
+ if (gpio == NULL)
+ return;
+
+ KASSERT(gpio->dev != NULL, ("GPIO pin device is NULL."));
+
+ busdev = GPIO_GET_BUS(gpio->dev);
+ if (busdev != NULL)
+ gpiobus_release_pin(busdev, gpio->pin);
+
+ free(gpio, M_DEVBUF);
+}
+
+int
+gpio_pin_set_active(gpio_pin_t pin, bool active)
+{
+ int rv;
+ uint32_t tmp;
+
+ if (pin->flags & GPIO_ACTIVE_LOW)
+ tmp = active ? 0 : 1;
+ else
+ tmp = active ? 1 : 0;
+
+ KASSERT(pin != NULL, ("GPIO pin is NULL."));
+ KASSERT(pin->dev != NULL, ("GPIO pin device is NULL."));
+ rv = GPIO_PIN_SET(pin->dev, pin->pin, tmp);
+ return (rv);
+}
+
+int
+gpio_pin_setflags(gpio_pin_t pin, uint32_t flags)
+{
+ int rv;
+
+ KASSERT(pin != NULL, ("GPIO pin is NULL."));
+ KASSERT(pin->dev != NULL, ("GPIO pin device is NULL."));
+
+ rv = GPIO_PIN_SETFLAGS(pin->dev, pin->pin, flags);
+ return (rv);
+}
+
static void
gpiobus_print_pins(struct gpiobus_ivar *devi, char *buf, size_t buflen)
{
@@ -372,8 +492,6 @@ gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask)
devi->pins[npins++] = i;
}
- if (gpiobus_acquire_child_pins(sc->sc_busdev, child) != 0)
- return (EINVAL);
return (0);
}
@@ -427,8 +545,6 @@ gpiobus_parse_pin_list(struct gpiobus_softc *sc, device_t child,
p = endp + 1;
}
- if (gpiobus_acquire_child_pins(sc->sc_busdev, child) != 0)
- return (EINVAL);
return (0);
}
@@ -602,6 +718,21 @@ gpiobus_add_child(device_t dev, u_int order, const char *name, int unit)
return (child);
}
+static int
+gpiobus_rescan(device_t dev)
+{
+
+ /*
+ * Re-scan is supposed to remove and add children, but if someone has
+ * deleted the hints for a child we attached earlier, we have no easy
+ * way to handle that. So this just attaches new children for whom new
+ * hints or drivers have arrived since we last tried.
+ */
+ bus_enumerate_hinted_children(dev);
+ bus_generic_attach(dev);
+ return (0);
+}
+
static void
gpiobus_hinted_child(device_t bus, const char *dname, int dunit)
{
@@ -611,6 +742,10 @@ gpiobus_hinted_child(device_t bus, const char *dname, int dunit)
const char *pins;
int irq, pinmask;
+ if (device_find_child(bus, dname, dunit) != NULL) {
+ return;
+ }
+
child = BUS_ADD_CHILD(bus, 0, dname, dunit);
devi = GPIOBUS_IVAR(child);
if (resource_int_value(dname, dunit, "pins", &pinmask) == 0) {
@@ -963,6 +1098,7 @@ static device_method_t gpiobus_methods[] = {
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_get_resource_list, gpiobus_get_resource_list),
DEVMETHOD(bus_add_child, gpiobus_add_child),
+ DEVMETHOD(bus_rescan, gpiobus_rescan),
DEVMETHOD(bus_probe_nomatch, gpiobus_probe_nomatch),
DEVMETHOD(bus_print_child, gpiobus_print_child),
DEVMETHOD(bus_child_pnpinfo_str, gpiobus_child_pnpinfo_str),
diff --git a/freebsd/sys/dev/gpio/gpiobusvar.h b/freebsd/sys/dev/gpio/gpiobusvar.h
index 3ba8993e..ff49784a 100644
--- a/freebsd/sys/dev/gpio/gpiobusvar.h
+++ b/freebsd/sys/dev/gpio/gpiobusvar.h
@@ -141,7 +141,7 @@ int ofw_gpiobus_parse_gpios(device_t, char *, struct gpiobus_pin **);
void ofw_gpiobus_register_provider(device_t);
void ofw_gpiobus_unregister_provider(device_t);
-/* Consumers interface. */
+/* Acquire a pin by parsing FDT data. */
int gpio_pin_get_by_ofw_name(device_t consumer, phandle_t node,
char *name, gpio_pin_t *gpio);
int gpio_pin_get_by_ofw_idx(device_t consumer, phandle_t node,
@@ -150,14 +150,29 @@ int gpio_pin_get_by_ofw_property(device_t consumer, phandle_t node,
char *name, gpio_pin_t *gpio);
int gpio_pin_get_by_ofw_propidx(device_t consumer, phandle_t node,
char *name, int idx, gpio_pin_t *gpio);
+#endif /* FDT */
+
+/* Acquire a pin by bus and pin number. */
+int gpio_pin_get_by_bus_pinnum(device_t _bus, uint32_t _pinnum, gpio_pin_t *_gp);
+
+/* Acquire a pin by child and index (used by direct children of gpiobus). */
+int gpio_pin_get_by_child_index(device_t _child, uint32_t _idx, gpio_pin_t *_gp);
+
+/* Release a pin acquired via any gpio_pin_get_xxx() function. */
void gpio_pin_release(gpio_pin_t gpio);
+
+/* Work with gpio pins acquired using the functions above. */
int gpio_pin_getcaps(gpio_pin_t pin, uint32_t *caps);
int gpio_pin_is_active(gpio_pin_t pin, bool *active);
int gpio_pin_set_active(gpio_pin_t pin, bool active);
int gpio_pin_setflags(gpio_pin_t pin, uint32_t flags);
-#endif
struct resource *gpio_alloc_intr_resource(device_t consumer_dev, int *rid,
u_int alloc_flags, gpio_pin_t pin, uint32_t intr_mode);
+
+/*
+ * Functions shared between gpiobus and other bus classes that derive from it;
+ * these should not be called directly by other drivers.
+ */
int gpio_check_flags(uint32_t, uint32_t);
device_t gpiobus_attach_bus(device_t);
int gpiobus_detach_bus(device_t);
diff --git a/freebsd/sys/dev/gpio/ofw_gpiobus.c b/freebsd/sys/dev/gpio/ofw_gpiobus.c
index 1cf3aa82..bd617ead 100644
--- a/freebsd/sys/dev/gpio/ofw_gpiobus.c
+++ b/freebsd/sys/dev/gpio/ofw_gpiobus.c
@@ -49,8 +49,6 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/gpiobus_if.h>
-#define GPIO_ACTIVE_LOW 1
-
static struct ofw_gpiobus_devinfo *ofw_gpiobus_setup_devinfo(device_t,
device_t, phandle_t);
static void ofw_gpiobus_destroy_devinfo(device_t, struct ofw_gpiobus_devinfo *);
@@ -146,82 +144,6 @@ gpio_pin_get_by_ofw_name(device_t consumer, phandle_t node,
return (gpio_pin_get_by_ofw_idx(consumer, node, idx, pin));
}
-void
-gpio_pin_release(gpio_pin_t gpio)
-{
- device_t busdev;
-
- if (gpio == NULL)
- return;
-
- KASSERT(gpio->dev != NULL, ("invalid pin state"));
-
- busdev = GPIO_GET_BUS(gpio->dev);
- if (busdev != NULL)
- gpiobus_release_pin(busdev, gpio->pin);
-
- /* XXXX Unreserve pin. */
- free(gpio, M_DEVBUF);
-}
-
-int
-gpio_pin_getcaps(gpio_pin_t pin, uint32_t *caps)
-{
-
- KASSERT(pin != NULL, ("GPIO pin is NULL."));
- KASSERT(pin->dev != NULL, ("GPIO pin device is NULL."));
- return (GPIO_PIN_GETCAPS(pin->dev, pin->pin, caps));
-}
-
-int
-gpio_pin_is_active(gpio_pin_t pin, bool *active)
-{
- int rv;
- uint32_t tmp;
-
- KASSERT(pin != NULL, ("GPIO pin is NULL."));
- KASSERT(pin->dev != NULL, ("GPIO pin device is NULL."));
- rv = GPIO_PIN_GET(pin->dev, pin->pin, &tmp);
- if (rv != 0) {
- return (rv);
- }
-
- if (pin->flags & GPIO_ACTIVE_LOW)
- *active = tmp == 0;
- else
- *active = tmp != 0;
- return (0);
-}
-
-int
-gpio_pin_set_active(gpio_pin_t pin, bool active)
-{
- int rv;
- uint32_t tmp;
-
- if (pin->flags & GPIO_ACTIVE_LOW)
- tmp = active ? 0 : 1;
- else
- tmp = active ? 1 : 0;
-
- KASSERT(pin != NULL, ("GPIO pin is NULL."));
- KASSERT(pin->dev != NULL, ("GPIO pin device is NULL."));
- rv = GPIO_PIN_SET(pin->dev, pin->pin, tmp);
- return (rv);
-}
-
-int
-gpio_pin_setflags(gpio_pin_t pin, uint32_t flags)
-{
- int rv;
-
- KASSERT(pin != NULL, ("GPIO pin is NULL."));
- KASSERT(pin->dev != NULL, ("GPIO pin device is NULL."));
-
- rv = GPIO_PIN_SETFLAGS(pin->dev, pin->pin, flags);
- return (rv);
-}
-
/*
* OFW_GPIOBUS driver.
*/
@@ -498,7 +420,7 @@ ofw_gpiobus_probe(device_t dev)
return (ENXIO);
device_set_desc(dev, "OFW GPIO bus");
- return (0);
+ return (BUS_PROBE_DEFAULT);
}
static int
@@ -517,6 +439,8 @@ ofw_gpiobus_attach(device_t dev)
*/
for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
child = OF_peer(child)) {
+ if (OF_hasprop(child, "gpio-hog"))
+ continue;
if (!OF_hasprop(child, "gpios"))
continue;
if (ofw_gpiobus_add_fdt_child(dev, NULL, child) == NULL)
diff --git a/freebsd/sys/dev/kbd/kbd.c b/freebsd/sys/dev/kbd/kbd.c
index b157e57e..235e8f78 100644
--- a/freebsd/sys/dev/kbd/kbd.c
+++ b/freebsd/sys/dev/kbd/kbd.c
@@ -178,6 +178,10 @@ kbd_add_driver(keyboard_driver_t *driver)
{
if (SLIST_NEXT(driver, link))
return (EINVAL);
+ if (driver->kbdsw->get_fkeystr == NULL)
+ driver->kbdsw->get_fkeystr = genkbd_get_fkeystr;
+ if (driver->kbdsw->diag == NULL)
+ driver->kbdsw->diag = genkbd_diag;
SLIST_INSERT_HEAD(&keyboard_drivers, driver, link);
return (0);
}
@@ -1516,3 +1520,20 @@ kbd_ev_event(keyboard_t *kbd, uint16_t type, uint16_t code, int32_t value)
kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
}
}
+
+static void
+kbd_drv_init(void)
+{
+ const keyboard_driver_t **list;
+ const keyboard_driver_t *p;
+
+ SET_FOREACH(list, kbddriver_set) {
+ p = *list;
+ if (p->kbdsw->get_fkeystr == NULL)
+ p->kbdsw->get_fkeystr = genkbd_get_fkeystr;
+ if (p->kbdsw->diag == NULL)
+ p->kbdsw->diag = genkbd_diag;
+ }
+}
+
+SYSINIT(kbd_drv_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, kbd_drv_init, NULL);
diff --git a/freebsd/sys/dev/kbd/kbdreg.h b/freebsd/sys/dev/kbd/kbdreg.h
index 07c4cfd9..886b6c49 100644
--- a/freebsd/sys/dev/kbd/kbdreg.h
+++ b/freebsd/sys/dev/kbd/kbdreg.h
@@ -205,14 +205,19 @@ typedef struct keyboard_switch {
#define kbdd_poll(kbd, on) \
(*kbdsw[(kbd)->kb_index]->poll)((kbd), (on))
#define kbdd_diag(kbd, level) \
- (*kbdsw[(kbd)->kb_index]->diag)((kbd), (leve))
+ (*kbdsw[(kbd)->kb_index]->diag)((kbd), (level))
-/* keyboard driver */
+/*
+ * Keyboard driver definition. Some of these be immutable after definition
+ * time, e.g. one shouldn't be able to rename a driver or use a different kbdsw
+ * entirely, but patching individual methods is acceptable.
+ */
typedef struct keyboard_driver {
SLIST_ENTRY(keyboard_driver) link;
- char *name;
- keyboard_switch_t *kbdsw;
- int (*configure)(int); /* backdoor for the console driver */
+ const char * const name;
+ keyboard_switch_t * const kbdsw;
+ /* backdoor for the console driver */
+ int (* const configure)(int);
} keyboard_driver_t;
#ifdef _KERNEL
diff --git a/freebsd/sys/dev/mii/mii.c b/freebsd/sys/dev/mii/mii.c
index 2ed40543..d0428f24 100644
--- a/freebsd/sys/dev/mii/mii.c
+++ b/freebsd/sys/dev/mii/mii.c
@@ -62,6 +62,7 @@ MODULE_VERSION(miibus, 1);
#include <rtems/bsd/local/miibus_if.h>
static device_attach_t miibus_attach;
+static bus_child_detached_t miibus_child_detached;
static bus_child_location_str_t miibus_child_location_str;
static bus_child_pnpinfo_str_t miibus_child_pnpinfo_str;
static device_detach_t miibus_detach;
@@ -87,6 +88,7 @@ static device_method_t miibus_methods[] = {
/* bus interface */
DEVMETHOD(bus_print_child, miibus_print_child),
DEVMETHOD(bus_read_ivar, miibus_read_ivar),
+ DEVMETHOD(bus_child_detached, miibus_child_detached),
DEVMETHOD(bus_child_pnpinfo_str, miibus_child_pnpinfo_str),
DEVMETHOD(bus_child_location_str, miibus_child_location_str),
DEVMETHOD(bus_hinted_child, miibus_hinted_child),
@@ -162,15 +164,27 @@ static int
miibus_detach(device_t dev)
{
struct mii_data *mii;
+ struct miibus_ivars *ivars;
+ ivars = device_get_ivars(dev);
bus_generic_detach(dev);
mii = device_get_softc(dev);
ifmedia_removeall(&mii->mii_media);
+ free(ivars, M_DEVBUF);
mii->mii_ifp = NULL;
return (0);
}
+static void
+miibus_child_detached(device_t dev, device_t child)
+{
+ struct mii_attach_args *args;
+
+ args = device_get_ivars(child);
+ free(args, M_DEVBUF);
+}
+
static int
miibus_print_child(device_t dev, device_t child)
{
diff --git a/freebsd/sys/dev/nvme/nvme.c b/freebsd/sys/dev/nvme/nvme.c
index 20b328c9..00759aa3 100644
--- a/freebsd/sys/dev/nvme/nvme.c
+++ b/freebsd/sys/dev/nvme/nvme.c
@@ -134,25 +134,6 @@ nvme_attach(device_t dev)
int status;
status = nvme_ctrlr_construct(ctrlr, dev);
-
- if (status != 0) {
- nvme_ctrlr_destruct(ctrlr, dev);
- return (status);
- }
-
- /*
- * Reset controller twice to ensure we do a transition from cc.en==1 to
- * cc.en==0. This is because we don't really know what status the
- * controller was left in when boot handed off to OS. Linux doesn't do
- * this, however. If we adopt that policy, see also nvme_ctrlr_resume().
- */
- status = nvme_ctrlr_hw_reset(ctrlr);
- if (status != 0) {
- nvme_ctrlr_destruct(ctrlr, dev);
- return (status);
- }
-
- status = nvme_ctrlr_hw_reset(ctrlr);
if (status != 0) {
nvme_ctrlr_destruct(ctrlr, dev);
return (status);
diff --git a/freebsd/sys/dev/nvme/nvme.h b/freebsd/sys/dev/nvme/nvme.h
index 16b9aa5f..21ae79cb 100644
--- a/freebsd/sys/dev/nvme/nvme.h
+++ b/freebsd/sys/dev/nvme/nvme.h
@@ -1561,9 +1561,19 @@ struct nvme_get_nsid {
uint32_t nsid;
};
+struct nvme_hmb_desc {
+ uint64_t addr;
+ uint32_t size;
+ uint32_t reserved;
+};
+
#define nvme_completion_is_error(cpl) \
(NVME_STATUS_GET_SC((cpl)->status) != 0 || NVME_STATUS_GET_SCT((cpl)->status) != 0)
+#ifdef __rtems__
+/* This function is also used by user-space programs */
+#define nvme_strvis _bsd_nvme_strvis
+#endif /* __rtems__ */
void nvme_strvis(uint8_t *dst, const uint8_t *src, int dstlen, int srclen);
#ifdef _KERNEL
@@ -1596,6 +1606,8 @@ int nvme_ctrlr_passthrough_cmd(struct nvme_controller *ctrlr,
/* Admin functions */
void nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr,
uint8_t feature, uint32_t cdw11,
+ uint32_t cdw12, uint32_t cdw13,
+ uint32_t cdw14, uint32_t cdw15,
void *payload, uint32_t payload_size,
nvme_cb_fn_t cb_fn, void *cb_arg);
void nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr,
diff --git a/freebsd/sys/dev/nvme/nvme_ctrlr.c b/freebsd/sys/dev/nvme/nvme_ctrlr.c
index 86cabfba..2c19e694 100644
--- a/freebsd/sys/dev/nvme/nvme_ctrlr.c
+++ b/freebsd/sys/dev/nvme/nvme_ctrlr.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/uio.h>
#include <sys/endian.h>
+#include <vm/vm.h>
#include "nvme_private.h"
#ifdef __rtems__
@@ -66,6 +67,11 @@ nvme_ctrlr_construct_admin_qpair(struct nvme_controller *ctrlr)
int error;
qpair = &ctrlr->adminq;
+ qpair->id = 0;
+#ifndef __rtems__
+ qpair->cpu = CPU_FFS(&cpuset_domain[ctrlr->domain]) - 1;
+ qpair->domain = ctrlr->domain;
+#endif /* __rtems__ */
num_entries = NVME_ADMIN_ENTRIES;
TUNABLE_INT_FETCH("hw.nvme.admin_entries", &num_entries);
@@ -84,34 +90,39 @@ nvme_ctrlr_construct_admin_qpair(struct nvme_controller *ctrlr)
* The admin queue's max xfer size is treated differently than the
* max I/O xfer size. 16KB is sufficient here - maybe even less?
*/
- error = nvme_qpair_construct(qpair,
- 0, /* qpair ID */
- 0, /* vector */
- num_entries,
- NVME_ADMIN_TRACKERS,
- ctrlr);
+ error = nvme_qpair_construct(qpair, num_entries, NVME_ADMIN_TRACKERS,
+ ctrlr);
return (error);
}
+#define QP(ctrlr, c) ((c) * (ctrlr)->num_io_queues / mp_ncpus)
+
static int
nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr)
{
struct nvme_qpair *qpair;
uint32_t cap_lo;
uint16_t mqes;
- int i, error, num_entries, num_trackers;
-
- num_entries = NVME_IO_ENTRIES;
- TUNABLE_INT_FETCH("hw.nvme.io_entries", &num_entries);
+ int c, error, i, n;
+ int num_entries, num_trackers, max_entries;
/*
- * NVMe spec sets a hard limit of 64K max entries, but
- * devices may specify a smaller limit, so we need to check
- * the MQES field in the capabilities register.
+ * NVMe spec sets a hard limit of 64K max entries, but devices may
+ * specify a smaller limit, so we need to check the MQES field in the
+ * capabilities register. We have to cap the number of entries to the
+ * current stride allows for in BAR 0/1, otherwise the remainder entries
+ * are inaccessable. MQES should reflect this, and this is just a
+ * fail-safe.
*/
+ max_entries =
+ (rman_get_size(ctrlr->resource) - nvme_mmio_offsetof(doorbell[0])) /
+ (1 << (ctrlr->dstrd + 1));
+ num_entries = NVME_IO_ENTRIES;
+ TUNABLE_INT_FETCH("hw.nvme.io_entries", &num_entries);
cap_lo = nvme_mmio_read_4(ctrlr, cap_lo);
mqes = NVME_CAP_LO_MQES(cap_lo);
num_entries = min(num_entries, mqes + 1);
+ num_entries = min(num_entries, max_entries);
num_trackers = NVME_IO_TRACKERS;
TUNABLE_INT_FETCH("hw.nvme.io_trackers", &num_trackers);
@@ -119,9 +130,9 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr)
num_trackers = max(num_trackers, NVME_MIN_IO_TRACKERS);
num_trackers = min(num_trackers, NVME_MAX_IO_TRACKERS);
/*
- * No need to have more trackers than entries in the submit queue.
- * Note also that for a queue size of N, we can only have (N-1)
- * commands outstanding, hence the "-1" here.
+ * No need to have more trackers than entries in the submit queue. Note
+ * also that for a queue size of N, we can only have (N-1) commands
+ * outstanding, hence the "-1" here.
*/
num_trackers = min(num_trackers, (num_entries-1));
@@ -133,32 +144,37 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr)
*/
ctrlr->max_hw_pend_io = num_trackers * ctrlr->num_io_queues * 3 / 4;
- /*
- * This was calculated previously when setting up interrupts, but
- * a controller could theoretically support fewer I/O queues than
- * MSI-X vectors. So calculate again here just to be safe.
- */
- ctrlr->num_cpus_per_ioq = howmany(mp_ncpus, ctrlr->num_io_queues);
-
ctrlr->ioq = malloc(ctrlr->num_io_queues * sizeof(struct nvme_qpair),
M_NVME, M_ZERO | M_WAITOK);
- for (i = 0; i < ctrlr->num_io_queues; i++) {
+ for (i = c = n = 0; i < ctrlr->num_io_queues; i++, c += n) {
qpair = &ctrlr->ioq[i];
/*
* Admin queue has ID=0. IO queues start at ID=1 -
* hence the 'i+1' here.
- *
+ */
+ qpair->id = i + 1;
+#ifndef __rtems__
+ if (ctrlr->num_io_queues > 1) {
+ /* Find number of CPUs served by this queue. */
+ for (n = 1; QP(ctrlr, c + n) == i; n++)
+ ;
+ /* Shuffle multiple NVMe devices between CPUs. */
+ qpair->cpu = c + (device_get_unit(ctrlr->dev)+n/2) % n;
+ qpair->domain = pcpu_find(qpair->cpu)->pc_domain;
+ } else {
+ qpair->cpu = CPU_FFS(&cpuset_domain[ctrlr->domain]) - 1;
+ qpair->domain = ctrlr->domain;
+ }
+#endif /* __rtems__ */
+
+ /*
* For I/O queues, use the controller-wide max_xfer_size
* calculated in nvme_attach().
*/
- error = nvme_qpair_construct(qpair,
- i+1, /* qpair ID */
- ctrlr->msix_enabled ? i+1 : 0, /* vector */
- num_entries,
- num_trackers,
- ctrlr);
+ error = nvme_qpair_construct(qpair, num_entries, num_trackers,
+ ctrlr);
if (error)
return (error);
@@ -167,8 +183,11 @@ nvme_ctrlr_construct_io_qpairs(struct nvme_controller *ctrlr)
* interrupt thread for this controller.
*/
if (ctrlr->num_io_queues > 1)
- bus_bind_intr(ctrlr->dev, qpair->res,
- i * ctrlr->num_cpus_per_ioq);
+#ifndef __rtems__
+ bus_bind_intr(ctrlr->dev, qpair->res, qpair->cpu);
+#else /* __rtems__ */
+ bus_bind_intr(ctrlr->dev, qpair->res, QP(ctrlr, i));
+#endif /* __rtems__ */
}
return (0);
@@ -179,7 +198,7 @@ nvme_ctrlr_fail(struct nvme_controller *ctrlr)
{
int i;
- ctrlr->is_failed = TRUE;
+ ctrlr->is_failed = true;
nvme_admin_qpair_disable(&ctrlr->adminq);
nvme_qpair_fail(&ctrlr->adminq);
if (ctrlr->ioq != NULL) {
@@ -461,6 +480,8 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr)
*/
ctrlr->num_io_queues = min(ctrlr->num_io_queues, sq_allocated);
ctrlr->num_io_queues = min(ctrlr->num_io_queues, cq_allocated);
+ if (ctrlr->num_io_queues > vm_ndomains)
+ ctrlr->num_io_queues -= ctrlr->num_io_queues % vm_ndomains;
return (0);
}
@@ -476,7 +497,7 @@ nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr)
qpair = &ctrlr->ioq[i];
status.done = 0;
- nvme_ctrlr_cmd_create_io_cq(ctrlr, qpair, qpair->vector,
+ nvme_ctrlr_cmd_create_io_cq(ctrlr, qpair,
nvme_completion_poll_cb, &status);
nvme_completion_poll(&status);
if (nvme_completion_is_error(&status.cpl)) {
@@ -542,7 +563,7 @@ nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr)
return (0);
}
-static boolean_t
+static bool
is_log_page_id_valid(uint8_t page_id)
{
@@ -554,10 +575,10 @@ is_log_page_id_valid(uint8_t page_id)
case NVME_LOG_COMMAND_EFFECT:
case NVME_LOG_RES_NOTIFICATION:
case NVME_LOG_SANITIZE_STATUS:
- return (TRUE);
+ return (true);
}
- return (FALSE);
+ return (false);
}
static uint32_t
@@ -778,7 +799,7 @@ nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
* Disable timeout here, since asynchronous event requests should by
* nature never be timed out.
*/
- req->timeout = FALSE;
+ req->timeout = false;
req->cmd.opc = NVME_OPC_ASYNC_EVENT_REQUEST;
nvme_ctrlr_submit_admin_request(ctrlr, req);
}
@@ -837,6 +858,173 @@ nvme_ctrlr_configure_int_coalescing(struct nvme_controller *ctrlr)
}
static void
+nvme_ctrlr_hmb_free(struct nvme_controller *ctrlr)
+{
+#ifndef __rtems__
+ struct nvme_hmb_chunk *hmbc;
+ int i;
+
+ if (ctrlr->hmb_desc_paddr) {
+ bus_dmamap_unload(ctrlr->hmb_desc_tag, ctrlr->hmb_desc_map);
+ bus_dmamem_free(ctrlr->hmb_desc_tag, ctrlr->hmb_desc_vaddr,
+ ctrlr->hmb_desc_map);
+ ctrlr->hmb_desc_paddr = 0;
+ }
+ if (ctrlr->hmb_desc_tag) {
+ bus_dma_tag_destroy(ctrlr->hmb_desc_tag);
+ ctrlr->hmb_desc_tag = NULL;
+ }
+ for (i = 0; i < ctrlr->hmb_nchunks; i++) {
+ hmbc = &ctrlr->hmb_chunks[i];
+ bus_dmamap_unload(ctrlr->hmb_tag, hmbc->hmbc_map);
+ bus_dmamem_free(ctrlr->hmb_tag, hmbc->hmbc_vaddr,
+ hmbc->hmbc_map);
+ }
+ ctrlr->hmb_nchunks = 0;
+ if (ctrlr->hmb_tag) {
+ bus_dma_tag_destroy(ctrlr->hmb_tag);
+ ctrlr->hmb_tag = NULL;
+ }
+ if (ctrlr->hmb_chunks) {
+ free(ctrlr->hmb_chunks, M_NVME);
+ ctrlr->hmb_chunks = NULL;
+ }
+#endif /* __rtems__ */
+}
+
+#ifndef __rtems__
+static void
+nvme_ctrlr_hmb_alloc(struct nvme_controller *ctrlr)
+{
+ struct nvme_hmb_chunk *hmbc;
+ size_t pref, min, minc, size;
+ int err, i;
+ uint64_t max;
+
+ /* Limit HMB to 5% of RAM size per device by default. */
+ max = (uint64_t)physmem * PAGE_SIZE / 20;
+ TUNABLE_UINT64_FETCH("hw.nvme.hmb_max", &max);
+
+ min = (long long unsigned)ctrlr->cdata.hmmin * 4096;
+ if (max == 0 || max < min)
+ return;
+ pref = MIN((long long unsigned)ctrlr->cdata.hmpre * 4096, max);
+ minc = MAX(ctrlr->cdata.hmminds * 4096, PAGE_SIZE);
+ if (min > 0 && ctrlr->cdata.hmmaxd > 0)
+ minc = MAX(minc, min / ctrlr->cdata.hmmaxd);
+ ctrlr->hmb_chunk = pref;
+
+again:
+ ctrlr->hmb_chunk = roundup2(ctrlr->hmb_chunk, PAGE_SIZE);
+ ctrlr->hmb_nchunks = howmany(pref, ctrlr->hmb_chunk);
+ if (ctrlr->cdata.hmmaxd > 0 && ctrlr->hmb_nchunks > ctrlr->cdata.hmmaxd)
+ ctrlr->hmb_nchunks = ctrlr->cdata.hmmaxd;
+ ctrlr->hmb_chunks = malloc(sizeof(struct nvme_hmb_chunk) *
+ ctrlr->hmb_nchunks, M_NVME, M_WAITOK);
+ err = bus_dma_tag_create(bus_get_dma_tag(ctrlr->dev),
+ PAGE_SIZE, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ ctrlr->hmb_chunk, 1, ctrlr->hmb_chunk, 0, NULL, NULL, &ctrlr->hmb_tag);
+ if (err != 0) {
+ nvme_printf(ctrlr, "HMB tag create failed %d\n", err);
+ nvme_ctrlr_hmb_free(ctrlr);
+ return;
+ }
+
+ for (i = 0; i < ctrlr->hmb_nchunks; i++) {
+ hmbc = &ctrlr->hmb_chunks[i];
+ if (bus_dmamem_alloc(ctrlr->hmb_tag,
+ (void **)&hmbc->hmbc_vaddr, BUS_DMA_NOWAIT,
+ &hmbc->hmbc_map)) {
+ nvme_printf(ctrlr, "failed to alloc HMB\n");
+ break;
+ }
+ if (bus_dmamap_load(ctrlr->hmb_tag, hmbc->hmbc_map,
+ hmbc->hmbc_vaddr, ctrlr->hmb_chunk, nvme_single_map,
+ &hmbc->hmbc_paddr, BUS_DMA_NOWAIT) != 0) {
+ bus_dmamem_free(ctrlr->hmb_tag, hmbc->hmbc_vaddr,
+ hmbc->hmbc_map);
+ nvme_printf(ctrlr, "failed to load HMB\n");
+ break;
+ }
+ bus_dmamap_sync(ctrlr->hmb_tag, hmbc->hmbc_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ }
+
+ if (i < ctrlr->hmb_nchunks && i * ctrlr->hmb_chunk < min &&
+ ctrlr->hmb_chunk / 2 >= minc) {
+ ctrlr->hmb_nchunks = i;
+ nvme_ctrlr_hmb_free(ctrlr);
+ ctrlr->hmb_chunk /= 2;
+ goto again;
+ }
+ ctrlr->hmb_nchunks = i;
+ if (ctrlr->hmb_nchunks * ctrlr->hmb_chunk < min) {
+ nvme_ctrlr_hmb_free(ctrlr);
+ return;
+ }
+
+ size = sizeof(struct nvme_hmb_desc) * ctrlr->hmb_nchunks;
+ err = bus_dma_tag_create(bus_get_dma_tag(ctrlr->dev),
+ 16, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ size, 1, size, 0, NULL, NULL, &ctrlr->hmb_desc_tag);
+ if (err != 0) {
+ nvme_printf(ctrlr, "HMB desc tag create failed %d\n", err);
+ nvme_ctrlr_hmb_free(ctrlr);
+ return;
+ }
+ if (bus_dmamem_alloc(ctrlr->hmb_desc_tag,
+ (void **)&ctrlr->hmb_desc_vaddr, BUS_DMA_WAITOK,
+ &ctrlr->hmb_desc_map)) {
+ nvme_printf(ctrlr, "failed to alloc HMB desc\n");
+ nvme_ctrlr_hmb_free(ctrlr);
+ return;
+ }
+ if (bus_dmamap_load(ctrlr->hmb_desc_tag, ctrlr->hmb_desc_map,
+ ctrlr->hmb_desc_vaddr, size, nvme_single_map,
+ &ctrlr->hmb_desc_paddr, BUS_DMA_NOWAIT) != 0) {
+ bus_dmamem_free(ctrlr->hmb_desc_tag, ctrlr->hmb_desc_vaddr,
+ ctrlr->hmb_desc_map);
+ nvme_printf(ctrlr, "failed to load HMB desc\n");
+ nvme_ctrlr_hmb_free(ctrlr);
+ return;
+ }
+
+ for (i = 0; i < ctrlr->hmb_nchunks; i++) {
+ ctrlr->hmb_desc_vaddr[i].addr =
+ htole64(ctrlr->hmb_chunks[i].hmbc_paddr);
+ ctrlr->hmb_desc_vaddr[i].size = htole32(ctrlr->hmb_chunk / 4096);
+ }
+ bus_dmamap_sync(ctrlr->hmb_desc_tag, ctrlr->hmb_desc_map,
+ BUS_DMASYNC_PREWRITE);
+
+ nvme_printf(ctrlr, "Allocated %lluMB host memory buffer\n",
+ (long long unsigned)ctrlr->hmb_nchunks * ctrlr->hmb_chunk
+ / 1024 / 1024);
+}
+
+static void
+nvme_ctrlr_hmb_enable(struct nvme_controller *ctrlr, bool enable, bool memret)
+{
+ struct nvme_completion_poll_status status;
+ uint32_t cdw11;
+
+ cdw11 = 0;
+ if (enable)
+ cdw11 |= 1;
+ if (memret)
+ cdw11 |= 2;
+ status.done = 0;
+ nvme_ctrlr_cmd_set_feature(ctrlr, NVME_FEAT_HOST_MEMORY_BUFFER, cdw11,
+ ctrlr->hmb_nchunks * ctrlr->hmb_chunk / 4096, ctrlr->hmb_desc_paddr,
+ ctrlr->hmb_desc_paddr >> 32, ctrlr->hmb_nchunks, NULL, 0,
+ nvme_completion_poll_cb, &status);
+ nvme_completion_poll(&status);
+ if (nvme_completion_is_error(&status.cpl))
+ nvme_printf(ctrlr, "nvme_ctrlr_hmb_enable failed!\n");
+}
+#endif /* __rtems__ */
+
+static void
nvme_ctrlr_start(void *ctrlr_arg, bool resetting)
{
struct nvme_controller *ctrlr = ctrlr_arg;
@@ -884,6 +1072,15 @@ nvme_ctrlr_start(void *ctrlr_arg, bool resetting)
}
}
+#ifndef __rtems__
+ if (ctrlr->cdata.hmpre > 0 && ctrlr->hmb_nchunks == 0) {
+ nvme_ctrlr_hmb_alloc(ctrlr);
+ if (ctrlr->hmb_nchunks > 0)
+ nvme_ctrlr_hmb_enable(ctrlr, true, false);
+ } else if (ctrlr->hmb_nchunks > 0)
+ nvme_ctrlr_hmb_enable(ctrlr, true, true);
+#endif /* __rtems__ */
+
if (nvme_ctrlr_create_qpairs(ctrlr) != 0) {
nvme_ctrlr_fail(ctrlr);
return;
@@ -905,6 +1102,25 @@ void
nvme_ctrlr_start_config_hook(void *arg)
{
struct nvme_controller *ctrlr = arg;
+ int status;
+
+ /*
+ * Reset controller twice to ensure we do a transition from cc.en==1 to
+ * cc.en==0. This is because we don't really know what status the
+ * controller was left in when boot handed off to OS. Linux doesn't do
+ * this, however. If we adopt that policy, see also nvme_ctrlr_resume().
+ */
+ status = nvme_ctrlr_hw_reset(ctrlr);
+ if (status != 0) {
+ nvme_ctrlr_fail(ctrlr);
+ return;
+ }
+
+ status = nvme_ctrlr_hw_reset(ctrlr);
+ if (status != 0) {
+ nvme_ctrlr_fail(ctrlr);
+ return;
+ }
nvme_qpair_reset(&ctrlr->adminq);
nvme_admin_qpair_enable(&ctrlr->adminq);
@@ -1135,22 +1351,19 @@ nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev)
uint32_t cap_lo;
uint32_t cap_hi;
uint32_t to;
- uint8_t dstrd;
uint8_t mpsmin;
int status, timeout_period;
ctrlr->dev = dev;
mtx_init(&ctrlr->lock, "nvme ctrlr lock", NULL, MTX_DEF);
+#ifndef __rtems__
+ if (bus_get_domain(dev, &ctrlr->domain) != 0)
+ ctrlr->domain = 0;
+#endif /* __rtems__ */
- /*
- * Software emulators may set the doorbell stride to something
- * other than zero, but this driver is not set up to handle that.
- */
cap_hi = nvme_mmio_read_4(ctrlr, cap_hi);
- dstrd = NVME_CAP_HI_DSTRD(cap_hi);
- if (dstrd != 0)
- return (ENXIO);
+ ctrlr->dstrd = NVME_CAP_HI_DSTRD(cap_hi) + 2;
mpsmin = NVME_CAP_HI_MPSMIN(cap_hi);
ctrlr->min_page_size = 1 << (12 + mpsmin);
@@ -1186,7 +1399,7 @@ nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev)
TASK_INIT(&ctrlr->reset_task, 0, nvme_ctrlr_reset_task, ctrlr);
TASK_INIT(&ctrlr->fail_req_task, 0, nvme_ctrlr_fail_req_task, ctrlr);
STAILQ_INIT(&ctrlr->fail_req);
- ctrlr->is_failed = FALSE;
+ ctrlr->is_failed = false;
make_dev_args_init(&md_args);
md_args.mda_devsw = &nvme_ctrlr_cdevsw;
@@ -1228,11 +1441,17 @@ nvme_ctrlr_destruct(struct nvme_controller *ctrlr, device_t dev)
destroy_dev(ctrlr->cdev);
if (ctrlr->is_initialized) {
- if (!gone)
+ if (!gone) {
+#ifndef __rtems__
+ if (ctrlr->hmb_nchunks > 0)
+ nvme_ctrlr_hmb_enable(ctrlr, false, false);
+#endif /* __rtems__ */
nvme_ctrlr_delete_qpairs(ctrlr);
+ }
for (i = 0; i < ctrlr->num_io_queues; i++)
nvme_io_qpair_destroy(&ctrlr->ioq[i]);
free(ctrlr->ioq, M_NVME);
+ nvme_ctrlr_hmb_free(ctrlr);
nvme_admin_qpair_destroy(&ctrlr->adminq);
}
@@ -1312,7 +1531,7 @@ nvme_ctrlr_submit_io_request(struct nvme_controller *ctrlr,
{
struct nvme_qpair *qpair;
- qpair = &ctrlr->ioq[curcpu / ctrlr->num_cpus_per_ioq];
+ qpair = &ctrlr->ioq[QP(ctrlr, curcpu)];
nvme_qpair_submit_request(qpair, req);
}
@@ -1356,6 +1575,11 @@ nvme_ctrlr_suspend(struct nvme_controller *ctrlr)
return (EWOULDBLOCK);
}
+#ifndef __rtems__
+ if (ctrlr->hmb_nchunks > 0)
+ nvme_ctrlr_hmb_enable(ctrlr, false, false);
+#endif /* __rtems__ */
+
/*
* Per Section 7.6.2 of NVMe spec 1.4, to properly suspend, we need to
* delete the hardware I/O queues, and then shutdown. This properly
diff --git a/freebsd/sys/dev/nvme/nvme_ctrlr_cmd.c b/freebsd/sys/dev/nvme/nvme_ctrlr_cmd.c
index f5c1832c..8ce51e1f 100644
--- a/freebsd/sys/dev/nvme/nvme_ctrlr_cmd.c
+++ b/freebsd/sys/dev/nvme/nvme_ctrlr_cmd.c
@@ -78,8 +78,7 @@ nvme_ctrlr_cmd_identify_namespace(struct nvme_controller *ctrlr, uint32_t nsid,
void
nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
- struct nvme_qpair *io_que, uint16_t vector, nvme_cb_fn_t cb_fn,
- void *cb_arg)
+ struct nvme_qpair *io_que, nvme_cb_fn_t cb_fn, void *cb_arg)
{
struct nvme_request *req;
struct nvme_command *cmd;
@@ -95,7 +94,7 @@ nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
*/
cmd->cdw10 = htole32(((io_que->num_entries-1) << 16) | io_que->id);
/* 0x3 = interrupts enabled | physically contiguous */
- cmd->cdw11 = htole32((vector << 16) | 0x3);
+ cmd->cdw11 = htole32((io_que->vector << 16) | 0x3);
cmd->prp1 = htole64(io_que->cpl_bus_addr);
nvme_ctrlr_submit_admin_request(ctrlr, req);
@@ -169,7 +168,8 @@ nvme_ctrlr_cmd_delete_io_sq(struct nvme_controller *ctrlr,
void
nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, uint8_t feature,
- uint32_t cdw11, void *payload, uint32_t payload_size,
+ uint32_t cdw11, uint32_t cdw12, uint32_t cdw13, uint32_t cdw14,
+ uint32_t cdw15, void *payload, uint32_t payload_size,
nvme_cb_fn_t cb_fn, void *cb_arg)
{
struct nvme_request *req;
@@ -181,6 +181,10 @@ nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, uint8_t feature,
cmd->opc = NVME_OPC_SET_FEATURES;
cmd->cdw10 = htole32(feature);
cmd->cdw11 = htole32(cdw11);
+ cmd->cdw12 = htole32(cdw12);
+ cmd->cdw13 = htole32(cdw13);
+ cmd->cdw14 = htole32(cdw14);
+ cmd->cdw15 = htole32(cdw15);
nvme_ctrlr_submit_admin_request(ctrlr, req);
}
@@ -211,7 +215,7 @@ nvme_ctrlr_cmd_set_num_queues(struct nvme_controller *ctrlr,
cdw11 = ((num_queues - 1) << 16) | (num_queues - 1);
nvme_ctrlr_cmd_set_feature(ctrlr, NVME_FEAT_NUMBER_OF_QUEUES, cdw11,
- NULL, 0, cb_fn, cb_arg);
+ 0, 0, 0, 0, NULL, 0, cb_fn, cb_arg);
}
void
@@ -222,8 +226,8 @@ nvme_ctrlr_cmd_set_async_event_config(struct nvme_controller *ctrlr,
cdw11 = state;
nvme_ctrlr_cmd_set_feature(ctrlr,
- NVME_FEAT_ASYNC_EVENT_CONFIGURATION, cdw11, NULL, 0, cb_fn,
- cb_arg);
+ NVME_FEAT_ASYNC_EVENT_CONFIGURATION, cdw11, 0, 0, 0, 0, NULL, 0,
+ cb_fn, cb_arg);
}
void
@@ -248,7 +252,7 @@ nvme_ctrlr_cmd_set_interrupt_coalescing(struct nvme_controller *ctrlr,
cdw11 = ((microseconds/100) << 8) | threshold;
nvme_ctrlr_cmd_set_feature(ctrlr, NVME_FEAT_INTERRUPT_COALESCING, cdw11,
- NULL, 0, cb_fn, cb_arg);
+ 0, 0, 0, 0, NULL, 0, cb_fn, cb_arg);
}
void
diff --git a/freebsd/sys/dev/nvme/nvme_pci.c b/freebsd/sys/dev/nvme/nvme_pci.c
index b9d46a8b..6b07a5ab 100644
--- a/freebsd/sys/dev/nvme/nvme_pci.c
+++ b/freebsd/sys/dev/nvme/nvme_pci.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/proc.h>
#include <sys/smp.h>
+#include <vm/vm.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
@@ -235,7 +236,6 @@ nvme_ctrlr_configure_intx(struct nvme_controller *ctrlr)
ctrlr->msix_enabled = 0;
ctrlr->num_io_queues = 1;
- ctrlr->num_cpus_per_ioq = mp_ncpus;
ctrlr->rid = 0;
ctrlr->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ,
&ctrlr->rid, RF_SHAREABLE | RF_ACTIVE);
@@ -261,82 +261,65 @@ static void
nvme_ctrlr_setup_interrupts(struct nvme_controller *ctrlr)
{
device_t dev;
- int per_cpu_io_queues;
+ int force_intx, num_io_queues, per_cpu_io_queues;
int min_cpus_per_ioq;
int num_vectors_requested, num_vectors_allocated;
- int num_vectors_available;
dev = ctrlr->dev;
- min_cpus_per_ioq = 1;
- TUNABLE_INT_FETCH("hw.nvme.min_cpus_per_ioq", &min_cpus_per_ioq);
- if (min_cpus_per_ioq < 1) {
- min_cpus_per_ioq = 1;
- } else if (min_cpus_per_ioq > mp_ncpus) {
- min_cpus_per_ioq = mp_ncpus;
+ force_intx = 0;
+ TUNABLE_INT_FETCH("hw.nvme.force_intx", &force_intx);
+ if (force_intx || pci_msix_count(dev) < 2) {
+ nvme_ctrlr_configure_intx(ctrlr);
+ return;
}
+ num_io_queues = mp_ncpus;
+ TUNABLE_INT_FETCH("hw.nvme.num_io_queues", &num_io_queues);
+ if (num_io_queues < 1 || num_io_queues > mp_ncpus)
+ num_io_queues = mp_ncpus;
+
per_cpu_io_queues = 1;
TUNABLE_INT_FETCH("hw.nvme.per_cpu_io_queues", &per_cpu_io_queues);
+ if (per_cpu_io_queues == 0)
+ num_io_queues = 1;
- if (per_cpu_io_queues == 0) {
- min_cpus_per_ioq = mp_ncpus;
+#ifndef __rtems__
+ min_cpus_per_ioq = smp_threads_per_core;
+#else /* __rtems__ */
+ min_cpus_per_ioq = 1;
+#endif /* __rtems__ */
+ TUNABLE_INT_FETCH("hw.nvme.min_cpus_per_ioq", &min_cpus_per_ioq);
+ if (min_cpus_per_ioq > 1) {
+ num_io_queues = min(num_io_queues,
+ max(1, mp_ncpus / min_cpus_per_ioq));
}
- ctrlr->force_intx = 0;
- TUNABLE_INT_FETCH("hw.nvme.force_intx", &ctrlr->force_intx);
-
- /*
- * FreeBSD currently cannot allocate more than about 190 vectors at
- * boot, meaning that systems with high core count and many devices
- * requesting per-CPU interrupt vectors will not get their full
- * allotment. So first, try to allocate as many as we may need to
- * understand what is available, then immediately release them.
- * Then figure out how many of those we will actually use, based on
- * assigning an equal number of cores to each I/O queue.
- */
+ num_io_queues = min(num_io_queues, pci_msix_count(dev) - 1);
+again:
+ if (num_io_queues > vm_ndomains)
+ num_io_queues -= num_io_queues % vm_ndomains;
/* One vector for per core I/O queue, plus one vector for admin queue. */
- num_vectors_available = min(pci_msix_count(dev), mp_ncpus + 1);
- if (pci_alloc_msix(dev, &num_vectors_available) != 0) {
- num_vectors_available = 0;
- }
- pci_release_msi(dev);
-
- if (ctrlr->force_intx || num_vectors_available < 2) {
- nvme_ctrlr_configure_intx(ctrlr);
- return;
- }
-
- /*
- * Do not use all vectors for I/O queues - one must be saved for the
- * admin queue.
- */
- ctrlr->num_cpus_per_ioq = max(min_cpus_per_ioq,
- howmany(mp_ncpus, num_vectors_available - 1));
-
- ctrlr->num_io_queues = howmany(mp_ncpus, ctrlr->num_cpus_per_ioq);
- num_vectors_requested = ctrlr->num_io_queues + 1;
+ num_vectors_requested = num_io_queues + 1;
num_vectors_allocated = num_vectors_requested;
-
- /*
- * Now just allocate the number of vectors we need. This should
- * succeed, since we previously called pci_alloc_msix()
- * successfully returning at least this many vectors, but just to
- * be safe, if something goes wrong just revert to INTx.
- */
if (pci_alloc_msix(dev, &num_vectors_allocated) != 0) {
nvme_ctrlr_configure_intx(ctrlr);
return;
}
-
- if (num_vectors_allocated < num_vectors_requested) {
+ if (num_vectors_allocated < 2) {
pci_release_msi(dev);
nvme_ctrlr_configure_intx(ctrlr);
return;
}
+ if (num_vectors_allocated != num_vectors_requested) {
+ pci_release_msi(dev);
+ num_io_queues = num_vectors_allocated - 1;
+ goto again;
+ }
ctrlr->msix_enabled = 1;
+ ctrlr->num_io_queues = num_io_queues;
}
static int
diff --git a/freebsd/sys/dev/nvme/nvme_private.h b/freebsd/sys/dev/nvme/nvme_private.h
index a49d2b94..54ce1bfc 100644
--- a/freebsd/sys/dev/nvme/nvme_private.h
+++ b/freebsd/sys/dev/nvme/nvme_private.h
@@ -147,7 +147,7 @@ struct nvme_request {
} u;
uint32_t type;
uint32_t payload_size;
- boolean_t timeout;
+ bool timeout;
nvme_cb_fn_t cb_fn;
void *cb_arg;
int32_t retries;
@@ -187,7 +187,10 @@ struct nvme_qpair {
struct nvme_controller *ctrlr;
uint32_t id;
- uint32_t phase;
+#ifndef __rtems__
+ int domain;
+ int cpu;
+#endif /* __rtems__ */
uint16_t vector;
int rid;
@@ -199,6 +202,7 @@ struct nvme_qpair {
uint32_t sq_tdbl_off;
uint32_t cq_hdbl_off;
+ uint32_t phase;
uint32_t sq_head;
uint32_t sq_tail;
uint32_t cq_head;
@@ -226,7 +230,7 @@ struct nvme_qpair {
struct nvme_tracker **act_tr;
- boolean_t is_enabled;
+ bool is_enabled;
struct mtx lock __aligned(CACHE_LINE_SIZE);
@@ -252,7 +256,9 @@ struct nvme_controller {
device_t dev;
struct mtx lock;
-
+#ifndef __rtems__
+ int domain;
+#endif /* __rtems__ */
uint32_t ready_timeout_in_ms;
uint32_t quirks;
#define QUIRK_DELAY_B4_CHK_RDY 1 /* Can't touch MMIO on disable */
@@ -272,11 +278,9 @@ struct nvme_controller {
struct resource *bar4_resource;
uint32_t msix_enabled;
- uint32_t force_intx;
uint32_t enable_aborts;
uint32_t num_io_queues;
- uint32_t num_cpus_per_ioq;
uint32_t max_hw_pend_io;
/* Fields for tracking progress during controller initialization. */
@@ -293,9 +297,6 @@ struct nvme_controller {
struct resource *res;
void *tag;
- bus_dma_tag_t hw_desc_tag;
- bus_dmamap_t hw_desc_map;
-
/** maximum i/o size in bytes */
uint32_t max_xfer_size;
@@ -311,6 +312,9 @@ struct nvme_controller {
/** timeout period in seconds */
uint32_t timeout_period;
+ /** doorbell stride */
+ uint32_t dstrd;
+
struct nvme_qpair adminq;
struct nvme_qpair *ioq;
@@ -333,8 +337,24 @@ struct nvme_controller {
uint32_t is_initialized;
uint32_t notification_sent;
- boolean_t is_failed;
+ bool is_failed;
STAILQ_HEAD(, nvme_request) fail_req;
+
+ /* Host Memory Buffer */
+#ifndef __rtems__
+ int hmb_nchunks;
+ size_t hmb_chunk;
+ bus_dma_tag_t hmb_tag;
+ struct nvme_hmb_chunk {
+ bus_dmamap_t hmbc_map;
+ void *hmbc_vaddr;
+ uint64_t hmbc_paddr;
+ } *hmb_chunks;
+ bus_dma_tag_t hmb_desc_tag;
+ bus_dmamap_t hmb_desc_map;
+ struct nvme_hmb_desc *hmb_desc_vaddr;
+ uint64_t hmb_desc_paddr;
+#endif /* __rtems__ */
};
#define nvme_mmio_offsetof(reg) \
@@ -388,7 +408,7 @@ void nvme_ctrlr_cmd_get_firmware_page(struct nvme_controller *ctrlr,
nvme_cb_fn_t cb_fn,
void *cb_arg);
void nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
- struct nvme_qpair *io_que, uint16_t vector,
+ struct nvme_qpair *io_que,
nvme_cb_fn_t cb_fn, void *cb_arg);
void nvme_ctrlr_cmd_create_io_sq(struct nvme_controller *ctrlr,
struct nvme_qpair *io_que,
@@ -424,9 +444,8 @@ void nvme_ctrlr_submit_io_request(struct nvme_controller *ctrlr,
void nvme_ctrlr_post_failed_request(struct nvme_controller *ctrlr,
struct nvme_request *req);
-int nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
- uint16_t vector, uint32_t num_entries,
- uint32_t num_trackers,
+int nvme_qpair_construct(struct nvme_qpair *qpair,
+ uint32_t num_entries, uint32_t num_trackers,
struct nvme_controller *ctrlr);
void nvme_qpair_submit_tracker(struct nvme_qpair *qpair,
struct nvme_tracker *tr);
@@ -499,7 +518,7 @@ _nvme_allocate_request(nvme_cb_fn_t cb_fn, void *cb_arg)
if (req != NULL) {
req->cb_fn = cb_fn;
req->cb_arg = cb_arg;
- req->timeout = TRUE;
+ req->timeout = true;
}
return (req);
}
diff --git a/freebsd/sys/dev/nvme/nvme_qpair.c b/freebsd/sys/dev/nvme/nvme_qpair.c
index 6c16240d..3955f09b 100644
--- a/freebsd/sys/dev/nvme/nvme_qpair.c
+++ b/freebsd/sys/dev/nvme/nvme_qpair.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/conf.h>
+#include <sys/domainset.h>
#include <sys/proc.h>
#include <dev/pci/pcivar.h>
@@ -358,7 +359,7 @@ nvme_qpair_print_completion(struct nvme_qpair *qpair,
cpl->cdw0);
}
-static boolean_t
+static bool
nvme_completion_is_retry(const struct nvme_completion *cpl)
{
uint8_t sct, sc, dnr;
@@ -419,11 +420,12 @@ nvme_completion_is_retry(const struct nvme_completion *cpl)
}
static void
-nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
+nvme_qpair_complete_tracker(struct nvme_tracker *tr,
struct nvme_completion *cpl, error_print_t print_on_error)
{
+ struct nvme_qpair * qpair = tr->qpair;
struct nvme_request *req;
- boolean_t retry, error, retriable;
+ bool retry, error, retriable;
req = tr->req;
error = nvme_completion_is_error(cpl);
@@ -444,8 +446,17 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
KASSERT(cpl->cid == req->cmd.cid, ("cpl cid does not match cmd cid\n"));
- if (req->cb_fn && !retry)
- req->cb_fn(req->cb_arg, cpl);
+ if (!retry) {
+#ifndef __rtems__
+ if (req->type != NVME_REQUEST_NULL) {
+ bus_dmamap_sync(qpair->dma_tag_payload,
+ tr->payload_dma_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ }
+#endif /* __rtems__ */
+ if (req->cb_fn)
+ req->cb_fn(req->cb_arg, cpl);
+ }
mtx_lock(&qpair->lock);
callout_stop(&tr->timer);
@@ -456,9 +467,6 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
} else {
#ifndef __rtems__
if (req->type != NVME_REQUEST_NULL) {
- bus_dmamap_sync(qpair->dma_tag_payload,
- tr->payload_dma_map,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(qpair->dma_tag_payload,
tr->payload_dma_map);
}
@@ -487,19 +495,22 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
}
static void
-nvme_qpair_manual_complete_tracker(struct nvme_qpair *qpair,
+nvme_qpair_manual_complete_tracker(
struct nvme_tracker *tr, uint32_t sct, uint32_t sc, uint32_t dnr,
error_print_t print_on_error)
{
struct nvme_completion cpl;
memset(&cpl, 0, sizeof(cpl));
+
+ struct nvme_qpair * qpair = tr->qpair;
+
cpl.sqid = qpair->id;
cpl.cid = tr->cid;
cpl.status |= (sct & NVME_STATUS_SCT_MASK) << NVME_STATUS_SCT_SHIFT;
cpl.status |= (sc & NVME_STATUS_SC_MASK) << NVME_STATUS_SC_SHIFT;
cpl.status |= (dnr & NVME_STATUS_DNR_MASK) << NVME_STATUS_DNR_SHIFT;
- nvme_qpair_complete_tracker(qpair, tr, &cpl, print_on_error);
+ nvme_qpair_complete_tracker(tr, &cpl, print_on_error);
}
void
@@ -507,7 +518,7 @@ nvme_qpair_manual_complete_request(struct nvme_qpair *qpair,
struct nvme_request *req, uint32_t sct, uint32_t sc)
{
struct nvme_completion cpl;
- boolean_t error;
+ bool error;
memset(&cpl, 0, sizeof(cpl));
cpl.sqid = qpair->id;
@@ -596,7 +607,7 @@ nvme_qpair_process_completions(struct nvme_qpair *qpair)
tr = qpair->act_tr[cpl.cid];
if (tr != NULL) {
- nvme_qpair_complete_tracker(qpair, tr, &cpl, ERROR_PRINT_ALL);
+ nvme_qpair_complete_tracker(tr, &cpl, ERROR_PRINT_ALL);
qpair->sq_head = cpl.sqhd;
done++;
} else if (!in_panic) {
@@ -630,8 +641,13 @@ nvme_qpair_process_completions(struct nvme_qpair *qpair)
qpair->phase = !qpair->phase; /* 3 */
}
- nvme_mmio_write_4(qpair->ctrlr, doorbell[qpair->id].cq_hdbl,
- qpair->cq_head);
+#ifndef __rtems__
+ bus_space_write_4(qpair->ctrlr->bus_tag, qpair->ctrlr->bus_handle,
+ qpair->cq_hdbl_off, qpair->cq_head);
+#else /* __rtems__ */
+ bus_space_write_4(qpair->ctrlr->bus_tag, qpair->ctrlr->bus_handle,
+ qpair->cq_hdbl_off, htole32(qpair->cq_head));
+#endif /* __rtems__ */
}
return (done != 0);
}
@@ -645,8 +661,8 @@ nvme_qpair_msix_handler(void *arg)
}
int
-nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
- uint16_t vector, uint32_t num_entries, uint32_t num_trackers,
+nvme_qpair_construct(struct nvme_qpair *qpair,
+ uint32_t num_entries, uint32_t num_trackers,
struct nvme_controller *ctrlr)
{
struct nvme_tracker *tr;
@@ -655,8 +671,7 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
uint8_t *queuemem, *prpmem, *prp_list;
int i, err;
- qpair->id = id;
- qpair->vector = vector;
+ qpair->vector = ctrlr->msix_enabled ? qpair->id : 0;
qpair->num_entries = num_entries;
qpair->num_trackers = num_trackers;
qpair->ctrlr = ctrlr;
@@ -667,19 +682,19 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
* MSI-X vector resource IDs start at 1, so we add one to
* the queue's vector to get the corresponding rid to use.
*/
- qpair->rid = vector + 1;
+ qpair->rid = qpair->vector + 1;
qpair->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ,
&qpair->rid, RF_ACTIVE);
bus_setup_intr(ctrlr->dev, qpair->res,
INTR_TYPE_MISC | INTR_MPSAFE, NULL,
nvme_qpair_msix_handler, qpair, &qpair->tag);
- if (id == 0) {
+ if (qpair->id == 0) {
bus_describe_intr(ctrlr->dev, qpair->res, qpair->tag,
"admin");
} else {
bus_describe_intr(ctrlr->dev, qpair->res, qpair->tag,
- "io%d", id - 1);
+ "io%d", qpair->id - 1);
}
}
@@ -717,6 +732,9 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
nvme_printf(ctrlr, "tag create failed %d\n", err);
goto out;
}
+#ifndef __rtems__
+ bus_dma_tag_set_domain(qpair->dma_tag, qpair->domain);
+#endif /* __rtems__ */
if (bus_dmamem_alloc(qpair->dma_tag, (void **)&queuemem,
BUS_DMA_NOWAIT, &qpair->queuemem_map)) {
@@ -741,8 +759,15 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
qpair->cpl_bus_addr = queuemem_phys + cmdsz;
prpmem_phys = queuemem_phys + cmdsz + cplsz;
- qpair->sq_tdbl_off = nvme_mmio_offsetof(doorbell[id].sq_tdbl);
- qpair->cq_hdbl_off = nvme_mmio_offsetof(doorbell[id].cq_hdbl);
+ /*
+ * Calcuate the stride of the doorbell register. Many emulators set this
+ * value to correspond to a cache line. However, some hardware has set
+ * it to various small values.
+ */
+ qpair->sq_tdbl_off = nvme_mmio_offsetof(doorbell[0]) +
+ (qpair->id << (ctrlr->dstrd + 1));
+ qpair->cq_hdbl_off = nvme_mmio_offsetof(doorbell[0]) +
+ (qpair->id << (ctrlr->dstrd + 1)) + (1 << ctrlr->dstrd);
TAILQ_INIT(&qpair->free_tr);
TAILQ_INIT(&qpair->outstanding_tr);
@@ -768,7 +793,8 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
(uint8_t *)roundup2((uintptr_t)prp_list, PAGE_SIZE);
}
- tr = malloc(sizeof(*tr), M_NVME, M_ZERO | M_WAITOK);
+ tr = malloc_domainset(sizeof(*tr), M_NVME,
+ DOMAINSET_PREF(qpair->domain), M_ZERO | M_WAITOK);
#ifndef __rtems__
bus_dmamap_create(qpair->dma_tag_payload, 0,
&tr->payload_dma_map);
@@ -788,8 +814,9 @@ nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
goto out;
}
- qpair->act_tr = malloc(sizeof(struct nvme_tracker *) *
- qpair->num_entries, M_NVME, M_ZERO | M_WAITOK);
+ qpair->act_tr = malloc_domainset(sizeof(struct nvme_tracker *) *
+ qpair->num_entries, M_NVME, DOMAINSET_PREF(qpair->domain),
+ M_ZERO | M_WAITOK);
return (0);
out:
@@ -819,7 +846,7 @@ nvme_qpair_destroy(struct nvme_qpair *qpair)
}
if (qpair->act_tr)
- free(qpair->act_tr, M_NVME);
+ free_domain(qpair->act_tr, M_NVME);
while (!TAILQ_EMPTY(&qpair->free_tr)) {
tr = TAILQ_FIRST(&qpair->free_tr);
@@ -828,7 +855,7 @@ nvme_qpair_destroy(struct nvme_qpair *qpair)
bus_dmamap_destroy(qpair->dma_tag_payload,
tr->payload_dma_map);
#endif /* __rtems__ */
- free(tr, M_NVME);
+ free_domain(tr, M_NVME);
}
if (qpair->dma_tag)
@@ -848,7 +875,7 @@ nvme_admin_qpair_abort_aers(struct nvme_qpair *qpair)
tr = TAILQ_FIRST(&qpair->outstanding_tr);
while (tr != NULL) {
if (tr->req->cmd.opc == NVME_OPC_ASYNC_EVENT_REQUEST) {
- nvme_qpair_manual_complete_tracker(qpair, tr,
+ nvme_qpair_manual_complete_tracker(tr,
NVME_SCT_GENERIC, NVME_SC_ABORTED_SQ_DELETION, 0,
ERROR_PRINT_NONE);
tr = TAILQ_FIRST(&qpair->outstanding_tr);
@@ -892,7 +919,7 @@ nvme_abort_complete(void *arg, const struct nvme_completion *status)
*/
nvme_printf(tr->qpair->ctrlr,
"abort command failed, aborting command manually\n");
- nvme_qpair_manual_complete_tracker(tr->qpair, tr,
+ nvme_qpair_manual_complete_tracker(tr,
NVME_SCT_GENERIC, NVME_SC_ABORTED_BY_REQUEST, 0, ERROR_PRINT_ALL);
}
}
@@ -947,8 +974,13 @@ nvme_qpair_submit_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr)
ctrlr = qpair->ctrlr;
if (req->timeout)
- callout_reset_curcpu(&tr->timer, ctrlr->timeout_period * hz,
- nvme_timeout, tr);
+#ifndef __rtems__
+ callout_reset_on(&tr->timer, ctrlr->timeout_period * hz,
+ nvme_timeout, tr, qpair->cpu);
+#else /* __rtems__ */
+ callout_reset_on(&tr->timer, ctrlr->timeout_period * hz,
+ nvme_timeout, tr, -1);
+#endif /* __rtems__ */
/* Copy the command from the tracker to the submission queue. */
memcpy(&qpair->cmd[qpair->sq_tail], &req->cmd, sizeof(req->cmd));
@@ -970,9 +1002,13 @@ nvme_qpair_submit_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr)
wmb();
#endif /* __rtems__ */
- nvme_mmio_write_4(qpair->ctrlr, doorbell[qpair->id].sq_tdbl,
- qpair->sq_tail);
-
+#ifndef __rtems__
+ bus_space_write_4(qpair->ctrlr->bus_tag, qpair->ctrlr->bus_handle,
+ qpair->sq_tdbl_off, qpair->sq_tail);
+#else /* __rtems__ */
+ bus_space_write_4(qpair->ctrlr->bus_tag, qpair->ctrlr->bus_handle,
+ qpair->sq_tdbl_off, htole32(qpair->sq_tail));
+#endif /* __rtems__ */
qpair->num_cmds++;
}
@@ -1199,7 +1235,7 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req)
* with the qpair lock held.
*/
mtx_unlock(&qpair->lock);
- nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
+ nvme_qpair_manual_complete_tracker(tr, NVME_SCT_GENERIC,
NVME_SC_DATA_TRANSFER_ERROR, DO_NOT_RETRY, ERROR_PRINT_ALL);
mtx_lock(&qpair->lock);
}
@@ -1218,7 +1254,7 @@ static void
nvme_qpair_enable(struct nvme_qpair *qpair)
{
- qpair->is_enabled = TRUE;
+ qpair->is_enabled = true;
}
void
@@ -1257,7 +1293,7 @@ nvme_admin_qpair_enable(struct nvme_qpair *qpair)
TAILQ_FOREACH_SAFE(tr, &qpair->outstanding_tr, tailq, tr_temp) {
nvme_printf(qpair->ctrlr,
"aborting outstanding admin command\n");
- nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
+ nvme_qpair_manual_complete_tracker(tr, NVME_SCT_GENERIC,
NVME_SC_ABORTED_BY_REQUEST, DO_NOT_RETRY, ERROR_PRINT_ALL);
}
@@ -1279,7 +1315,7 @@ nvme_io_qpair_enable(struct nvme_qpair *qpair)
*/
TAILQ_FOREACH_SAFE(tr, &qpair->outstanding_tr, tailq, tr_temp) {
nvme_printf(qpair->ctrlr, "aborting outstanding i/o\n");
- nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
+ nvme_qpair_manual_complete_tracker(tr, NVME_SCT_GENERIC,
NVME_SC_ABORTED_BY_REQUEST, 0, ERROR_PRINT_NO_RETRY);
}
@@ -1306,7 +1342,7 @@ nvme_qpair_disable(struct nvme_qpair *qpair)
{
struct nvme_tracker *tr;
- qpair->is_enabled = FALSE;
+ qpair->is_enabled = false;
mtx_lock(&qpair->lock);
TAILQ_FOREACH(tr, &qpair->outstanding_tr, tailq)
callout_stop(&tr->timer);
@@ -1358,11 +1394,10 @@ nvme_qpair_fail(struct nvme_qpair *qpair)
*/
nvme_printf(qpair->ctrlr, "failing outstanding i/o\n");
mtx_unlock(&qpair->lock);
- nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC,
+ nvme_qpair_manual_complete_tracker(tr, NVME_SCT_GENERIC,
NVME_SC_ABORTED_BY_REQUEST, DO_NOT_RETRY, ERROR_PRINT_ALL);
mtx_lock(&qpair->lock);
}
mtx_unlock(&qpair->lock);
}
-
diff --git a/freebsd/sys/dev/nvme/nvme_sysctl.c b/freebsd/sys/dev/nvme/nvme_sysctl.c
index 7110cb80..589f4f43 100644
--- a/freebsd/sys/dev/nvme/nvme_sysctl.c
+++ b/freebsd/sys/dev/nvme/nvme_sysctl.c
@@ -308,9 +308,9 @@ nvme_sysctl_initialize_ctrlr(struct nvme_controller *ctrlr)
ctrlr_tree = device_get_sysctl_tree(ctrlr->dev);
ctrlr_list = SYSCTL_CHILDREN(ctrlr_tree);
- SYSCTL_ADD_UINT(ctrlr_ctx, ctrlr_list, OID_AUTO, "num_cpus_per_ioq",
- CTLFLAG_RD, &ctrlr->num_cpus_per_ioq, 0,
- "Number of CPUs assigned per I/O queue pair");
+ SYSCTL_ADD_UINT(ctrlr_ctx, ctrlr_list, OID_AUTO, "num_io_queues",
+ CTLFLAG_RD, &ctrlr->num_io_queues, 0,
+ "Number of I/O queue pairs");
SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO,
"int_coal_time", CTLTYPE_UINT | CTLFLAG_RW, ctrlr, 0,
diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.h b/freebsd/sys/dev/ofw/ofw_bus_subr.h
index 218ba710..4a55037b 100644
--- a/freebsd/sys/dev/ofw/ofw_bus_subr.h
+++ b/freebsd/sys/dev/ofw/ofw_bus_subr.h
@@ -69,7 +69,8 @@ struct intr_map_data_fdt {
#define FDTCOMPAT_PNP_INFO(t, busname) \
MODULE_PNP_INFO(FDTCOMPAT_PNP_DESCR, busname, t, t, sizeof(t) / sizeof(t[0]));
-#define SIMPLEBUS_PNP_INFO(t) FDTCOMPAT_PNP_INFO(t, simplebus)
+#define OFWBUS_PNP_INFO(t) FDTCOMPAT_PNP_INFO(t, ofwbus)
+#define SIMPLEBUS_PNP_INFO(t) FDTCOMPAT_PNP_INFO(t, simplebus)
/* Generic implementation of ofw_bus_if.m methods and helper routines */
int ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *, phandle_t);
diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c
index 586efc3d..f1501208 100644
--- a/freebsd/sys/dev/pci/pci.c
+++ b/freebsd/sys/dev/pci/pci.c
@@ -108,8 +108,6 @@ static void pci_assign_interrupt(device_t bus, device_t dev,
static int pci_add_map(device_t bus, device_t dev, int reg,
struct resource_list *rl, int force, int prefetch);
static int pci_probe(device_t dev);
-static int pci_attach(device_t dev);
-static int pci_detach(device_t dev);
static void pci_load_vendor_data(void);
static int pci_describe_parse_line(char **ptr, int *vendor,
int *device, char **desc);
@@ -250,6 +248,7 @@ struct pci_quirk {
#define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */
#define PCI_QUIRK_DISABLE_MSIX 5 /* MSI-X doesn't work */
#define PCI_QUIRK_MSI_INTX_BUG 6 /* PCIM_CMD_INTxDIS disables MSI */
+#define PCI_QUIRK_REALLOC_BAR 7 /* Can't allocate memory at the default address */
int arg1;
int arg2;
};
@@ -331,6 +330,12 @@ static const struct pci_quirk pci_quirks[] = {
{ 0x167814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715 */
{ 0x167914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715S */
+ /*
+ * HPE Gen 10 VGA has a memory range that can't be allocated in the
+ * expected place.
+ */
+ { 0x98741002, PCI_QUIRK_REALLOC_BAR, 0, 0 },
+
{ 0 }
};
@@ -3311,7 +3316,9 @@ pci_add_map(device_t bus, device_t dev, int reg, struct resource_list *rl,
*/
res = resource_list_reserve(rl, bus, dev, type, &reg, start, end, count,
flags);
- if (pci_do_realloc_bars && res == NULL && (start != 0 || end != ~0)) {
+ if ((pci_do_realloc_bars
+ || pci_has_quirk(pci_get_devid(dev), PCI_QUIRK_REALLOC_BAR))
+ && res == NULL && (start != 0 || end != ~0)) {
/*
* If the allocation fails, try to allocate a resource for
* this BAR using any available range. The firmware felt
@@ -4404,7 +4411,7 @@ pci_attach_common(device_t dev)
return (0);
}
-static int
+int
pci_attach(device_t dev)
{
int busno, domain, error;
@@ -4425,7 +4432,7 @@ pci_attach(device_t dev)
return (bus_generic_attach(dev));
}
-static int
+int
pci_detach(device_t dev)
{
#ifdef PCI_RES_BUS
diff --git a/freebsd/sys/dev/pci/pci_private.h b/freebsd/sys/dev/pci/pci_private.h
index f468152b..d891f592 100644
--- a/freebsd/sys/dev/pci/pci_private.h
+++ b/freebsd/sys/dev/pci/pci_private.h
@@ -58,7 +58,9 @@ void pci_add_resources(device_t bus, device_t dev, int force,
uint32_t prefetchmask);
void pci_add_resources_ea(device_t bus, device_t dev, int alloc_iov);
struct pci_devinfo *pci_alloc_devinfo_method(device_t dev);
+int pci_attach(device_t dev);
int pci_attach_common(device_t dev);
+int pci_detach(device_t dev);
int pci_rescan_method(device_t dev);
void pci_driver_added(device_t dev, driver_t *driver);
int pci_ea_is_enabled(device_t dev, int rid);
diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c
index 5d9cf26c..ed6010e8 100644
--- a/freebsd/sys/dev/sdhci/sdhci.c
+++ b/freebsd/sys/dev/sdhci/sdhci.c
@@ -904,8 +904,13 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num)
slot->host.host_ocr |= MMC_OCR_320_330 | MMC_OCR_330_340;
if (caps & SDHCI_CAN_VDD_300)
slot->host.host_ocr |= MMC_OCR_290_300 | MMC_OCR_300_310;
- /* 1.8V VDD is not supposed to be used for removable cards. */
- if ((caps & SDHCI_CAN_VDD_180) && (slot->opt & SDHCI_SLOT_EMBEDDED))
+ /*
+ * 1.8V VDD is not supposed to be used for removable cards. Hardware
+ * prior to v3.0 had no way to indicate embedded slots, but did
+ * sometimes support 1.8v for non-removable devices.
+ */
+ if ((caps & SDHCI_CAN_VDD_180) && (slot->version < SDHCI_SPEC_300 ||
+ (slot->opt & SDHCI_SLOT_EMBEDDED)))
slot->host.host_ocr |= MMC_OCR_LOW_VOLTAGE;
if (slot->host.host_ocr == 0) {
slot_printf(slot, "Hardware doesn't report any "
diff --git a/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c b/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c
index a7110887..65343be9 100644
--- a/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c
+++ b/freebsd/sys/dev/usb/controller/dwc_otg_fdt.c
@@ -83,6 +83,20 @@ dwc_otg_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
+static int
+dwc_otg_irq_index(device_t dev, int *rid)
+{
+ int idx, rv;
+ phandle_t node;
+
+ node = ofw_bus_get_node(dev);
+ rv = ofw_bus_find_string_index(node, "interrupt-names", "usb", &idx);
+ if (rv != 0)
+ return (rv);
+ *rid = idx;
+ return (0);
+}
+
int
dwc_otg_attach(device_t dev)
{
@@ -135,10 +149,16 @@ dwc_otg_attach(device_t dev)
/*
- * brcm,bcm2708-usb FDT provides two interrupts,
- * we need only second one (VC_USB)
+ * brcm,bcm2708-usb FDT provides two interrupts, we need only the USB
+ * interrupt (VC_USB). The latest FDT for it provides an
+ * interrupt-names property and swapped them around, while older ones
+ * did not have interrupt-names and put the usb interrupt in the second
+ * position. We'll attempt to use interrupt-names first with a fallback
+ * to the old method of assuming the index based on the compatible
+ * string.
*/
- rid = ofw_bus_is_compatible(dev, "brcm,bcm2708-usb") ? 1 : 0;
+ if (dwc_otg_irq_index(dev, &rid) != 0)
+ rid = ofw_bus_is_compatible(dev, "brcm,bcm2708-usb") ? 1 : 0;
sc->sc_otg.sc_irq_res =
bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
if (sc->sc_otg.sc_irq_res == NULL)
diff --git a/freebsd/sys/dev/usb/input/uep.c b/freebsd/sys/dev/usb/input/uep.c
index 247bfb9c..6d11b1f7 100644
--- a/freebsd/sys/dev/usb/input/uep.c
+++ b/freebsd/sys/dev/usb/input/uep.c
@@ -59,7 +59,6 @@
#else
#include <sys/ioccom.h>
#include <sys/fcntl.h>
-#include <sys/tty.h>
#endif
#define USB_DEBUG_VAR uep_debug
diff --git a/freebsd/sys/dev/usb/input/ukbd.c b/freebsd/sys/dev/usb/input/ukbd.c
index 770d1d3f..5cdaaffd 100644
--- a/freebsd/sys/dev/usb/input/ukbd.c
+++ b/freebsd/sys/dev/usb/input/ukbd.c
@@ -82,7 +82,6 @@ __FBSDID("$FreeBSD$");
#include <sys/ioccom.h>
#include <sys/filio.h>
-#include <sys/tty.h>
#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
@@ -1372,7 +1371,7 @@ ukbd_attach(device_t dev)
sc->sc_flags |= UKBD_FLAG_ATTACHED;
if (bootverbose) {
- genkbd_diag(kbd, bootverbose);
+ kbdd_diag(kbd, bootverbose);
}
#ifdef USB_DEBUG
@@ -2287,9 +2286,7 @@ static keyboard_switch_t ukbdsw = {
.clear_state = &ukbd_clear_state,
.get_state = &ukbd_get_state,
.set_state = &ukbd_set_state,
- .get_fkeystr = &genkbd_get_fkeystr,
.poll = &ukbd_poll,
- .diag = &genkbd_diag,
};
KEYBOARD_DRIVER(ukbd, ukbdsw, ukbd_configure);
diff --git a/freebsd/sys/dev/usb/input/ums.c b/freebsd/sys/dev/usb/input/ums.c
index 4a0d1f34..65c76b4a 100644
--- a/freebsd/sys/dev/usb/input/ums.c
+++ b/freebsd/sys/dev/usb/input/ums.c
@@ -81,7 +81,6 @@ __FBSDID("$FreeBSD$");
#include <sys/ioccom.h>
#include <sys/filio.h>
-#include <sys/tty.h>
#include <sys/mouse.h>
#ifdef USB_DEBUG
diff --git a/freebsd/sys/dev/usb/serial/uslcom.c b/freebsd/sys/dev/usb/serial/uslcom.c
index 4128802d..26986b8b 100644
--- a/freebsd/sys/dev/usb/serial/uslcom.c
+++ b/freebsd/sys/dev/usb/serial/uslcom.c
@@ -315,6 +315,7 @@ static const STRUCT_USB_HOST_ID uslcom_devs[] = {
USLCOM_DEV(SILABS, HAMLINKUSB),
USLCOM_DEV(SILABS, HELICOM),
USLCOM_DEV(SILABS, HUBZ),
+ USLCOM_DEV(SILABS, BV_AV2010_10),
USLCOM_DEV(SILABS, IMS_USB_RS422),
USLCOM_DEV(SILABS, INFINITY_MIC),
USLCOM_DEV(SILABS, INGENI_ZIGBEE),
@@ -626,7 +627,11 @@ uslcom_pre_param(struct ucom_softc *ucom, struct termios *t)
case USLCOM_PARTNUM_CP2102:
case USLCOM_PARTNUM_CP2103:
default:
- maxspeed = 921600;
+ /*
+ * Datasheet for cp2102 says 921600 max. Testing shows that
+ * 1228800 and 1843200 work fine.
+ */
+ maxspeed = 1843200;
break;
}
if (t->c_ospeed <= 0 || t->c_ospeed > maxspeed)
diff --git a/freebsd/sys/dev/usb/usb_bus.h b/freebsd/sys/dev/usb/usb_bus.h
index 710436c1..07784ded 100644
--- a/freebsd/sys/dev/usb/usb_bus.h
+++ b/freebsd/sys/dev/usb/usb_bus.h
@@ -2,7 +2,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-2019 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,19 +42,10 @@ struct usb_bus_msg {
};
/*
- * The following structure defines the USB statistics structure.
- */
-struct usb_bus_stat {
- uint32_t uds_requests[4];
-};
-
-/*
* The following structure defines an USB BUS. There is one USB BUS
* for every Host or Device controller.
*/
struct usb_bus {
- struct usb_bus_stat stats_err;
- struct usb_bus_stat stats_ok;
#if USB_HAVE_ROOT_MOUNT_HOLD
struct root_hold_token *bus_roothold;
#endif
@@ -131,6 +122,7 @@ struct usb_bus {
uint8_t do_probe; /* set if USB should be re-probed */
uint8_t no_explore; /* don't explore USB ports */
uint8_t dma_bits; /* number of DMA address lines */
+ uint8_t control_ep_quirk; /* need 64kByte buffer for data stage */
};
#endif /* _USB_BUS_H_ */
diff --git a/freebsd/sys/dev/usb/usb_device.h b/freebsd/sys/dev/usb/usb_device.h
index 1cf48ea1..691b2b38 100644
--- a/freebsd/sys/dev/usb/usb_device.h
+++ b/freebsd/sys/dev/usb/usb_device.h
@@ -2,7 +2,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-2019 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -177,10 +177,22 @@ union usb_device_scratch {
};
/*
+ * Helper structure to keep track of USB device statistics.
+ */
+struct usb_device_statistics {
+ uint32_t uds_requests[4];
+};
+
+/*
* The following structure defines an USB device. There exists one of
* these structures for every USB device.
*/
struct usb_device {
+ /* statistics */
+ struct usb_device_statistics stats_err;
+ struct usb_device_statistics stats_ok;
+ struct usb_device_statistics stats_cancelled;
+
/* generic clear stall message */
struct usb_udev_msg cs_msg[2];
struct sx enum_sx;
diff --git a/freebsd/sys/dev/usb/usb_generic.c b/freebsd/sys/dev/usb/usb_generic.c
index d45a0bf6..b3f12249 100644
--- a/freebsd/sys/dev/usb/usb_generic.c
+++ b/freebsd/sys/dev/usb/usb_generic.c
@@ -2229,10 +2229,9 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
for (n = 0; n != 4; n++) {
u.stat->uds_requests_fail[n] =
- f->udev->bus->stats_err.uds_requests[n];
-
+ f->udev->stats_err.uds_requests[n];
u.stat->uds_requests_ok[n] =
- f->udev->bus->stats_ok.uds_requests[n];
+ f->udev->stats_ok.uds_requests[n];
}
break;
diff --git a/freebsd/sys/dev/usb/usb_ioctl.h b/freebsd/sys/dev/usb/usb_ioctl.h
index e7e63fb9..c4023cab 100644
--- a/freebsd/sys/dev/usb/usb_ioctl.h
+++ b/freebsd/sys/dev/usb/usb_ioctl.h
@@ -224,7 +224,7 @@ struct usb_fs_uninit {
} USB_IOCTL_STRUCT_ALIGN(1);
struct usb_fs_open {
-#define USB_FS_MAX_BUFSIZE (1 << 18)
+#define USB_FS_MAX_BUFSIZE (1 << 25) /* 32 MBytes */
uint32_t max_bufsize;
#define USB_FS_MAX_FRAMES (1U << 12)
#define USB_FS_MAX_FRAMES_PRE_SCALE (1U << 31) /* for ISOCHRONOUS transfers */
diff --git a/freebsd/sys/dev/usb/usb_transfer.c b/freebsd/sys/dev/usb/usb_transfer.c
index 7ea25337..2478d937 100644
--- a/freebsd/sys/dev/usb/usb_transfer.c
+++ b/freebsd/sys/dev/usb/usb_transfer.c
@@ -111,6 +111,33 @@ static const struct usb_config usb_control_ep_cfg[USB_CTRL_XFER_MAX] = {
},
};
+static const struct usb_config usb_control_ep_quirk_cfg[USB_CTRL_XFER_MAX] = {
+
+ /* This transfer is used for generic control endpoint transfers */
+
+ [0] = {
+ .type = UE_CONTROL,
+ .endpoint = 0x00, /* Control endpoint */
+ .direction = UE_DIR_ANY,
+ .bufsize = 65535, /* bytes */
+ .callback = &usb_request_callback,
+ .usb_mode = USB_MODE_DUAL, /* both modes */
+ },
+
+ /* This transfer is used for generic clear stall only */
+
+ [1] = {
+ .type = UE_CONTROL,
+ .endpoint = 0x00, /* Control pipe */
+ .direction = UE_DIR_ANY,
+ .bufsize = sizeof(struct usb_device_request),
+ .callback = &usb_do_clear_stall_callback,
+ .timeout = 1000, /* 1 second */
+ .interval = 50, /* 50ms */
+ .usb_mode = USB_MODE_HOST,
+ },
+};
+
/* function prototypes */
static void usbd_update_max_frame_size(struct usb_xfer *);
@@ -1051,7 +1078,8 @@ usbd_transfer_setup(struct usb_device *udev,
* context, else there is a chance of
* deadlock!
*/
- if (setup_start == usb_control_ep_cfg)
+ if (setup_start == usb_control_ep_cfg ||
+ setup_start == usb_control_ep_quirk_cfg)
info->done_p =
USB_BUS_CONTROL_XFER_PROC(udev->bus);
else if (xfer_mtx == &Giant)
@@ -2595,11 +2623,14 @@ usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error)
}
#endif
/* keep some statistics */
- if (xfer->error) {
- info->bus->stats_err.uds_requests
+ if (xfer->error == USB_ERR_CANCELLED) {
+ info->udev->stats_cancelled.uds_requests
+ [xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE]++;
+ } else if (xfer->error != USB_ERR_NORMAL_COMPLETION) {
+ info->udev->stats_err.uds_requests
[xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE]++;
} else {
- info->bus->stats_ok.uds_requests
+ info->udev->stats_ok.uds_requests
[xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE]++;
}
@@ -3179,7 +3210,8 @@ repeat:
*/
iface_index = 0;
if (usbd_transfer_setup(udev, &iface_index,
- udev->ctrl_xfer, usb_control_ep_cfg, USB_CTRL_XFER_MAX, NULL,
+ udev->ctrl_xfer, udev->bus->control_ep_quirk ?
+ usb_control_ep_quirk_cfg : usb_control_ep_cfg, USB_CTRL_XFER_MAX, NULL,
&udev->device_mtx)) {
DPRINTFN(0, "could not setup default "
"USB transfer\n");
diff --git a/freebsd/sys/fs/devfs/devfs_vnops.c b/freebsd/sys/fs/devfs/devfs_vnops.c
index 86808e21..f1027e6f 100644
--- a/freebsd/sys/fs/devfs/devfs_vnops.c
+++ b/freebsd/sys/fs/devfs/devfs_vnops.c
@@ -298,38 +298,27 @@ devfs_vptocnp(struct vop_vptocnp_args *ap)
if (error != 0)
return (error);
- i = *buflen;
+ if (vp->v_type != VCHR && vp->v_type != VDIR) {
+ error = ENOENT;
+ goto finished;
+ }
+
dd = vp->v_data;
+ if (vp->v_type == VDIR && dd == dmp->dm_rootdir) {
+ *dvp = vp;
+ vref(*dvp);
+ goto finished;
+ }
- if (vp->v_type == VCHR) {
- i -= strlen(dd->de_cdp->cdp_c.si_name);
- if (i < 0) {
- error = ENOMEM;
- goto finished;
- }
- bcopy(dd->de_cdp->cdp_c.si_name, buf + i,
- strlen(dd->de_cdp->cdp_c.si_name));
- de = dd->de_dir;
- } else if (vp->v_type == VDIR) {
- if (dd == dmp->dm_rootdir) {
- *dvp = vp;
- vref(*dvp);
- goto finished;
- }
- i -= dd->de_dirent->d_namlen;
- if (i < 0) {
- error = ENOMEM;
- goto finished;
- }
- bcopy(dd->de_dirent->d_name, buf + i,
- dd->de_dirent->d_namlen);
- de = dd;
- } else {
- error = ENOENT;
+ i = *buflen;
+ i -= dd->de_dirent->d_namlen;
+ if (i < 0) {
+ error = ENOMEM;
goto finished;
}
+ bcopy(dd->de_dirent->d_name, buf + i, dd->de_dirent->d_namlen);
*buflen = i;
- de = devfs_parent_dirent(de);
+ de = devfs_parent_dirent(dd);
if (de == NULL) {
error = ENOENT;
goto finished;
@@ -828,9 +817,16 @@ out:
error = ENOTTY;
if (error == 0 && com == TIOCSCTTY) {
- /* Do nothing if reassigning same control tty */
+ /*
+ * Do nothing if reassigning same control tty, or if the
+ * control tty has already disappeared. If it disappeared,
+ * it's because we were racing with TIOCNOTTY. TIOCNOTTY
+ * already took care of releasing the old vnode and we have
+ * nothing left to do.
+ */
sx_slock(&proctree_lock);
- if (td->td_proc->p_session->s_ttyvp == vp) {
+ if (td->td_proc->p_session->s_ttyvp == vp ||
+ td->td_proc->p_session->s_ttyp == NULL) {
sx_sunlock(&proctree_lock);
return (0);
}
@@ -938,8 +934,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT))
return (EIO);
- error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td);
- if (error)
+ error = vn_dir_check_exec(dvp, cnp);
+ if (error != 0)
return (error);
if (cnp->cn_namelen == 1 && *pname == '.') {
diff --git a/freebsd/sys/kern/kern_conf.c b/freebsd/sys/kern/kern_conf.c
index 8605cc43..e1553915 100644
--- a/freebsd/sys/kern/kern_conf.c
+++ b/freebsd/sys/kern/kern_conf.c
@@ -174,12 +174,6 @@ dev_rel(struct cdev *dev)
dev->si_refcount--;
KASSERT(dev->si_refcount >= 0,
("dev_rel(%s) gave negative count", devtoname(dev)));
-#if 0
- if (dev->si_usecount == 0 &&
- (dev->si_flags & SI_CHEAPCLONE) && (dev->si_flags & SI_NAMED))
- ;
- else
-#endif
if (dev->si_devsw == NULL && dev->si_refcount == 0) {
LIST_REMOVE(dev, si_list);
flag = 1;
@@ -601,20 +595,41 @@ newdev(struct make_dev_args *args, struct cdev *si)
mtx_assert(&devmtx, MA_OWNED);
csw = args->mda_devsw;
+ si2 = NULL;
if (csw->d_flags & D_NEEDMINOR) {
/* We may want to return an existing device */
LIST_FOREACH(si2, &csw->d_devs, si_list) {
if (dev2unit(si2) == args->mda_unit) {
dev_free_devlocked(si);
- return (si2);
+ si = si2;
+ break;
}
}
+
+ /*
+ * If we're returning an existing device, we should make sure
+ * it isn't already initialized. This would have been caught
+ * in consumers anyways, but it's good to catch such a case
+ * early. We still need to complete initialization of the
+ * device, and we'll use whatever make_dev_args were passed in
+ * to do so.
+ */
+ KASSERT(si2 == NULL || (si2->si_flags & SI_NAMED) == 0,
+ ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)",
+ args->mda_devsw->d_name, dev2unit(si2), devtoname(si2)));
}
si->si_drv0 = args->mda_unit;
- si->si_devsw = csw;
si->si_drv1 = args->mda_si_drv1;
si->si_drv2 = args->mda_si_drv2;
- LIST_INSERT_HEAD(&csw->d_devs, si, si_list);
+ /* Only push to csw->d_devs if it's not a cloned device. */
+ if (si2 == NULL) {
+ si->si_devsw = csw;
+ LIST_INSERT_HEAD(&csw->d_devs, si, si_list);
+ } else {
+ KASSERT(si->si_devsw == csw,
+ ("%s: inconsistent devsw between clone_create() and make_dev()",
+ __func__));
+ }
return (si);
}
@@ -832,17 +847,6 @@ make_dev_sv(struct make_dev_args *args1, struct cdev **dres,
dev_refl(dev);
if ((args.mda_flags & MAKEDEV_ETERNAL) != 0)
dev->si_flags |= SI_ETERNAL;
- if (dev->si_flags & SI_CHEAPCLONE &&
- dev->si_flags & SI_NAMED) {
- /*
- * This is allowed as it removes races and generally
- * simplifies cloning devices.
- * XXX: still ??
- */
- dev_unlock_and_free();
- *dres = dev;
- return (0);
- }
KASSERT(!(dev->si_flags & SI_NAMED),
("make_dev() by driver %s on pre-existing device (min=%x, name=%s)",
args.mda_devsw->d_name, dev2unit(dev), devtoname(dev)));
@@ -1592,7 +1596,6 @@ DB_SHOW_COMMAND(cdev, db_show_cdev)
SI_FLAG(SI_ETERNAL);
SI_FLAG(SI_ALIAS);
SI_FLAG(SI_NAMED);
- SI_FLAG(SI_CHEAPCLONE);
SI_FLAG(SI_CHILD);
SI_FLAG(SI_DUMPDEV);
SI_FLAG(SI_CLONELIST);
diff --git a/freebsd/sys/kern/kern_linker.c b/freebsd/sys/kern/kern_linker.c
index 07fbd418..4571cbed 100644
--- a/freebsd/sys/kern/kern_linker.c
+++ b/freebsd/sys/kern/kern_linker.c
@@ -640,6 +640,10 @@ linker_make_file(const char *pathname, linker_class_t lc)
lf->ndeps = 0;
lf->deps = NULL;
lf->loadcnt = ++loadcnt;
+#ifdef __arm__
+ lf->exidx_addr = 0;
+ lf->exidx_size = 0;
+#endif
STAILQ_INIT(&lf->common);
TAILQ_INIT(&lf->modules);
TAILQ_INSERT_TAIL(&linker_files, lf, link);
@@ -2077,14 +2081,18 @@ linker_load_module(const char *kldname, const char *modname,
*/
KASSERT(verinfo == NULL, ("linker_load_module: verinfo"
" is not NULL"));
+ /* check if root file system is not mounted */
+ if (rootvnode == NULL || curproc->p_fd->fd_rdir == NULL)
+ return (ENXIO);
pathname = linker_search_kld(kldname);
} else {
if (modlist_lookup2(modname, verinfo) != NULL)
return (EEXIST);
+ /* check if root file system is not mounted */
+ if (rootvnode == NULL || curproc->p_fd->fd_rdir == NULL)
+ return (ENXIO);
if (kldname != NULL)
pathname = strdup(kldname, M_LINKER);
- else if (rootvnode == NULL)
- pathname = NULL;
else
/*
* Need to find a KLD with required module
diff --git a/freebsd/sys/kern/kern_mib.c b/freebsd/sys/kern/kern_mib.c
index b1c02570..d7d8a356 100644
--- a/freebsd/sys/kern/kern_mib.c
+++ b/freebsd/sys/kern/kern_mib.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_config.h>
#include <sys/param.h>
+#include <sys/boot.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/limits.h>
@@ -87,6 +88,8 @@ SYSCTL_ROOT_NODE(CTL_HW, hw, CTLFLAG_RW, 0,
#ifndef __rtems__
SYSCTL_ROOT_NODE(CTL_MACHDEP, machdep, CTLFLAG_RW, 0,
"machine dependent");
+SYSCTL_NODE(_machdep, OID_AUTO, mitigations, CTLFLAG_RW, 0,
+ "Machine dependent platform mitigations.");
SYSCTL_ROOT_NODE(CTL_USER, user, CTLFLAG_RW, 0,
"user-level");
SYSCTL_ROOT_NODE(CTL_P1003_1B, p1003_1b, CTLFLAG_RW, 0,
@@ -148,7 +151,7 @@ SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD|CTLFLAG_CAPRD,
SYSCTL_NULL_INT_PTR, 0, "Whether saved set-group/user ID is available");
#endif
-char kernelname[MAXPATHLEN] = "/boot/kernel/kernel"; /* XXX bloat */
+char kernelname[MAXPATHLEN] = PATH_KERNEL; /* XXX bloat */
SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW | CTLFLAG_MPSAFE,
kernelname, sizeof kernelname, "Name of kernel file booted");
diff --git a/freebsd/sys/kern/kern_mtxpool.c b/freebsd/sys/kern/kern_mtxpool.c
index bc47d826..a7fc1078 100644
--- a/freebsd/sys/kern/kern_mtxpool.c
+++ b/freebsd/sys/kern/kern_mtxpool.c
@@ -85,7 +85,7 @@ struct mtx_pool {
#define mtx_pool_next mtx_pool_header.mtxpool_next
#ifndef __rtems__
-struct mtx_pool *mtxpool_sleep;
+struct mtx_pool __read_frequently *mtxpool_sleep;
#endif /* __rtems__ */
#if UINTPTR_MAX == UINT64_MAX /* 64 bits */
diff --git a/freebsd/sys/kern/kern_sysctl.c b/freebsd/sys/kern/kern_sysctl.c
index b7ba41ea..f529704a 100644
--- a/freebsd/sys/kern/kern_sysctl.c
+++ b/freebsd/sys/kern/kern_sysctl.c
@@ -940,13 +940,18 @@ SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_register_all, NULL);
* (be aware though, that the proper interface isn't as obvious as it
* may seem, there are various conflicting requirements.
*
- * {0,0} printf the entire MIB-tree.
- * {0,1,...} return the name of the "..." OID.
- * {0,2,...} return the next OID.
- * {0,3} return the OID of the name in "new"
- * {0,4,...} return the kind & format info for the "..." OID.
- * {0,5,...} return the description of the "..." OID.
- * {0,6,...} return the aggregation label of the "..." OID.
+ * {CTL_SYSCTL, CTL_SYSCTL_DEBUG} printf the entire MIB-tree.
+ * {CTL_SYSCTL, CTL_SYSCTL_NAME, ...} return the name of the "..."
+ * OID.
+ * {CTL_SYSCTL, CTL_SYSCTL_NEXT, ...} return the next OID.
+ * {CTL_SYSCTL, CTL_SYSCTL_NAME2OID} return the OID of the name in
+ * "new"
+ * {CTL_SYSCTL, CTL_SYSCTL_OIDFMT, ...} return the kind & format info
+ * for the "..." OID.
+ * {CTL_SYSCTL, CTL_SYSCTL_OIDDESCR, ...} return the description of the
+ * "..." OID.
+ * {CTL_SYSCTL, CTL_SYSCTL_OIDLABEL, ...} return the aggregation label of
+ * the "..." OID.
*/
#ifdef SYSCTL_DEBUG
@@ -1014,8 +1019,8 @@ sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS)
return (ENOENT);
}
-SYSCTL_PROC(_sysctl, 0, debug, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE,
- 0, 0, sysctl_sysctl_debug, "-", "");
+SYSCTL_PROC(_sysctl, CTL_SYSCTL_DEBUG, debug, CTLTYPE_STRING | CTLFLAG_RD |
+ CTLFLAG_MPSAFE, 0, 0, sysctl_sysctl_debug, "-", "");
#endif
static int
@@ -1080,8 +1085,8 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
* XXXRW/JA: Shouldn't return name data for nodes that we don't permit in
* capability mode.
*/
-static SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD,
- sysctl_sysctl_name, "");
+static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NAME, name, CTLFLAG_RD |
+ CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, "");
static int
sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen,
@@ -1167,8 +1172,8 @@ sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
* XXXRW/JA: Shouldn't return next data for nodes that we don't permit in
* capability mode.
*/
-static SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD,
- sysctl_sysctl_next, "");
+static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXT, next, CTLFLAG_RD |
+ CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, "");
static int
name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp)
@@ -1254,9 +1259,9 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
* XXXRW/JA: Shouldn't return name2oid data for nodes that we don't permit in
* capability mode.
*/
-SYSCTL_PROC(_sysctl, 3, name2oid,
- CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE
- | CTLFLAG_CAPRW, 0, 0, sysctl_sysctl_name2oid, "I", "");
+SYSCTL_PROC(_sysctl, CTL_SYSCTL_NAME2OID, name2oid, CTLTYPE_INT | CTLFLAG_RW |
+ CTLFLAG_ANYBODY | CTLFLAG_MPSAFE | CTLFLAG_CAPRW, 0, 0,
+ sysctl_sysctl_name2oid, "I", "");
static int
sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
@@ -1284,8 +1289,8 @@ sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
}
-static SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_CAPRD,
- sysctl_sysctl_oidfmt, "");
+static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDFMT, oidfmt, CTLFLAG_RD |
+ CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidfmt, "");
static int
sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
@@ -1309,8 +1314,8 @@ sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
return (error);
}
-static SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_CAPRD,
- sysctl_sysctl_oiddescr, "");
+static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDDESCR, oiddescr, CTLFLAG_RD |
+ CTLFLAG_MPSAFE|CTLFLAG_CAPRD, sysctl_sysctl_oiddescr, "");
static int
sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS)
@@ -1334,8 +1339,8 @@ sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS)
return (error);
}
-static SYSCTL_NODE(_sysctl, 6, oidlabel,
- CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, "");
+static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDLABEL, oidlabel, CTLFLAG_RD |
+ CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, "");
/*
* Default "handler" functions.
@@ -1830,8 +1835,8 @@ kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
size_t oidlen, plen;
int error;
- oid[0] = 0; /* sysctl internal magic */
- oid[1] = 3; /* name2oid */
+ oid[0] = CTL_SYSCTL;
+ oid[1] = CTL_SYSCTL_NAME2OID;
oidlen = sizeof(oid);
error = kernel_sysctl(td, oid, 2, oid, &oidlen,
diff --git a/freebsd/sys/kern/kern_timeout.c b/freebsd/sys/kern/kern_timeout.c
index 2f478afc..b9162020 100644
--- a/freebsd/sys/kern/kern_timeout.c
+++ b/freebsd/sys/kern/kern_timeout.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/callout.h>
+#include <sys/domainset.h>
#include <sys/file.h>
#include <sys/interrupt.h>
#include <sys/kernel.h>
@@ -135,7 +136,8 @@ SYSCTL_INT(_kern, OID_AUTO, pin_pcpu_swi, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &pin_
* TODO:
* allocate more timeout table slots when table overflows.
*/
-u_int callwheelsize, callwheelmask;
+static u_int __read_mostly callwheelsize;
+static u_int __read_mostly callwheelmask;
#else /* __rtems__ */
#define callwheelsize (2 * ncallout)
#define callwheelmask (callwheelsize - 1)
@@ -234,7 +236,7 @@ struct callout_cpu cc_cpu;
#define CC_LOCK_ASSERT(cc) mtx_assert(&(cc)->cc_lock, MA_OWNED)
#ifndef __rtems__
-static int timeout_cpu;
+static int __read_mostly timeout_cpu;
#else /* __rtems__ */
#define timeout_cpu 0
#endif /* __rtems__ */
@@ -426,8 +428,9 @@ callout_cpu_init(struct callout_cpu *cc, int cpu)
SLIST_INIT(&cc->cc_callfree);
cc->cc_inited = 1;
#ifndef __rtems__
- cc->cc_callwheel = malloc(sizeof(struct callout_list) * callwheelsize,
- M_CALLOUT, M_WAITOK);
+ cc->cc_callwheel = malloc_domainset(sizeof(struct callout_list) *
+ callwheelsize, M_CALLOUT,
+ DOMAINSET_PREF(pcpu_find(cpu)->pc_domain), M_WAITOK);
#endif /* __rtems__ */
for (i = 0; i < callwheelsize; i++)
LIST_INIT(&cc->cc_callwheel[i]);
diff --git a/freebsd/sys/kern/subr_bus.c b/freebsd/sys/kern/subr_bus.c
index bfeb1c34..e43d0030 100644
--- a/freebsd/sys/kern/subr_bus.c
+++ b/freebsd/sys/kern/subr_bus.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/conf.h>
+#include <sys/domainset.h>
#include <sys/eventhandler.h>
#include <sys/filio.h>
#include <sys/lock.h>
@@ -2564,7 +2565,7 @@ void
device_set_softc(device_t dev, void *softc)
{
if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC))
- free(dev->softc, M_BUS_SC);
+ free_domain(dev->softc, M_BUS_SC);
dev->softc = softc;
if (dev->softc)
dev->flags |= DF_EXTERNALSOFTC;
@@ -2581,7 +2582,7 @@ device_set_softc(device_t dev, void *softc)
void
device_free_softc(void *softc)
{
- free(softc, M_BUS_SC);
+ free_domain(softc, M_BUS_SC);
}
/**
@@ -2830,6 +2831,11 @@ device_set_devclass_fixed(device_t dev, const char *classname)
int
device_set_driver(device_t dev, driver_t *driver)
{
+#ifndef __rtems__
+ int domain;
+ struct domainset *policy;
+#endif /* __rtems__ */
+
if (dev->state >= DS_ATTACHED)
return (EBUSY);
@@ -2837,7 +2843,7 @@ device_set_driver(device_t dev, driver_t *driver)
return (0);
if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
- free(dev->softc, M_BUS_SC);
+ free_domain(dev->softc, M_BUS_SC);
dev->softc = NULL;
}
device_set_desc(dev, NULL);
@@ -2846,8 +2852,14 @@ device_set_driver(device_t dev, driver_t *driver)
if (driver) {
kobj_init((kobj_t) dev, (kobj_class_t) driver);
if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) {
- dev->softc = malloc(driver->size, M_BUS_SC,
- M_NOWAIT | M_ZERO);
+#ifndef __rtems__
+ if (bus_get_domain(dev, &domain) == 0)
+ policy = DOMAINSET_PREF(domain);
+ else
+ policy = DOMAINSET_RR();
+#endif /* __rtems__ */
+ dev->softc = malloc_domainset(driver->size, M_BUS_SC,
+ policy, M_NOWAIT | M_ZERO);
if (!dev->softc) {
kobj_delete((kobj_t) dev, NULL);
kobj_init((kobj_t) dev, &null_class);
@@ -3771,6 +3783,22 @@ bus_generic_attach(device_t dev)
}
/**
+ * @brief Helper function for delaying attaching children
+ *
+ * Many buses can't run transactions on the bus which children need to probe and
+ * attach until after interrupts and/or timers are running. This function
+ * delays their attach until interrupts and timers are enabled.
+ */
+int
+bus_delayed_attach_children(device_t dev)
+{
+ /* Probe and attach the bus children when interrupts are available */
+ config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
+
+ return (0);
+}
+
+/**
* @brief Helper function for implementing DEVICE_DETACH()
*
* This function can be used to help implement the DEVICE_DETACH() for
diff --git a/freebsd/sys/kern/subr_firmware.c b/freebsd/sys/kern/subr_firmware.c
index cc8bb691..2780963c 100644
--- a/freebsd/sys/kern/subr_firmware.c
+++ b/freebsd/sys/kern/subr_firmware.c
@@ -260,7 +260,6 @@ firmware_unregister(const char *imagename)
static void
loadimage(void *arg, int npending)
{
- struct thread *td = curthread;
char *imagename = arg;
struct priv_fw *fp;
linker_file_t result;
@@ -270,11 +269,6 @@ loadimage(void *arg, int npending)
mtx_lock(&firmware_mtx);
mtx_unlock(&firmware_mtx);
- if (td->td_proc->p_fd->fd_rdir == NULL) {
- printf("%s: root not mounted yet, no way to load image\n",
- imagename);
- goto done;
- }
error = linker_reference_module(imagename, NULL, &result);
if (error != 0) {
printf("%s: could not load firmware image, error %d\n",
diff --git a/freebsd/sys/kern/subr_gtaskqueue.c b/freebsd/sys/kern/subr_gtaskqueue.c
index 173cfa08..c061c6b0 100644
--- a/freebsd/sys/kern/subr_gtaskqueue.c
+++ b/freebsd/sys/kern/subr_gtaskqueue.c
@@ -63,26 +63,26 @@ TASKQGROUP_DEFINE(softirq, mp_ncpus, 1);
TASKQGROUP_DEFINE(config, 1, 1);
struct gtaskqueue_busy {
- struct gtask *tb_running;
- TAILQ_ENTRY(gtaskqueue_busy) tb_link;
+ struct gtask *tb_running;
+ u_int tb_seq;
+ LIST_ENTRY(gtaskqueue_busy) tb_link;
};
-static struct gtask * const TB_DRAIN_WAITER = (struct gtask *)0x1;
-
typedef void (*gtaskqueue_enqueue_fn)(void *context);
struct gtaskqueue {
STAILQ_HEAD(, gtask) tq_queue;
+ LIST_HEAD(, gtaskqueue_busy) tq_active;
+ u_int tq_seq;
+ int tq_callouts;
+ struct mtx_padalign tq_mutex;
gtaskqueue_enqueue_fn tq_enqueue;
void *tq_context;
char *tq_name;
- TAILQ_HEAD(, gtaskqueue_busy) tq_active;
- struct mtx tq_mutex;
struct thread **tq_threads;
int tq_tcount;
int tq_spin;
int tq_flags;
- int tq_callouts;
taskqueue_callback_fn tq_callbacks[TASKQUEUE_NUM_CALLBACKS];
void *tq_cb_contexts[TASKQUEUE_NUM_CALLBACKS];
};
@@ -121,12 +121,11 @@ gtask_dump(struct gtask *gtask)
#endif
static __inline int
-TQ_SLEEP(struct gtaskqueue *tq, void *p, struct mtx *m, int pri, const char *wm,
- int t)
+TQ_SLEEP(struct gtaskqueue *tq, void *p, const char *wm)
{
if (tq->tq_spin)
- return (msleep_spin(p, m, wm, t));
- return (msleep(p, m, pri, wm, t));
+ return (msleep_spin(p, (struct mtx *)&tq->tq_mutex, wm, 0));
+ return (msleep(p, &tq->tq_mutex, 0, wm, 0));
}
static struct gtaskqueue *
@@ -150,7 +149,7 @@ _gtaskqueue_create(const char *name, int mflags,
}
STAILQ_INIT(&queue->tq_queue);
- TAILQ_INIT(&queue->tq_active);
+ LIST_INIT(&queue->tq_active);
queue->tq_enqueue = enqueue;
queue->tq_context = context;
queue->tq_name = tq_name;
@@ -173,7 +172,7 @@ gtaskqueue_terminate(struct thread **pp, struct gtaskqueue *tq)
while (tq->tq_tcount > 0 || tq->tq_callouts > 0) {
wakeup(tq);
- TQ_SLEEP(tq, pp, &tq->tq_mutex, PWAIT, "taskqueue_destroy", 0);
+ TQ_SLEEP(tq, pp, "gtq_destroy");
}
}
@@ -184,7 +183,7 @@ gtaskqueue_free(struct gtaskqueue *queue)
TQ_LOCK(queue);
queue->tq_flags &= ~TQ_FLAGS_ACTIVE;
gtaskqueue_terminate(queue->tq_threads, queue);
- KASSERT(TAILQ_EMPTY(&queue->tq_active), ("Tasks still running?"));
+ KASSERT(LIST_EMPTY(&queue->tq_active), ("Tasks still running?"));
KASSERT(queue->tq_callouts == 0, ("Armed timeout tasks"));
mtx_destroy(&queue->tq_mutex);
free(queue->tq_threads, M_GTASKQUEUE);
@@ -291,7 +290,7 @@ gtaskqueue_drain_tq_queue(struct gtaskqueue *queue)
* have completed or are currently executing.
*/
while (t_barrier.ta_flags & TASK_ENQUEUED)
- TQ_SLEEP(queue, &t_barrier, &queue->tq_mutex, PWAIT, "-", 0);
+ TQ_SLEEP(queue, &t_barrier, "gtq_qdrain");
}
/*
@@ -302,31 +301,24 @@ gtaskqueue_drain_tq_queue(struct gtaskqueue *queue)
static void
gtaskqueue_drain_tq_active(struct gtaskqueue *queue)
{
- struct gtaskqueue_busy tb_marker, *tb_first;
+ struct gtaskqueue_busy *tb;
+ u_int seq;
- if (TAILQ_EMPTY(&queue->tq_active))
+ if (LIST_EMPTY(&queue->tq_active))
return;
/* Block taskq_terminate().*/
queue->tq_callouts++;
- /*
- * Wait for all currently executing taskqueue threads
- * to go idle.
- */
- tb_marker.tb_running = TB_DRAIN_WAITER;
- TAILQ_INSERT_TAIL(&queue->tq_active, &tb_marker, tb_link);
- while (TAILQ_FIRST(&queue->tq_active) != &tb_marker)
- TQ_SLEEP(queue, &tb_marker, &queue->tq_mutex, PWAIT, "-", 0);
- TAILQ_REMOVE(&queue->tq_active, &tb_marker, tb_link);
-
- /*
- * Wakeup any other drain waiter that happened to queue up
- * without any intervening active thread.
- */
- tb_first = TAILQ_FIRST(&queue->tq_active);
- if (tb_first != NULL && tb_first->tb_running == TB_DRAIN_WAITER)
- wakeup(tb_first);
+ /* Wait for any active task with sequence from the past. */
+ seq = queue->tq_seq;
+restart:
+ LIST_FOREACH(tb, &queue->tq_active, tb_link) {
+ if ((int)(tb->tb_seq - seq) <= 0) {
+ TQ_SLEEP(queue, tb->tb_running, "gtq_adrain");
+ goto restart;
+ }
+ }
/* Release taskqueue_terminate(). */
queue->tq_callouts--;
@@ -358,40 +350,27 @@ static void
gtaskqueue_run_locked(struct gtaskqueue *queue)
{
struct gtaskqueue_busy tb;
- struct gtaskqueue_busy *tb_first;
struct gtask *gtask;
KASSERT(queue != NULL, ("tq is NULL"));
TQ_ASSERT_LOCKED(queue);
tb.tb_running = NULL;
+ LIST_INSERT_HEAD(&queue->tq_active, &tb, tb_link);
- while (STAILQ_FIRST(&queue->tq_queue)) {
- TAILQ_INSERT_TAIL(&queue->tq_active, &tb, tb_link);
-
- /*
- * Carefully remove the first task from the queue and
- * clear its TASK_ENQUEUED flag
- */
- gtask = STAILQ_FIRST(&queue->tq_queue);
- KASSERT(gtask != NULL, ("task is NULL"));
+ while ((gtask = STAILQ_FIRST(&queue->tq_queue)) != NULL) {
STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link);
gtask->ta_flags &= ~TASK_ENQUEUED;
tb.tb_running = gtask;
+ tb.tb_seq = ++queue->tq_seq;
TQ_UNLOCK(queue);
KASSERT(gtask->ta_func != NULL, ("task->ta_func is NULL"));
gtask->ta_func(gtask->ta_context);
TQ_LOCK(queue);
- tb.tb_running = NULL;
wakeup(gtask);
-
- TAILQ_REMOVE(&queue->tq_active, &tb, tb_link);
- tb_first = TAILQ_FIRST(&queue->tq_active);
- if (tb_first != NULL &&
- tb_first->tb_running == TB_DRAIN_WAITER)
- wakeup(tb_first);
}
+ LIST_REMOVE(&tb, tb_link);
}
static int
@@ -400,7 +379,7 @@ task_is_running(struct gtaskqueue *queue, struct gtask *gtask)
struct gtaskqueue_busy *tb;
TQ_ASSERT_LOCKED(queue);
- TAILQ_FOREACH(tb, &queue->tq_active, tb_link) {
+ LIST_FOREACH(tb, &queue->tq_active, tb_link) {
if (tb->tb_running == gtask)
return (1);
}
@@ -433,7 +412,7 @@ static void
gtaskqueue_drain_locked(struct gtaskqueue *queue, struct gtask *gtask)
{
while ((gtask->ta_flags & TASK_ENQUEUED) || task_is_running(queue, gtask))
- TQ_SLEEP(queue, gtask, &queue->tq_mutex, PWAIT, "-", 0);
+ TQ_SLEEP(queue, gtask, "gtq_drain");
}
void
@@ -580,7 +559,7 @@ gtaskqueue_thread_loop(void *arg)
*/
if ((tq->tq_flags & TQ_FLAGS_ACTIVE) == 0)
break;
- TQ_SLEEP(tq, tq, &tq->tq_mutex, 0, "-", 0);
+ TQ_SLEEP(tq, tq, "-");
}
gtaskqueue_run_locked(tq);
/*
@@ -606,7 +585,7 @@ gtaskqueue_thread_enqueue(void *context)
tqp = context;
tq = *tqp;
- wakeup_one(tq);
+ wakeup_any(tq);
}
diff --git a/freebsd/sys/kern/subr_taskqueue.c b/freebsd/sys/kern/subr_taskqueue.c
index 67e62fc8..85912248 100644
--- a/freebsd/sys/kern/subr_taskqueue.c
+++ b/freebsd/sys/kern/subr_taskqueue.c
@@ -58,26 +58,27 @@ static void taskqueue_swi_enqueue(void *);
static void taskqueue_swi_giant_enqueue(void *);
struct taskqueue_busy {
- struct task *tb_running;
- TAILQ_ENTRY(taskqueue_busy) tb_link;
+ struct task *tb_running;
+ u_int tb_seq;
+ LIST_ENTRY(taskqueue_busy) tb_link;
};
-struct task * const TB_DRAIN_WAITER = (struct task *)0x1;
-
struct taskqueue {
STAILQ_HEAD(, task) tq_queue;
+ LIST_HEAD(, taskqueue_busy) tq_active;
+ struct task *tq_hint;
+ u_int tq_seq;
+ int tq_callouts;
+ struct mtx_padalign tq_mutex;
taskqueue_enqueue_fn tq_enqueue;
void *tq_context;
char *tq_name;
- TAILQ_HEAD(, taskqueue_busy) tq_active;
- struct mtx tq_mutex;
struct thread **tq_threads;
int tq_tcount;
#ifndef __rtems__
int tq_spin;
#endif /* __rtems__ */
int tq_flags;
- int tq_callouts;
taskqueue_callback_fn tq_callbacks[TASKQUEUE_NUM_CALLBACKS];
void *tq_cb_contexts[TASKQUEUE_NUM_CALLBACKS];
};
@@ -134,14 +135,13 @@ _timeout_task_init(struct taskqueue *queue, struct timeout_task *timeout_task,
}
static __inline int
-TQ_SLEEP(struct taskqueue *tq, void *p, struct mtx *m, int pri, const char *wm,
- int t)
+TQ_SLEEP(struct taskqueue *tq, void *p, const char *wm)
{
#ifndef __rtems__
if (tq->tq_spin)
- return (msleep_spin(p, m, wm, t));
+ return (msleep_spin(p, (struct mtx *)&tq->tq_mutex, wm, 0));
#endif /* __rtems__ */
- return (msleep(p, m, pri, wm, t));
+ return (msleep(p, &tq->tq_mutex, 0, wm, 0));
}
static struct taskqueue *
@@ -165,7 +165,7 @@ _taskqueue_create(const char *name, int mflags,
snprintf(tq_name, TASKQUEUE_NAMELEN, "%s", (name) ? name : "taskqueue");
STAILQ_INIT(&queue->tq_queue);
- TAILQ_INIT(&queue->tq_active);
+ LIST_INIT(&queue->tq_active);
queue->tq_enqueue = enqueue;
queue->tq_context = context;
queue->tq_name = tq_name;
@@ -223,7 +223,7 @@ taskqueue_terminate(struct thread **pp, struct taskqueue *tq)
while (tq->tq_tcount > 0 || tq->tq_callouts > 0) {
wakeup(tq);
- TQ_SLEEP(tq, pp, &tq->tq_mutex, PWAIT, "taskqueue_destroy", 0);
+ TQ_SLEEP(tq, pp, "tq_destroy");
}
}
@@ -234,7 +234,7 @@ taskqueue_free(struct taskqueue *queue)
TQ_LOCK(queue);
queue->tq_flags &= ~TQ_FLAGS_ACTIVE;
taskqueue_terminate(queue->tq_threads, queue);
- KASSERT(TAILQ_EMPTY(&queue->tq_active), ("Tasks still running?"));
+ KASSERT(LIST_EMPTY(&queue->tq_active), ("Tasks still running?"));
KASSERT(queue->tq_callouts == 0, ("Armed timeout tasks"));
mtx_destroy(&queue->tq_mutex);
free(queue->tq_threads, M_TASKQUEUE);
@@ -260,21 +260,30 @@ taskqueue_enqueue_locked(struct taskqueue *queue, struct task *task)
}
/*
- * Optimise the case when all tasks have the same priority.
+ * Optimise cases when all tasks use small set of priorities.
+ * In case of only one priority we always insert at the end.
+ * In case of two tq_hint typically gives the insertion point.
+ * In case of more then two tq_hint should halve the search.
*/
prev = STAILQ_LAST(&queue->tq_queue, task, ta_link);
if (!prev || prev->ta_priority >= task->ta_priority) {
STAILQ_INSERT_TAIL(&queue->tq_queue, task, ta_link);
} else {
- prev = NULL;
- for (ins = STAILQ_FIRST(&queue->tq_queue); ins;
- prev = ins, ins = STAILQ_NEXT(ins, ta_link))
+ prev = queue->tq_hint;
+ if (prev && prev->ta_priority >= task->ta_priority) {
+ ins = STAILQ_NEXT(prev, ta_link);
+ } else {
+ prev = NULL;
+ ins = STAILQ_FIRST(&queue->tq_queue);
+ }
+ for (; ins; prev = ins, ins = STAILQ_NEXT(ins, ta_link))
if (ins->ta_priority < task->ta_priority)
break;
- if (prev)
+ if (prev) {
STAILQ_INSERT_AFTER(&queue->tq_queue, prev, task, ta_link);
- else
+ queue->tq_hint = task;
+ } else
STAILQ_INSERT_HEAD(&queue->tq_queue, task, ta_link);
}
@@ -393,6 +402,7 @@ taskqueue_drain_tq_queue(struct taskqueue *queue)
*/
TASK_INIT(&t_barrier, USHRT_MAX, taskqueue_task_nop_fn, &t_barrier);
STAILQ_INSERT_TAIL(&queue->tq_queue, &t_barrier, ta_link);
+ queue->tq_hint = &t_barrier;
t_barrier.ta_pending = 1;
/*
@@ -400,7 +410,7 @@ taskqueue_drain_tq_queue(struct taskqueue *queue)
* have completed or are currently executing.
*/
while (t_barrier.ta_pending != 0)
- TQ_SLEEP(queue, &t_barrier, &queue->tq_mutex, PWAIT, "-", 0);
+ TQ_SLEEP(queue, &t_barrier, "tq_qdrain");
return (1);
}
@@ -412,31 +422,24 @@ taskqueue_drain_tq_queue(struct taskqueue *queue)
static int
taskqueue_drain_tq_active(struct taskqueue *queue)
{
- struct taskqueue_busy tb_marker, *tb_first;
+ struct taskqueue_busy *tb;
+ u_int seq;
- if (TAILQ_EMPTY(&queue->tq_active))
+ if (LIST_EMPTY(&queue->tq_active))
return (0);
/* Block taskq_terminate().*/
queue->tq_callouts++;
- /*
- * Wait for all currently executing taskqueue threads
- * to go idle.
- */
- tb_marker.tb_running = TB_DRAIN_WAITER;
- TAILQ_INSERT_TAIL(&queue->tq_active, &tb_marker, tb_link);
- while (TAILQ_FIRST(&queue->tq_active) != &tb_marker)
- TQ_SLEEP(queue, &tb_marker, &queue->tq_mutex, PWAIT, "-", 0);
- TAILQ_REMOVE(&queue->tq_active, &tb_marker, tb_link);
-
- /*
- * Wakeup any other drain waiter that happened to queue up
- * without any intervening active thread.
- */
- tb_first = TAILQ_FIRST(&queue->tq_active);
- if (tb_first != NULL && tb_first->tb_running == TB_DRAIN_WAITER)
- wakeup(tb_first);
+ /* Wait for any active task with sequence from the past. */
+ seq = queue->tq_seq;
+restart:
+ LIST_FOREACH(tb, &queue->tq_active, tb_link) {
+ if ((int)(tb->tb_seq - seq) <= 0) {
+ TQ_SLEEP(queue, tb->tb_running, "tq_adrain");
+ goto restart;
+ }
+ }
/* Release taskqueue_terminate(). */
queue->tq_callouts--;
@@ -469,42 +472,31 @@ static void
taskqueue_run_locked(struct taskqueue *queue)
{
struct taskqueue_busy tb;
- struct taskqueue_busy *tb_first;
struct task *task;
int pending;
KASSERT(queue != NULL, ("tq is NULL"));
TQ_ASSERT_LOCKED(queue);
tb.tb_running = NULL;
+ LIST_INSERT_HEAD(&queue->tq_active, &tb, tb_link);
- while (STAILQ_FIRST(&queue->tq_queue)) {
- TAILQ_INSERT_TAIL(&queue->tq_active, &tb, tb_link);
-
- /*
- * Carefully remove the first task from the queue and
- * zero its pending count.
- */
- task = STAILQ_FIRST(&queue->tq_queue);
- KASSERT(task != NULL, ("task is NULL"));
+ while ((task = STAILQ_FIRST(&queue->tq_queue)) != NULL) {
STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link);
+ if (queue->tq_hint == task)
+ queue->tq_hint = NULL;
pending = task->ta_pending;
task->ta_pending = 0;
tb.tb_running = task;
+ tb.tb_seq = ++queue->tq_seq;
TQ_UNLOCK(queue);
KASSERT(task->ta_func != NULL, ("task->ta_func is NULL"));
task->ta_func(task->ta_context, pending);
TQ_LOCK(queue);
- tb.tb_running = NULL;
wakeup(task);
-
- TAILQ_REMOVE(&queue->tq_active, &tb, tb_link);
- tb_first = TAILQ_FIRST(&queue->tq_active);
- if (tb_first != NULL &&
- tb_first->tb_running == TB_DRAIN_WAITER)
- wakeup(tb_first);
}
+ LIST_REMOVE(&tb, tb_link);
}
void
@@ -522,7 +514,7 @@ task_is_running(struct taskqueue *queue, struct task *task)
struct taskqueue_busy *tb;
TQ_ASSERT_LOCKED(queue);
- TAILQ_FOREACH(tb, &queue->tq_active, tb_link) {
+ LIST_FOREACH(tb, &queue->tq_active, tb_link) {
if (tb->tb_running == task)
return (1);
}
@@ -551,8 +543,11 @@ taskqueue_cancel_locked(struct taskqueue *queue, struct task *task,
u_int *pendp)
{
- if (task->ta_pending > 0)
+ if (task->ta_pending > 0) {
STAILQ_REMOVE(&queue->tq_queue, task, task, ta_link);
+ if (queue->tq_hint == task)
+ queue->tq_hint = NULL;
+ }
if (pendp != NULL)
*pendp = task->ta_pending;
task->ta_pending = 0;
@@ -603,7 +598,7 @@ taskqueue_drain(struct taskqueue *queue, struct task *task)
TQ_LOCK(queue);
while (task->ta_pending != 0 || task_is_running(queue, task))
- TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0);
+ TQ_SLEEP(queue, task, "tq_drain");
TQ_UNLOCK(queue);
}
@@ -687,7 +682,7 @@ taskqueue_swi_giant_run(void *dummy)
static int
_taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
- cpuset_t *mask, const char *name, va_list ap)
+ cpuset_t *mask, struct proc *p, const char *name, va_list ap)
{
char ktname[MAXCOMLEN + 1];
struct thread *td;
@@ -709,10 +704,10 @@ _taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
for (i = 0; i < count; i++) {
if (count == 1)
- error = kthread_add(taskqueue_thread_loop, tqp, NULL,
+ error = kthread_add(taskqueue_thread_loop, tqp, p,
&tq->tq_threads[i], RFSTOPPED, 0, "%s", ktname);
else
- error = kthread_add(taskqueue_thread_loop, tqp, NULL,
+ error = kthread_add(taskqueue_thread_loop, tqp, p,
&tq->tq_threads[i], RFSTOPPED, 0,
"%s_%d", ktname, i);
if (error) {
@@ -766,7 +761,20 @@ taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
int error;
va_start(ap, name);
- error = _taskqueue_start_threads(tqp, count, pri, NULL, name, ap);
+ error = _taskqueue_start_threads(tqp, count, pri, NULL, NULL, name, ap);
+ va_end(ap);
+ return (error);
+}
+
+int
+taskqueue_start_threads_in_proc(struct taskqueue **tqp, int count, int pri,
+ struct proc *proc, const char *name, ...)
+{
+ va_list ap;
+ int error;
+
+ va_start(ap, name);
+ error = _taskqueue_start_threads(tqp, count, pri, NULL, proc, name, ap);
va_end(ap);
return (error);
}
@@ -779,7 +787,7 @@ taskqueue_start_threads_cpuset(struct taskqueue **tqp, int count, int pri,
int error;
va_start(ap, name);
- error = _taskqueue_start_threads(tqp, count, pri, mask, name, ap);
+ error = _taskqueue_start_threads(tqp, count, pri, mask, NULL, name, ap);
va_end(ap);
return (error);
}
@@ -815,7 +823,7 @@ taskqueue_thread_loop(void *arg)
*/
if ((tq->tq_flags & TQ_FLAGS_ACTIVE) == 0)
break;
- TQ_SLEEP(tq, tq, &tq->tq_mutex, 0, "-", 0);
+ TQ_SLEEP(tq, tq, "-");
}
taskqueue_run_locked(tq);
/*
diff --git a/freebsd/sys/kern/sys_pipe.c b/freebsd/sys/kern/sys_pipe.c
index e20c67ea..aef35fc1 100755
--- a/freebsd/sys/kern/sys_pipe.c
+++ b/freebsd/sys/kern/sys_pipe.c
@@ -1135,15 +1135,8 @@ retry:
goto error1;
}
- while (wpipe->pipe_map.cnt != 0) {
- if (wpipe->pipe_state & PIPE_EOF) {
- wpipe->pipe_map.cnt = 0;
- pipe_destroy_write_buffer(wpipe);
- pipeselwakeup(wpipe);
- pipeunlock(wpipe);
- error = EPIPE;
- goto error1;
- }
+ while (wpipe->pipe_map.cnt != 0 &&
+ (wpipe->pipe_state & PIPE_EOF) == 0) {
if (wpipe->pipe_state & PIPE_WANTR) {
wpipe->pipe_state &= ~PIPE_WANTR;
wakeup(wpipe);
@@ -1158,12 +1151,16 @@ retry:
break;
}
- if (wpipe->pipe_state & PIPE_EOF)
+ if ((wpipe->pipe_state & PIPE_EOF) != 0) {
+ wpipe->pipe_map.cnt = 0;
+ pipe_destroy_write_buffer(wpipe);
+ pipeselwakeup(wpipe);
error = EPIPE;
- if (error == EINTR || error == ERESTART)
+ } else if (error == EINTR || error == ERESTART) {
pipe_clone_write_buffer(wpipe);
- else
+ } else {
pipe_destroy_write_buffer(wpipe);
+ }
pipeunlock(wpipe);
KASSERT((wpipe->pipe_state & PIPE_DIRECTW) == 0,
("pipe %p leaked PIPE_DIRECTW", wpipe));
diff --git a/freebsd/sys/kern/tty.c b/freebsd/sys/kern/tty.c
index 88b928b9..d0b5633c 100644
--- a/freebsd/sys/kern/tty.c
+++ b/freebsd/sys/kern/tty.c
@@ -1184,6 +1184,7 @@ void
tty_rel_gone(struct tty *tp)
{
+ tty_lock_assert(tp, MA_OWNED);
MPASS(!tty_gone(tp));
/* Simulate carrier removal. */
@@ -1198,6 +1199,73 @@ tty_rel_gone(struct tty *tp)
tty_rel_free(tp);
}
+#ifndef __rtems__
+static int
+tty_drop_ctty(struct tty *tp, struct proc *p)
+{
+ struct session *session;
+ struct vnode *vp;
+
+ /*
+ * This looks terrible, but it's generally safe as long as the tty
+ * hasn't gone away while we had the lock dropped. All of our sanity
+ * checking that this operation is OK happens after we've picked it back
+ * up, so other state changes are generally not fatal and the potential
+ * for this particular operation to happen out-of-order in a
+ * multithreaded scenario is likely a non-issue.
+ */
+ tty_unlock(tp);
+ sx_xlock(&proctree_lock);
+ tty_lock(tp);
+ if (tty_gone(tp)) {
+ sx_xunlock(&proctree_lock);
+ return (ENODEV);
+ }
+
+ /*
+ * If the session doesn't have a controlling TTY, or if we weren't
+ * invoked on the controlling TTY, we'll return ENOIOCTL as we've
+ * historically done.
+ */
+ session = p->p_session;
+ if (session->s_ttyp == NULL || session->s_ttyp != tp) {
+ sx_xunlock(&proctree_lock);
+ return (ENOTTY);
+ }
+
+ if (!SESS_LEADER(p)) {
+ sx_xunlock(&proctree_lock);
+ return (EPERM);
+ }
+
+ PROC_LOCK(p);
+ SESS_LOCK(session);
+ vp = session->s_ttyvp;
+ session->s_ttyp = NULL;
+ session->s_ttyvp = NULL;
+ session->s_ttydp = NULL;
+ SESS_UNLOCK(session);
+
+ tp->t_sessioncnt--;
+ p->p_flag &= ~P_CONTROLT;
+ PROC_UNLOCK(p);
+ sx_xunlock(&proctree_lock);
+
+ /*
+ * If we did have a vnode, release our reference. Ordinarily we manage
+ * these at the devfs layer, but we can't necessarily know that we were
+ * invoked on the vnode referenced in the session (i.e. the vnode we
+ * hold a reference to). We explicitly don't check VBAD/VI_DOOMED here
+ * to avoid a vnode leak -- in circumstances elsewhere where we'd hit a
+ * VI_DOOMED vnode, release has been deferred until the controlling TTY
+ * is either changed or released.
+ */
+ if (vp != NULL)
+ vrele(vp);
+ return (0);
+}
+#endif /* __rtems__ */
+
/*
* Exposing information about current TTY's through sysctl
*/
@@ -1738,6 +1806,10 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
*(int *)data = NO_PID;
#endif /* __rtems__ */
return (0);
+#ifndef __rtems__
+ case TIOCNOTTY:
+ return (tty_drop_ctty(tp, td->td_proc));
+#endif /* __rtems__ */
case TIOCSCTTY: {
#ifndef __rtems__
struct proc *p = td->td_proc;
diff --git a/freebsd/sys/kern/uipc_mbuf2.c b/freebsd/sys/kern/uipc_mbuf2.c
index 6f98b0a2..7a0b9cf0 100644
--- a/freebsd/sys/kern/uipc_mbuf2.c
+++ b/freebsd/sys/kern/uipc_mbuf2.c
@@ -103,8 +103,8 @@ m_pulldown(struct mbuf *m, int off, int len, int *offp)
int writable;
/* check invalid arguments. */
- if (m == NULL)
- panic("m == NULL in m_pulldown()");
+ KASSERT(m != NULL, ("%s: fix caller: m is NULL off %d len %d offp %p\n",
+ __func__, off, len, offp));
if (len > MCLBYTES) {
m_freem(m);
return NULL; /* impossible */
diff --git a/freebsd/sys/kern/uipc_usrreq.c b/freebsd/sys/kern/uipc_usrreq.c
index fc4ee85d..13fca66d 100644
--- a/freebsd/sys/kern/uipc_usrreq.c
+++ b/freebsd/sys/kern/uipc_usrreq.c
@@ -2504,7 +2504,8 @@ unp_internalize(struct mbuf **controlp, struct thread *td)
goto out;
}
- controlp = &(*controlp)->m_next;
+ if (*controlp != NULL)
+ controlp = &(*controlp)->m_next;
if (CMSG_SPACE(datalen) < clen) {
clen -= CMSG_SPACE(datalen);
cm = (struct cmsghdr *)
diff --git a/freebsd/sys/net/dlt.h b/freebsd/sys/net/dlt.h
index 639e5a7f..31ad4e01 100644
--- a/freebsd/sys/net/dlt.h
+++ b/freebsd/sys/net/dlt.h
@@ -769,8 +769,17 @@
* IPMB packet for IPMI, beginning with the I2C slave address, followed
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
* <chanthy.toeung@ca.kontron.com>.
+ *
+ * XXX - this used to be called DLT_IPMB, back when we got the
+ * impression from the email thread requesting it that the packet
+ * had no extra 2-byte header. We've renamed it; if anybody used
+ * DLT_IPMB and assumed no 2-byte header, this will cause the compile
+ * to fail, at which point we'll have to figure out what to do about
+ * the two header types using the same DLT_/LINKTYPE_ value. If that
+ * doesn't happen, we'll assume nobody used it and that the redefinition
+ * is safe.
*/
-#define DLT_IPMB 199
+#define DLT_IPMB_KONTRON 199
/*
* Juniper-private data link type, as per request from
@@ -1365,6 +1374,11 @@
#define DLT_DISPLAYPORT_AUX 275
/*
+ * Linux cooked sockets v2.
+ */
+#define DLT_LINUX_SLL2 276
+
+/*
* In case the code that includes this file (directly or indirectly)
* has also included OS files that happen to define DLT_MATCHING_MAX,
* with a different value (perhaps because that OS hasn't picked up
@@ -1374,7 +1388,7 @@
#ifdef DLT_MATCHING_MAX
#undef DLT_MATCHING_MAX
#endif
-#define DLT_MATCHING_MAX 275 /* highest value in the "matching" range */
+#define DLT_MATCHING_MAX 276 /* highest value in the "matching" range */
/*
* DLT and savefile link type values are split into a class and
diff --git a/freebsd/sys/net/if.c b/freebsd/sys/net/if.c
index d57e6983..37e1581b 100644
--- a/freebsd/sys/net/if.c
+++ b/freebsd/sys/net/if.c
@@ -34,6 +34,7 @@
* $FreeBSD$
*/
+#include <rtems/bsd/local/opt_bpf.h>
#include <rtems/bsd/local/opt_inet6.h>
#include <rtems/bsd/local/opt_inet.h>
@@ -1253,16 +1254,20 @@ static void
if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
{
struct if_clone *ifc;
+#ifdef DEV_BPF
u_int bif_dlt, bif_hdrlen;
+#endif
void *old;
int rc;
+#ifdef DEV_BPF
/*
* if_detach_internal() will call the eventhandler to notify
* interface departure. That will detach if_bpf. We need to
* safe the dlt and hdrlen so we can re-attach it later.
*/
bpf_get_bp_params(ifp->if_bpf, &bif_dlt, &bif_hdrlen);
+#endif
/*
* Detach from current vnet, but preserve LLADDR info, do not
@@ -1309,8 +1314,10 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
if_attach_internal(ifp, 1, ifc);
+#ifdef DEV_BPF
if (ifp->if_bpf == NULL)
bpfattach(ifp, bif_dlt, bif_hdrlen);
+#endif
CURVNET_RESTORE();
}
@@ -1447,14 +1454,12 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
return (EEXIST);
}
- if ((ifgl = (struct ifg_list *)malloc(sizeof(struct ifg_list), M_TEMP,
- M_NOWAIT)) == NULL) {
+ if ((ifgl = malloc(sizeof(*ifgl), M_TEMP, M_NOWAIT)) == NULL) {
IFNET_WUNLOCK();
return (ENOMEM);
}
- if ((ifgm = (struct ifg_member *)malloc(sizeof(struct ifg_member),
- M_TEMP, M_NOWAIT)) == NULL) {
+ if ((ifgm = malloc(sizeof(*ifgm), M_TEMP, M_NOWAIT)) == NULL) {
free(ifgl, M_TEMP);
IFNET_WUNLOCK();
return (ENOMEM);
@@ -1465,8 +1470,7 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
break;
if (ifg == NULL) {
- if ((ifg = (struct ifg_group *)malloc(sizeof(struct ifg_group),
- M_TEMP, M_NOWAIT)) == NULL) {
+ if ((ifg = malloc(sizeof(*ifg), M_TEMP, M_NOWAIT)) == NULL) {
free(ifgl, M_TEMP);
free(ifgm, M_TEMP);
IFNET_WUNLOCK();
@@ -1498,39 +1502,36 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
}
/*
- * Remove a group from an interface
+ * Helper function to remove a group out of an interface. Expects the global
+ * ifnet lock to be write-locked, and drops it before returning.
*/
-int
-if_delgroup(struct ifnet *ifp, const char *groupname)
+static void
+_if_delgroup_locked(struct ifnet *ifp, struct ifg_list *ifgl,
+ const char *groupname)
{
- struct ifg_list *ifgl;
- struct ifg_member *ifgm;
- int freeifgl;
+ struct ifg_member *ifgm;
+ bool freeifgl;
- IFNET_WLOCK();
- CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
- if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
- break;
- if (ifgl == NULL) {
- IFNET_WUNLOCK();
- return (ENOENT);
- }
+ IFNET_WLOCK_ASSERT();
- freeifgl = 0;
IF_ADDR_WLOCK(ifp);
CK_STAILQ_REMOVE(&ifp->if_groups, ifgl, ifg_list, ifgl_next);
IF_ADDR_WUNLOCK(ifp);
- CK_STAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
- if (ifgm->ifgm_ifp == ifp)
+ CK_STAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next) {
+ if (ifgm->ifgm_ifp == ifp) {
+ CK_STAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm,
+ ifg_member, ifgm_next);
break;
-
- if (ifgm != NULL)
- CK_STAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifg_member, ifgm_next);
+ }
+ }
if (--ifgl->ifgl_group->ifg_refcnt == 0) {
- CK_STAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_group, ifg_next);
- freeifgl = 1;
+ CK_STAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_group,
+ ifg_next);
+ freeifgl = true;
+ } else {
+ freeifgl = false;
}
IFNET_WUNLOCK();
@@ -1543,6 +1544,26 @@ if_delgroup(struct ifnet *ifp, const char *groupname)
free(ifgl, M_TEMP);
EVENTHANDLER_INVOKE(group_change_event, groupname);
+}
+
+/*
+ * Remove a group from an interface
+ */
+int
+if_delgroup(struct ifnet *ifp, const char *groupname)
+{
+ struct ifg_list *ifgl;
+
+ IFNET_WLOCK();
+ CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
+ if (strcmp(ifgl->ifgl_group->ifg_group, groupname) == 0)
+ break;
+ if (ifgl == NULL) {
+ IFNET_WUNLOCK();
+ return (ENOENT);
+ }
+
+ _if_delgroup_locked(ifp, ifgl, groupname);
return (0);
}
@@ -1553,44 +1574,13 @@ if_delgroup(struct ifnet *ifp, const char *groupname)
static void
if_delgroups(struct ifnet *ifp)
{
- struct ifg_list *ifgl;
- struct ifg_member *ifgm;
+ struct ifg_list *ifgl;
char groupname[IFNAMSIZ];
- int ifglfree;
IFNET_WLOCK();
- while (!CK_STAILQ_EMPTY(&ifp->if_groups)) {
- ifgl = CK_STAILQ_FIRST(&ifp->if_groups);
-
+ while ((ifgl = CK_STAILQ_FIRST(&ifp->if_groups)) != NULL) {
strlcpy(groupname, ifgl->ifgl_group->ifg_group, IFNAMSIZ);
-
- IF_ADDR_WLOCK(ifp);
- CK_STAILQ_REMOVE(&ifp->if_groups, ifgl, ifg_list, ifgl_next);
- IF_ADDR_WUNLOCK(ifp);
-
- CK_STAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
- if (ifgm->ifgm_ifp == ifp)
- break;
-
- if (ifgm != NULL)
- CK_STAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifg_member,
- ifgm_next);
- ifglfree = 0;
- if (--ifgl->ifgl_group->ifg_refcnt == 0) {
- CK_STAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_group, ifg_next);
- ifglfree = 1;
- }
-
- IFNET_WUNLOCK();
- epoch_wait_preempt(net_epoch_preempt);
- free(ifgm, M_TEMP);
- if (ifglfree) {
- EVENTHANDLER_INVOKE(group_detach_event,
- ifgl->ifgl_group);
- free(ifgl->ifgl_group, M_TEMP);
- }
- EVENTHANDLER_INVOKE(group_change_event, groupname);
-
+ _if_delgroup_locked(ifp, ifgl, groupname);
IFNET_WLOCK();
}
IFNET_WUNLOCK();
@@ -1678,7 +1668,7 @@ if_getgroupmembers(struct ifgroupreq *ifgr)
IFNET_RLOCK();
CK_STAILQ_FOREACH(ifg, &V_ifg_head, ifg_next)
- if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
+ if (strcmp(ifg->ifg_group, ifgr->ifgr_name) == 0)
break;
if (ifg == NULL) {
IFNET_RUNLOCK();
@@ -1957,10 +1947,13 @@ ifa_maintain_loopback_route(int cmd, const char *otype, struct ifaddr *ifa,
error = rtrequest1_fib(cmd, &info, NULL, ifp->if_fib);
- if (error != 0 &&
- !(cmd == RTM_ADD && error == EEXIST) &&
- !(cmd == RTM_DELETE && error == ENOENT))
- if_printf(ifp, "%s failed: %d\n", otype, error);
+ if (error == 0 ||
+ (cmd == RTM_ADD && error == EEXIST) ||
+ (cmd == RTM_DELETE && (error == ENOENT || error == ESRCH)))
+ return (error);
+
+ log(LOG_DEBUG, "%s: %s failed for interface %s: %u\n",
+ __func__, otype, if_name(ifp), error);
return (error);
}
@@ -2951,6 +2944,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
case SIOCGIFGENERIC:
case SIOCGIFRSSKEY:
case SIOCGIFRSSHASH:
+ case SIOCGIFDOWNREASON:
if (ifp->if_ioctl == NULL)
return (EOPNOTSUPP);
error = (*ifp->if_ioctl)(ifp, cmd, data);
diff --git a/freebsd/sys/net/if_bridge.c b/freebsd/sys/net/if_bridge.c
index 4bfb67a8..2544c4f5 100644
--- a/freebsd/sys/net/if_bridge.c
+++ b/freebsd/sys/net/if_bridge.c
@@ -137,6 +137,14 @@ __FBSDID("$FreeBSD$");
#include <net/route.h>
+#ifdef INET6
+/*
+ * XXX: declare here to avoid to include many inet6 related files..
+ * should be more generalized?
+ */
+extern void nd6_setmtu(struct ifnet *);
+#endif
+
/*
* Size of the route hash table. Must be a power of two.
*/
@@ -774,7 +782,7 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
} args;
struct ifdrv *ifd = (struct ifdrv *) data;
const struct bridge_control *bc;
- int error = 0;
+ int error = 0, oldmtu;
switch (cmd) {
@@ -820,12 +828,24 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
+ oldmtu = ifp->if_mtu;
BRIDGE_LOCK(sc);
error = (*bc->bc_func)(sc, &args);
BRIDGE_UNLOCK(sc);
if (error)
break;
+ /*
+ * Bridge MTU may change during addition of the first port.
+ * If it did, do network layer specific procedure.
+ */
+ if (ifp->if_mtu != oldmtu) {
+#ifdef INET6
+ nd6_setmtu(ifp);
+#endif
+ rt_updatemtu(ifp);
+ }
+
if (bc->bc_flags & BC_F_COPYOUT)
error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
diff --git a/freebsd/sys/net/if_clone.c b/freebsd/sys/net/if_clone.c
index 1fa79766..ac59b635 100644
--- a/freebsd/sys/net/if_clone.c
+++ b/freebsd/sys/net/if_clone.c
@@ -213,6 +213,18 @@ if_clone_create(char *name, size_t len, caddr_t params)
return (if_clone_createif(ifc, name, len, params));
}
+void
+if_clone_addif(struct if_clone *ifc, struct ifnet *ifp)
+{
+
+ if ((ifc->ifc_flags & IFC_NOGROUP) == 0)
+ if_addgroup(ifp, ifc->ifc_name);
+
+ IF_CLONE_LOCK(ifc);
+ IFC_IFLIST_INSERT(ifc, ifp);
+ IF_CLONE_UNLOCK(ifc);
+}
+
/*
* Create a clone network interface.
*/
@@ -235,12 +247,7 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
if (ifp == NULL)
panic("%s: lookup failed for %s", __func__, name);
- if ((ifc->ifc_flags & IFC_NOGROUP) == 0)
- if_addgroup(ifp, ifc->ifc_name);
-
- IF_CLONE_LOCK(ifc);
- IFC_IFLIST_INSERT(ifc, ifp);
- IF_CLONE_UNLOCK(ifc);
+ if_clone_addif(ifc, ifp);
}
return (err);
diff --git a/freebsd/sys/net/if_clone.h b/freebsd/sys/net/if_clone.h
index 5dceacf6..b721e294 100644
--- a/freebsd/sys/net/if_clone.h
+++ b/freebsd/sys/net/if_clone.h
@@ -79,7 +79,8 @@ int if_clone_list(struct if_clonereq *);
struct if_clone *if_clone_findifc(struct ifnet *);
void if_clone_addgroup(struct ifnet *, struct if_clone *);
-/* The below interface used only by epair(4). */
+/* The below interfaces are used only by epair(4). */
+void if_clone_addif(struct if_clone *, struct ifnet *);
int if_clone_destroyif(struct if_clone *, struct ifnet *);
#endif /* _KERNEL */
diff --git a/freebsd/sys/net/if_epair.c b/freebsd/sys/net/if_epair.c
index 69ff3efc..f4a875b7 100644
--- a/freebsd/sys/net/if_epair.c
+++ b/freebsd/sys/net/if_epair.c
@@ -713,6 +713,21 @@ epair_clone_match(struct if_clone *ifc, const char *name)
return (1);
}
+static void
+epair_clone_add(struct if_clone *ifc, struct epair_softc *scb)
+{
+ struct ifnet *ifp;
+ uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */
+
+ ifp = scb->ifp;
+ /* Copy epairNa etheraddr and change the last byte. */
+ memcpy(eaddr, scb->oifp->if_hw_addr, ETHER_ADDR_LEN);
+ eaddr[5] = 0x0b;
+ ether_ifattach(ifp, eaddr);
+
+ if_clone_addif(ifc, ifp);
+}
+
static int
epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
{
@@ -725,24 +740,6 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
uint32_t hash;
uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */
- /*
- * We are abusing params to create our second interface.
- * Actually we already created it and called if_clone_create()
- * for it to do the official insertion procedure the moment we knew
- * it cannot fail anymore. So just do attach it here.
- */
- if (params) {
- scb = (struct epair_softc *)params;
- ifp = scb->ifp;
- /* Copy epairNa etheraddr and change the last byte. */
- memcpy(eaddr, scb->oifp->if_hw_addr, ETHER_ADDR_LEN);
- eaddr[5] = 0x0b;
- ether_ifattach(ifp, eaddr);
- /* Correctly set the name for the cloner list. */
- strlcpy(name, ifp->if_xname, len);
- return (0);
- }
-
/* Try to see if a special unit was requested. */
error = ifc_name2unit(name, &unit);
if (error != 0)
@@ -893,10 +890,11 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
if_setsendqready(ifp);
/* We need to play some tricks here for the second interface. */
strlcpy(name, epairname, len);
- error = if_clone_create(name, len, (caddr_t)scb);
- if (error)
- panic("%s: if_clone_create() for our 2nd iface failed: %d",
- __func__, error);
+
+ /* Correctly set the name for the cloner list. */
+ strlcpy(name, scb->ifp->if_xname, len);
+ epair_clone_add(ifc, scb);
+
scb->if_qflush = ifp->if_qflush;
ifp->if_qflush = epair_qflush;
ifp->if_transmit = epair_transmit;
diff --git a/freebsd/sys/net/if_lagg.c b/freebsd/sys/net/if_lagg.c
index af6f1667..2d133ec4 100644
--- a/freebsd/sys/net/if_lagg.c
+++ b/freebsd/sys/net/if_lagg.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/bpf.h>
+#include <net/route.h>
#include <net/vnet.h>
#if defined(INET) || defined(INET6)
@@ -75,6 +76,14 @@ __FBSDID("$FreeBSD$");
#include <net/if_lagg.h>
#include <net/ieee8023ad_lacp.h>
+#ifdef INET6
+/*
+ * XXX: declare here to avoid to include many inet6 related files..
+ * should be more generalized?
+ */
+extern void nd6_setmtu(struct ifnet *);
+#endif
+
#define LAGG_RLOCK() struct epoch_tracker lagg_et; epoch_enter_preempt(net_epoch_preempt, &lagg_et)
#define LAGG_RUNLOCK() epoch_exit_preempt(net_epoch_preempt, &lagg_et)
#define LAGG_RLOCK_ASSERT() MPASS(in_epoch(net_epoch_preempt))
@@ -1154,7 +1163,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
struct ifnet *tpif;
struct thread *td = curthread;
char *buf, *outbuf;
- int count, buflen, len, error = 0;
+ int count, buflen, len, error = 0, oldmtu;
bzero(&rpbuf, sizeof(rpbuf));
@@ -1221,23 +1230,35 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
ro->ro_active += LAGG_PORTACTIVE(lp);
}
- ro->ro_bkt = sc->sc_bkt;
+ ro->ro_bkt = sc->sc_stride;
ro->ro_flapping = sc->sc_flapping;
ro->ro_flowid_shift = sc->flowid_shift;
LAGG_XUNLOCK(sc);
break;
case SIOCSLAGGOPTS:
- if (sc->sc_proto == LAGG_PROTO_ROUNDROBIN) {
- if (ro->ro_bkt == 0)
- sc->sc_bkt = 1; // Minimum 1 packet per iface.
- else
- sc->sc_bkt = ro->ro_bkt;
- }
error = priv_check(td, PRIV_NET_LAGG);
if (error)
break;
- if (ro->ro_opts == 0)
+
+ /*
+ * The stride option was added without defining a corresponding
+ * LAGG_OPT flag, so handle a non-zero value before checking
+ * anything else to preserve compatibility.
+ */
+ LAGG_XLOCK(sc);
+ if (ro->ro_opts == 0 && ro->ro_bkt != 0) {
+ if (sc->sc_proto != LAGG_PROTO_ROUNDROBIN) {
+ LAGG_XUNLOCK(sc);
+ error = EINVAL;
+ break;
+ }
+ sc->sc_stride = ro->ro_bkt;
+ }
+ if (ro->ro_opts == 0) {
+ LAGG_XUNLOCK(sc);
break;
+ }
+
/*
* Set options. LACP options are stored in sc->sc_psc,
* not in sc_opts.
@@ -1248,6 +1269,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case LAGG_OPT_USE_FLOWID:
case -LAGG_OPT_USE_FLOWID:
case LAGG_OPT_FLOWIDSHIFT:
+ case LAGG_OPT_RR_LIMIT:
valid = 1;
lacp = 0;
break;
@@ -1266,8 +1288,6 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
- LAGG_XLOCK(sc);
-
if (valid == 0 ||
(lacp == 1 && sc->sc_proto != LAGG_PROTO_LACP)) {
/* Invalid combination of options specified. */
@@ -1275,14 +1295,23 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
LAGG_XUNLOCK(sc);
break; /* Return from SIOCSLAGGOPTS. */
}
+
/*
* Store new options into sc->sc_opts except for
- * FLOWIDSHIFT and LACP options.
+ * FLOWIDSHIFT, RR and LACP options.
*/
if (lacp == 0) {
if (ro->ro_opts == LAGG_OPT_FLOWIDSHIFT)
sc->flowid_shift = ro->ro_flowid_shift;
- else if (ro->ro_opts > 0)
+ else if (ro->ro_opts == LAGG_OPT_RR_LIMIT) {
+ if (sc->sc_proto != LAGG_PROTO_ROUNDROBIN ||
+ ro->ro_bkt == 0) {
+ error = EINVAL;
+ LAGG_XUNLOCK(sc);
+ break;
+ }
+ sc->sc_stride = ro->ro_bkt;
+ } else if (ro->ro_opts > 0)
sc->sc_opts |= ro->ro_opts;
else
sc->sc_opts &= ~ro->ro_opts;
@@ -1407,10 +1436,23 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
tpif->if_xname);
}
#endif
+ oldmtu = ifp->if_mtu;
LAGG_XLOCK(sc);
error = lagg_port_create(sc, tpif);
LAGG_XUNLOCK(sc);
if_rele(tpif);
+
+ /*
+ * LAGG MTU may change during addition of the first port.
+ * If it did, do network layer specific procedure.
+ */
+ if (ifp->if_mtu != oldmtu) {
+#ifdef INET6
+ nd6_setmtu(ifp);
+#endif
+ rt_updatemtu(ifp);
+ }
+
VLAN_CAPABILITIES(ifp);
break;
case SIOCSLAGGDELPORT:
@@ -1904,7 +1946,7 @@ static void
lagg_rr_attach(struct lagg_softc *sc)
{
sc->sc_seq = 0;
- sc->sc_bkt_count = sc->sc_bkt;
+ sc->sc_stride = 1;
}
static int
@@ -1913,18 +1955,8 @@ lagg_rr_start(struct lagg_softc *sc, struct mbuf *m)
struct lagg_port *lp;
uint32_t p;
- if (sc->sc_bkt_count == 0 && sc->sc_bkt > 0)
- sc->sc_bkt_count = sc->sc_bkt;
-
- if (sc->sc_bkt > 0) {
- atomic_subtract_int(&sc->sc_bkt_count, 1);
- if (atomic_cmpset_int(&sc->sc_bkt_count, 0, sc->sc_bkt))
- p = atomic_fetchadd_32(&sc->sc_seq, 1);
- else
- p = sc->sc_seq;
- } else
- p = atomic_fetchadd_32(&sc->sc_seq, 1);
-
+ p = atomic_fetchadd_32(&sc->sc_seq, 1);
+ p /= sc->sc_stride;
p %= sc->sc_count;
lp = CK_SLIST_FIRST(&sc->sc_ports);
diff --git a/freebsd/sys/net/if_lagg.h b/freebsd/sys/net/if_lagg.h
index f1e2d8f4..c4256a45 100644
--- a/freebsd/sys/net/if_lagg.h
+++ b/freebsd/sys/net/if_lagg.h
@@ -63,11 +63,11 @@ struct lagg_protos {
#define LAGG_PROTO_DEFAULT LAGG_PROTO_FAILOVER
#define LAGG_PROTOS { \
- { "failover", LAGG_PROTO_FAILOVER }, \
+ { "failover", LAGG_PROTO_FAILOVER }, \
{ "lacp", LAGG_PROTO_LACP }, \
{ "loadbalance", LAGG_PROTO_LOADBALANCE }, \
- { "roundrobin", LAGG_PROTO_ROUNDROBIN }, \
- { "broadcast", LAGG_PROTO_BROADCAST }, \
+ { "roundrobin", LAGG_PROTO_ROUNDROBIN }, \
+ { "broadcast", LAGG_PROTO_BROADCAST }, \
{ "none", LAGG_PROTO_NONE }, \
{ "default", LAGG_PROTO_DEFAULT } \
}
@@ -148,11 +148,12 @@ struct lagg_reqopts {
#define LAGG_OPT_LACP_TXTEST 0x20 /* LACP debug: txtest */
#define LAGG_OPT_LACP_RXTEST 0x40 /* LACP debug: rxtest */
#define LAGG_OPT_LACP_TIMEOUT 0x80 /* LACP timeout */
+#define LAGG_OPT_RR_LIMIT 0x100 /* RR stride */
u_int ro_count; /* number of ports */
u_int ro_active; /* active port count */
u_int ro_flapping; /* number of flapping */
int ro_flowid_shift; /* shift the flowid */
- uint32_t ro_bkt; /* packet bucket for roundrobin */
+ uint32_t ro_bkt; /* stride for RR */
};
#define SIOCGLAGGOPTS _IOWR('i', 152, struct lagg_reqopts)
@@ -214,6 +215,7 @@ struct lagg_softc {
struct ifmedia sc_media; /* media config */
void *sc_psc; /* protocol data */
uint32_t sc_seq; /* sequence counter */
+ uint32_t sc_stride; /* stride for RR */
uint32_t sc_flags;
int sc_destroying; /* destroying lagg */
@@ -225,8 +227,6 @@ struct lagg_softc {
struct callout sc_callout;
u_int sc_opts;
int flowid_shift; /* shift the flowid */
- uint32_t sc_bkt; /* packates bucket for roundrobin */
- uint32_t sc_bkt_count; /* packates bucket count for roundrobin */
struct lagg_counters detached_counters; /* detached ports sum */
};
diff --git a/freebsd/sys/net/if_llatbl.c b/freebsd/sys/net/if_llatbl.c
index b220d7aa..7b5c3a91 100644
--- a/freebsd/sys/net/if_llatbl.c
+++ b/freebsd/sys/net/if_llatbl.c
@@ -81,11 +81,6 @@ RW_SYSINIT(lltable_list_lock, &lltable_list_lock, "lltable_list_lock");
static void lltable_unlink(struct lltable *llt);
static void llentries_unlink(struct lltable *llt, struct llentries *head);
-static void htable_unlink_entry(struct llentry *lle);
-static void htable_link_entry(struct lltable *llt, struct llentry *lle);
-static int htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f,
- void *farg);
-
/*
* Dump lle state for a specific address family.
*/
@@ -182,15 +177,16 @@ static void
htable_unlink_entry(struct llentry *lle)
{
- if ((lle->la_flags & LLE_LINKED) != 0) {
- IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp);
- CK_LIST_REMOVE(lle, lle_next);
- lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
+ if ((lle->la_flags & LLE_LINKED) == 0)
+ return;
+
+ IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp);
+ CK_LIST_REMOVE(lle, lle_next);
+ lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
#if 0
- lle->lle_tbl = NULL;
- lle->lle_head = NULL;
+ lle->lle_tbl = NULL;
+ lle->lle_head = NULL;
#endif
- }
}
struct prefix_match_data {
diff --git a/freebsd/sys/net/if_tap.c b/freebsd/sys/net/if_tap.c
deleted file mode 100644
index 4ca35b66..00000000
--- a/freebsd/sys/net/if_tap.c
+++ /dev/null
@@ -1,1153 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
- *
- * BASED ON:
- * -------------------------------------------------------------------------
- *
- * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
- * Nottingham University 1987.
- */
-
-/*
- * $FreeBSD$
- * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $
- */
-
-#include <rtems/bsd/local/opt_inet.h>
-
-#include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/lock.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/jail.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <sys/poll.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/selinfo.h>
-#include <sys/signalvar.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/sx.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
-#include <sys/ttycom.h>
-#include <sys/uio.h>
-#include <sys/queue.h>
-
-#include <net/bpf.h>
-#include <net/ethernet.h>
-#include <net/if.h>
-#include <net/if_var.h>
-#include <net/if_clone.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-#include <net/route.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-
-#include <net/if_tapvar.h>
-#include <net/if_tap.h>
-
-#define CDEV_NAME "tap"
-#define TAPDEBUG if (tapdebug) printf
-
-static const char tapname[] = "tap";
-static const char vmnetname[] = "vmnet";
-#define TAPMAXUNIT 0x7fff
-#define VMNET_DEV_MASK CLONE_FLAG0
-
-/* module */
-static int tapmodevent(module_t, int, void *);
-
-/* device */
-static void tapclone(void *, struct ucred *, char *, int,
- struct cdev **);
-static void tapcreate(struct cdev *);
-
-/* network interface */
-static void tapifstart(struct ifnet *);
-static int tapifioctl(struct ifnet *, u_long, caddr_t);
-static void tapifinit(void *);
-
-static int tap_clone_create(struct if_clone *, int, caddr_t);
-static void tap_clone_destroy(struct ifnet *);
-static struct if_clone *tap_cloner;
-static int vmnet_clone_create(struct if_clone *, int, caddr_t);
-static void vmnet_clone_destroy(struct ifnet *);
-static struct if_clone *vmnet_cloner;
-
-/* character device */
-static d_open_t tapopen;
-static d_close_t tapclose;
-static d_read_t tapread;
-static d_write_t tapwrite;
-static d_ioctl_t tapioctl;
-static d_poll_t tappoll;
-static d_kqfilter_t tapkqfilter;
-
-/* kqueue(2) */
-static int tapkqread(struct knote *, long);
-static int tapkqwrite(struct knote *, long);
-static void tapkqdetach(struct knote *);
-
-static struct filterops tap_read_filterops = {
- .f_isfd = 1,
- .f_attach = NULL,
- .f_detach = tapkqdetach,
- .f_event = tapkqread,
-};
-
-static struct filterops tap_write_filterops = {
- .f_isfd = 1,
- .f_attach = NULL,
- .f_detach = tapkqdetach,
- .f_event = tapkqwrite,
-};
-
-static struct cdevsw tap_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDMINOR,
- .d_open = tapopen,
- .d_close = tapclose,
- .d_read = tapread,
- .d_write = tapwrite,
- .d_ioctl = tapioctl,
- .d_poll = tappoll,
- .d_name = CDEV_NAME,
- .d_kqfilter = tapkqfilter,
-};
-
-/*
- * All global variables in if_tap.c are locked with tapmtx, with the
- * exception of tapdebug, which is accessed unlocked; tapclones is
- * static at runtime.
- */
-static struct mtx tapmtx;
-static int tapdebug = 0; /* debug flag */
-static int tapuopen = 0; /* allow user open() */
-static int tapuponopen = 0; /* IFF_UP on open() */
-static int tapdclone = 1; /* enable devfs cloning */
-static SLIST_HEAD(, tap_softc) taphead; /* first device */
-static struct clonedevs *tapclones;
-
-MALLOC_DECLARE(M_TAP);
-MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface");
-SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, "");
-
-static struct sx tap_ioctl_sx;
-SX_SYSINIT(tap_ioctl_sx, &tap_ioctl_sx, "tap_ioctl");
-
-SYSCTL_DECL(_net_link);
-static SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0,
- "Ethernet tunnel software network interface");
-SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tapuopen, 0,
- "Allow user to open /dev/tap (based on node permissions)");
-SYSCTL_INT(_net_link_tap, OID_AUTO, up_on_open, CTLFLAG_RW, &tapuponopen, 0,
- "Bring interface up when /dev/tap is opened");
-SYSCTL_INT(_net_link_tap, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tapdclone, 0,
- "Enable legacy devfs interface creation");
-SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tapdebug, 0, "");
-
-DEV_MODULE(if_tap, tapmodevent, NULL);
-MODULE_VERSION(if_tap, 1);
-
-static int
-tap_clone_create(struct if_clone *ifc, int unit, caddr_t params)
-{
- struct cdev *dev;
- int i;
-
- /* Find any existing device, or allocate new unit number. */
- i = clone_create(&tapclones, &tap_cdevsw, &unit, &dev, 0);
- if (i) {
- dev = make_dev(&tap_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600,
- "%s%d", tapname, unit);
- }
-
- tapcreate(dev);
- return (0);
-}
-
-/* vmnet devices are tap devices in disguise */
-static int
-vmnet_clone_create(struct if_clone *ifc, int unit, caddr_t params)
-{
- struct cdev *dev;
- int i;
-
- /* Find any existing device, or allocate new unit number. */
- i = clone_create(&tapclones, &tap_cdevsw, &unit, &dev, VMNET_DEV_MASK);
- if (i) {
- dev = make_dev(&tap_cdevsw, unit | VMNET_DEV_MASK, UID_ROOT,
- GID_WHEEL, 0600, "%s%d", vmnetname, unit);
- }
-
- tapcreate(dev);
- return (0);
-}
-
-static void
-tap_destroy(struct tap_softc *tp)
-{
- struct ifnet *ifp = tp->tap_ifp;
-
- CURVNET_SET(ifp->if_vnet);
-
- destroy_dev(tp->tap_dev);
- seldrain(&tp->tap_rsel);
- knlist_clear(&tp->tap_rsel.si_note, 0);
- knlist_destroy(&tp->tap_rsel.si_note);
- ether_ifdetach(ifp);
-
- sx_xlock(&tap_ioctl_sx);
- ifp->if_softc = NULL;
- sx_xunlock(&tap_ioctl_sx);
-
- if_free(ifp);
-
- mtx_destroy(&tp->tap_mtx);
- free(tp, M_TAP);
- CURVNET_RESTORE();
-}
-
-static void
-tap_clone_destroy(struct ifnet *ifp)
-{
- struct tap_softc *tp = ifp->if_softc;
-
- mtx_lock(&tapmtx);
- SLIST_REMOVE(&taphead, tp, tap_softc, tap_next);
- mtx_unlock(&tapmtx);
- tap_destroy(tp);
-}
-
-/* vmnet devices are tap devices in disguise */
-static void
-vmnet_clone_destroy(struct ifnet *ifp)
-{
- tap_clone_destroy(ifp);
-}
-
-/*
- * tapmodevent
- *
- * module event handler
- */
-static int
-tapmodevent(module_t mod, int type, void *data)
-{
- static eventhandler_tag eh_tag = NULL;
- struct tap_softc *tp = NULL;
- struct ifnet *ifp = NULL;
-
- switch (type) {
- case MOD_LOAD:
-
- /* intitialize device */
-
- mtx_init(&tapmtx, "tapmtx", NULL, MTX_DEF);
- SLIST_INIT(&taphead);
-
- clone_setup(&tapclones);
- eh_tag = EVENTHANDLER_REGISTER(dev_clone, tapclone, 0, 1000);
- if (eh_tag == NULL) {
- clone_cleanup(&tapclones);
- mtx_destroy(&tapmtx);
- return (ENOMEM);
- }
- tap_cloner = if_clone_simple(tapname, tap_clone_create,
- tap_clone_destroy, 0);
- vmnet_cloner = if_clone_simple(vmnetname, vmnet_clone_create,
- vmnet_clone_destroy, 0);
- return (0);
-
- case MOD_UNLOAD:
- /*
- * The EBUSY algorithm here can't quite atomically
- * guarantee that this is race-free since we have to
- * release the tap mtx to deregister the clone handler.
- */
- mtx_lock(&tapmtx);
- SLIST_FOREACH(tp, &taphead, tap_next) {
- mtx_lock(&tp->tap_mtx);
- if (tp->tap_flags & TAP_OPEN) {
- mtx_unlock(&tp->tap_mtx);
- mtx_unlock(&tapmtx);
- return (EBUSY);
- }
- mtx_unlock(&tp->tap_mtx);
- }
- mtx_unlock(&tapmtx);
-
- EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
- if_clone_detach(tap_cloner);
- if_clone_detach(vmnet_cloner);
- drain_dev_clone_events();
-
- mtx_lock(&tapmtx);
- while ((tp = SLIST_FIRST(&taphead)) != NULL) {
- SLIST_REMOVE_HEAD(&taphead, tap_next);
- mtx_unlock(&tapmtx);
-
- ifp = tp->tap_ifp;
-
- TAPDEBUG("detaching %s\n", ifp->if_xname);
-
- tap_destroy(tp);
- mtx_lock(&tapmtx);
- }
- mtx_unlock(&tapmtx);
- clone_cleanup(&tapclones);
-
- mtx_destroy(&tapmtx);
-
- break;
-
- default:
- return (EOPNOTSUPP);
- }
-
- return (0);
-} /* tapmodevent */
-
-
-/*
- * DEVFS handler
- *
- * We need to support two kind of devices - tap and vmnet
- */
-static void
-tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev)
-{
- char devname[SPECNAMELEN + 1];
- int i, unit, append_unit;
- int extra;
-
- if (*dev != NULL)
- return;
-
- if (!tapdclone ||
- (!tapuopen && priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0))
- return;
-
- unit = 0;
- append_unit = 0;
- extra = 0;
-
- /* We're interested in only tap/vmnet devices. */
- if (strcmp(name, tapname) == 0) {
- unit = -1;
- } else if (strcmp(name, vmnetname) == 0) {
- unit = -1;
- extra = VMNET_DEV_MASK;
- } else if (dev_stdclone(name, NULL, tapname, &unit) != 1) {
- if (dev_stdclone(name, NULL, vmnetname, &unit) != 1) {
- return;
- } else {
- extra = VMNET_DEV_MASK;
- }
- }
-
- if (unit == -1)
- append_unit = 1;
-
- CURVNET_SET(CRED_TO_VNET(cred));
- /* find any existing device, or allocate new unit number */
- i = clone_create(&tapclones, &tap_cdevsw, &unit, dev, extra);
- if (i) {
- if (append_unit) {
- /*
- * We were passed 'tun' or 'tap', with no unit specified
- * so we'll need to append it now.
- */
- namelen = snprintf(devname, sizeof(devname), "%s%d", name,
- unit);
- name = devname;
- }
-
- *dev = make_dev_credf(MAKEDEV_REF, &tap_cdevsw, unit | extra,
- cred, UID_ROOT, GID_WHEEL, 0600, "%s", name);
- }
-
- if_clone_create(name, namelen, NULL);
- CURVNET_RESTORE();
-} /* tapclone */
-
-
-/*
- * tapcreate
- *
- * to create interface
- */
-static void
-tapcreate(struct cdev *dev)
-{
- struct ifnet *ifp = NULL;
- struct tap_softc *tp = NULL;
- unsigned short macaddr_hi;
- uint32_t macaddr_mid;
- int unit;
- const char *name = NULL;
- u_char eaddr[6];
-
- /* allocate driver storage and create device */
- tp = malloc(sizeof(*tp), M_TAP, M_WAITOK | M_ZERO);
- mtx_init(&tp->tap_mtx, "tap_mtx", NULL, MTX_DEF);
- mtx_lock(&tapmtx);
- SLIST_INSERT_HEAD(&taphead, tp, tap_next);
- mtx_unlock(&tapmtx);
-
- unit = dev2unit(dev);
-
- /* select device: tap or vmnet */
- if (unit & VMNET_DEV_MASK) {
- name = vmnetname;
- tp->tap_flags |= TAP_VMNET;
- } else
- name = tapname;
-
- unit &= TAPMAXUNIT;
-
- TAPDEBUG("tapcreate(%s%d). minor = %#x\n", name, unit, dev2unit(dev));
-
- /* generate fake MAC address: 00 bd xx xx xx unit_no */
- macaddr_hi = htons(0x00bd);
- macaddr_mid = (uint32_t) ticks;
- bcopy(&macaddr_hi, eaddr, sizeof(short));
- bcopy(&macaddr_mid, &eaddr[2], sizeof(uint32_t));
- eaddr[5] = (u_char)unit;
-
- /* fill the rest and attach interface */
- ifp = tp->tap_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL)
- panic("%s%d: can not if_alloc()", name, unit);
- ifp->if_softc = tp;
- if_initname(ifp, name, unit);
- ifp->if_init = tapifinit;
- ifp->if_start = tapifstart;
- ifp->if_ioctl = tapifioctl;
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_capabilities |= IFCAP_LINKSTATE;
- ifp->if_capenable |= IFCAP_LINKSTATE;
-
- dev->si_drv1 = tp;
- tp->tap_dev = dev;
-
- ether_ifattach(ifp, eaddr);
-
- mtx_lock(&tp->tap_mtx);
- tp->tap_flags |= TAP_INITED;
- mtx_unlock(&tp->tap_mtx);
-
- knlist_init_mtx(&tp->tap_rsel.si_note, &tp->tap_mtx);
-
- TAPDEBUG("interface %s is created. minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
-} /* tapcreate */
-
-
-/*
- * tapopen
- *
- * to open tunnel. must be superuser
- */
-static int
-tapopen(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct tap_softc *tp = NULL;
- struct ifnet *ifp = NULL;
- int error;
-
- if (tapuopen == 0) {
- error = priv_check(td, PRIV_NET_TAP);
- if (error)
- return (error);
- }
-
- if ((dev2unit(dev) & CLONE_UNITMASK) > TAPMAXUNIT)
- return (ENXIO);
-
- tp = dev->si_drv1;
-
- mtx_lock(&tp->tap_mtx);
- if (tp->tap_flags & TAP_OPEN) {
- mtx_unlock(&tp->tap_mtx);
- return (EBUSY);
- }
-
- bcopy(IF_LLADDR(tp->tap_ifp), tp->ether_addr, sizeof(tp->ether_addr));
-#ifndef __rtems__
- tp->tap_pid = td->td_proc->p_pid;
-#else /* __rtems__ */
- tp->tap_pid = BSD_DEFAULT_PID;
-#endif /* __rtems__ */
- tp->tap_flags |= TAP_OPEN;
- ifp = tp->tap_ifp;
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- if (tapuponopen)
- ifp->if_flags |= IFF_UP;
- if_link_state_change(ifp, LINK_STATE_UP);
- mtx_unlock(&tp->tap_mtx);
-
- TAPDEBUG("%s is open. minor = %#x\n", ifp->if_xname, dev2unit(dev));
-
- return (0);
-} /* tapopen */
-
-
-/*
- * tapclose
- *
- * close the device - mark i/f down & delete routing info
- */
-static int
-tapclose(struct cdev *dev, int foo, int bar, struct thread *td)
-{
- struct ifaddr *ifa;
- struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = tp->tap_ifp;
-
- /* junk all pending output */
- mtx_lock(&tp->tap_mtx);
- CURVNET_SET(ifp->if_vnet);
- IF_DRAIN(&ifp->if_snd);
-
- /*
- * Do not bring the interface down, and do not anything with
- * interface, if we are in VMnet mode. Just close the device.
- */
- if (((tp->tap_flags & TAP_VMNET) == 0) &&
- (ifp->if_flags & (IFF_UP | IFF_LINK0)) == IFF_UP) {
- mtx_unlock(&tp->tap_mtx);
- if_down(ifp);
- mtx_lock(&tp->tap_mtx);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- mtx_unlock(&tp->tap_mtx);
- CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- rtinit(ifa, (int)RTM_DELETE, 0);
- }
- if_purgeaddrs(ifp);
- mtx_lock(&tp->tap_mtx);
- }
- }
-
- if_link_state_change(ifp, LINK_STATE_DOWN);
- CURVNET_RESTORE();
-
- funsetown(&tp->tap_sigio);
- selwakeuppri(&tp->tap_rsel, PZERO+1);
- KNOTE_LOCKED(&tp->tap_rsel.si_note, 0);
-
- tp->tap_flags &= ~TAP_OPEN;
- tp->tap_pid = 0;
- mtx_unlock(&tp->tap_mtx);
-
- TAPDEBUG("%s is closed. minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
-
- return (0);
-} /* tapclose */
-
-
-/*
- * tapifinit
- *
- * network interface initialization function
- */
-static void
-tapifinit(void *xtp)
-{
- struct tap_softc *tp = (struct tap_softc *)xtp;
- struct ifnet *ifp = tp->tap_ifp;
-
- TAPDEBUG("initializing %s\n", ifp->if_xname);
-
- mtx_lock(&tp->tap_mtx);
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- mtx_unlock(&tp->tap_mtx);
-
- /* attempt to start output */
- tapifstart(ifp);
-} /* tapifinit */
-
-
-/*
- * tapifioctl
- *
- * Process an ioctl request on network interface
- */
-static int
-tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct tap_softc *tp;
- struct ifreq *ifr = (struct ifreq *)data;
- struct ifstat *ifs = NULL;
- struct ifmediareq *ifmr = NULL;
- int dummy, error = 0;
-
- sx_xlock(&tap_ioctl_sx);
- tp = ifp->if_softc;
- if (tp == NULL) {
- error = ENXIO;
- goto bad;
- }
- switch (cmd) {
- case SIOCSIFFLAGS: /* XXX -- just like vmnet does */
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- break;
-
- case SIOCGIFMEDIA:
- ifmr = (struct ifmediareq *)data;
- dummy = ifmr->ifm_count;
- ifmr->ifm_count = 1;
- ifmr->ifm_status = IFM_AVALID;
- ifmr->ifm_active = IFM_ETHER;
- if (tp->tap_flags & TAP_OPEN)
- ifmr->ifm_status |= IFM_ACTIVE;
- ifmr->ifm_current = ifmr->ifm_active;
- if (dummy >= 1) {
- int media = IFM_ETHER;
- error = copyout(&media, ifmr->ifm_ulist,
- sizeof(int));
- }
- break;
-
- case SIOCSIFMTU:
- ifp->if_mtu = ifr->ifr_mtu;
- break;
-
- case SIOCGIFSTATUS:
- ifs = (struct ifstat *)data;
- mtx_lock(&tp->tap_mtx);
- if (tp->tap_pid != 0)
- snprintf(ifs->ascii, sizeof(ifs->ascii),
- "\tOpened by PID %d\n", tp->tap_pid);
- else
- ifs->ascii[0] = '\0';
- mtx_unlock(&tp->tap_mtx);
- break;
-
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
- }
-
-bad:
- sx_xunlock(&tap_ioctl_sx);
- return (error);
-} /* tapifioctl */
-
-
-/*
- * tapifstart
- *
- * queue packets from higher level ready to put out
- */
-static void
-tapifstart(struct ifnet *ifp)
-{
- struct tap_softc *tp = ifp->if_softc;
-
- TAPDEBUG("%s starting\n", ifp->if_xname);
-
- /*
- * do not junk pending output if we are in VMnet mode.
- * XXX: can this do any harm because of queue overflow?
- */
-
- mtx_lock(&tp->tap_mtx);
- if (((tp->tap_flags & TAP_VMNET) == 0) &&
- ((tp->tap_flags & TAP_READY) != TAP_READY)) {
- struct mbuf *m;
-
- /* Unlocked read. */
- TAPDEBUG("%s not ready, tap_flags = 0x%x\n", ifp->if_xname,
- tp->tap_flags);
-
- for (;;) {
- IF_DEQUEUE(&ifp->if_snd, m);
- if (m != NULL) {
- m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- } else
- break;
- }
- mtx_unlock(&tp->tap_mtx);
-
- return;
- }
-
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
- if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
- if (tp->tap_flags & TAP_RWAIT) {
- tp->tap_flags &= ~TAP_RWAIT;
- wakeup(tp);
- }
-
- if ((tp->tap_flags & TAP_ASYNC) && (tp->tap_sigio != NULL)) {
- mtx_unlock(&tp->tap_mtx);
- pgsigio(&tp->tap_sigio, SIGIO, 0);
- mtx_lock(&tp->tap_mtx);
- }
-
- selwakeuppri(&tp->tap_rsel, PZERO+1);
- KNOTE_LOCKED(&tp->tap_rsel.si_note, 0);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); /* obytes are counted in ether_output */
- }
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- mtx_unlock(&tp->tap_mtx);
-} /* tapifstart */
-
-
-/*
- * tapioctl
- *
- * the cdevsw interface is now pretty minimal
- */
-static int
-tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
-{
- struct ifreq ifr;
- struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = tp->tap_ifp;
- struct tapinfo *tapp = NULL;
- int f;
- int error;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4)
- int ival;
-#endif
-
- switch (cmd) {
- case TAPSIFINFO:
- tapp = (struct tapinfo *)data;
- if (ifp->if_type != tapp->type)
- return (EPROTOTYPE);
- mtx_lock(&tp->tap_mtx);
- if (ifp->if_mtu != tapp->mtu) {
- strlcpy(ifr.ifr_name, if_name(ifp), IFNAMSIZ);
- ifr.ifr_mtu = tapp->mtu;
- CURVNET_SET(ifp->if_vnet);
- error = ifhwioctl(SIOCSIFMTU, ifp,
- (caddr_t)&ifr, td);
- CURVNET_RESTORE();
- if (error) {
- mtx_unlock(&tp->tap_mtx);
- return (error);
- }
- }
- ifp->if_baudrate = tapp->baudrate;
- mtx_unlock(&tp->tap_mtx);
- break;
-
- case TAPGIFINFO:
- tapp = (struct tapinfo *)data;
- mtx_lock(&tp->tap_mtx);
- tapp->mtu = ifp->if_mtu;
- tapp->type = ifp->if_type;
- tapp->baudrate = ifp->if_baudrate;
- mtx_unlock(&tp->tap_mtx);
- break;
-
- case TAPSDEBUG:
- tapdebug = *(int *)data;
- break;
-
- case TAPGDEBUG:
- *(int *)data = tapdebug;
- break;
-
- case TAPGIFNAME: {
- struct ifreq *ifr = (struct ifreq *) data;
-
- strlcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ);
- } break;
-
- case FIONBIO:
- break;
-
- case FIOASYNC:
- mtx_lock(&tp->tap_mtx);
- if (*(int *)data)
- tp->tap_flags |= TAP_ASYNC;
- else
- tp->tap_flags &= ~TAP_ASYNC;
- mtx_unlock(&tp->tap_mtx);
- break;
-
- case FIONREAD:
- if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
- struct mbuf *mb;
-
- IFQ_LOCK(&ifp->if_snd);
- IFQ_POLL_NOLOCK(&ifp->if_snd, mb);
- for (*(int *)data = 0; mb != NULL;
- mb = mb->m_next)
- *(int *)data += mb->m_len;
- IFQ_UNLOCK(&ifp->if_snd);
- } else
- *(int *)data = 0;
- break;
-
- case FIOSETOWN:
- return (fsetown(*(int *)data, &tp->tap_sigio));
-
- case FIOGETOWN:
- *(int *)data = fgetown(&tp->tap_sigio);
- return (0);
-
- /* this is deprecated, FIOSETOWN should be used instead */
- case TIOCSPGRP:
- return (fsetown(-(*(int *)data), &tp->tap_sigio));
-
- /* this is deprecated, FIOGETOWN should be used instead */
- case TIOCGPGRP:
- *(int *)data = -fgetown(&tp->tap_sigio);
- return (0);
-
- /* VMware/VMnet port ioctl's */
-
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4)
- case _IO('V', 0):
- ival = IOCPARM_IVAL(data);
- data = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case VMIO_SIOCSIFFLAGS: /* VMware/VMnet SIOCSIFFLAGS */
- f = *(int *)data;
- f &= 0x0fff;
- f &= ~IFF_CANTCHANGE;
- f |= IFF_UP;
-
- mtx_lock(&tp->tap_mtx);
- ifp->if_flags = f | (ifp->if_flags & IFF_CANTCHANGE);
- mtx_unlock(&tp->tap_mtx);
- break;
-
- case SIOCGIFADDR: /* get MAC address of the remote side */
- mtx_lock(&tp->tap_mtx);
- bcopy(tp->ether_addr, data, sizeof(tp->ether_addr));
- mtx_unlock(&tp->tap_mtx);
- break;
-
- case SIOCSIFADDR: /* set MAC address of the remote side */
- mtx_lock(&tp->tap_mtx);
- bcopy(data, tp->ether_addr, sizeof(tp->ether_addr));
- mtx_unlock(&tp->tap_mtx);
- break;
-
- default:
- return (ENOTTY);
- }
- return (0);
-} /* tapioctl */
-
-
-/*
- * tapread
- *
- * the cdevsw read interface - reads a packet at a time, or at
- * least as much of a packet as can be read
- */
-static int
-tapread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = tp->tap_ifp;
- struct mbuf *m = NULL;
- int error = 0, len;
-
- TAPDEBUG("%s reading, minor = %#x\n", ifp->if_xname, dev2unit(dev));
-
- mtx_lock(&tp->tap_mtx);
- if ((tp->tap_flags & TAP_READY) != TAP_READY) {
- mtx_unlock(&tp->tap_mtx);
-
- /* Unlocked read. */
- TAPDEBUG("%s not ready. minor = %#x, tap_flags = 0x%x\n",
- ifp->if_xname, dev2unit(dev), tp->tap_flags);
-
- return (EHOSTDOWN);
- }
-
- tp->tap_flags &= ~TAP_RWAIT;
-
- /* sleep until we get a packet */
- do {
- IF_DEQUEUE(&ifp->if_snd, m);
-
- if (m == NULL) {
- if (flag & O_NONBLOCK) {
- mtx_unlock(&tp->tap_mtx);
- return (EWOULDBLOCK);
- }
-
- tp->tap_flags |= TAP_RWAIT;
- error = mtx_sleep(tp, &tp->tap_mtx, PCATCH | (PZERO + 1),
- "taprd", 0);
- if (error) {
- mtx_unlock(&tp->tap_mtx);
- return (error);
- }
- }
- } while (m == NULL);
- mtx_unlock(&tp->tap_mtx);
-
- /* feed packet to bpf */
- BPF_MTAP(ifp, m);
-
- /* xfer packet to user space */
- while ((m != NULL) && (uio->uio_resid > 0) && (error == 0)) {
- len = min(uio->uio_resid, m->m_len);
- if (len == 0)
- break;
-
- error = uiomove(mtod(m, void *), len, uio);
- m = m_free(m);
- }
-
- if (m != NULL) {
- TAPDEBUG("%s dropping mbuf, minor = %#x\n", ifp->if_xname,
- dev2unit(dev));
- m_freem(m);
- }
-
- return (error);
-} /* tapread */
-
-
-/*
- * tapwrite
- *
- * the cdevsw write interface - an atomic write is a packet - or else!
- */
-static int
-tapwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- struct ether_header *eh;
- struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = tp->tap_ifp;
- struct mbuf *m;
-
- TAPDEBUG("%s writing, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
-
- if (uio->uio_resid == 0)
- return (0);
-
- if ((uio->uio_resid < 0) || (uio->uio_resid > TAPMRU)) {
- TAPDEBUG("%s invalid packet len = %zd, minor = %#x\n",
- ifp->if_xname, uio->uio_resid, dev2unit(dev));
-
- return (EIO);
- }
-
- if ((m = m_uiotombuf(uio, M_NOWAIT, 0, ETHER_ALIGN,
- M_PKTHDR)) == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
- return (ENOBUFS);
- }
-
- m->m_pkthdr.rcvif = ifp;
-
- /*
- * Only pass a unicast frame to ether_input(), if it would actually
- * have been received by non-virtual hardware.
- */
- if (m->m_len < sizeof(struct ether_header)) {
- m_freem(m);
- return (0);
- }
- eh = mtod(m, struct ether_header *);
-
- if (eh && (ifp->if_flags & IFF_PROMISC) == 0 &&
- !ETHER_IS_MULTICAST(eh->ether_dhost) &&
- bcmp(eh->ether_dhost, IF_LLADDR(ifp), ETHER_ADDR_LEN) != 0) {
- m_freem(m);
- return (0);
- }
-
- /* Pass packet up to parent. */
- CURVNET_SET(ifp->if_vnet);
- (*ifp->if_input)(ifp, m);
- CURVNET_RESTORE();
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); /* ibytes are counted in parent */
-
- return (0);
-} /* tapwrite */
-
-
-/*
- * tappoll
- *
- * the poll interface, this is only useful on reads
- * really. the write detect always returns true, write never blocks
- * anyway, it either accepts the packet or drops it
- */
-static int
-tappoll(struct cdev *dev, int events, struct thread *td)
-{
- struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = tp->tap_ifp;
- int revents = 0;
-
- TAPDEBUG("%s polling, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
-
- if (events & (POLLIN | POLLRDNORM)) {
- IFQ_LOCK(&ifp->if_snd);
- if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
- TAPDEBUG("%s have data in queue. len = %d, " \
- "minor = %#x\n", ifp->if_xname,
- ifp->if_snd.ifq_len, dev2unit(dev));
-
- revents |= (events & (POLLIN | POLLRDNORM));
- } else {
- TAPDEBUG("%s waiting for data, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
-
- selrecord(td, &tp->tap_rsel);
- }
- IFQ_UNLOCK(&ifp->if_snd);
- }
-
- if (events & (POLLOUT | POLLWRNORM))
- revents |= (events & (POLLOUT | POLLWRNORM));
-
- return (revents);
-} /* tappoll */
-
-
-/*
- * tap_kqfilter
- *
- * support for kevent() system call
- */
-static int
-tapkqfilter(struct cdev *dev, struct knote *kn)
-{
- struct tap_softc *tp = dev->si_drv1;
- struct ifnet *ifp = tp->tap_ifp;
-
- switch (kn->kn_filter) {
- case EVFILT_READ:
- TAPDEBUG("%s kqfilter: EVFILT_READ, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
- kn->kn_fop = &tap_read_filterops;
- break;
-
- case EVFILT_WRITE:
- TAPDEBUG("%s kqfilter: EVFILT_WRITE, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
- kn->kn_fop = &tap_write_filterops;
- break;
-
- default:
- TAPDEBUG("%s kqfilter: invalid filter, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
- return (EINVAL);
- /* NOT REACHED */
- }
-
- kn->kn_hook = tp;
- knlist_add(&tp->tap_rsel.si_note, kn, 0);
-
- return (0);
-} /* tapkqfilter */
-
-
-/*
- * tap_kqread
- *
- * Return true if there is data in the interface queue
- */
-static int
-tapkqread(struct knote *kn, long hint)
-{
- int ret;
- struct tap_softc *tp = kn->kn_hook;
- struct cdev *dev = tp->tap_dev;
- struct ifnet *ifp = tp->tap_ifp;
-
- if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
- TAPDEBUG("%s have data in queue. len = %d, minor = %#x\n",
- ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev));
- ret = 1;
- } else {
- TAPDEBUG("%s waiting for data, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
- ret = 0;
- }
-
- return (ret);
-} /* tapkqread */
-
-
-/*
- * tap_kqwrite
- *
- * Always can write. Return the MTU in kn->data
- */
-static int
-tapkqwrite(struct knote *kn, long hint)
-{
- struct tap_softc *tp = kn->kn_hook;
- struct ifnet *ifp = tp->tap_ifp;
-
- kn->kn_data = ifp->if_mtu;
-
- return (1);
-} /* tapkqwrite */
-
-
-static void
-tapkqdetach(struct knote *kn)
-{
- struct tap_softc *tp = kn->kn_hook;
-
- knlist_remove(&tp->tap_rsel.si_note, kn, 0);
-} /* tapkqdetach */
-
diff --git a/freebsd/sys/net/if_tap.h b/freebsd/sys/net/if_tap.h
index 34f44b38..9718cee4 100644
--- a/freebsd/sys/net/if_tap.h
+++ b/freebsd/sys/net/if_tap.h
@@ -40,24 +40,22 @@
#ifndef _NET_IF_TAP_H_
#define _NET_IF_TAP_H_
-/* refer to if_tapvar.h for the softc stuff */
+#include <net/if_tun.h>
/* maximum receive packet size (hard limit) */
#define TAPMRU 16384
-struct tapinfo {
- int baudrate; /* linespeed */
- short mtu; /* maximum transmission unit */
- u_char type; /* ethernet, tokenring, etc. */
- u_char dummy; /* place holder */
-};
+#define tapinfo tuninfo
-/* ioctl's for get/set debug */
-#define TAPSDEBUG _IOW('t', 90, int)
-#define TAPGDEBUG _IOR('t', 89, int)
-#define TAPSIFINFO _IOW('t', 91, struct tapinfo)
-#define TAPGIFINFO _IOR('t', 92, struct tapinfo)
-#define TAPGIFNAME _IOR('t', 93, struct ifreq)
+/*
+ * ioctl's for get/set debug; these are aliases of TUN* ioctls, see net/if_tun.h
+ * for details.
+ */
+#define TAPSDEBUG TUNSDEBUG
+#define TAPGDEBUG TUNGDEBUG
+#define TAPSIFINFO TUNSIFINFO
+#define TAPGIFINFO TUNGIFINFO
+#define TAPGIFNAME TUNGIFNAME
/* VMware ioctl's */
#define VMIO_SIOCSIFFLAGS _IOWINT('V', 0)
diff --git a/freebsd/sys/net/if_tapvar.h b/freebsd/sys/net/if_tapvar.h
deleted file mode 100644
index f5cf9f3e..00000000
--- a/freebsd/sys/net/if_tapvar.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
- *
- * BASED ON:
- * -------------------------------------------------------------------------
- *
- * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
- * All rights reserved.
- *
- * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
- * Nottingham University 1987.
- */
-
-/*
- * $FreeBSD$
- * $Id: if_tapvar.h,v 0.6 2000/07/11 02:16:08 max Exp $
- */
-
-#ifndef _NET_IF_TAPVAR_H_
-#define _NET_IF_TAPVAR_H_
-
-/*
- * tap_mtx locks tap_flags, tap_pid. tap_next locked with global tapmtx.
- * Other fields locked by owning subsystems.
- */
-struct tap_softc {
- struct ifnet *tap_ifp;
- u_short tap_flags; /* misc flags */
-#define TAP_OPEN (1 << 0)
-#define TAP_INITED (1 << 1)
-#define TAP_RWAIT (1 << 2)
-#define TAP_ASYNC (1 << 3)
-#define TAP_READY (TAP_OPEN|TAP_INITED)
-#define TAP_VMNET (1 << 4)
-
- u_int8_t ether_addr[ETHER_ADDR_LEN]; /* ether addr of the remote side */
-
- pid_t tap_pid; /* PID of process to open */
- struct sigio *tap_sigio; /* information for async I/O */
- struct selinfo tap_rsel; /* read select */
-
- SLIST_ENTRY(tap_softc) tap_next; /* next device in chain */
- struct cdev *tap_dev;
- struct mtx tap_mtx; /* per-softc mutex */
-};
-
-#endif /* !_NET_IF_TAPVAR_H_ */
diff --git a/freebsd/sys/net/if_tun.c b/freebsd/sys/net/if_tun.c
deleted file mode 100644
index c96b2163..00000000
--- a/freebsd/sys/net/if_tun.c
+++ /dev/null
@@ -1,1132 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */
-
-/*-
- * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
- * Nottingham University 1987.
- *
- * This source may be freely distributed, however I would be interested
- * in any changes that are made.
- *
- * This driver takes packets off the IP i/f and hands them up to a
- * user process to have its wicked way with. This driver has it's
- * roots in a similar driver written by Phil Cockcroft (formerly) at
- * UCL. This driver is based much more on read/write/poll mode of
- * operation though.
- *
- * $FreeBSD$
- */
-
-#include <rtems/bsd/local/opt_inet.h>
-#include <rtems/bsd/local/opt_inet6.h>
-
-#include <sys/param.h>
-#include <sys/lock.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/jail.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/sockio.h>
-#include <sys/sx.h>
-#include <sys/ttycom.h>
-#include <sys/poll.h>
-#include <sys/selinfo.h>
-#include <sys/signalvar.h>
-#include <sys/filedesc.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/malloc.h>
-#include <sys/random.h>
-#include <sys/ctype.h>
-
-#include <net/if.h>
-#include <net/if_var.h>
-#include <net/if_clone.h>
-#include <net/if_types.h>
-#include <net/netisr.h>
-#include <net/route.h>
-#include <net/vnet.h>
-#ifdef INET
-#include <netinet/in.h>
-#endif
-#include <net/bpf.h>
-#include <net/if_tun.h>
-
-#include <sys/queue.h>
-#include <sys/condvar.h>
-
-#include <security/mac/mac_framework.h>
-
-/*
- * tun_list is protected by global tunmtx. Other mutable fields are
- * protected by tun->tun_mtx, or by their owning subsystem. tun_dev is
- * static for the duration of a tunnel interface.
- */
-struct tun_softc {
- TAILQ_ENTRY(tun_softc) tun_list;
- struct cdev *tun_dev;
- u_short tun_flags; /* misc flags */
-#define TUN_OPEN 0x0001
-#define TUN_INITED 0x0002
-#define TUN_RCOLL 0x0004
-#define TUN_IASET 0x0008
-#define TUN_DSTADDR 0x0010
-#define TUN_LMODE 0x0020
-#define TUN_RWAIT 0x0040
-#define TUN_ASYNC 0x0080
-#define TUN_IFHEAD 0x0100
-#define TUN_DYING 0x0200
-
-#define TUN_READY (TUN_OPEN | TUN_INITED)
-
-#ifndef __rtems__
- pid_t tun_pid; /* owning pid */
-#endif /* __rtems__ */
- struct ifnet *tun_ifp; /* the interface */
- struct sigio *tun_sigio; /* information for async I/O */
- struct selinfo tun_rsel; /* read select */
- struct mtx tun_mtx; /* protect mutable softc fields */
- struct cv tun_cv; /* protect against ref'd dev destroy */
-};
-#define TUN2IFP(sc) ((sc)->tun_ifp)
-
-#define TUNDEBUG if (tundebug) if_printf
-
-/*
- * All mutable global variables in if_tun are locked using tunmtx, with
- * the exception of tundebug, which is used unlocked, and tunclones,
- * which is static after setup.
- */
-static struct mtx tunmtx;
-static eventhandler_tag tag;
-static const char tunname[] = "tun";
-static MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
-static int tundebug = 0;
-static int tundclone = 1;
-static struct clonedevs *tunclones;
-static TAILQ_HEAD(,tun_softc) tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
-SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
-
-static struct sx tun_ioctl_sx;
-SX_SYSINIT(tun_ioctl_sx, &tun_ioctl_sx, "tun_ioctl");
-
-SYSCTL_DECL(_net_link);
-static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,
- "IP tunnel software network interface.");
-SYSCTL_INT(_net_link_tun, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tundclone, 0,
- "Enable legacy devfs interface creation.");
-
-static void tunclone(void *arg, struct ucred *cred, char *name,
- int namelen, struct cdev **dev);
-static void tuncreate(const char *name, struct cdev *dev);
-static int tunifioctl(struct ifnet *, u_long, caddr_t);
-static void tuninit(struct ifnet *);
-static int tunmodevent(module_t, int, void *);
-static int tunoutput(struct ifnet *, struct mbuf *,
- const struct sockaddr *, struct route *ro);
-static void tunstart(struct ifnet *);
-
-static int tun_clone_match(struct if_clone *ifc, const char *name);
-static int tun_clone_create(struct if_clone *, char *, size_t, caddr_t);
-static int tun_clone_destroy(struct if_clone *, struct ifnet *);
-static struct unrhdr *tun_unrhdr;
-VNET_DEFINE_STATIC(struct if_clone *, tun_cloner);
-#define V_tun_cloner VNET(tun_cloner)
-
-static d_open_t tunopen;
-static d_close_t tunclose;
-static d_read_t tunread;
-static d_write_t tunwrite;
-static d_ioctl_t tunioctl;
-static d_poll_t tunpoll;
-static d_kqfilter_t tunkqfilter;
-
-static int tunkqread(struct knote *, long);
-static int tunkqwrite(struct knote *, long);
-static void tunkqdetach(struct knote *);
-
-static struct filterops tun_read_filterops = {
- .f_isfd = 1,
- .f_attach = NULL,
- .f_detach = tunkqdetach,
- .f_event = tunkqread,
-};
-
-static struct filterops tun_write_filterops = {
- .f_isfd = 1,
- .f_attach = NULL,
- .f_detach = tunkqdetach,
- .f_event = tunkqwrite,
-};
-
-static struct cdevsw tun_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDMINOR,
- .d_open = tunopen,
- .d_close = tunclose,
- .d_read = tunread,
- .d_write = tunwrite,
- .d_ioctl = tunioctl,
- .d_poll = tunpoll,
- .d_kqfilter = tunkqfilter,
- .d_name = tunname,
-};
-
-static int
-tun_clone_match(struct if_clone *ifc, const char *name)
-{
- if (strncmp(tunname, name, 3) == 0 &&
- (name[3] == '\0' || isdigit(name[3])))
- return (1);
-
- return (0);
-}
-
-static int
-tun_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
-{
- struct cdev *dev;
- int err, unit, i;
-
- err = ifc_name2unit(name, &unit);
- if (err != 0)
- return (err);
-
- if (unit != -1) {
- /* If this unit number is still available that/s okay. */
- if (alloc_unr_specific(tun_unrhdr, unit) == -1)
- return (EEXIST);
- } else {
- unit = alloc_unr(tun_unrhdr);
- }
-
- snprintf(name, IFNAMSIZ, "%s%d", tunname, unit);
-
- /* find any existing device, or allocate new unit number */
- i = clone_create(&tunclones, &tun_cdevsw, &unit, &dev, 0);
- if (i) {
- /* No preexisting struct cdev *, create one */
- dev = make_dev(&tun_cdevsw, unit,
- UID_UUCP, GID_DIALER, 0600, "%s%d", tunname, unit);
- }
- tuncreate(tunname, dev);
-
- return (0);
-}
-
-static void
-tunclone(void *arg, struct ucred *cred, char *name, int namelen,
- struct cdev **dev)
-{
- char devname[SPECNAMELEN + 1];
- int u, i, append_unit;
-
- if (*dev != NULL)
- return;
-
- /*
- * If tun cloning is enabled, only the superuser can create an
- * interface.
- */
- if (!tundclone || priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0)
- return;
-
- if (strcmp(name, tunname) == 0) {
- u = -1;
- } else if (dev_stdclone(name, NULL, tunname, &u) != 1)
- return; /* Don't recognise the name */
- if (u != -1 && u > IF_MAXUNIT)
- return; /* Unit number too high */
-
- if (u == -1)
- append_unit = 1;
- else
- append_unit = 0;
-
- CURVNET_SET(CRED_TO_VNET(cred));
- /* find any existing device, or allocate new unit number */
- i = clone_create(&tunclones, &tun_cdevsw, &u, dev, 0);
- if (i) {
- if (append_unit) {
- namelen = snprintf(devname, sizeof(devname), "%s%d",
- name, u);
- name = devname;
- }
- /* No preexisting struct cdev *, create one */
- *dev = make_dev_credf(MAKEDEV_REF, &tun_cdevsw, u, cred,
- UID_UUCP, GID_DIALER, 0600, "%s", name);
- }
-
- if_clone_create(name, namelen, NULL);
- CURVNET_RESTORE();
-}
-
-static void
-tun_destroy(struct tun_softc *tp)
-{
- struct cdev *dev;
-
- mtx_lock(&tp->tun_mtx);
- tp->tun_flags |= TUN_DYING;
- if ((tp->tun_flags & TUN_OPEN) != 0)
- cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
- else
- mtx_unlock(&tp->tun_mtx);
-
- CURVNET_SET(TUN2IFP(tp)->if_vnet);
-
- dev = tp->tun_dev;
- bpfdetach(TUN2IFP(tp));
- if_detach(TUN2IFP(tp));
-
- sx_xlock(&tun_ioctl_sx);
- TUN2IFP(tp)->if_softc = NULL;
- sx_xunlock(&tun_ioctl_sx);
-
- free_unr(tun_unrhdr, TUN2IFP(tp)->if_dunit);
- if_free(TUN2IFP(tp));
- destroy_dev(dev);
- seldrain(&tp->tun_rsel);
- knlist_clear(&tp->tun_rsel.si_note, 0);
- knlist_destroy(&tp->tun_rsel.si_note);
- mtx_destroy(&tp->tun_mtx);
- cv_destroy(&tp->tun_cv);
- free(tp, M_TUN);
- CURVNET_RESTORE();
-}
-
-static int
-tun_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
-{
- struct tun_softc *tp = ifp->if_softc;
-
- mtx_lock(&tunmtx);
- TAILQ_REMOVE(&tunhead, tp, tun_list);
- mtx_unlock(&tunmtx);
- tun_destroy(tp);
-
- return (0);
-}
-
-static void
-vnet_tun_init(const void *unused __unused)
-{
- V_tun_cloner = if_clone_advanced(tunname, 0, tun_clone_match,
- tun_clone_create, tun_clone_destroy);
-}
-VNET_SYSINIT(vnet_tun_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
- vnet_tun_init, NULL);
-
-static void
-vnet_tun_uninit(const void *unused __unused)
-{
- if_clone_detach(V_tun_cloner);
-}
-VNET_SYSUNINIT(vnet_tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY,
- vnet_tun_uninit, NULL);
-
-static void
-tun_uninit(const void *unused __unused)
-{
- struct tun_softc *tp;
-
- EVENTHANDLER_DEREGISTER(dev_clone, tag);
- drain_dev_clone_events();
-
- mtx_lock(&tunmtx);
- while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
- TAILQ_REMOVE(&tunhead, tp, tun_list);
- mtx_unlock(&tunmtx);
- tun_destroy(tp);
- mtx_lock(&tunmtx);
- }
- mtx_unlock(&tunmtx);
- delete_unrhdr(tun_unrhdr);
- clone_cleanup(&tunclones);
- mtx_destroy(&tunmtx);
-}
-SYSUNINIT(tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY, tun_uninit, NULL);
-
-static int
-tunmodevent(module_t mod, int type, void *data)
-{
-
- switch (type) {
- case MOD_LOAD:
- mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF);
- clone_setup(&tunclones);
- tun_unrhdr = new_unrhdr(0, IF_MAXUNIT, &tunmtx);
- tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
- if (tag == NULL)
- return (ENOMEM);
- break;
- case MOD_UNLOAD:
- /* See tun_uninit, so it's done after the vnet_sysuninit() */
- break;
- default:
- return EOPNOTSUPP;
- }
- return 0;
-}
-
-static moduledata_t tun_mod = {
- "if_tun",
- tunmodevent,
- 0
-};
-
-DECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
-MODULE_VERSION(if_tun, 1);
-
-static void
-tunstart(struct ifnet *ifp)
-{
- struct tun_softc *tp = ifp->if_softc;
- struct mbuf *m;
-
- TUNDEBUG(ifp,"%s starting\n", ifp->if_xname);
- if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
- IFQ_LOCK(&ifp->if_snd);
- IFQ_POLL_NOLOCK(&ifp->if_snd, m);
- if (m == NULL) {
- IFQ_UNLOCK(&ifp->if_snd);
- return;
- }
- IFQ_UNLOCK(&ifp->if_snd);
- }
-
- mtx_lock(&tp->tun_mtx);
- if (tp->tun_flags & TUN_RWAIT) {
- tp->tun_flags &= ~TUN_RWAIT;
- wakeup(tp);
- }
- selwakeuppri(&tp->tun_rsel, PZERO + 1);
- KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
- if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) {
- mtx_unlock(&tp->tun_mtx);
- pgsigio(&tp->tun_sigio, SIGIO, 0);
- } else
- mtx_unlock(&tp->tun_mtx);
-}
-
-/* XXX: should return an error code so it can fail. */
-static void
-tuncreate(const char *name, struct cdev *dev)
-{
- struct tun_softc *sc;
- struct ifnet *ifp;
-
- sc = malloc(sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
- mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF);
- cv_init(&sc->tun_cv, "tun_condvar");
- sc->tun_flags = TUN_INITED;
- sc->tun_dev = dev;
- mtx_lock(&tunmtx);
- TAILQ_INSERT_TAIL(&tunhead, sc, tun_list);
- mtx_unlock(&tunmtx);
-
- ifp = sc->tun_ifp = if_alloc(IFT_PPP);
- if (ifp == NULL)
- panic("%s%d: failed to if_alloc() interface.\n",
- name, dev2unit(dev));
- if_initname(ifp, name, dev2unit(dev));
- ifp->if_mtu = TUNMTU;
- ifp->if_ioctl = tunifioctl;
- ifp->if_output = tunoutput;
- ifp->if_start = tunstart;
- ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
- ifp->if_softc = sc;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = 0;
- IFQ_SET_READY(&ifp->if_snd);
- knlist_init_mtx(&sc->tun_rsel.si_note, &sc->tun_mtx);
- ifp->if_capabilities |= IFCAP_LINKSTATE;
- ifp->if_capenable |= IFCAP_LINKSTATE;
-
- if_attach(ifp);
- bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
- dev->si_drv1 = sc;
- TUNDEBUG(ifp, "interface %s is created, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
-}
-
-static int
-tunopen(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct ifnet *ifp;
- struct tun_softc *tp;
-
- /*
- * XXXRW: Non-atomic test and set of dev->si_drv1 requires
- * synchronization.
- */
- tp = dev->si_drv1;
- if (!tp) {
- tuncreate(tunname, dev);
- tp = dev->si_drv1;
- }
-
- mtx_lock(&tp->tun_mtx);
- if ((tp->tun_flags & (TUN_OPEN | TUN_DYING)) != 0) {
- mtx_unlock(&tp->tun_mtx);
- return (EBUSY);
- }
-
-#ifndef __rtems__
- tp->tun_pid = td->td_proc->p_pid;
-#endif /* __rtems__ */
- tp->tun_flags |= TUN_OPEN;
- ifp = TUN2IFP(tp);
- if_link_state_change(ifp, LINK_STATE_UP);
- TUNDEBUG(ifp, "open\n");
- mtx_unlock(&tp->tun_mtx);
-
- return (0);
-}
-
-/*
- * tunclose - close the device - mark i/f down & delete
- * routing info
- */
-static int
-tunclose(struct cdev *dev, int foo, int bar, struct thread *td)
-{
- struct tun_softc *tp;
- struct ifnet *ifp;
-
- tp = dev->si_drv1;
- ifp = TUN2IFP(tp);
-
- mtx_lock(&tp->tun_mtx);
-#ifndef __rtems__
- /*
- * Simply close the device if this isn't the controlling process. This
- * may happen if, for instance, the tunnel has been handed off to
- * another process. The original controller should be able to close it
- * without putting us into an inconsistent state.
- */
- if (td->td_proc->p_pid != tp->tun_pid) {
- mtx_unlock(&tp->tun_mtx);
- return (0);
- }
-#endif /* __rtems__ */
-
- /*
- * junk all pending output
- */
- CURVNET_SET(ifp->if_vnet);
- IFQ_PURGE(&ifp->if_snd);
-
- if (ifp->if_flags & IFF_UP) {
- mtx_unlock(&tp->tun_mtx);
- if_down(ifp);
- mtx_lock(&tp->tun_mtx);
- }
-
- /* Delete all addresses and routes which reference this interface. */
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- struct ifaddr *ifa;
-
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- mtx_unlock(&tp->tun_mtx);
- CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- /* deal w/IPv4 PtP destination; unlocked read */
- if (ifa->ifa_addr->sa_family == AF_INET) {
- rtinit(ifa, (int)RTM_DELETE,
- tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
- } else {
- rtinit(ifa, (int)RTM_DELETE, 0);
- }
- }
- if_purgeaddrs(ifp);
- mtx_lock(&tp->tun_mtx);
- }
- if_link_state_change(ifp, LINK_STATE_DOWN);
- CURVNET_RESTORE();
-
- funsetown(&tp->tun_sigio);
- selwakeuppri(&tp->tun_rsel, PZERO + 1);
- KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
- TUNDEBUG (ifp, "closed\n");
- tp->tun_flags &= ~TUN_OPEN;
-#ifndef __rtems__
- tp->tun_pid = 0;
-#endif /* __rtems__ */
-
- cv_broadcast(&tp->tun_cv);
- mtx_unlock(&tp->tun_mtx);
- return (0);
-}
-
-static void
-tuninit(struct ifnet *ifp)
-{
- struct tun_softc *tp = ifp->if_softc;
-#ifdef INET
- struct ifaddr *ifa;
-#endif
-
- TUNDEBUG(ifp, "tuninit\n");
-
- mtx_lock(&tp->tun_mtx);
- ifp->if_flags |= IFF_UP;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- getmicrotime(&ifp->if_lastchange);
-
-#ifdef INET
- if_addr_rlock(ifp);
- CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- if (ifa->ifa_addr->sa_family == AF_INET) {
- struct sockaddr_in *si;
-
- si = (struct sockaddr_in *)ifa->ifa_addr;
- if (si->sin_addr.s_addr)
- tp->tun_flags |= TUN_IASET;
-
- si = (struct sockaddr_in *)ifa->ifa_dstaddr;
- if (si && si->sin_addr.s_addr)
- tp->tun_flags |= TUN_DSTADDR;
- }
- }
- if_addr_runlock(ifp);
-#endif
- mtx_unlock(&tp->tun_mtx);
-}
-
-/*
- * Process an ioctl request.
- */
-static int
-tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct ifreq *ifr = (struct ifreq *)data;
- struct tun_softc *tp;
- struct ifstat *ifs;
- int error = 0;
-
- sx_xlock(&tun_ioctl_sx);
- tp = ifp->if_softc;
- if (tp == NULL) {
- error = ENXIO;
- goto bad;
- }
- switch(cmd) {
- case SIOCGIFSTATUS:
- ifs = (struct ifstat *)data;
- mtx_lock(&tp->tun_mtx);
-#ifndef __rtems__
- if (tp->tun_pid)
- snprintf(ifs->ascii, sizeof(ifs->ascii),
- "\tOpened by PID %d\n", tp->tun_pid);
- else
-#endif /* __rtems__ */
- ifs->ascii[0] = '\0';
- mtx_unlock(&tp->tun_mtx);
- break;
- case SIOCSIFADDR:
- tuninit(ifp);
- TUNDEBUG(ifp, "address set\n");
- break;
- case SIOCSIFMTU:
- ifp->if_mtu = ifr->ifr_mtu;
- TUNDEBUG(ifp, "mtu set\n");
- break;
- case SIOCSIFFLAGS:
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- break;
- default:
- error = EINVAL;
- }
-bad:
- sx_xunlock(&tun_ioctl_sx);
- return (error);
-}
-
-/*
- * tunoutput - queue packets from higher level ready to put out.
- */
-static int
-tunoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
- struct route *ro)
-{
- struct tun_softc *tp = ifp->if_softc;
- u_short cached_tun_flags;
- int error;
- u_int32_t af;
-
- TUNDEBUG (ifp, "tunoutput\n");
-
-#ifdef MAC
- error = mac_ifnet_check_transmit(ifp, m0);
- if (error) {
- m_freem(m0);
- return (error);
- }
-#endif
-
- /* Could be unlocked read? */
- mtx_lock(&tp->tun_mtx);
- cached_tun_flags = tp->tun_flags;
- mtx_unlock(&tp->tun_mtx);
- if ((cached_tun_flags & TUN_READY) != TUN_READY) {
- TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
- m_freem (m0);
- return (EHOSTDOWN);
- }
-
- if ((ifp->if_flags & IFF_UP) != IFF_UP) {
- m_freem (m0);
- return (EHOSTDOWN);
- }
-
- /* BPF writes need to be handled specially. */
- if (dst->sa_family == AF_UNSPEC)
- bcopy(dst->sa_data, &af, sizeof(af));
- else
- af = dst->sa_family;
-
- if (bpf_peers_present(ifp->if_bpf))
- bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m0);
-
- /* prepend sockaddr? this may abort if the mbuf allocation fails */
- if (cached_tun_flags & TUN_LMODE) {
- /* allocate space for sockaddr */
- M_PREPEND(m0, dst->sa_len, M_NOWAIT);
-
- /* if allocation failed drop packet */
- if (m0 == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- return (ENOBUFS);
- } else {
- bcopy(dst, m0->m_data, dst->sa_len);
- }
- }
-
- if (cached_tun_flags & TUN_IFHEAD) {
- /* Prepend the address family */
- M_PREPEND(m0, 4, M_NOWAIT);
-
- /* if allocation failed drop packet */
- if (m0 == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- return (ENOBUFS);
- } else
- *(u_int32_t *)m0->m_data = htonl(af);
- } else {
-#ifdef INET
- if (af != AF_INET)
-#endif
- {
- m_freem(m0);
- return (EAFNOSUPPORT);
- }
- }
-
- error = (ifp->if_transmit)(ifp, m0);
- if (error)
- return (ENOBUFS);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- return (0);
-}
-
-/*
- * the cdevsw interface is now pretty minimal.
- */
-static int
-tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
- struct thread *td)
-{
- struct ifreq ifr, *ifrp;
- struct tun_softc *tp = dev->si_drv1;
- struct tuninfo *tunp;
- int error;
-
- switch (cmd) {
- case TUNGIFNAME:
- ifrp = (struct ifreq *)data;
- strlcpy(ifrp->ifr_name, TUN2IFP(tp)->if_xname, IFNAMSIZ);
- break;
- case TUNSIFINFO:
- tunp = (struct tuninfo *)data;
- if (TUN2IFP(tp)->if_type != tunp->type)
- return (EPROTOTYPE);
- mtx_lock(&tp->tun_mtx);
- if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
- strlcpy(ifr.ifr_name, if_name(TUN2IFP(tp)), IFNAMSIZ);
- ifr.ifr_mtu = tunp->mtu;
- CURVNET_SET(TUN2IFP(tp)->if_vnet);
- error = ifhwioctl(SIOCSIFMTU, TUN2IFP(tp),
- (caddr_t)&ifr, td);
- CURVNET_RESTORE();
- if (error) {
- mtx_unlock(&tp->tun_mtx);
- return (error);
- }
- }
- TUN2IFP(tp)->if_baudrate = tunp->baudrate;
- mtx_unlock(&tp->tun_mtx);
- break;
- case TUNGIFINFO:
- tunp = (struct tuninfo *)data;
- mtx_lock(&tp->tun_mtx);
- tunp->mtu = TUN2IFP(tp)->if_mtu;
- tunp->type = TUN2IFP(tp)->if_type;
- tunp->baudrate = TUN2IFP(tp)->if_baudrate;
- mtx_unlock(&tp->tun_mtx);
- break;
- case TUNSDEBUG:
- tundebug = *(int *)data;
- break;
- case TUNGDEBUG:
- *(int *)data = tundebug;
- break;
- case TUNSLMODE:
- mtx_lock(&tp->tun_mtx);
- if (*(int *)data) {
- tp->tun_flags |= TUN_LMODE;
- tp->tun_flags &= ~TUN_IFHEAD;
- } else
- tp->tun_flags &= ~TUN_LMODE;
- mtx_unlock(&tp->tun_mtx);
- break;
- case TUNSIFHEAD:
- mtx_lock(&tp->tun_mtx);
- if (*(int *)data) {
- tp->tun_flags |= TUN_IFHEAD;
- tp->tun_flags &= ~TUN_LMODE;
- } else
- tp->tun_flags &= ~TUN_IFHEAD;
- mtx_unlock(&tp->tun_mtx);
- break;
- case TUNGIFHEAD:
- mtx_lock(&tp->tun_mtx);
- *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
- mtx_unlock(&tp->tun_mtx);
- break;
- case TUNSIFMODE:
- /* deny this if UP */
- if (TUN2IFP(tp)->if_flags & IFF_UP)
- return(EBUSY);
-
- switch (*(int *)data & ~IFF_MULTICAST) {
- case IFF_POINTOPOINT:
- case IFF_BROADCAST:
- mtx_lock(&tp->tun_mtx);
- TUN2IFP(tp)->if_flags &=
- ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
- TUN2IFP(tp)->if_flags |= *(int *)data;
- mtx_unlock(&tp->tun_mtx);
- break;
- default:
- return(EINVAL);
- }
- break;
- case TUNSIFPID:
-#ifndef __rtems__
- mtx_lock(&tp->tun_mtx);
- tp->tun_pid = curthread->td_proc->p_pid;
- mtx_unlock(&tp->tun_mtx);
-#endif /* __rtems__ */
- break;
- case FIONBIO:
- break;
- case FIOASYNC:
- mtx_lock(&tp->tun_mtx);
- if (*(int *)data)
- tp->tun_flags |= TUN_ASYNC;
- else
- tp->tun_flags &= ~TUN_ASYNC;
- mtx_unlock(&tp->tun_mtx);
- break;
- case FIONREAD:
- if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) {
- struct mbuf *mb;
- IFQ_LOCK(&TUN2IFP(tp)->if_snd);
- IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb);
- for (*(int *)data = 0; mb != NULL; mb = mb->m_next)
- *(int *)data += mb->m_len;
- IFQ_UNLOCK(&TUN2IFP(tp)->if_snd);
- } else
- *(int *)data = 0;
- break;
- case FIOSETOWN:
- return (fsetown(*(int *)data, &tp->tun_sigio));
-
- case FIOGETOWN:
- *(int *)data = fgetown(&tp->tun_sigio);
- return (0);
-
- /* This is deprecated, FIOSETOWN should be used instead. */
- case TIOCSPGRP:
- return (fsetown(-(*(int *)data), &tp->tun_sigio));
-
- /* This is deprecated, FIOGETOWN should be used instead. */
- case TIOCGPGRP:
- *(int *)data = -fgetown(&tp->tun_sigio);
- return (0);
-
- default:
- return (ENOTTY);
- }
- return (0);
-}
-
-/*
- * The cdevsw read interface - reads a packet at a time, or at
- * least as much of a packet as can be read.
- */
-static int
-tunread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct tun_softc *tp = dev->si_drv1;
- struct ifnet *ifp = TUN2IFP(tp);
- struct mbuf *m;
- int error=0, len;
-
- TUNDEBUG (ifp, "read\n");
- mtx_lock(&tp->tun_mtx);
- if ((tp->tun_flags & TUN_READY) != TUN_READY) {
- mtx_unlock(&tp->tun_mtx);
- TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
- return (EHOSTDOWN);
- }
-
- tp->tun_flags &= ~TUN_RWAIT;
-
- do {
- IFQ_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL) {
- if (flag & O_NONBLOCK) {
- mtx_unlock(&tp->tun_mtx);
- return (EWOULDBLOCK);
- }
- tp->tun_flags |= TUN_RWAIT;
- error = mtx_sleep(tp, &tp->tun_mtx, PCATCH | (PZERO + 1),
- "tunread", 0);
- if (error != 0) {
- mtx_unlock(&tp->tun_mtx);
- return (error);
- }
- }
- } while (m == NULL);
- mtx_unlock(&tp->tun_mtx);
-
- while (m && uio->uio_resid > 0 && error == 0) {
- len = min(uio->uio_resid, m->m_len);
- if (len != 0)
- error = uiomove(mtod(m, void *), len, uio);
- m = m_free(m);
- }
-
- if (m) {
- TUNDEBUG(ifp, "Dropping mbuf\n");
- m_freem(m);
- }
- return (error);
-}
-
-/*
- * the cdevsw write interface - an atomic write is a packet - or else!
- */
-static int
-tunwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- struct tun_softc *tp = dev->si_drv1;
- struct ifnet *ifp = TUN2IFP(tp);
- struct mbuf *m;
- uint32_t family, mru;
- int isr;
-
- TUNDEBUG(ifp, "tunwrite\n");
-
- if ((ifp->if_flags & IFF_UP) != IFF_UP)
- /* ignore silently */
- return (0);
-
- if (uio->uio_resid == 0)
- return (0);
-
- mru = TUNMRU;
- if (tp->tun_flags & TUN_IFHEAD)
- mru += sizeof(family);
- if (uio->uio_resid < 0 || uio->uio_resid > mru) {
- TUNDEBUG(ifp, "len=%zd!\n", uio->uio_resid);
- return (EIO);
- }
-
- if ((m = m_uiotombuf(uio, M_NOWAIT, 0, 0, M_PKTHDR)) == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
- return (ENOBUFS);
- }
-
- m->m_pkthdr.rcvif = ifp;
-#ifdef MAC
- mac_ifnet_create_mbuf(ifp, m);
-#endif
-
- /* Could be unlocked read? */
- mtx_lock(&tp->tun_mtx);
- if (tp->tun_flags & TUN_IFHEAD) {
- mtx_unlock(&tp->tun_mtx);
- if (m->m_len < sizeof(family) &&
- (m = m_pullup(m, sizeof(family))) == NULL)
- return (ENOBUFS);
- family = ntohl(*mtod(m, u_int32_t *));
- m_adj(m, sizeof(family));
- } else {
- mtx_unlock(&tp->tun_mtx);
- family = AF_INET;
- }
-
- BPF_MTAP2(ifp, &family, sizeof(family), m);
-
- switch (family) {
-#ifdef INET
- case AF_INET:
- isr = NETISR_IP;
- break;
-#endif
-#ifdef INET6
- case AF_INET6:
- isr = NETISR_IPV6;
- break;
-#endif
- default:
- m_freem(m);
- return (EAFNOSUPPORT);
- }
- random_harvest_queue(m, sizeof(*m), RANDOM_NET_TUN);
- if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
- CURVNET_SET(ifp->if_vnet);
- M_SETFIB(m, ifp->if_fib);
- netisr_dispatch(isr, m);
- CURVNET_RESTORE();
- return (0);
-}
-
-/*
- * tunpoll - the poll interface, this is only useful on reads
- * really. The write detect always returns true, write never blocks
- * anyway, it either accepts the packet or drops it.
- */
-static int
-tunpoll(struct cdev *dev, int events, struct thread *td)
-{
- struct tun_softc *tp = dev->si_drv1;
- struct ifnet *ifp = TUN2IFP(tp);
- int revents = 0;
- struct mbuf *m;
-
- TUNDEBUG(ifp, "tunpoll\n");
-
- if (events & (POLLIN | POLLRDNORM)) {
- IFQ_LOCK(&ifp->if_snd);
- IFQ_POLL_NOLOCK(&ifp->if_snd, m);
- if (m != NULL) {
- TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
- revents |= events & (POLLIN | POLLRDNORM);
- } else {
- TUNDEBUG(ifp, "tunpoll waiting\n");
- selrecord(td, &tp->tun_rsel);
- }
- IFQ_UNLOCK(&ifp->if_snd);
- }
- if (events & (POLLOUT | POLLWRNORM))
- revents |= events & (POLLOUT | POLLWRNORM);
-
- return (revents);
-}
-
-/*
- * tunkqfilter - support for the kevent() system call.
- */
-static int
-tunkqfilter(struct cdev *dev, struct knote *kn)
-{
- struct tun_softc *tp = dev->si_drv1;
- struct ifnet *ifp = TUN2IFP(tp);
-
- switch(kn->kn_filter) {
- case EVFILT_READ:
- TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
- kn->kn_fop = &tun_read_filterops;
- break;
-
- case EVFILT_WRITE:
- TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
- kn->kn_fop = &tun_write_filterops;
- break;
-
- default:
- TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n",
- ifp->if_xname, dev2unit(dev));
- return(EINVAL);
- }
-
- kn->kn_hook = tp;
- knlist_add(&tp->tun_rsel.si_note, kn, 0);
-
- return (0);
-}
-
-/*
- * Return true of there is data in the interface queue.
- */
-static int
-tunkqread(struct knote *kn, long hint)
-{
- int ret;
- struct tun_softc *tp = kn->kn_hook;
- struct cdev *dev = tp->tun_dev;
- struct ifnet *ifp = TUN2IFP(tp);
-
- if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
- TUNDEBUG(ifp,
- "%s have data in the queue. Len = %d, minor = %#x\n",
- ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev));
- ret = 1;
- } else {
- TUNDEBUG(ifp,
- "%s waiting for data, minor = %#x\n", ifp->if_xname,
- dev2unit(dev));
- ret = 0;
- }
-
- return (ret);
-}
-
-/*
- * Always can write, always return MTU in kn->data.
- */
-static int
-tunkqwrite(struct knote *kn, long hint)
-{
- struct tun_softc *tp = kn->kn_hook;
- struct ifnet *ifp = TUN2IFP(tp);
-
- kn->kn_data = ifp->if_mtu;
-
- return (1);
-}
-
-static void
-tunkqdetach(struct knote *kn)
-{
- struct tun_softc *tp = kn->kn_hook;
-
- knlist_remove(&tp->tun_rsel.si_note, kn, 0);
-}
diff --git a/freebsd/sys/net/if_tuntap.c b/freebsd/sys/net/if_tuntap.c
new file mode 100644
index 00000000..e366aac7
--- /dev/null
+++ b/freebsd/sys/net/if_tuntap.c
@@ -0,0 +1,1923 @@
+#include <machine/rtems-bsd-kernel-space.h>
+
+/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com>
+ * All rights reserved.
+ * Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ *
+ * BASED ON:
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
+ * Nottingham University 1987.
+ *
+ * This source may be freely distributed, however I would be interested
+ * in any changes that are made.
+ *
+ * This driver takes packets off the IP i/f and hands them up to a
+ * user process to have its wicked way with. This driver has it's
+ * roots in a similar driver written by Phil Cockcroft (formerly) at
+ * UCL. This driver is based much more on read/write/poll mode of
+ * operation though.
+ *
+ * $FreeBSD$
+ */
+
+#include <rtems/bsd/local/opt_inet.h>
+#include <rtems/bsd/local/opt_inet6.h>
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/jail.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+#include <sys/fcntl.h>
+#include <sys/filio.h>
+#include <sys/sockio.h>
+#include <sys/sx.h>
+#include <sys/syslog.h>
+#include <sys/ttycom.h>
+#include <sys/poll.h>
+#include <sys/selinfo.h>
+#include <sys/signalvar.h>
+#include <sys/filedesc.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+#include <sys/random.h>
+#include <sys/ctype.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_clone.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/netisr.h>
+#include <net/route.h>
+#include <net/vnet.h>
+#ifdef INET
+#include <netinet/in.h>
+#endif
+#include <net/bpf.h>
+#include <net/if_tap.h>
+#include <net/if_tun.h>
+
+#include <sys/queue.h>
+#include <sys/condvar.h>
+#include <security/mac/mac_framework.h>
+
+struct tuntap_driver;
+
+/*
+ * tun_list is protected by global tunmtx. Other mutable fields are
+ * protected by tun->tun_mtx, or by their owning subsystem. tun_dev is
+ * static for the duration of a tunnel interface.
+ */
+struct tuntap_softc {
+ TAILQ_ENTRY(tuntap_softc) tun_list;
+ struct cdev *tun_alias;
+ struct cdev *tun_dev;
+ u_short tun_flags; /* misc flags */
+#define TUN_OPEN 0x0001
+#define TUN_INITED 0x0002
+#define TUN_UNUSED1 0x0008
+#define TUN_DSTADDR 0x0010
+#define TUN_LMODE 0x0020
+#define TUN_RWAIT 0x0040
+#define TUN_ASYNC 0x0080
+#define TUN_IFHEAD 0x0100
+#define TUN_DYING 0x0200
+#define TUN_L2 0x0400
+#define TUN_VMNET 0x0800
+
+#define TUN_DRIVER_IDENT_MASK (TUN_L2 | TUN_VMNET)
+#define TUN_READY (TUN_OPEN | TUN_INITED)
+
+#ifndef __rtems__
+ pid_t tun_pid; /* owning pid */
+#endif /* __rtems__ */
+ struct ifnet *tun_ifp; /* the interface */
+ struct sigio *tun_sigio; /* async I/O info */
+ struct tuntap_driver *tun_drv; /* appropriate driver */
+ struct selinfo tun_rsel; /* read select */
+ struct mtx tun_mtx; /* softc field mutex */
+ struct cv tun_cv; /* for ref'd dev destroy */
+ struct ether_addr tun_ether; /* remote address */
+ int tun_busy; /* busy count */
+};
+#define TUN2IFP(sc) ((sc)->tun_ifp)
+
+#define TUNDEBUG if (tundebug) if_printf
+
+#define TUN_LOCK(tp) mtx_lock(&(tp)->tun_mtx)
+#define TUN_UNLOCK(tp) mtx_unlock(&(tp)->tun_mtx)
+#define TUN_LOCK_ASSERT(tp) mtx_assert(&(tp)->tun_mtx, MA_OWNED);
+
+#define TUN_VMIO_FLAG_MASK 0x0fff
+
+/*
+ * All mutable global variables in if_tun are locked using tunmtx, with
+ * the exception of tundebug, which is used unlocked, and the drivers' *clones,
+ * which are static after setup.
+ */
+static struct mtx tunmtx;
+static eventhandler_tag arrival_tag;
+static eventhandler_tag clone_tag;
+static const char tunname[] = "tun";
+static const char tapname[] = "tap";
+static const char vmnetname[] = "vmnet";
+static MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
+static int tundebug = 0;
+static int tundclone = 1;
+static int tap_allow_uopen = 0; /* allow user open() */
+static int tapuponopen = 0; /* IFF_UP on open() */
+static int tapdclone = 1; /* enable devfs cloning */
+
+static TAILQ_HEAD(,tuntap_softc) tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
+SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
+
+static struct sx tun_ioctl_sx;
+SX_SYSINIT(tun_ioctl_sx, &tun_ioctl_sx, "tun_ioctl");
+
+SYSCTL_DECL(_net_link);
+/* tun */
+static SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,
+ "IP tunnel software network interface");
+SYSCTL_INT(_net_link_tun, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tundclone, 0,
+ "Enable legacy devfs interface creation");
+
+/* tap */
+static SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0,
+ "Ethernet tunnel software network interface");
+SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tap_allow_uopen, 0,
+ "Allow user to open /dev/tap (based on node permissions)");
+SYSCTL_INT(_net_link_tap, OID_AUTO, up_on_open, CTLFLAG_RW, &tapuponopen, 0,
+ "Bring interface up when /dev/tap is opened");
+SYSCTL_INT(_net_link_tap, OID_AUTO, devfs_cloning, CTLFLAG_RWTUN, &tapdclone, 0,
+ "Enable legacy devfs interface creation");
+SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tundebug, 0, "");
+
+static int tun_create_device(struct tuntap_driver *drv, int unit,
+ struct ucred *cr, struct cdev **dev, const char *name);
+static int tun_busy_locked(struct tuntap_softc *tp);
+static void tun_unbusy_locked(struct tuntap_softc *tp);
+static int tun_busy(struct tuntap_softc *tp);
+static void tun_unbusy(struct tuntap_softc *tp);
+
+static int tuntap_name2info(const char *name, int *unit, int *flags);
+static void tunclone(void *arg, struct ucred *cred, char *name,
+ int namelen, struct cdev **dev);
+static void tuncreate(struct cdev *dev);
+static void tundtor(void *data);
+static void tunrename(void *arg, struct ifnet *ifp);
+static int tunifioctl(struct ifnet *, u_long, caddr_t);
+static void tuninit(struct ifnet *);
+static void tunifinit(void *xtp);
+static int tuntapmodevent(module_t, int, void *);
+static int tunoutput(struct ifnet *, struct mbuf *,
+ const struct sockaddr *, struct route *ro);
+static void tunstart(struct ifnet *);
+static void tunstart_l2(struct ifnet *);
+
+static int tun_clone_match(struct if_clone *ifc, const char *name);
+static int tap_clone_match(struct if_clone *ifc, const char *name);
+static int vmnet_clone_match(struct if_clone *ifc, const char *name);
+static int tun_clone_create(struct if_clone *, char *, size_t, caddr_t);
+static int tun_clone_destroy(struct if_clone *, struct ifnet *);
+
+static d_open_t tunopen;
+static d_read_t tunread;
+static d_write_t tunwrite;
+static d_ioctl_t tunioctl;
+static d_poll_t tunpoll;
+static d_kqfilter_t tunkqfilter;
+
+static int tunkqread(struct knote *, long);
+static int tunkqwrite(struct knote *, long);
+static void tunkqdetach(struct knote *);
+
+static struct filterops tun_read_filterops = {
+ .f_isfd = 1,
+ .f_attach = NULL,
+ .f_detach = tunkqdetach,
+ .f_event = tunkqread,
+};
+
+static struct filterops tun_write_filterops = {
+ .f_isfd = 1,
+ .f_attach = NULL,
+ .f_detach = tunkqdetach,
+ .f_event = tunkqwrite,
+};
+
+static struct tuntap_driver {
+ struct cdevsw cdevsw;
+ int ident_flags;
+ struct unrhdr *unrhdr;
+ struct clonedevs *clones;
+ ifc_match_t *clone_match_fn;
+ ifc_create_t *clone_create_fn;
+ ifc_destroy_t *clone_destroy_fn;
+} tuntap_drivers[] = {
+ {
+ .ident_flags = 0,
+ .cdevsw = {
+ .d_version = D_VERSION,
+ .d_flags = D_NEEDMINOR,
+ .d_open = tunopen,
+ .d_read = tunread,
+ .d_write = tunwrite,
+ .d_ioctl = tunioctl,
+ .d_poll = tunpoll,
+ .d_kqfilter = tunkqfilter,
+ .d_name = tunname,
+ },
+ .clone_match_fn = tun_clone_match,
+ .clone_create_fn = tun_clone_create,
+ .clone_destroy_fn = tun_clone_destroy,
+ },
+ {
+ .ident_flags = TUN_L2,
+ .cdevsw = {
+ .d_version = D_VERSION,
+ .d_flags = D_NEEDMINOR,
+ .d_open = tunopen,
+ .d_read = tunread,
+ .d_write = tunwrite,
+ .d_ioctl = tunioctl,
+ .d_poll = tunpoll,
+ .d_kqfilter = tunkqfilter,
+ .d_name = tapname,
+ },
+ .clone_match_fn = tap_clone_match,
+ .clone_create_fn = tun_clone_create,
+ .clone_destroy_fn = tun_clone_destroy,
+ },
+ {
+ .ident_flags = TUN_L2 | TUN_VMNET,
+ .cdevsw = {
+ .d_version = D_VERSION,
+ .d_flags = D_NEEDMINOR,
+ .d_open = tunopen,
+ .d_read = tunread,
+ .d_write = tunwrite,
+ .d_ioctl = tunioctl,
+ .d_poll = tunpoll,
+ .d_kqfilter = tunkqfilter,
+ .d_name = vmnetname,
+ },
+ .clone_match_fn = vmnet_clone_match,
+ .clone_create_fn = tun_clone_create,
+ .clone_destroy_fn = tun_clone_destroy,
+ },
+};
+
+struct tuntap_driver_cloner {
+ SLIST_ENTRY(tuntap_driver_cloner) link;
+ struct tuntap_driver *drv;
+ struct if_clone *cloner;
+};
+
+VNET_DEFINE_STATIC(SLIST_HEAD(, tuntap_driver_cloner), tuntap_driver_cloners) =
+ SLIST_HEAD_INITIALIZER(tuntap_driver_cloners);
+
+#define V_tuntap_driver_cloners VNET(tuntap_driver_cloners)
+
+/*
+ * Mechanism for marking a tunnel device as busy so that we can safely do some
+ * orthogonal operations (such as operations on devices) without racing against
+ * tun_destroy. tun_destroy will wait on the condvar if we're at all busy or
+ * open, to be woken up when the condition is alleviated.
+ */
+static int
+tun_busy_locked(struct tuntap_softc *tp)
+{
+
+ TUN_LOCK_ASSERT(tp);
+ if ((tp->tun_flags & TUN_DYING) != 0) {
+ /*
+ * Perhaps unintuitive, but the device is busy going away.
+ * Other interpretations of EBUSY from tun_busy make little
+ * sense, since making a busy device even more busy doesn't
+ * sound like a problem.
+ */
+ return (EBUSY);
+ }
+
+ ++tp->tun_busy;
+ return (0);
+}
+
+static void
+tun_unbusy_locked(struct tuntap_softc *tp)
+{
+
+ TUN_LOCK_ASSERT(tp);
+ KASSERT(tp->tun_busy != 0, ("tun_unbusy: called for non-busy tunnel"));
+
+ --tp->tun_busy;
+ /* Wake up anything that may be waiting on our busy tunnel. */
+ if (tp->tun_busy == 0)
+ cv_broadcast(&tp->tun_cv);
+}
+
+static int
+tun_busy(struct tuntap_softc *tp)
+{
+ int ret;
+
+ TUN_LOCK(tp);
+ ret = tun_busy_locked(tp);
+ TUN_UNLOCK(tp);
+ return (ret);
+}
+
+
+static void
+tun_unbusy(struct tuntap_softc *tp)
+{
+
+ TUN_LOCK(tp);
+ tun_unbusy_locked(tp);
+ TUN_UNLOCK(tp);
+}
+
+/*
+ * Sets unit and/or flags given the device name. Must be called with correct
+ * vnet context.
+ */
+static int
+tuntap_name2info(const char *name, int *outunit, int *outflags)
+{
+ struct tuntap_driver *drv;
+ struct tuntap_driver_cloner *drvc;
+ char *dname;
+ int flags, unit;
+ bool found;
+
+ if (name == NULL)
+ return (EINVAL);
+
+ /*
+ * Needed for dev_stdclone, but dev_stdclone will not modify, it just
+ * wants to be able to pass back a char * through the second param. We
+ * will always set that as NULL here, so we'll fake it.
+ */
+ dname = __DECONST(char *, name);
+ found = false;
+
+ KASSERT(!SLIST_EMPTY(&V_tuntap_driver_cloners),
+ ("tuntap_driver_cloners failed to initialize"));
+ SLIST_FOREACH(drvc, &V_tuntap_driver_cloners, link) {
+ KASSERT(drvc->drv != NULL,
+ ("tuntap_driver_cloners entry not properly initialized"));
+ drv = drvc->drv;
+
+ if (strcmp(name, drv->cdevsw.d_name) == 0) {
+ found = true;
+ unit = -1;
+ flags = drv->ident_flags;
+ break;
+ }
+
+ if (dev_stdclone(dname, NULL, drv->cdevsw.d_name, &unit) == 1) {
+ found = true;
+ flags = drv->ident_flags;
+ break;
+ }
+ }
+
+ if (!found)
+ return (ENXIO);
+
+ if (outunit != NULL)
+ *outunit = unit;
+ if (outflags != NULL)
+ *outflags = flags;
+ return (0);
+}
+
+/*
+ * Get driver information from a set of flags specified. Masks the identifying
+ * part of the flags and compares it against all of the available
+ * tuntap_drivers. Must be called with correct vnet context.
+ */
+static struct tuntap_driver *
+tuntap_driver_from_flags(int tun_flags)
+{
+ struct tuntap_driver *drv;
+ struct tuntap_driver_cloner *drvc;
+
+ KASSERT(!SLIST_EMPTY(&V_tuntap_driver_cloners),
+ ("tuntap_driver_cloners failed to initialize"));
+ SLIST_FOREACH(drvc, &V_tuntap_driver_cloners, link) {
+ KASSERT(drvc->drv != NULL,
+ ("tuntap_driver_cloners entry not properly initialized"));
+ drv = drvc->drv;
+ if ((tun_flags & TUN_DRIVER_IDENT_MASK) == drv->ident_flags)
+ return (drv);
+ }
+
+ return (NULL);
+}
+
+
+
+static int
+tun_clone_match(struct if_clone *ifc, const char *name)
+{
+ int tunflags;
+
+ if (tuntap_name2info(name, NULL, &tunflags) == 0) {
+ if ((tunflags & TUN_L2) == 0)
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+tap_clone_match(struct if_clone *ifc, const char *name)
+{
+ int tunflags;
+
+ if (tuntap_name2info(name, NULL, &tunflags) == 0) {
+ if ((tunflags & (TUN_L2 | TUN_VMNET)) == TUN_L2)
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+vmnet_clone_match(struct if_clone *ifc, const char *name)
+{
+ int tunflags;
+
+ if (tuntap_name2info(name, NULL, &tunflags) == 0) {
+ if ((tunflags & TUN_VMNET) != 0)
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+tun_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+{
+ struct tuntap_driver *drv;
+ struct cdev *dev;
+ int err, i, tunflags, unit;
+
+ tunflags = 0;
+ /* The name here tells us exactly what we're creating */
+ err = tuntap_name2info(name, &unit, &tunflags);
+ if (err != 0)
+ return (err);
+
+ drv = tuntap_driver_from_flags(tunflags);
+ if (drv == NULL)
+ return (ENXIO);
+
+ if (unit != -1) {
+ /* If this unit number is still available that's okay. */
+ if (alloc_unr_specific(drv->unrhdr, unit) == -1)
+ return (EEXIST);
+ } else {
+ unit = alloc_unr(drv->unrhdr);
+ }
+
+ snprintf(name, IFNAMSIZ, "%s%d", drv->cdevsw.d_name, unit);
+
+ /* find any existing device, or allocate new unit number */
+ dev = NULL;
+ i = clone_create(&drv->clones, &drv->cdevsw, &unit, &dev, 0);
+ /* No preexisting struct cdev *, create one */
+ if (i != 0)
+ i = tun_create_device(drv, unit, NULL, &dev, name);
+ if (i == 0)
+ tuncreate(dev);
+
+ return (i);
+}
+
+static void
+tunclone(void *arg, struct ucred *cred, char *name, int namelen,
+ struct cdev **dev)
+{
+ char devname[SPECNAMELEN + 1];
+ struct tuntap_driver *drv;
+ int append_unit, i, u, tunflags;
+ bool mayclone;
+
+ if (*dev != NULL)
+ return;
+
+ tunflags = 0;
+ CURVNET_SET(CRED_TO_VNET(cred));
+ if (tuntap_name2info(name, &u, &tunflags) != 0)
+ goto out; /* Not recognized */
+
+ if (u != -1 && u > IF_MAXUNIT)
+ goto out; /* Unit number too high */
+
+ mayclone = priv_check_cred(cred, PRIV_NET_IFCREATE, 0) == 0;
+ if ((tunflags & TUN_L2) != 0) {
+ /* tap/vmnet allow user open with a sysctl */
+ mayclone = (mayclone || tap_allow_uopen) && tapdclone;
+ } else {
+ mayclone = mayclone && tundclone;
+ }
+
+ /*
+ * If tun cloning is enabled, only the superuser can create an
+ * interface.
+ */
+ if (!mayclone)
+ goto out;
+
+ if (u == -1)
+ append_unit = 1;
+ else
+ append_unit = 0;
+
+ drv = tuntap_driver_from_flags(tunflags);
+ if (drv == NULL)
+ goto out;
+
+ /* find any existing device, or allocate new unit number */
+ i = clone_create(&drv->clones, &drv->cdevsw, &u, dev, 0);
+ if (i) {
+ if (append_unit) {
+ namelen = snprintf(devname, sizeof(devname), "%s%d",
+ name, u);
+ name = devname;
+ }
+
+ i = tun_create_device(drv, u, cred, dev, name);
+ }
+ if (i == 0)
+ if_clone_create(name, namelen, NULL);
+out:
+ CURVNET_RESTORE();
+}
+
+static void
+tun_destroy(struct tuntap_softc *tp)
+{
+
+ TUN_LOCK(tp);
+ tp->tun_flags |= TUN_DYING;
+ if (tp->tun_busy != 0)
+ cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
+ else
+ TUN_UNLOCK(tp);
+
+ CURVNET_SET(TUN2IFP(tp)->if_vnet);
+
+ /* destroy_dev will take care of any alias. */
+ destroy_dev(tp->tun_dev);
+ seldrain(&tp->tun_rsel);
+ knlist_clear(&tp->tun_rsel.si_note, 0);
+ knlist_destroy(&tp->tun_rsel.si_note);
+ if ((tp->tun_flags & TUN_L2) != 0) {
+ ether_ifdetach(TUN2IFP(tp));
+ } else {
+ bpfdetach(TUN2IFP(tp));
+ if_detach(TUN2IFP(tp));
+ }
+ sx_xlock(&tun_ioctl_sx);
+ TUN2IFP(tp)->if_softc = NULL;
+ sx_xunlock(&tun_ioctl_sx);
+ free_unr(tp->tun_drv->unrhdr, TUN2IFP(tp)->if_dunit);
+ if_free(TUN2IFP(tp));
+ mtx_destroy(&tp->tun_mtx);
+ cv_destroy(&tp->tun_cv);
+ free(tp, M_TUN);
+ CURVNET_RESTORE();
+}
+
+static int
+tun_clone_destroy(struct if_clone *ifc __unused, struct ifnet *ifp)
+{
+ struct tuntap_softc *tp = ifp->if_softc;
+
+ mtx_lock(&tunmtx);
+ TAILQ_REMOVE(&tunhead, tp, tun_list);
+ mtx_unlock(&tunmtx);
+ tun_destroy(tp);
+
+ return (0);
+}
+
+static void
+vnet_tun_init(const void *unused __unused)
+{
+ struct tuntap_driver *drv;
+ struct tuntap_driver_cloner *drvc;
+ int i;
+
+ for (i = 0; i < nitems(tuntap_drivers); ++i) {
+ drv = &tuntap_drivers[i];
+ drvc = malloc(sizeof(*drvc), M_TUN, M_WAITOK | M_ZERO);
+
+ drvc->drv = drv;
+ drvc->cloner = if_clone_advanced(drv->cdevsw.d_name, 0,
+ drv->clone_match_fn, drv->clone_create_fn,
+ drv->clone_destroy_fn);
+ SLIST_INSERT_HEAD(&V_tuntap_driver_cloners, drvc, link);
+ };
+}
+VNET_SYSINIT(vnet_tun_init, SI_SUB_PROTO_IF, SI_ORDER_ANY,
+ vnet_tun_init, NULL);
+
+static void
+vnet_tun_uninit(const void *unused __unused)
+{
+ struct tuntap_driver_cloner *drvc;
+
+ while (!SLIST_EMPTY(&V_tuntap_driver_cloners)) {
+ drvc = SLIST_FIRST(&V_tuntap_driver_cloners);
+ SLIST_REMOVE_HEAD(&V_tuntap_driver_cloners, link);
+
+ if_clone_detach(drvc->cloner);
+ free(drvc, M_TUN);
+ }
+}
+VNET_SYSUNINIT(vnet_tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY,
+ vnet_tun_uninit, NULL);
+
+static void
+tun_uninit(const void *unused __unused)
+{
+ struct tuntap_driver *drv;
+ struct tuntap_softc *tp;
+ int i;
+
+ EVENTHANDLER_DEREGISTER(ifnet_arrival_event, arrival_tag);
+ EVENTHANDLER_DEREGISTER(dev_clone, clone_tag);
+ drain_dev_clone_events();
+
+ mtx_lock(&tunmtx);
+ while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
+ TAILQ_REMOVE(&tunhead, tp, tun_list);
+ mtx_unlock(&tunmtx);
+ tun_destroy(tp);
+ mtx_lock(&tunmtx);
+ }
+ mtx_unlock(&tunmtx);
+ for (i = 0; i < nitems(tuntap_drivers); ++i) {
+ drv = &tuntap_drivers[i];
+ delete_unrhdr(drv->unrhdr);
+ clone_cleanup(&drv->clones);
+ }
+ mtx_destroy(&tunmtx);
+}
+SYSUNINIT(tun_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY, tun_uninit, NULL);
+
+static struct tuntap_driver *
+tuntap_driver_from_ifnet(const struct ifnet *ifp)
+{
+ struct tuntap_driver *drv;
+ int i;
+
+ if (ifp == NULL)
+ return (NULL);
+
+ for (i = 0; i < nitems(tuntap_drivers); ++i) {
+ drv = &tuntap_drivers[i];
+ if (strcmp(ifp->if_dname, drv->cdevsw.d_name) == 0)
+ return (drv);
+ }
+
+ return (NULL);
+}
+
+static int
+tuntapmodevent(module_t mod, int type, void *data)
+{
+ struct tuntap_driver *drv;
+ int i;
+
+ switch (type) {
+ case MOD_LOAD:
+ mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF);
+ for (i = 0; i < nitems(tuntap_drivers); ++i) {
+ drv = &tuntap_drivers[i];
+ clone_setup(&drv->clones);
+ drv->unrhdr = new_unrhdr(0, IF_MAXUNIT, &tunmtx);
+ }
+ arrival_tag = EVENTHANDLER_REGISTER(ifnet_arrival_event,
+ tunrename, 0, 1000);
+ if (arrival_tag == NULL)
+ return (ENOMEM);
+ clone_tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
+ if (clone_tag == NULL)
+ return (ENOMEM);
+ break;
+ case MOD_UNLOAD:
+ /* See tun_uninit, so it's done after the vnet_sysuninit() */
+ break;
+ default:
+ return EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static moduledata_t tuntap_mod = {
+ "if_tuntap",
+ tuntapmodevent,
+ 0
+};
+
+/* We'll only ever have these two, so no need for a macro. */
+static moduledata_t tun_mod = { "if_tun", NULL, 0 };
+static moduledata_t tap_mod = { "if_tap", NULL, 0 };
+
+DECLARE_MODULE(if_tuntap, tuntap_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+MODULE_VERSION(if_tuntap, 1);
+DECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+MODULE_VERSION(if_tun, 1);
+DECLARE_MODULE(if_tap, tap_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+MODULE_VERSION(if_tap, 1);
+
+static int
+tun_create_device(struct tuntap_driver *drv, int unit, struct ucred *cr,
+ struct cdev **dev, const char *name)
+{
+ struct make_dev_args args;
+ struct tuntap_softc *tp;
+ int error;
+
+ tp = malloc(sizeof(*tp), M_TUN, M_WAITOK | M_ZERO);
+ mtx_init(&tp->tun_mtx, "tun_mtx", NULL, MTX_DEF);
+ cv_init(&tp->tun_cv, "tun_condvar");
+ tp->tun_flags = drv->ident_flags;
+ tp->tun_drv = drv;
+
+ make_dev_args_init(&args);
+ if (cr != NULL)
+ args.mda_flags = MAKEDEV_REF;
+ args.mda_devsw = &drv->cdevsw;
+ args.mda_cr = cr;
+ args.mda_uid = UID_UUCP;
+ args.mda_gid = GID_DIALER;
+ args.mda_mode = 0600;
+ args.mda_unit = unit;
+ args.mda_si_drv1 = tp;
+ error = make_dev_s(&args, dev, "%s", name);
+ if (error != 0) {
+ free(tp, M_TUN);
+ return (error);
+ }
+
+ KASSERT((*dev)->si_drv1 != NULL,
+ ("Failed to set si_drv1 at %s creation", name));
+ tp->tun_dev = *dev;
+ knlist_init_mtx(&tp->tun_rsel.si_note, &tp->tun_mtx);
+ mtx_lock(&tunmtx);
+ TAILQ_INSERT_TAIL(&tunhead, tp, tun_list);
+ mtx_unlock(&tunmtx);
+ return (0);
+}
+
+static void
+tunstart(struct ifnet *ifp)
+{
+ struct tuntap_softc *tp = ifp->if_softc;
+ struct mbuf *m;
+
+ TUNDEBUG(ifp, "starting\n");
+ if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
+ IFQ_LOCK(&ifp->if_snd);
+ IFQ_POLL_NOLOCK(&ifp->if_snd, m);
+ if (m == NULL) {
+ IFQ_UNLOCK(&ifp->if_snd);
+ return;
+ }
+ IFQ_UNLOCK(&ifp->if_snd);
+ }
+
+ TUN_LOCK(tp);
+ if (tp->tun_flags & TUN_RWAIT) {
+ tp->tun_flags &= ~TUN_RWAIT;
+ wakeup(tp);
+ }
+ selwakeuppri(&tp->tun_rsel, PZERO + 1);
+ KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
+ if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) {
+ TUN_UNLOCK(tp);
+ pgsigio(&tp->tun_sigio, SIGIO, 0);
+ } else
+ TUN_UNLOCK(tp);
+}
+
+/*
+ * tunstart_l2
+ *
+ * queue packets from higher level ready to put out
+ */
+static void
+tunstart_l2(struct ifnet *ifp)
+{
+ struct tuntap_softc *tp = ifp->if_softc;
+
+ TUNDEBUG(ifp, "starting\n");
+
+ /*
+ * do not junk pending output if we are in VMnet mode.
+ * XXX: can this do any harm because of queue overflow?
+ */
+
+ TUN_LOCK(tp);
+ if (((tp->tun_flags & TUN_VMNET) == 0) &&
+ ((tp->tun_flags & TUN_READY) != TUN_READY)) {
+ struct mbuf *m;
+
+ /* Unlocked read. */
+ TUNDEBUG(ifp, "not ready, tun_flags = 0x%x\n", tp->tun_flags);
+
+ for (;;) {
+ IF_DEQUEUE(&ifp->if_snd, m);
+ if (m != NULL) {
+ m_freem(m);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ } else
+ break;
+ }
+ TUN_UNLOCK(tp);
+
+ return;
+ }
+
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+
+ if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
+ if (tp->tun_flags & TUN_RWAIT) {
+ tp->tun_flags &= ~TUN_RWAIT;
+ wakeup(tp);
+ }
+
+ if ((tp->tun_flags & TUN_ASYNC) && (tp->tun_sigio != NULL)) {
+ TUN_UNLOCK(tp);
+ pgsigio(&tp->tun_sigio, SIGIO, 0);
+ TUN_LOCK(tp);
+ }
+
+ selwakeuppri(&tp->tun_rsel, PZERO+1);
+ KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); /* obytes are counted in ether_output */
+ }
+
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ TUN_UNLOCK(tp);
+} /* tunstart_l2 */
+
+/* XXX: should return an error code so it can fail. */
+static void
+tuncreate(struct cdev *dev)
+{
+ struct tuntap_driver *drv;
+ struct tuntap_softc *tp;
+ struct ifnet *ifp;
+ struct ether_addr eaddr;
+ int iflags;
+ u_char type;
+
+ tp = dev->si_drv1;
+ KASSERT(tp != NULL,
+ ("si_drv1 should have been initialized at creation"));
+
+ drv = tp->tun_drv;
+ iflags = IFF_MULTICAST;
+ if ((tp->tun_flags & TUN_L2) != 0) {
+ type = IFT_ETHER;
+ iflags |= IFF_BROADCAST | IFF_SIMPLEX;
+ } else {
+ type = IFT_PPP;
+ iflags |= IFF_POINTOPOINT;
+ }
+ ifp = tp->tun_ifp = if_alloc(type);
+ if (ifp == NULL)
+ panic("%s%d: failed to if_alloc() interface.\n",
+ drv->cdevsw.d_name, dev2unit(dev));
+ ifp->if_softc = tp;
+ if_initname(ifp, drv->cdevsw.d_name, dev2unit(dev));
+ ifp->if_ioctl = tunifioctl;
+ ifp->if_flags = iflags;
+ IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
+ ifp->if_capabilities |= IFCAP_LINKSTATE;
+ ifp->if_capenable |= IFCAP_LINKSTATE;
+
+ if ((tp->tun_flags & TUN_L2) != 0) {
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_init = tunifinit;
+ ifp->if_start = tunstart_l2;
+
+ ether_gen_addr(ifp, &eaddr);
+ ether_ifattach(ifp, eaddr.octet);
+ } else {
+ ifp->if_mtu = TUNMTU;
+ ifp->if_start = tunstart;
+ ifp->if_output = tunoutput;
+
+ ifp->if_snd.ifq_drv_maxlen = 0;
+ IFQ_SET_READY(&ifp->if_snd);
+
+ if_attach(ifp);
+ bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
+ }
+
+ TUN_LOCK(tp);
+ tp->tun_flags |= TUN_INITED;
+ TUN_UNLOCK(tp);
+
+ TUNDEBUG(ifp, "interface %s is created, minor = %#x\n",
+ ifp->if_xname, dev2unit(dev));
+}
+
+static void
+tunrename(void *arg __unused, struct ifnet *ifp)
+{
+ struct tuntap_softc *tp;
+ int error;
+
+ if ((ifp->if_flags & IFF_RENAMING) == 0)
+ return;
+
+ if (tuntap_driver_from_ifnet(ifp) == NULL)
+ return;
+
+ /*
+ * We need to grab the ioctl sx long enough to make sure the softc is
+ * still there. If it is, we can safely try to busy the tun device.
+ * The busy may fail if the device is currently dying, in which case
+ * we do nothing. If it doesn't fail, the busy count stops the device
+ * from dying until we've created the alias (that will then be
+ * subsequently destroyed).
+ */
+ sx_xlock(&tun_ioctl_sx);
+ tp = ifp->if_softc;
+ if (tp == NULL) {
+ sx_xunlock(&tun_ioctl_sx);
+ return;
+ }
+ error = tun_busy(tp);
+ sx_xunlock(&tun_ioctl_sx);
+ if (error != 0)
+ return;
+ if (tp->tun_alias != NULL) {
+ destroy_dev(tp->tun_alias);
+ tp->tun_alias = NULL;
+ }
+
+ if (strcmp(ifp->if_xname, tp->tun_dev->si_name) == 0)
+ goto out;
+
+ /*
+ * Failure's ok, aliases are created on a best effort basis. If a
+ * tun user/consumer decides to rename the interface to conflict with
+ * another device (non-ifnet) on the system, we will assume they know
+ * what they are doing. make_dev_alias_p won't touch tun_alias on
+ * failure, so we use it but ignore the return value.
+ */
+ make_dev_alias_p(MAKEDEV_CHECKNAME, &tp->tun_alias, tp->tun_dev, "%s",
+ ifp->if_xname);
+out:
+ tun_unbusy(tp);
+}
+
+static int
+tunopen(struct cdev *dev, int flag, int mode, struct thread *td)
+{
+ struct ifnet *ifp;
+ struct tuntap_softc *tp;
+ int error, tunflags;
+
+ tunflags = 0;
+ CURVNET_SET(TD_TO_VNET(td));
+ error = tuntap_name2info(dev->si_name, NULL, &tunflags);
+ if (error != 0) {
+ CURVNET_RESTORE();
+ return (error); /* Shouldn't happen */
+ }
+
+ if ((tunflags & TUN_L2) != 0) {
+ /* Restrict? */
+ if (tap_allow_uopen == 0) {
+ error = priv_check(td, PRIV_NET_TAP);
+ if (error != 0) {
+ CURVNET_RESTORE();
+ return (error);
+ }
+ }
+ }
+
+ tp = dev->si_drv1;
+ KASSERT(tp != NULL,
+ ("si_drv1 should have been initialized at creation"));
+
+ TUN_LOCK(tp);
+ if ((tp->tun_flags & TUN_INITED) == 0) {
+ TUN_UNLOCK(tp);
+ CURVNET_RESTORE();
+ return (ENXIO);
+ }
+ if ((tp->tun_flags & (TUN_OPEN | TUN_DYING)) != 0) {
+ TUN_UNLOCK(tp);
+ CURVNET_RESTORE();
+ return (EBUSY);
+ }
+
+ error = tun_busy_locked(tp);
+ KASSERT(error == 0, ("Must be able to busy an unopen tunnel"));
+ ifp = TUN2IFP(tp);
+
+ if ((tp->tun_flags & TUN_L2) != 0) {
+ bcopy(IF_LLADDR(ifp), tp->tun_ether.octet,
+ sizeof(tp->tun_ether.octet));
+
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+ if (tapuponopen)
+ ifp->if_flags |= IFF_UP;
+ }
+
+#ifndef __rtems__
+ tp->tun_pid = td->td_proc->p_pid;
+#endif /* __rtems__ */
+ tp->tun_flags |= TUN_OPEN;
+
+ if_link_state_change(ifp, LINK_STATE_UP);
+ TUNDEBUG(ifp, "open\n");
+ TUN_UNLOCK(tp);
+
+ /*
+ * This can fail with either ENOENT or EBUSY. This is in the middle of
+ * d_open, so ENOENT should not be possible. EBUSY is possible, but
+ * the only cdevpriv dtor being set will be tundtor and the softc being
+ * passed is constant for a given cdev. We ignore the possible error
+ * because of this as either "unlikely" or "not actually a problem."
+ */
+ (void)devfs_set_cdevpriv(tp, tundtor);
+ CURVNET_RESTORE();
+ return (0);
+}
+
+/*
+ * tundtor - tear down the device - mark i/f down & delete
+ * routing info
+ */
+static void
+tundtor(void *data)
+{
+#ifndef __rtems__
+ struct proc *p;
+#endif /* __rtems__ */
+ struct tuntap_softc *tp;
+ struct ifnet *ifp;
+ bool l2tun;
+
+ tp = data;
+#ifndef __rtems__
+ p = curproc;
+#endif /* __rtems__ */
+ ifp = TUN2IFP(tp);
+
+ TUN_LOCK(tp);
+
+#ifndef __rtems__
+ /*
+ * Realistically, we can't be obstinate here. This only means that the
+ * tuntap device was closed out of order, and the last closer wasn't the
+ * controller. These are still good to know about, though, as software
+ * should avoid multiple processes with a tuntap device open and
+ * ill-defined transfer of control (e.g., handoff, TUNSIFPID, close in
+ * parent).
+ */
+ if (p->p_pid != tp->tun_pid) {
+ log(LOG_INFO,
+ "pid %d (%s), %s: tun/tap protocol violation, non-controlling process closed last.\n",
+ p->p_pid, p->p_comm, tp->tun_dev->si_name);
+ }
+#endif /* __rtems__ */
+
+ /*
+ * junk all pending output
+ */
+ CURVNET_SET(ifp->if_vnet);
+
+ l2tun = false;
+ if ((tp->tun_flags & TUN_L2) != 0) {
+ l2tun = true;
+ IF_DRAIN(&ifp->if_snd);
+ } else {
+ IFQ_PURGE(&ifp->if_snd);
+ }
+
+ /* For vmnet, we won't do most of the address/route bits */
+ if ((tp->tun_flags & TUN_VMNET) != 0 ||
+ (l2tun && (ifp->if_flags & IFF_LINK0) != 0))
+ goto out;
+
+ if (ifp->if_flags & IFF_UP) {
+ TUN_UNLOCK(tp);
+ if_down(ifp);
+ TUN_LOCK(tp);
+ }
+
+ /* Delete all addresses and routes which reference this interface. */
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ struct ifaddr *ifa;
+
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ TUN_UNLOCK(tp);
+ CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ /* deal w/IPv4 PtP destination; unlocked read */
+ if (!l2tun && ifa->ifa_addr->sa_family == AF_INET) {
+ rtinit(ifa, (int)RTM_DELETE,
+ tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
+ } else {
+ rtinit(ifa, (int)RTM_DELETE, 0);
+ }
+ }
+ if_purgeaddrs(ifp);
+ TUN_LOCK(tp);
+ }
+
+out:
+ if_link_state_change(ifp, LINK_STATE_DOWN);
+ CURVNET_RESTORE();
+
+ funsetown(&tp->tun_sigio);
+ selwakeuppri(&tp->tun_rsel, PZERO + 1);
+ KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
+ TUNDEBUG (ifp, "closed\n");
+ tp->tun_flags &= ~TUN_OPEN;
+#ifndef __rtems__
+ tp->tun_pid = 0;
+#endif /* __rtems__ */
+
+ tun_unbusy_locked(tp);
+ TUN_UNLOCK(tp);
+}
+
+static void
+tuninit(struct ifnet *ifp)
+{
+ struct tuntap_softc *tp = ifp->if_softc;
+#ifdef INET
+ struct ifaddr *ifa;
+#endif
+
+ TUNDEBUG(ifp, "tuninit\n");
+
+ TUN_LOCK(tp);
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ if ((tp->tun_flags & TUN_L2) == 0) {
+ ifp->if_flags |= IFF_UP;
+ getmicrotime(&ifp->if_lastchange);
+#ifdef INET
+ if_addr_rlock(ifp);
+ CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr->sa_family == AF_INET) {
+ struct sockaddr_in *si;
+
+ si = (struct sockaddr_in *)ifa->ifa_dstaddr;
+ if (si && si->sin_addr.s_addr) {
+ tp->tun_flags |= TUN_DSTADDR;
+ break;
+ }
+ }
+ }
+ if_addr_runlock(ifp);
+#endif
+ TUN_UNLOCK(tp);
+ } else {
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ TUN_UNLOCK(tp);
+ /* attempt to start output */
+ tunstart_l2(ifp);
+ }
+
+}
+
+/*
+ * Used only for l2 tunnel.
+ */
+static void
+tunifinit(void *xtp)
+{
+ struct tuntap_softc *tp;
+
+ tp = (struct tuntap_softc *)xtp;
+ tuninit(tp->tun_ifp);
+}
+
+/*
+ * Process an ioctl request.
+ */
+static int
+tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct tuntap_softc *tp;
+ struct ifstat *ifs;
+ struct ifmediareq *ifmr;
+ int dummy, error = 0;
+ bool l2tun;
+
+ ifmr = NULL;
+ sx_xlock(&tun_ioctl_sx);
+ tp = ifp->if_softc;
+ if (tp == NULL) {
+ error = ENXIO;
+ goto bad;
+ }
+ l2tun = (tp->tun_flags & TUN_L2) != 0;
+ switch(cmd) {
+ case SIOCGIFSTATUS:
+ ifs = (struct ifstat *)data;
+ TUN_LOCK(tp);
+#ifndef __rtems__
+ if (tp->tun_pid)
+ snprintf(ifs->ascii, sizeof(ifs->ascii),
+ "\tOpened by PID %d\n", tp->tun_pid);
+ else
+#endif /* __rtems__ */
+ ifs->ascii[0] = '\0';
+ TUN_UNLOCK(tp);
+ break;
+ case SIOCSIFADDR:
+ if (l2tun)
+ error = ether_ioctl(ifp, cmd, data);
+ else
+ tuninit(ifp);
+ if (error == 0)
+ TUNDEBUG(ifp, "address set\n");
+ break;
+ case SIOCSIFMTU:
+ ifp->if_mtu = ifr->ifr_mtu;
+ TUNDEBUG(ifp, "mtu set\n");
+ break;
+ case SIOCSIFFLAGS:
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ break;
+ case SIOCGIFMEDIA:
+ if (!l2tun) {
+ error = EINVAL;
+ break;
+ }
+
+ ifmr = (struct ifmediareq *)data;
+ dummy = ifmr->ifm_count;
+ ifmr->ifm_count = 1;
+ ifmr->ifm_status = IFM_AVALID;
+ ifmr->ifm_active = IFM_ETHER;
+ if (tp->tun_flags & TUN_OPEN)
+ ifmr->ifm_status |= IFM_ACTIVE;
+ ifmr->ifm_current = ifmr->ifm_active;
+ if (dummy >= 1) {
+ int media = IFM_ETHER;
+ error = copyout(&media, ifmr->ifm_ulist, sizeof(int));
+ }
+ break;
+ default:
+ if (l2tun) {
+ error = ether_ioctl(ifp, cmd, data);
+ } else {
+ error = EINVAL;
+ }
+ }
+bad:
+ sx_xunlock(&tun_ioctl_sx);
+ return (error);
+}
+
+/*
+ * tunoutput - queue packets from higher level ready to put out.
+ */
+static int
+tunoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
+ struct route *ro)
+{
+ struct tuntap_softc *tp = ifp->if_softc;
+ u_short cached_tun_flags;
+ int error;
+ u_int32_t af;
+
+ TUNDEBUG (ifp, "tunoutput\n");
+
+#ifdef MAC
+ error = mac_ifnet_check_transmit(ifp, m0);
+ if (error) {
+ m_freem(m0);
+ return (error);
+ }
+#endif
+
+ /* Could be unlocked read? */
+ TUN_LOCK(tp);
+ cached_tun_flags = tp->tun_flags;
+ TUN_UNLOCK(tp);
+ if ((cached_tun_flags & TUN_READY) != TUN_READY) {
+ TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
+ m_freem (m0);
+ return (EHOSTDOWN);
+ }
+
+ if ((ifp->if_flags & IFF_UP) != IFF_UP) {
+ m_freem (m0);
+ return (EHOSTDOWN);
+ }
+
+ /* BPF writes need to be handled specially. */
+ if (dst->sa_family == AF_UNSPEC)
+ bcopy(dst->sa_data, &af, sizeof(af));
+ else
+ af = dst->sa_family;
+
+ if (bpf_peers_present(ifp->if_bpf))
+ bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m0);
+
+ /* prepend sockaddr? this may abort if the mbuf allocation fails */
+ if (cached_tun_flags & TUN_LMODE) {
+ /* allocate space for sockaddr */
+ M_PREPEND(m0, dst->sa_len, M_NOWAIT);
+
+ /* if allocation failed drop packet */
+ if (m0 == NULL) {
+ if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ return (ENOBUFS);
+ } else {
+ bcopy(dst, m0->m_data, dst->sa_len);
+ }
+ }
+
+ if (cached_tun_flags & TUN_IFHEAD) {
+ /* Prepend the address family */
+ M_PREPEND(m0, 4, M_NOWAIT);
+
+ /* if allocation failed drop packet */
+ if (m0 == NULL) {
+ if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ return (ENOBUFS);
+ } else
+ *(u_int32_t *)m0->m_data = htonl(af);
+ } else {
+#ifdef INET
+ if (af != AF_INET)
+#endif
+ {
+ m_freem(m0);
+ return (EAFNOSUPPORT);
+ }
+ }
+
+ error = (ifp->if_transmit)(ifp, m0);
+ if (error)
+ return (ENOBUFS);
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ return (0);
+}
+
+/*
+ * the cdevsw interface is now pretty minimal.
+ */
+static int
+tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
+ struct thread *td)
+{
+ struct ifreq ifr, *ifrp;
+ struct tuntap_softc *tp = dev->si_drv1;
+ struct tuninfo *tunp;
+ int error, iflags;
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD4)
+ int ival;
+#endif
+ bool l2tun;
+
+ l2tun = (tp->tun_flags & TUN_L2) != 0;
+ if (l2tun) {
+ /* tap specific ioctls */
+ switch(cmd) {
+ /* VMware/VMnet port ioctl's */
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD4)
+ case _IO('V', 0):
+ ival = IOCPARM_IVAL(data);
+ data = (caddr_t)&ival;
+ /* FALLTHROUGH */
+#endif
+ case VMIO_SIOCSIFFLAGS: /* VMware/VMnet SIOCSIFFLAGS */
+ iflags = *(int *)data;
+ iflags &= TUN_VMIO_FLAG_MASK;
+ iflags &= ~IFF_CANTCHANGE;
+ iflags |= IFF_UP;
+
+ TUN_LOCK(tp);
+ TUN2IFP(tp)->if_flags = iflags |
+ (TUN2IFP(tp)->if_flags & IFF_CANTCHANGE);
+ TUN_UNLOCK(tp);
+
+ return (0);
+ case SIOCGIFADDR: /* get MAC address of the remote side */
+ TUN_LOCK(tp);
+ bcopy(&tp->tun_ether.octet, data,
+ sizeof(tp->tun_ether.octet));
+ TUN_UNLOCK(tp);
+
+ return (0);
+ case SIOCSIFADDR: /* set MAC address of the remote side */
+ TUN_LOCK(tp);
+ bcopy(data, &tp->tun_ether.octet,
+ sizeof(tp->tun_ether.octet));
+ TUN_UNLOCK(tp);
+
+ return (0);
+ }
+
+ /* Fall through to the common ioctls if unhandled */
+ } else {
+ switch (cmd) {
+ case TUNSLMODE:
+ TUN_LOCK(tp);
+ if (*(int *)data) {
+ tp->tun_flags |= TUN_LMODE;
+ tp->tun_flags &= ~TUN_IFHEAD;
+ } else
+ tp->tun_flags &= ~TUN_LMODE;
+ TUN_UNLOCK(tp);
+
+ return (0);
+ case TUNSIFHEAD:
+ TUN_LOCK(tp);
+ if (*(int *)data) {
+ tp->tun_flags |= TUN_IFHEAD;
+ tp->tun_flags &= ~TUN_LMODE;
+ } else
+ tp->tun_flags &= ~TUN_IFHEAD;
+ TUN_UNLOCK(tp);
+
+ return (0);
+ case TUNGIFHEAD:
+ TUN_LOCK(tp);
+ *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
+ TUN_UNLOCK(tp);
+
+ return (0);
+ case TUNSIFMODE:
+ /* deny this if UP */
+ if (TUN2IFP(tp)->if_flags & IFF_UP)
+ return (EBUSY);
+
+ switch (*(int *)data & ~IFF_MULTICAST) {
+ case IFF_POINTOPOINT:
+ case IFF_BROADCAST:
+ TUN_LOCK(tp);
+ TUN2IFP(tp)->if_flags &=
+ ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
+ TUN2IFP(tp)->if_flags |= *(int *)data;
+ TUN_UNLOCK(tp);
+
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (0);
+ case TUNSIFPID:
+#ifndef __rtems__
+ TUN_LOCK(tp);
+ tp->tun_pid = curthread->td_proc->p_pid;
+ TUN_UNLOCK(tp);
+#endif /* __rtems__ */
+
+ return (0);
+ }
+ /* Fall through to the common ioctls if unhandled */
+ }
+
+ switch (cmd) {
+ case TUNGIFNAME:
+ ifrp = (struct ifreq *)data;
+ strlcpy(ifrp->ifr_name, TUN2IFP(tp)->if_xname, IFNAMSIZ);
+
+ return (0);
+ case TUNSIFINFO:
+ tunp = (struct tuninfo *)data;
+ if (TUN2IFP(tp)->if_type != tunp->type)
+ return (EPROTOTYPE);
+ TUN_LOCK(tp);
+ if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
+ strlcpy(ifr.ifr_name, if_name(TUN2IFP(tp)), IFNAMSIZ);
+ ifr.ifr_mtu = tunp->mtu;
+ CURVNET_SET(TUN2IFP(tp)->if_vnet);
+ error = ifhwioctl(SIOCSIFMTU, TUN2IFP(tp),
+ (caddr_t)&ifr, td);
+ CURVNET_RESTORE();
+ if (error) {
+ TUN_UNLOCK(tp);
+ return (error);
+ }
+ }
+ TUN2IFP(tp)->if_baudrate = tunp->baudrate;
+ TUN_UNLOCK(tp);
+ break;
+ case TUNGIFINFO:
+ tunp = (struct tuninfo *)data;
+ TUN_LOCK(tp);
+ tunp->mtu = TUN2IFP(tp)->if_mtu;
+ tunp->type = TUN2IFP(tp)->if_type;
+ tunp->baudrate = TUN2IFP(tp)->if_baudrate;
+ TUN_UNLOCK(tp);
+ break;
+ case TUNSDEBUG:
+ tundebug = *(int *)data;
+ break;
+ case TUNGDEBUG:
+ *(int *)data = tundebug;
+ break;
+ case FIONBIO:
+ break;
+ case FIOASYNC:
+ TUN_LOCK(tp);
+ if (*(int *)data)
+ tp->tun_flags |= TUN_ASYNC;
+ else
+ tp->tun_flags &= ~TUN_ASYNC;
+ TUN_UNLOCK(tp);
+ break;
+ case FIONREAD:
+ if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) {
+ struct mbuf *mb;
+ IFQ_LOCK(&TUN2IFP(tp)->if_snd);
+ IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb);
+ for (*(int *)data = 0; mb != NULL; mb = mb->m_next)
+ *(int *)data += mb->m_len;
+ IFQ_UNLOCK(&TUN2IFP(tp)->if_snd);
+ } else
+ *(int *)data = 0;
+ break;
+ case FIOSETOWN:
+ return (fsetown(*(int *)data, &tp->tun_sigio));
+
+ case FIOGETOWN:
+ *(int *)data = fgetown(&tp->tun_sigio);
+ return (0);
+
+ /* This is deprecated, FIOSETOWN should be used instead. */
+ case TIOCSPGRP:
+ return (fsetown(-(*(int *)data), &tp->tun_sigio));
+
+ /* This is deprecated, FIOGETOWN should be used instead. */
+ case TIOCGPGRP:
+ *(int *)data = -fgetown(&tp->tun_sigio);
+ return (0);
+
+ default:
+ return (ENOTTY);
+ }
+ return (0);
+}
+
+/*
+ * The cdevsw read interface - reads a packet at a time, or at
+ * least as much of a packet as can be read.
+ */
+static int
+tunread(struct cdev *dev, struct uio *uio, int flag)
+{
+ struct tuntap_softc *tp = dev->si_drv1;
+ struct ifnet *ifp = TUN2IFP(tp);
+ struct mbuf *m;
+ int error=0, len;
+
+ TUNDEBUG (ifp, "read\n");
+ TUN_LOCK(tp);
+ if ((tp->tun_flags & TUN_READY) != TUN_READY) {
+ TUN_UNLOCK(tp);
+ TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
+ return (EHOSTDOWN);
+ }
+
+ tp->tun_flags &= ~TUN_RWAIT;
+
+ for (;;) {
+ IFQ_DEQUEUE(&ifp->if_snd, m);
+ if (m != NULL)
+ break;
+ if (flag & O_NONBLOCK) {
+ TUN_UNLOCK(tp);
+ return (EWOULDBLOCK);
+ }
+ tp->tun_flags |= TUN_RWAIT;
+ error = mtx_sleep(tp, &tp->tun_mtx, PCATCH | (PZERO + 1),
+ "tunread", 0);
+ if (error != 0) {
+ TUN_UNLOCK(tp);
+ return (error);
+ }
+ }
+ TUN_UNLOCK(tp);
+
+ if ((tp->tun_flags & TUN_L2) != 0)
+ BPF_MTAP(ifp, m);
+
+ while (m && uio->uio_resid > 0 && error == 0) {
+ len = min(uio->uio_resid, m->m_len);
+ if (len != 0)
+ error = uiomove(mtod(m, void *), len, uio);
+ m = m_free(m);
+ }
+
+ if (m) {
+ TUNDEBUG(ifp, "Dropping mbuf\n");
+ m_freem(m);
+ }
+ return (error);
+}
+
+static int
+tunwrite_l2(struct tuntap_softc *tp, struct mbuf *m)
+{
+ struct ether_header *eh;
+ struct ifnet *ifp;
+
+ ifp = TUN2IFP(tp);
+
+ /*
+ * Only pass a unicast frame to ether_input(), if it would
+ * actually have been received by non-virtual hardware.
+ */
+ if (m->m_len < sizeof(struct ether_header)) {
+ m_freem(m);
+ return (0);
+ }
+
+ eh = mtod(m, struct ether_header *);
+
+ if (eh && (ifp->if_flags & IFF_PROMISC) == 0 &&
+ !ETHER_IS_MULTICAST(eh->ether_dhost) &&
+ bcmp(eh->ether_dhost, IF_LLADDR(ifp), ETHER_ADDR_LEN) != 0) {
+ m_freem(m);
+ return (0);
+ }
+
+ /* Pass packet up to parent. */
+ CURVNET_SET(ifp->if_vnet);
+ (*ifp->if_input)(ifp, m);
+ CURVNET_RESTORE();
+ /* ibytes are counted in parent */
+ if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
+ return (0);
+}
+
+static int
+tunwrite_l3(struct tuntap_softc *tp, struct mbuf *m)
+{
+ struct ifnet *ifp;
+ int family, isr;
+
+ ifp = TUN2IFP(tp);
+ /* Could be unlocked read? */
+ TUN_LOCK(tp);
+ if (tp->tun_flags & TUN_IFHEAD) {
+ TUN_UNLOCK(tp);
+ if (m->m_len < sizeof(family) &&
+ (m = m_pullup(m, sizeof(family))) == NULL)
+ return (ENOBUFS);
+ family = ntohl(*mtod(m, u_int32_t *));
+ m_adj(m, sizeof(family));
+ } else {
+ TUN_UNLOCK(tp);
+ family = AF_INET;
+ }
+
+ BPF_MTAP2(ifp, &family, sizeof(family), m);
+
+ switch (family) {
+#ifdef INET
+ case AF_INET:
+ isr = NETISR_IP;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ isr = NETISR_IPV6;
+ break;
+#endif
+ default:
+ m_freem(m);
+ return (EAFNOSUPPORT);
+ }
+ random_harvest_queue(m, sizeof(*m), RANDOM_NET_TUN);
+ if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
+ if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
+ CURVNET_SET(ifp->if_vnet);
+ M_SETFIB(m, ifp->if_fib);
+ netisr_dispatch(isr, m);
+ CURVNET_RESTORE();
+ return (0);
+}
+
+/*
+ * the cdevsw write interface - an atomic write is a packet - or else!
+ */
+static int
+tunwrite(struct cdev *dev, struct uio *uio, int flag)
+{
+ struct tuntap_softc *tp;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ uint32_t mru;
+ int align;
+ bool l2tun;
+
+ tp = dev->si_drv1;
+ ifp = TUN2IFP(tp);
+ TUNDEBUG(ifp, "tunwrite\n");
+ if ((ifp->if_flags & IFF_UP) != IFF_UP)
+ /* ignore silently */
+ return (0);
+
+ if (uio->uio_resid == 0)
+ return (0);
+
+ l2tun = (tp->tun_flags & TUN_L2) != 0;
+ align = 0;
+ mru = l2tun ? TAPMRU : TUNMRU;
+ if (l2tun)
+ align = ETHER_ALIGN;
+ else if ((tp->tun_flags & TUN_IFHEAD) != 0)
+ mru += sizeof(uint32_t); /* family */
+ if (uio->uio_resid < 0 || uio->uio_resid > mru) {
+ TUNDEBUG(ifp, "len=%zd!\n", uio->uio_resid);
+ return (EIO);
+ }
+
+ if ((m = m_uiotombuf(uio, M_NOWAIT, 0, align, M_PKTHDR)) == NULL) {
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ return (ENOBUFS);
+ }
+
+ m->m_pkthdr.rcvif = ifp;
+#ifdef MAC
+ mac_ifnet_create_mbuf(ifp, m);
+#endif
+
+ if (l2tun)
+ return (tunwrite_l2(tp, m));
+
+ return (tunwrite_l3(tp, m));
+}
+
+/*
+ * tunpoll - the poll interface, this is only useful on reads
+ * really. The write detect always returns true, write never blocks
+ * anyway, it either accepts the packet or drops it.
+ */
+static int
+tunpoll(struct cdev *dev, int events, struct thread *td)
+{
+ struct tuntap_softc *tp = dev->si_drv1;
+ struct ifnet *ifp = TUN2IFP(tp);
+ int revents = 0;
+
+ TUNDEBUG(ifp, "tunpoll\n");
+
+ if (events & (POLLIN | POLLRDNORM)) {
+ IFQ_LOCK(&ifp->if_snd);
+ if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
+ TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
+ revents |= events & (POLLIN | POLLRDNORM);
+ } else {
+ TUNDEBUG(ifp, "tunpoll waiting\n");
+ selrecord(td, &tp->tun_rsel);
+ }
+ IFQ_UNLOCK(&ifp->if_snd);
+ }
+ revents |= events & (POLLOUT | POLLWRNORM);
+
+ return (revents);
+}
+
+/*
+ * tunkqfilter - support for the kevent() system call.
+ */
+static int
+tunkqfilter(struct cdev *dev, struct knote *kn)
+{
+ struct tuntap_softc *tp = dev->si_drv1;
+ struct ifnet *ifp = TUN2IFP(tp);
+
+ switch(kn->kn_filter) {
+ case EVFILT_READ:
+ TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n",
+ ifp->if_xname, dev2unit(dev));
+ kn->kn_fop = &tun_read_filterops;
+ break;
+
+ case EVFILT_WRITE:
+ TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n",
+ ifp->if_xname, dev2unit(dev));
+ kn->kn_fop = &tun_write_filterops;
+ break;
+
+ default:
+ TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n",
+ ifp->if_xname, dev2unit(dev));
+ return(EINVAL);
+ }
+
+ kn->kn_hook = tp;
+ knlist_add(&tp->tun_rsel.si_note, kn, 0);
+
+ return (0);
+}
+
+/*
+ * Return true of there is data in the interface queue.
+ */
+static int
+tunkqread(struct knote *kn, long hint)
+{
+ int ret;
+ struct tuntap_softc *tp = kn->kn_hook;
+ struct cdev *dev = tp->tun_dev;
+ struct ifnet *ifp = TUN2IFP(tp);
+
+ if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
+ TUNDEBUG(ifp,
+ "%s have data in the queue. Len = %d, minor = %#x\n",
+ ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev));
+ ret = 1;
+ } else {
+ TUNDEBUG(ifp,
+ "%s waiting for data, minor = %#x\n", ifp->if_xname,
+ dev2unit(dev));
+ ret = 0;
+ }
+
+ return (ret);
+}
+
+/*
+ * Always can write, always return MTU in kn->data.
+ */
+static int
+tunkqwrite(struct knote *kn, long hint)
+{
+ struct tuntap_softc *tp = kn->kn_hook;
+ struct ifnet *ifp = TUN2IFP(tp);
+
+ kn->kn_data = ifp->if_mtu;
+
+ return (1);
+}
+
+static void
+tunkqdetach(struct knote *kn)
+{
+ struct tuntap_softc *tp = kn->kn_hook;
+
+ knlist_remove(&tp->tun_rsel.si_note, kn, 0);
+}
diff --git a/freebsd/sys/net/if_vlan.c b/freebsd/sys/net/if_vlan.c
index 8f108b9d..2b5b3488 100644
--- a/freebsd/sys/net/if_vlan.c
+++ b/freebsd/sys/net/if_vlan.c
@@ -48,6 +48,7 @@
__FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_inet.h>
+#include <rtems/bsd/local/opt_inet6.h>
#include <rtems/bsd/local/opt_vlan.h>
#include <rtems/bsd/local/opt_ratelimit.h>
@@ -76,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/if_vlan_var.h>
+#include <net/route.h>
#include <net/vnet.h>
#ifdef INET
@@ -83,6 +85,14 @@ __FBSDID("$FreeBSD$");
#include <netinet/if_ether.h>
#endif
+#ifdef INET6
+/*
+ * XXX: declare here to avoid to include many inet6 related files..
+ * should be more generalized?
+ */
+extern void nd6_setmtu(struct ifnet *);
+#endif
+
#define VLAN_DEF_HWIDTH 4
#define VLAN_IFFLAGS (IFF_BROADCAST | IFF_MULTICAST)
@@ -1410,11 +1420,19 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid)
* Set up our interface address to reflect the underlying
* physical interface's.
*/
- bcopy(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen);
+ TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv);
((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen =
p->if_addrlen;
- TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv);
+ /*
+ * Do not schedule link address update if it was the same
+ * as previous parent's. This helps avoid updating for each
+ * associated llentry.
+ */
+ if (memcmp(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen) != 0) {
+ bcopy(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen);
+ taskqueue_enqueue(taskqueue_thread, &ifv->lladdr_task);
+ }
/* We are ready for operation now. */
ifp->if_drv_flags |= IFF_DRV_RUNNING;
@@ -1725,7 +1743,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
struct ifvlan *ifv;
struct ifvlantrunk *trunk;
struct vlanreq vlr;
- int error = 0;
+ int error = 0, oldmtu;
ifr = (struct ifreq *)data;
ifa = (struct ifaddr *) data;
@@ -1819,8 +1837,20 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = ENOENT;
break;
}
+ oldmtu = ifp->if_mtu;
error = vlan_config(ifv, p, vlr.vlr_tag);
if_rele(p);
+
+ /*
+ * VLAN MTU may change during addition of the vlandev.
+ * If it did, do network layer specific procedure.
+ */
+ if (ifp->if_mtu != oldmtu) {
+#ifdef INET6
+ nd6_setmtu(ifp);
+#endif
+ rt_updatemtu(ifp);
+ }
break;
case SIOCGETVLAN:
diff --git a/freebsd/sys/net/iflib.h b/freebsd/sys/net/iflib.h
index 2395439a..b0215daf 100644
--- a/freebsd/sys/net/iflib.h
+++ b/freebsd/sys/net/iflib.h
@@ -361,6 +361,11 @@ typedef enum {
* Interface needs admin task to ignore interface up/down status
*/
#define IFLIB_ADMIN_ALWAYS_RUN 0x10000
+/*
+ * When using a single hardware interrupt for the interface, only process RX
+ * interrupts instead of doing combined RX/TX processing.
+ */
+#define IFLIB_SINGLE_IRQ_RX_ONLY 0x40000
/*
diff --git a/freebsd/sys/net/route.c b/freebsd/sys/net/route.c
index 0933c3a8..adbf91bd 100644
--- a/freebsd/sys/net/route.c
+++ b/freebsd/sys/net/route.c
@@ -865,7 +865,7 @@ rtrequest_fib(int req,
* to reflect size of the provided buffer. if no NHR_COPY is specified,
* point dst,netmask and gw @info fields to appropriate @rt values.
*
- * if @flags contains NHR_REF, do refcouting on rt_ifp.
+ * if @flags contains NHR_REF, do refcouting on rt_ifp and rt_ifa.
*
* Returns 0 on success.
*/
@@ -935,10 +935,9 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
info->rti_flags = rt->rt_flags;
info->rti_ifp = rt->rt_ifp;
info->rti_ifa = rt->rt_ifa;
- ifa_ref(info->rti_ifa);
if (flags & NHR_REF) {
- /* Do 'traditional' refcouting */
if_ref(info->rti_ifp);
+ ifa_ref(info->rti_ifa);
}
return (0);
@@ -948,8 +947,8 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
* Lookups up route entry for @dst in RIB database for fib @fibnum.
* Exports entry data to @info using rt_exportinfo().
*
- * if @flags contains NHR_REF, refcouting is performed on rt_ifp.
- * All references can be released later by calling rib_free_info()
+ * If @flags contains NHR_REF, refcouting is performed on rt_ifp and rt_ifa.
+ * All references can be released later by calling rib_free_info().
*
* Returns 0 on success.
* Returns ENOENT for lookup failure, ENOMEM for export failure.
@@ -995,6 +994,7 @@ void
rib_free_info(struct rt_addrinfo *info)
{
+ ifa_free(info->rti_ifa);
if_rele(info->rti_ifp);
}
@@ -1627,9 +1627,12 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
error = rt_getifa_fib(info, fibnum);
if (error)
return (error);
+ } else {
+ ifa_ref(info->rti_ifa);
}
rt = uma_zalloc(V_rtzone, M_NOWAIT);
if (rt == NULL) {
+ ifa_free(info->rti_ifa);
return (ENOBUFS);
}
rt->rt_flags = RTF_UP | flags;
@@ -1638,6 +1641,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
* Add the gateway. Possibly re-malloc-ing the storage for it.
*/
if ((error = rt_setgate(rt, dst, gateway)) != 0) {
+ ifa_free(info->rti_ifa);
uma_zfree(V_rtzone, rt);
return (error);
}
@@ -1661,7 +1665,6 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
* examine the ifa and ifa->ifa_ifp if it so desires.
*/
ifa = info->rti_ifa;
- ifa_ref(ifa);
rt->rt_ifa = ifa;
rt->rt_ifp = ifa->ifa_ifp;
rt->rt_weight = 1;
@@ -2101,7 +2104,6 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
* Do the actual request
*/
bzero((caddr_t)&info, sizeof(info));
- ifa_ref(ifa);
info.rti_ifa = ifa;
info.rti_flags = flags |
(ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED;
@@ -2116,7 +2118,6 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
info.rti_info[RTAX_NETMASK] = netmask;
error = rtrequest1_fib(cmd, &info, &rt, fibnum);
-
if (error == 0 && rt != NULL) {
/*
* notify any listening routing agents of the change
diff --git a/freebsd/sys/net/sff8472.h b/freebsd/sys/net/sff8472.h
index d38fcfc0..9fa465a1 100644
--- a/freebsd/sys/net/sff8472.h
+++ b/freebsd/sys/net/sff8472.h
@@ -379,7 +379,7 @@ enum {
/*
* Table 3.2 Identifier values.
- * Identifier constants has taken from SFF-8024 rev 4.2 table 4.1
+ * Identifier constants has taken from SFF-8024 rev 4.6 table 4.1
* (as referenced by table 3.2 footer)
* */
enum {
@@ -396,10 +396,10 @@ enum {
SFF_8024_ID_X2 = 0xA, /* X2 */
SFF_8024_ID_DWDM_SFP = 0xB, /* DWDM-SFP */
SFF_8024_ID_QSFP = 0xC, /* QSFP */
- SFF_8024_ID_QSFPPLUS = 0xD, /* QSFP+ */
+ SFF_8024_ID_QSFPPLUS = 0xD, /* QSFP+ or later */
SFF_8024_ID_CXP = 0xE, /* CXP */
- SFF_8024_ID_HD4X = 0xF, /* Shielded Mini Multilane HD 4X */
- SFF_8024_ID_HD8X = 0x10, /* Shielded Mini Multilane HD 8X */
+ SFF_8024_ID_HD4X = 0xF, /* Shielded Mini Multilane HD 4X */
+ SFF_8024_ID_HD8X = 0x10, /* Shielded Mini Multilane HD 8X */
SFF_8024_ID_QSFP28 = 0x11, /* QSFP28 or later */
SFF_8024_ID_CXP2 = 0x12, /* CXP2 (aka CXP28) */
SFF_8024_ID_CDFP = 0x13, /* CDFP (Style 1/Style 2) */
@@ -408,34 +408,49 @@ enum {
SFF_8024_ID_CDFP3 = 0x16, /* CDFP (Style3) */
SFF_8024_ID_MICROQSFP = 0x17, /* microQSFP */
SFF_8024_ID_QSFP_DD = 0x18, /* QSFP-DD 8X Pluggable Transceiver */
- SFF_8024_ID_LAST = SFF_8024_ID_QSFP_DD
- };
-
-static const char *sff_8024_id[SFF_8024_ID_LAST + 1] = {"Unknown",
- "GBIC",
- "SFF",
- "SFP/SFP+/SFP28",
- "XBI",
- "Xenpak",
- "XFP",
- "XFF",
- "XFP-E",
- "XPAK",
- "X2",
- "DWDM-SFP/SFP+",
- "QSFP",
- "QSFP+",
- "CXP",
- "HD4X",
- "HD8X",
- "QSFP28",
- "CXP2",
- "CDFP",
- "SMM4",
- "SMM8",
- "CDFP3",
- "microQSFP",
- "QSFP-DD"};
+ SFF_8024_ID_OSFP8X = 0x19, /* OSFP 8X Pluggable Transceiver */
+ SFF_8024_ID_SFP_DD = 0x1A, /* SFP-DD 2X Pluggable Transceiver */
+ SFF_8024_ID_DSFP = 0x1B, /* DSFP Dual SFF Pluggable Transceiver */
+ SFF_8024_ID_X4ML = 0x1C, /* x4 MiniLink/OcuLink */
+ SFF_8024_ID_X8ML = 0x1D, /* x8 MiniLink */
+ SFF_8024_ID_QSFP_CMIS = 0x1E, /* QSFP+ or later w/ Common Management
+ Interface Specification */
+ SFF_8024_ID_LAST = SFF_8024_ID_QSFP_CMIS
+};
+
+static const char *sff_8024_id[SFF_8024_ID_LAST + 1] = {
+ "Unknown",
+ "GBIC",
+ "SFF",
+ "SFP/SFP+/SFP28",
+ "XBI",
+ "Xenpak",
+ "XFP",
+ "XFF",
+ "XFP-E",
+ "XPAK",
+ "X2",
+ "DWDM-SFP/SFP+",
+ "QSFP",
+ "QSFP+",
+ "CXP",
+ "HD4X",
+ "HD8X",
+ "QSFP28",
+ "CXP2",
+ "CDFP",
+ "SMM4",
+ "SMM8",
+ "CDFP3",
+ "microQSFP",
+ "QSFP-DD",
+ "QSFP8X",
+ "SFP-DD",
+ "DSFP",
+ "x4MiniLink/OcuLink",
+ "x8MiniLink",
+ "QSFP+(CIMS)"
+};
/* Keep compatibility with old definitions */
#define SFF_8472_ID_UNKNOWN SFF_8024_ID_UNKNOWN
diff --git a/freebsd/sys/net/vnet.h b/freebsd/sys/net/vnet.h
index b4168750..2d69a8a9 100644
--- a/freebsd/sys/net/vnet.h
+++ b/freebsd/sys/net/vnet.h
@@ -325,6 +325,8 @@ struct vnet_sysinit {
};
#define VNET_SYSINIT(ident, subsystem, order, func, arg) \
+ CTASSERT((subsystem) > SI_SUB_VNET && \
+ (subsystem) <= SI_SUB_VNET_DONE); \
static struct vnet_sysinit ident ## _vnet_init = { \
subsystem, \
order, \
@@ -337,6 +339,8 @@ struct vnet_sysinit {
vnet_deregister_sysinit, &ident ## _vnet_init)
#define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \
+ CTASSERT((subsystem) > SI_SUB_VNET && \
+ (subsystem) <= SI_SUB_VNET_DONE); \
static struct vnet_sysinit ident ## _vnet_uninit = { \
subsystem, \
order, \
diff --git a/freebsd/sys/net80211/ieee80211.c b/freebsd/sys/net80211/ieee80211.c
index 927905bb..f003c769 100644
--- a/freebsd/sys/net80211/ieee80211.c
+++ b/freebsd/sys/net80211/ieee80211.c
@@ -1388,6 +1388,8 @@ getflags(const uint8_t bands[], uint32_t flags[], int ht40, int vht80)
/*
* Add one 20 MHz channel into specified channel list.
+ * You MUST NOT mix bands when calling this. It will not add 5ghz
+ * channels if you have any B/G/N band bit set.
*/
/* XXX VHT */
int
diff --git a/freebsd/sys/netinet/in_mcast.c b/freebsd/sys/netinet/in_mcast.c
index ff442399..cbb6c6d3 100644
--- a/freebsd/sys/netinet/in_mcast.c
+++ b/freebsd/sys/netinet/in_mcast.c
@@ -2207,7 +2207,11 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
__func__);
goto out_inp_locked;
}
- inm_acquire(imf->imf_inm);
+ /*
+ * NOTE: Refcount from in_joingroup_locked()
+ * is protecting membership.
+ */
+ ip_mfilter_insert(&imo->imo_head, imf);
} else {
CTR1(KTR_IGMPV3, "%s: merge inm state", __func__);
IN_MULTI_LIST_LOCK();
@@ -2231,8 +2235,6 @@ inp_join_group(struct inpcb *inp, struct sockopt *sopt)
goto out_inp_locked;
}
}
- if (is_new)
- ip_mfilter_insert(&imo->imo_head, imf);
imf_commit(imf);
imf = NULL;
@@ -2401,6 +2403,12 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
if (is_final) {
ip_mfilter_remove(&imo->imo_head, imf);
imf_leave(imf);
+
+ /*
+ * Give up the multicast address record to which
+ * the membership points.
+ */
+ (void) in_leavegroup_locked(imf->imf_inm, imf);
} else {
if (imf->imf_st[0] == MCAST_EXCLUDE) {
error = EADDRNOTAVAIL;
@@ -2455,14 +2463,8 @@ inp_leave_group(struct inpcb *inp, struct sockopt *sopt)
out_inp_locked:
INP_WUNLOCK(inp);
- if (is_final && imf) {
- /*
- * Give up the multicast address record to which
- * the membership points.
- */
- (void) in_leavegroup_locked(imf->imf_inm, imf);
+ if (is_final && imf)
ip_mfilter_free(imf);
- }
IN_MULTI_UNLOCK();
return (error);
diff --git a/freebsd/sys/netinet/ip_carp.c b/freebsd/sys/netinet/ip_carp.c
index 02a24bb8..30b09198 100644
--- a/freebsd/sys/netinet/ip_carp.c
+++ b/freebsd/sys/netinet/ip_carp.c
@@ -568,13 +568,16 @@ carp6_input(struct mbuf **mp, int *offp, int proto)
}
/* verify that we have a complete carp packet */
- len = m->m_len;
- IP6_EXTHDR_GET(ch, struct carp_header *, m, *offp, sizeof(*ch));
- if (ch == NULL) {
- CARPSTATS_INC(carps_badlen);
- CARP_DEBUG("%s: packet size %u too small\n", __func__, len);
- return (IPPROTO_DONE);
+ if (m->m_len < *offp + sizeof(*ch)) {
+ len = m->m_len;
+ m = m_pullup(m, *offp + sizeof(*ch));
+ if (m == NULL) {
+ CARPSTATS_INC(carps_badlen);
+ CARP_DEBUG("%s: packet size %u too small\n", __func__, len);
+ return (IPPROTO_DONE);
+ }
}
+ ch = (struct carp_header *)(mtod(m, char *) + *offp);
/* verify the CARP checksum */
@@ -1189,7 +1192,7 @@ carp_iamatch6(struct ifnet *ifp, struct in6_addr *taddr)
return (ifa);
}
-caddr_t
+char *
carp_macmatch6(struct ifnet *ifp, struct mbuf *m, const struct in6_addr *taddr)
{
struct ifaddr *ifa;
@@ -1231,14 +1234,15 @@ carp_forus(struct ifnet *ifp, u_char *dhost)
CIF_LOCK(ifp->if_carp);
IFNET_FOREACH_CARP(ifp, sc) {
- CARP_LOCK(sc);
+ /*
+ * CARP_LOCK() is not here, since would protect nothing, but
+ * cause deadlock with if_bridge, calling this under its lock.
+ */
if (sc->sc_state == MASTER && !bcmp(dhost, LLADDR(&sc->sc_addr),
ETHER_ADDR_LEN)) {
- CARP_UNLOCK(sc);
CIF_UNLOCK(ifp->if_carp);
return (1);
}
- CARP_UNLOCK(sc);
}
CIF_UNLOCK(ifp->if_carp);
@@ -1848,7 +1852,7 @@ carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td)
carp_carprcp(&carpr, sc, priveleged);
carpr.carpr_count = count;
error = copyout(&carpr,
- (caddr_t)ifr_data_get_ptr(ifr) +
+ (char *)ifr_data_get_ptr(ifr) +
(i * sizeof(carpr)), sizeof(carpr));
if (error) {
CIF_UNLOCK(ifp->if_carp);
diff --git a/freebsd/sys/netinet/ip_carp.h b/freebsd/sys/netinet/ip_carp.h
index fc591ac3..f8ee38dd 100644
--- a/freebsd/sys/netinet/ip_carp.h
+++ b/freebsd/sys/netinet/ip_carp.h
@@ -149,7 +149,7 @@ int carp_output (struct ifnet *, struct mbuf *,
int carp_master(struct ifaddr *);
int carp_iamatch(struct ifaddr *, uint8_t **);
struct ifaddr *carp_iamatch6(struct ifnet *, struct in6_addr *);
-caddr_t carp_macmatch6(struct ifnet *, struct mbuf *, const struct in6_addr *);
+char * carp_macmatch6(struct ifnet *, struct mbuf *, const struct in6_addr *);
int carp_forus(struct ifnet *, u_char *);
/* These are external networking stack hooks for CARP */
@@ -174,7 +174,7 @@ extern int (*carp_iamatch_p)(struct ifaddr *, uint8_t **);
#ifdef INET6
/* netinet6/nd6_nbr.c */
extern struct ifaddr *(*carp_iamatch6_p)(struct ifnet *, struct in6_addr *);
-extern caddr_t (*carp_macmatch6_p)(struct ifnet *, struct mbuf *,
+extern char * (*carp_macmatch6_p)(struct ifnet *, struct mbuf *,
const struct in6_addr *);
#endif
#endif
diff --git a/freebsd/sys/netinet/ip_mroute.c b/freebsd/sys/netinet/ip_mroute.c
index 3dd887f3..3b27781e 100644
--- a/freebsd/sys/netinet/ip_mroute.c
+++ b/freebsd/sys/netinet/ip_mroute.c
@@ -181,10 +181,14 @@ static struct mtx mfc_mtx;
VNET_DEFINE_STATIC(vifi_t, numvifs);
#define V_numvifs VNET(numvifs)
-VNET_DEFINE_STATIC(struct vif, viftable[MAXVIFS]);
+VNET_DEFINE_STATIC(struct vif *, viftable);
#define V_viftable VNET(viftable)
+/*
+ * No one should be able to "query" this before initialisation happened in
+ * vnet_mroute_init(), so we should still be fine.
+ */
SYSCTL_OPAQUE(_net_inet_ip, OID_AUTO, viftable, CTLFLAG_VNET | CTLFLAG_RD,
- &VNET_NAME(viftable), sizeof(V_viftable), "S,vif[MAXVIFS]",
+ &VNET_NAME(viftable), sizeof(*V_viftable) * MAXVIFS, "S,vif[MAXVIFS]",
"IPv4 Multicast Interfaces (struct vif[MAXVIFS], netinet/ip_mroute.h)");
static struct mtx vif_mtx;
@@ -212,7 +216,7 @@ static MALLOC_DEFINE(M_BWMETER, "bwmeter", "multicast upcall bw meters");
* expiration time. Periodically, the entries are analysed and processed.
*/
#define BW_METER_BUCKETS 1024
-VNET_DEFINE_STATIC(struct bw_meter*, bw_meter_timers[BW_METER_BUCKETS]);
+VNET_DEFINE_STATIC(struct bw_meter **, bw_meter_timers);
#define V_bw_meter_timers VNET(bw_meter_timers)
VNET_DEFINE_STATIC(struct callout, bw_meter_ch);
#define V_bw_meter_ch VNET(bw_meter_ch)
@@ -222,7 +226,7 @@ VNET_DEFINE_STATIC(struct callout, bw_meter_ch);
* Pending upcalls are stored in a vector which is flushed when
* full, or periodically
*/
-VNET_DEFINE_STATIC(struct bw_upcall, bw_upcalls[BW_UPCALLS_MAX]);
+VNET_DEFINE_STATIC(struct bw_upcall *, bw_upcalls);
#define V_bw_upcalls VNET(bw_upcalls)
VNET_DEFINE_STATIC(u_int, bw_upcalls_n); /* # of pending upcalls */
#define V_bw_upcalls_n VNET(bw_upcalls_n)
@@ -766,7 +770,7 @@ X_ip_mrouter_done(void)
bzero(V_nexpire, sizeof(V_nexpire[0]) * mfchashsize);
V_bw_upcalls_n = 0;
- bzero(V_bw_meter_timers, sizeof(V_bw_meter_timers));
+ bzero(V_bw_meter_timers, BW_METER_BUCKETS * sizeof(*V_bw_meter_timers));
MFC_UNLOCK();
@@ -2807,7 +2811,14 @@ vnet_mroute_init(const void *unused __unused)
{
V_nexpire = malloc(mfchashsize, M_MRTABLE, M_WAITOK|M_ZERO);
- bzero(V_bw_meter_timers, sizeof(V_bw_meter_timers));
+
+ V_viftable = mallocarray(MAXVIFS, sizeof(*V_viftable),
+ M_MRTABLE, M_WAITOK|M_ZERO);
+ V_bw_meter_timers = mallocarray(BW_METER_BUCKETS,
+ sizeof(*V_bw_meter_timers), M_MRTABLE, M_WAITOK|M_ZERO);
+ V_bw_upcalls = mallocarray(BW_UPCALLS_MAX, sizeof(*V_bw_upcalls),
+ M_MRTABLE, M_WAITOK|M_ZERO);
+
callout_init(&V_expire_upcalls_ch, 1);
callout_init(&V_bw_upcalls_ch, 1);
callout_init(&V_bw_meter_ch, 1);
@@ -2820,6 +2831,9 @@ static void
vnet_mroute_uninit(const void *unused __unused)
{
+ free(V_bw_upcalls, M_MRTABLE);
+ free(V_bw_meter_timers, M_MRTABLE);
+ free(V_viftable, M_MRTABLE);
free(V_nexpire, M_MRTABLE);
V_nexpire = NULL;
}
diff --git a/freebsd/sys/netinet/ip_output.c b/freebsd/sys/netinet/ip_output.c
index c9eb7aa3..343874e5 100644
--- a/freebsd/sys/netinet/ip_output.c
+++ b/freebsd/sys/netinet/ip_output.c
@@ -655,6 +655,7 @@ sendit:
in_pcboutput_txrtlmt(inp, ifp, m);
/* stamp send tag on mbuf */
m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+ m->m_pkthdr.csum_flags |= CSUM_SND_TAG;
} else {
m->m_pkthdr.snd_tag = NULL;
}
@@ -707,6 +708,7 @@ sendit:
in_pcboutput_txrtlmt(inp, ifp, m);
/* stamp send tag on mbuf */
m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+ m->m_pkthdr.csum_flags |= CSUM_SND_TAG;
} else {
m->m_pkthdr.snd_tag = NULL;
}
diff --git a/freebsd/sys/netinet/ip_reass.c b/freebsd/sys/netinet/ip_reass.c
index 70a6edae..036d19fe 100644
--- a/freebsd/sys/netinet/ip_reass.c
+++ b/freebsd/sys/netinet/ip_reass.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/eventhandler.h>
+#include <sys/kernel.h>
#include <sys/hash.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
@@ -48,7 +49,10 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_var.h>
#include <net/rss_config.h>
#include <net/netisr.h>
#include <net/vnet.h>
@@ -182,6 +186,7 @@ ip_reass(struct mbuf *m)
struct ip *ip;
struct mbuf *p, *q, *nq, *t;
struct ipq *fp;
+ struct ifnet *srcifp;
struct ipqhead *head;
int i, hlen, next, tmpmax;
u_int8_t ecn, ecn0;
@@ -242,6 +247,11 @@ ip_reass(struct mbuf *m)
}
/*
+ * Store receive network interface pointer for later.
+ */
+ srcifp = m->m_pkthdr.rcvif;
+
+ /*
* Attempt reassembly; if it succeeds, proceed.
* ip_reass() will return a different mbuf.
*/
@@ -491,8 +501,11 @@ ip_reass(struct mbuf *m)
m->m_len += (ip->ip_hl << 2);
m->m_data -= (ip->ip_hl << 2);
/* some debugging cruft by sklower, below, will go away soon */
- if (m->m_flags & M_PKTHDR) /* XXX this should be done elsewhere */
+ if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
m_fixhdr(m);
+ /* set valid receive interface pointer */
+ m->m_pkthdr.rcvif = srcifp;
+ }
IPSTAT_INC(ips_reassembled);
IPQ_UNLOCK(hash);
@@ -608,6 +621,46 @@ ipreass_drain(void)
}
}
+/*
+ * Drain off all datagram fragments belonging to
+ * the given network interface.
+ */
+static void
+ipreass_cleanup(void *arg __unused, struct ifnet *ifp)
+{
+ struct ipq *fp, *temp;
+ struct mbuf *m;
+ int i;
+
+ KASSERT(ifp != NULL, ("%s: ifp is NULL", __func__));
+
+ CURVNET_SET_QUIET(ifp->if_vnet);
+
+ /*
+ * Skip processing if IPv4 reassembly is not initialised or
+ * torn down by ipreass_destroy().
+ */
+ if (V_ipq_zone == NULL) {
+ CURVNET_RESTORE();
+ return;
+ }
+
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ IPQ_LOCK(i);
+ /* Scan fragment list. */
+ TAILQ_FOREACH_SAFE(fp, &V_ipq[i].head, ipq_list, temp) {
+ for (m = fp->ipq_frags; m != NULL; m = m->m_nextpkt) {
+ /* clear no longer valid rcvif pointer */
+ if (m->m_pkthdr.rcvif == ifp)
+ m->m_pkthdr.rcvif = NULL;
+ }
+ }
+ IPQ_UNLOCK(i);
+ }
+ CURVNET_RESTORE();
+}
+EVENTHANDLER_DEFINE(ifnet_departure_event, ipreass_cleanup, NULL, 0);
+
#ifdef VIMAGE
/*
* Destroy IP reassembly structures.
@@ -618,6 +671,7 @@ ipreass_destroy(void)
ipreass_drain();
uma_zdestroy(V_ipq_zone);
+ V_ipq_zone = NULL;
for (int i = 0; i < IPREASS_NHASH; i++)
mtx_destroy(&V_ipq[i].lock);
}
diff --git a/freebsd/sys/netinet/sctp_asconf.c b/freebsd/sys/netinet/sctp_asconf.c
index 4de01ed7..a13f4040 100644
--- a/freebsd/sys/netinet/sctp_asconf.c
+++ b/freebsd/sys/netinet/sctp_asconf.c
@@ -107,42 +107,47 @@ sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t *error_tlv,
struct mbuf *m_reply = NULL;
struct sctp_asconf_paramhdr *aph;
struct sctp_error_cause *error;
+ size_t buf_len;
+ uint16_t i, param_length, cause_length, padding_length;
uint8_t *tlv;
- m_reply = sctp_get_mbuf_for_msg((sizeof(struct sctp_asconf_paramhdr) +
- tlv_length +
- sizeof(struct sctp_error_cause)),
- 0, M_NOWAIT, 1, MT_DATA);
+ if (error_tlv == NULL) {
+ tlv_length = 0;
+ }
+ cause_length = sizeof(struct sctp_error_cause) + tlv_length;
+ param_length = sizeof(struct sctp_asconf_paramhdr) + cause_length;
+ padding_length = tlv_length % 4;
+ if (padding_length != 0) {
+ padding_length = 4 - padding_length;
+ }
+ buf_len = param_length + padding_length;
+ if (buf_len > MLEN) {
+ SCTPDBG(SCTP_DEBUG_ASCONF1,
+ "asconf_error_response: tlv_length (%xh) too big\n",
+ tlv_length);
+ return (NULL);
+ }
+ m_reply = sctp_get_mbuf_for_msg(buf_len, 0, M_NOWAIT, 1, MT_DATA);
if (m_reply == NULL) {
SCTPDBG(SCTP_DEBUG_ASCONF1,
"asconf_error_response: couldn't get mbuf!\n");
return (NULL);
}
aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
- error = (struct sctp_error_cause *)(aph + 1);
-
- aph->correlation_id = id;
aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
+ aph->ph.param_length = htons(param_length);
+ aph->correlation_id = id;
+ error = (struct sctp_error_cause *)(aph + 1);
error->code = htons(cause);
- error->length = tlv_length + sizeof(struct sctp_error_cause);
- aph->ph.param_length = error->length +
- sizeof(struct sctp_asconf_paramhdr);
-
- if (aph->ph.param_length > MLEN) {
- SCTPDBG(SCTP_DEBUG_ASCONF1,
- "asconf_error_response: tlv_length (%xh) too big\n",
- tlv_length);
- sctp_m_freem(m_reply); /* discard */
- return (NULL);
- }
+ error->length = htons(cause_length);
if (error_tlv != NULL) {
tlv = (uint8_t *)(error + 1);
memcpy(tlv, error_tlv, tlv_length);
+ for (i = 0; i < padding_length; i++) {
+ tlv[tlv_length + i] = 0;
+ }
}
- SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
- error->length = htons(error->length);
- aph->ph.param_length = htons(aph->ph.param_length);
-
+ SCTP_BUF_LEN(m_reply) = buf_len;
return (m_reply);
}
@@ -171,10 +176,16 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
#endif
aparam_length = ntohs(aph->ph.param_length);
+ if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
+ return (NULL);
+ }
ph = (struct sctp_paramhdr *)(aph + 1);
param_type = ntohs(ph->param_type);
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
+ if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
+ return (NULL);
+ }
#endif
sa = &store.sa;
switch (param_type) {
@@ -238,6 +249,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
"process_asconf_add_ip: using source addr ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
}
+ net = NULL;
/* add the address */
if (bad_address) {
m_reply = sctp_asconf_error_response(aph->correlation_id,
@@ -252,17 +264,19 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
SCTP_CAUSE_RESOURCE_SHORTAGE, (uint8_t *)aph,
aparam_length);
} else {
- /* notify upper layer */
- sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
if (response_required) {
m_reply =
sctp_asconf_success_response(aph->correlation_id);
}
- sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
- sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
- stcb, net);
- if (send_hb) {
- sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
+ if (net != NULL) {
+ /* notify upper layer */
+ sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
+ sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
+ sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
+ stcb, net);
+ if (send_hb) {
+ sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
+ }
}
}
return (m_reply);
@@ -271,7 +285,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
static int
sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
{
- struct sctp_nets *src_net, *net;
+ struct sctp_nets *src_net, *net, *nnet;
/* make sure the source address exists as a destination net */
src_net = sctp_findnet(stcb, src);
@@ -281,10 +295,9 @@ sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
}
/* delete all destination addresses except the source */
- TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
+ TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) {
if (net != src_net) {
/* delete this address */
- sctp_remove_net(stcb, net);
SCTPDBG(SCTP_DEBUG_ASCONF1,
"asconf_del_remote_addrs_except: deleting ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
@@ -292,6 +305,7 @@ sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
/* notify upper layer */
sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
(struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
+ sctp_remove_net(stcb, net);
}
}
return (0);
@@ -322,10 +336,16 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
#endif
aparam_length = ntohs(aph->ph.param_length);
+ if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
+ return (NULL);
+ }
ph = (struct sctp_paramhdr *)(aph + 1);
param_type = ntohs(ph->param_type);
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
+ if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
+ return (NULL);
+ }
#endif
sa = &store.sa;
switch (param_type) {
@@ -453,10 +473,16 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
#endif
aparam_length = ntohs(aph->ph.param_length);
+ if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
+ return (NULL);
+ }
ph = (struct sctp_paramhdr *)(aph + 1);
param_type = ntohs(ph->param_type);
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
+ if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
+ return (NULL);
+ }
#endif
sa = &store.sa;
switch (param_type) {
@@ -675,8 +701,8 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
sctp_m_freem(m_ack);
return;
}
- /* param_length is already validated in process_control... */
- offset += ntohs(p_addr->ph.param_length); /* skip lookup addr */
+ /* skip lookup addr */
+ offset += SCTP_SIZE32(ntohs(p_addr->ph.param_length));
/* get pointer to first asconf param in ASCONF */
aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *)&aparam_buf);
if (aph == NULL) {
@@ -705,6 +731,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
if (param_length <= sizeof(struct sctp_paramhdr)) {
SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) too short\n", param_length);
sctp_m_freem(m_ack);
+ return;
}
/* get the entire parameter */
aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
@@ -760,8 +787,6 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
if (m_result != NULL) {
SCTP_BUF_NEXT(m_tail) = m_result;
m_tail = m_result;
- /* update lengths, make sure it's aligned too */
- SCTP_BUF_LEN(m_result) = SCTP_SIZE32(SCTP_BUF_LEN(m_result));
ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
/* set flag to force success reports */
error = 1;
@@ -1956,12 +1981,10 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
case AF_INET:
{
struct sockaddr_in *sin;
- struct in6pcb *inp6;
- inp6 = (struct in6pcb *)&inp->ip_inp.inp;
/* invalid if we are a v6 only endpoint */
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp6))
+ SCTP_IPV6_V6ONLY(&inp->ip_inp.inp))
return;
sin = &ifa->address.sin;
@@ -2034,11 +2057,9 @@ sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNU
case AF_INET:
{
/* invalid if we are a v6 only endpoint */
- struct in6pcb *inp6;
- inp6 = (struct in6pcb *)&inp->ip_inp.inp;
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp6)) {
+ SCTP_IPV6_V6ONLY(&inp->ip_inp.inp)) {
cnt_invalid++;
if (asc->cnt == cnt_invalid)
return (1);
@@ -2149,13 +2170,11 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
case AF_INET:
{
/* invalid if we are a v6 only endpoint */
- struct in6pcb *inp6;
struct sockaddr_in *sin;
- inp6 = (struct in6pcb *)&inp->ip_inp.inp;
/* invalid if we are a v6 only endpoint */
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp6))
+ SCTP_IPV6_V6ONLY(&inp->ip_inp.inp))
continue;
sin = &ifa->address.sin;
@@ -2172,7 +2191,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
continue;
}
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp6)) {
+ SCTP_IPV6_V6ONLY(&inp->ip_inp.inp)) {
cnt_invalid++;
if (asc->cnt == cnt_invalid)
return;
diff --git a/freebsd/sys/netinet/sctp_dtrace_define.h b/freebsd/sys/netinet/sctp_dtrace_define.h
deleted file mode 100644
index ad7c8526..00000000
--- a/freebsd/sys/netinet/sctp_dtrace_define.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
- * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * a) Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * b) 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.
- *
- * c) Neither the name of Cisco Systems, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#ifndef _NETINET_SCTP_DTRACE_DEFINE_H_
-#define _NETINET_SCTP_DTRACE_DEFINE_H_
-
-#include <sys/kernel.h>
-#include <sys/sdt.h>
-
-SDT_PROVIDER_DECLARE(sctp);
-
-/********************************************************/
-/* Cwnd probe - tracks changes in the congestion window on a netp */
-/********************************************************/
-/* Initial */
-SDT_PROBE_DEFINE5(sctp, cwnd, net, init,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "uintptr_t", /* The pointer to the struct sctp_nets *
- * changing */
- "int", /* The old value of the cwnd */
- "int"); /* The new value of the cwnd */
-
-/* ACK-INCREASE */
-SDT_PROBE_DEFINE5(sctp, cwnd, net, ack,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "uintptr_t", /* The pointer to the struct sctp_nets *
- * changing */
- "int", /* The old value of the cwnd */
- "int"); /* The new value of the cwnd */
-
-/* ACK-INCREASE */
-SDT_PROBE_DEFINE5(sctp, cwnd, net, rttvar,
- "uint64_t", /* The Vtag << 32 | localport << 16 |
- * remoteport */
- "uint64_t", /* obw | nbw */
- "uint64_t", /* bwrtt | newrtt */
- "uint64_t", /* flight */
- "uint64_t"); /* (cwnd << 32) | point << 16 | retval(0/1) */
-
-SDT_PROBE_DEFINE5(sctp, cwnd, net, rttstep,
- "uint64_t", /* The Vtag << 32 | localport << 16 |
- * remoteport */
- "uint64_t", /* obw | nbw */
- "uint64_t", /* bwrtt | newrtt */
- "uint64_t", /* flight */
- "uint64_t"); /* (cwnd << 32) | point << 16 | retval(0/1) */
-
-/* FastRetransmit-DECREASE */
-SDT_PROBE_DEFINE5(sctp, cwnd, net, fr,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "uintptr_t", /* The pointer to the struct sctp_nets *
- * changing */
- "int", /* The old value of the cwnd */
- "int"); /* The new value of the cwnd */
-
-/* TimeOut-DECREASE */
-SDT_PROBE_DEFINE5(sctp, cwnd, net, to,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "uintptr_t", /* The pointer to the struct sctp_nets *
- * changing */
- "int", /* The old value of the cwnd */
- "int"); /* The new value of the cwnd */
-
-/* BurstLimit-DECREASE */
-SDT_PROBE_DEFINE5(sctp, cwnd, net, bl,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "uintptr_t", /* The pointer to the struct sctp_nets *
- * changing */
- "int", /* The old value of the cwnd */
- "int"); /* The new value of the cwnd */
-
-/* ECN-DECREASE */
-SDT_PROBE_DEFINE5(sctp, cwnd, net, ecn,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "uintptr_t", /* The pointer to the struct sctp_nets *
- * changing */
- "int", /* The old value of the cwnd */
- "int"); /* The new value of the cwnd */
-
-/* PacketDrop-DECREASE */
-SDT_PROBE_DEFINE5(sctp, cwnd, net, pd,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "uintptr_t", /* The pointer to the struct sctp_nets *
- * changing */
- "int", /* The old value of the cwnd */
- "int"); /* The new value of the cwnd */
-
-/********************************************************/
-/* Rwnd probe - tracks changes in the receiver window for an assoc */
-/********************************************************/
-SDT_PROBE_DEFINE4(sctp, rwnd, assoc, val,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "int", /* The up/down amount */
- "int"); /* The new value of the cwnd */
-
-/********************************************************/
-/* flight probe - tracks changes in the flight size on a net or assoc */
-/********************************************************/
-SDT_PROBE_DEFINE5(sctp, flightsize, net, val,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "uintptr_t", /* The pointer to the struct sctp_nets *
- * changing */
- "int", /* The up/down amount */
- "int"); /* The new value of the cwnd */
-
-/********************************************************/
-/* The total flight version */
-/********************************************************/
-SDT_PROBE_DEFINE4(sctp, flightsize, assoc, val,
- "uint32_t", /* The Vtag for this end */
- "uint32_t", /* The port number of the local side << 16 |
- * port number of remote in network byte
- * order. */
- "int", /* The up/down amount */
- "int"); /* The new value of the cwnd */
-
-#endif
diff --git a/freebsd/sys/netinet/sctp_indata.c b/freebsd/sys/netinet/sctp_indata.c
index c4a11fec..1b28cc38 100644
--- a/freebsd/sys/netinet/sctp_indata.c
+++ b/freebsd/sys/netinet/sctp_indata.c
@@ -474,6 +474,11 @@ sctp_clean_up_control(struct sctp_tcb *stcb, struct sctp_queued_to_read *control
chk->data = NULL;
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
}
+ sctp_free_remote_addr(control->whoFrom);
+ if (control->data) {
+ sctp_m_freem(control->data);
+ control->data = NULL;
+ }
sctp_free_a_readq(stcb, control);
}
@@ -713,6 +718,7 @@ sctp_add_to_tail_pointer(struct sctp_queued_to_read *control, struct mbuf *m, ui
}
if (control->tail_mbuf == NULL) {
/* TSNH */
+ sctp_m_freem(control->data);
control->data = m;
sctp_setup_tail_pointer(control);
return;
@@ -2116,10 +2122,13 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct mbuf *mm;
control->data = dmbuf;
+ control->tail_mbuf = NULL;
for (mm = control->data; mm; mm = mm->m_next) {
control->length += SCTP_BUF_LEN(mm);
+ if (SCTP_BUF_NEXT(mm) == NULL) {
+ control->tail_mbuf = mm;
+ }
}
- control->tail_mbuf = NULL;
control->end_added = 1;
control->last_frag_seen = 1;
control->first_frag_seen = 1;
@@ -3110,13 +3119,12 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
* update RTO too ?
*/
if (tp1->do_rtt) {
- if (*rto_ok) {
- tp1->whoTo->RTO =
- sctp_calculate_rto(stcb,
- &stcb->asoc,
- tp1->whoTo,
- &tp1->sent_rcv_time,
- SCTP_RTT_FROM_DATA);
+ if (*rto_ok &&
+ sctp_calculate_rto(stcb,
+ &stcb->asoc,
+ tp1->whoTo,
+ &tp1->sent_rcv_time,
+ SCTP_RTT_FROM_DATA)) {
*rto_ok = 0;
}
if (tp1->whoTo->rto_needed == 0) {
@@ -4088,16 +4096,12 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
/* update RTO too? */
if (tp1->do_rtt) {
- if (rto_ok) {
- tp1->whoTo->RTO =
- /*
- * sa_ignore
- * NO_NULL_CHK
- */
- sctp_calculate_rto(stcb,
- asoc, tp1->whoTo,
- &tp1->sent_rcv_time,
- SCTP_RTT_FROM_DATA);
+ if (rto_ok &&
+ sctp_calculate_rto(stcb,
+ &stcb->asoc,
+ tp1->whoTo,
+ &tp1->sent_rcv_time,
+ SCTP_RTT_FROM_DATA)) {
rto_ok = 0;
}
if (tp1->whoTo->rto_needed == 0) {
@@ -4706,12 +4710,12 @@ hopeless_peer:
/* update RTO too? */
if (tp1->do_rtt) {
- if (rto_ok) {
- tp1->whoTo->RTO =
- sctp_calculate_rto(stcb,
- asoc, tp1->whoTo,
- &tp1->sent_rcv_time,
- SCTP_RTT_FROM_DATA);
+ if (rto_ok &&
+ sctp_calculate_rto(stcb,
+ &stcb->asoc,
+ tp1->whoTo,
+ &tp1->sent_rcv_time,
+ SCTP_RTT_FROM_DATA)) {
rto_ok = 0;
}
if (tp1->whoTo->rto_needed == 0) {
diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c
index 3f4e2f5f..4191d24c 100644
--- a/freebsd/sys/netinet/sctp_input.c
+++ b/freebsd/sys/netinet/sctp_input.c
@@ -467,6 +467,10 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
if (!cookie_found) {
uint16_t len;
+ /* Only report the missing cookie parameter */
+ if (op_err != NULL) {
+ sctp_m_freem(op_err);
+ }
len = (uint16_t)(sizeof(struct sctp_error_missing_param) + sizeof(uint16_t));
/* We abort with an error of missing mandatory param */
op_err = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
@@ -550,7 +554,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
asoc->primary_destination, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
/* calculate the RTO */
- net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered,
+ sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered,
SCTP_RTT_FROM_NON_DATA);
retval = sctp_send_cookie_echo(m, offset, initack_limit, stcb, net);
return (retval);
@@ -650,7 +654,7 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
tv.tv_sec = cp->heartbeat.hb_info.time_value_1;
tv.tv_usec = cp->heartbeat.hb_info.time_value_2;
/* Now lets do a RTO with this */
- r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv,
+ sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv,
SCTP_RTT_FROM_NON_DATA);
if (!(r_net->dest_state & SCTP_ADDR_REACHABLE)) {
r_net->dest_state |= SCTP_ADDR_REACHABLE;
@@ -705,34 +709,37 @@ static int
sctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
{
/*
- * return 0 means we want you to proceed with the abort non-zero
- * means no abort processing
+ * Return 0 means we want you to proceed with the abort non-zero
+ * means no abort processing.
*/
+ uint32_t new_vtag;
struct sctpasochead *head;
if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
(SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
+ new_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_INFO_WLOCK();
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
+ } else {
+ return (0);
}
if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) {
/* generate a new vtag and send init */
LIST_REMOVE(stcb, sctp_asocs);
- stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
+ stcb->asoc.my_vtag = new_vtag;
head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
/*
* put it in the bucket in the vtag hash of assoc's for the
* system
*/
LIST_INSERT_HEAD(head, stcb, sctp_asocs);
- sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
SCTP_INP_INFO_WUNLOCK();
+ sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
return (1);
- }
- if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED) {
+ } else {
/*
* treat like a case where the cookie expired i.e.: - dump
* current cookie. - generate a new vtag. - resend init.
@@ -742,15 +749,15 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
sctp_stop_all_cookie_timers(stcb);
sctp_toss_old_cookies(stcb, &stcb->asoc);
- stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
+ stcb->asoc.my_vtag = new_vtag;
head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
/*
* put it in the bucket in the vtag hash of assoc's for the
* system
*/
LIST_INSERT_HEAD(head, stcb, sctp_asocs);
- sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
SCTP_INP_INFO_WUNLOCK();
+ sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
return (1);
}
return (0);
@@ -1676,8 +1683,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
old.tv_sec = cookie->time_entered.tv_sec;
old.tv_usec = cookie->time_entered.tv_usec;
net->hb_responded = 1;
- net->RTO = sctp_calculate_rto(stcb, asoc, net,
- &old,
+ sctp_calculate_rto(stcb, asoc, net, &old,
SCTP_RTT_FROM_NON_DATA);
if (stcb->asoc.sctp_autoclose_ticks &&
@@ -2401,8 +2407,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
/* calculate the RTT and set the encaps port */
old.tv_sec = cookie->time_entered.tv_sec;
old.tv_usec = cookie->time_entered.tv_usec;
- (*netp)->RTO = sctp_calculate_rto(stcb, asoc, *netp,
- &old, SCTP_RTT_FROM_NON_DATA);
+ sctp_calculate_rto(stcb, asoc, *netp, &old, SCTP_RTT_FROM_NON_DATA);
}
/* respond with a COOKIE-ACK */
sctp_send_cookie_ack(stcb);
@@ -2978,8 +2983,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
SCTP_STAT_INCR_GAUGE32(sctps_currestab);
if (asoc->overall_error_count == 0) {
- net->RTO = sctp_calculate_rto(stcb, asoc, net,
- &asoc->time_entered,
+ sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered,
SCTP_RTT_FROM_NON_DATA);
}
(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
diff --git a/freebsd/sys/netinet/sctp_os_bsd.h b/freebsd/sys/netinet/sctp_os_bsd.h
index abe8e2c9..3db2d5e2 100644
--- a/freebsd/sys/netinet/sctp_os_bsd.h
+++ b/freebsd/sys/netinet/sctp_os_bsd.h
@@ -97,9 +97,6 @@ __FBSDID("$FreeBSD$");
#include <crypto/sha1.h>
#include <crypto/sha2/sha256.h>
-#ifndef in6pcb
-#define in6pcb inpcb
-#endif
/* Declare all the malloc names for all the various mallocs */
MALLOC_DECLARE(SCTP_M_MAP);
MALLOC_DECLARE(SCTP_M_STRMI);
@@ -368,7 +365,7 @@ typedef struct callout sctp_os_timer_t;
*/
/* get the v6 hop limit */
-#define SCTP_GET_HLIM(inp, ro) in6_selecthlim((struct in6pcb *)&inp->ip_inp.inp, (ro ? (ro->ro_rt ? (ro->ro_rt->rt_ifp) : (NULL)) : (NULL)));
+#define SCTP_GET_HLIM(inp, ro) in6_selecthlim((struct inpcb *)&inp->ip_inp.inp, (ro ? (ro->ro_rt ? (ro->ro_rt->rt_ifp) : (NULL)) : (NULL)));
/* is the endpoint v6only? */
#define SCTP_IPV6_V6ONLY(inp) (((struct inpcb *)inp)->inp_flags & IN6P_IPV6_V6ONLY)
@@ -431,7 +428,7 @@ typedef struct rtentry sctp_rtentry_t;
m_clrprotoflags(o_pak); \
if (local_stcb && local_stcb->sctp_ep) \
result = ip6_output(o_pak, \
- ((struct in6pcb *)(local_stcb->sctp_ep))->in6p_outputopts, \
+ ((struct inpcb *)(local_stcb->sctp_ep))->in6p_outputopts, \
(ro), 0, 0, ifp, NULL); \
else \
result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL); \
diff --git a/freebsd/sys/netinet/sctp_output.c b/freebsd/sys/netinet/sctp_output.c
index 9221080d..522825da 100644
--- a/freebsd/sys/netinet/sctp_output.c
+++ b/freebsd/sys/netinet/sctp_output.c
@@ -4338,7 +4338,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
* at the SCTP layer. So use the value from
* the IP layer.
*/
- flowlabel = ntohl(((struct in6pcb *)inp)->in6p_flowinfo);
+ flowlabel = ntohl(((struct inpcb *)inp)->inp_flow);
}
flowlabel &= 0x000fffff;
len = SCTP_MIN_OVERHEAD;
@@ -4393,7 +4393,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
* at the SCTP layer. So use the value from
* the IP layer.
*/
- tos_value = (ntohl(((struct in6pcb *)inp)->in6p_flowinfo) >> 20) & 0xff;
+ tos_value = (ntohl(((struct inpcb *)inp)->inp_flow) >> 20) & 0xff;
}
tos_value &= 0xfc;
if (ecn_ok) {
@@ -7874,8 +7874,8 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
int bundle_at, ctl_cnt, no_data_chunks, eeor_mode;
unsigned int mtu, r_mtu, omtu, mx_mtu, to_out;
int tsns_sent = 0;
- uint32_t auth_offset = 0;
- struct sctp_auth_chunk *auth = NULL;
+ uint32_t auth_offset;
+ struct sctp_auth_chunk *auth;
uint16_t auth_keyid;
int override_ok = 1;
int skip_fill_up = 0;
@@ -8070,6 +8070,8 @@ again_one_more_time:
}
bundle_at = 0;
endoutchain = outchain = NULL;
+ auth = NULL;
+ auth_offset = 0;
no_fragmentflg = 1;
one_chunk = 0;
if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
@@ -9061,8 +9063,7 @@ sctp_send_cookie_echo(struct mbuf *m,
pad = 4 - pad;
}
if (pad > 0) {
- cookie = sctp_pad_lastmbuf(cookie, pad, NULL);
- if (cookie == NULL) {
+ if (sctp_pad_lastmbuf(cookie, pad, NULL) == NULL) {
return (-8);
}
}
diff --git a/freebsd/sys/netinet/sctp_pcb.c b/freebsd/sys/netinet/sctp_pcb.c
index 10e4768e..c72cb5a9 100644
--- a/freebsd/sys/netinet/sctp_pcb.c
+++ b/freebsd/sys/netinet/sctp_pcb.c
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_output.h>
#include <netinet/sctp_timer.h>
#include <netinet/sctp_bsd_addr.h>
-#include <netinet/sctp_dtrace_define.h>
#if defined(INET) || defined(INET6)
#include <netinet/udp.h>
#endif
@@ -3647,12 +3646,8 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
#ifdef INET6
- if (ip_pcb->inp_vflag & INP_IPV6) {
- struct in6pcb *in6p;
-
- in6p = (struct in6pcb *)inp;
- ip6_freepcbopts(in6p->in6p_outputopts);
- }
+ if (ip_pcb->inp_vflag & INP_IPV6)
+ ip6_freepcbopts(((struct inpcb *)inp)->in6p_outputopts);
#endif /* INET6 */
ip_pcb->inp_vflag = 0;
/* free up authentication fields */
diff --git a/freebsd/sys/netinet/sctp_pcb.h b/freebsd/sys/netinet/sctp_pcb.h
index 0f5aca88..cbe51c7d 100644
--- a/freebsd/sys/netinet/sctp_pcb.h
+++ b/freebsd/sys/netinet/sctp_pcb.h
@@ -362,7 +362,7 @@ struct sctp_inpcb {
*/
union {
struct inpcb inp;
- char align[(sizeof(struct in6pcb) + SCTP_ALIGNM1) &
+ char align[(sizeof(struct inpcb) + SCTP_ALIGNM1) &
~SCTP_ALIGNM1];
} ip_inp;
diff --git a/freebsd/sys/netinet/sctp_usrreq.c b/freebsd/sys/netinet/sctp_usrreq.c
index 01759156..0783462a 100644
--- a/freebsd/sys/netinet/sctp_usrreq.c
+++ b/freebsd/sys/netinet/sctp_usrreq.c
@@ -1414,10 +1414,8 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
}
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
(num_v4 > 0)) {
- struct in6pcb *inp6;
- inp6 = (struct in6pcb *)inp;
- if (SCTP_IPV6_V6ONLY(inp6)) {
+ if (SCTP_IPV6_V6ONLY(inp)) {
/*
* if IPV6_V6ONLY flag, ignore connections destined
* to a v4 addr or v4-mapped addr
@@ -6918,14 +6916,14 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
#ifdef INET6
case AF_INET6:
{
- struct sockaddr_in6 *sin6p;
+ struct sockaddr_in6 *sin6;
if (addr->sa_len != sizeof(struct sockaddr_in6)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
return (EINVAL);
}
- sin6p = (struct sockaddr_in6 *)addr;
- if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6p->sin6_addr)) != 0) {
+ sin6 = (struct sockaddr_in6 *)addr;
+ if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6->sin6_addr)) != 0) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
return (error);
}
diff --git a/freebsd/sys/netinet/sctputil.c b/freebsd/sys/netinet/sctputil.c
index c7d4499c..6ae999b0 100644
--- a/freebsd/sys/netinet/sctputil.c
+++ b/freebsd/sys/netinet/sctputil.c
@@ -2471,25 +2471,24 @@ sctp_mtu_size_reset(struct sctp_inpcb *inp,
/*
- * given an association and starting time of the current RTT period return
- * RTO in number of msecs net should point to the current network
+ * Given an association and starting time of the current RTT period, update
+ * RTO in number of msecs. net should point to the current network.
+ * Return 1, if an RTO update was performed, return 0 if no update was
+ * performed due to invalid starting point.
*/
-uint32_t
+int
sctp_calculate_rto(struct sctp_tcb *stcb,
struct sctp_association *asoc,
struct sctp_nets *net,
struct timeval *old,
int rtt_from_sack)
{
- /*-
- * given an association and the starting time of the current RTT
- * period (in value1/value2) return RTO in number of msecs.
- */
+ struct timeval now;
+ uint64_t rtt_us; /* RTT in us */
int32_t rtt; /* RTT in ms */
uint32_t new_rto;
int first_measure = 0;
- struct timeval now;
/************************/
/* 1. calculate new RTT */
@@ -2500,10 +2499,19 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
} else {
(void)SCTP_GETTIME_TIMEVAL(&now);
}
+ if ((old->tv_sec > now.tv_sec) ||
+ ((old->tv_sec == now.tv_sec) && (old->tv_sec > now.tv_sec))) {
+ /* The starting point is in the future. */
+ return (0);
+ }
timevalsub(&now, old);
+ rtt_us = (uint64_t)1000000 * (uint64_t)now.tv_sec + (uint64_t)now.tv_usec;
+ if (rtt_us > SCTP_RTO_UPPER_BOUND * 1000) {
+ /* The RTT is larger than a sane value. */
+ return (0);
+ }
/* store the current RTT in us */
- net->rtt = (uint64_t)1000000 * (uint64_t)now.tv_sec +
- (uint64_t)now.tv_usec;
+ net->rtt = rtt_us;
/* compute rtt in ms */
rtt = (int32_t)(net->rtt / 1000);
if ((asoc->cc_functions.sctp_rtt_calculated) && (rtt_from_sack == SCTP_RTT_FROM_DATA)) {
@@ -2535,7 +2543,7 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
* Paper "Congestion Avoidance and Control", Annex A.
*
* (net->lastsa >> SCTP_RTT_SHIFT) is the srtt
- * (net->lastsa >> SCTP_RTT_VAR_SHIFT) is the rttvar
+ * (net->lastsv >> SCTP_RTT_VAR_SHIFT) is the rttvar
*/
if (net->RTO_measured) {
rtt -= (net->lastsa >> SCTP_RTT_SHIFT);
@@ -2576,8 +2584,8 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
if (new_rto > stcb->asoc.maxrto) {
new_rto = stcb->asoc.maxrto;
}
- /* we are now returning the RTO */
- return (new_rto);
+ net->RTO = new_rto;
+ return (1);
}
/*
diff --git a/freebsd/sys/netinet/sctputil.h b/freebsd/sys/netinet/sctputil.h
index 690e6125..c67c021f 100644
--- a/freebsd/sys/netinet/sctputil.h
+++ b/freebsd/sys/netinet/sctputil.h
@@ -133,7 +133,7 @@ uint32_t sctp_get_next_mtu(uint32_t);
void
sctp_timeout_handler(void *);
-uint32_t
+int
sctp_calculate_rto(struct sctp_tcb *, struct sctp_association *,
struct sctp_nets *, struct timeval *, int);
diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c
index 05891306..fc111d9c 100644
--- a/freebsd/sys/netinet/tcp_input.c
+++ b/freebsd/sys/netinet/tcp_input.c
@@ -131,9 +131,9 @@ __FBSDID("$FreeBSD$");
const int tcprexmtthresh = 3;
-int tcp_log_in_vain = 0;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW,
- &tcp_log_in_vain, 0,
+VNET_DEFINE(int, tcp_log_in_vain) = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(tcp_log_in_vain), 0,
"Log all incoming TCP segments to closed ports");
VNET_DEFINE(int, blackhole) = 0;
@@ -536,11 +536,19 @@ cc_ecnpkt_handler(struct tcpcb *tp, struct tcphdr *th, uint8_t iptos)
int
tcp6_input(struct mbuf **mp, int *offp, int proto)
{
- struct mbuf *m = *mp;
+ struct mbuf *m;
struct in6_ifaddr *ia6;
struct ip6_hdr *ip6;
- IP6_EXTHDR_CHECK(m, *offp, sizeof(struct tcphdr), IPPROTO_DONE);
+ m = *mp;
+ if (m->m_len < *offp + sizeof(struct tcphdr)) {
+ m = m_pullup(m, *offp + sizeof(struct tcphdr));
+ if (m == NULL) {
+ *mp = m;
+ TCPSTAT_INC(tcps_rcvshort);
+ return (IPPROTO_DONE);
+ }
+ }
/*
* draft-itojun-ipv6-tcp-to-anycast
@@ -549,17 +557,17 @@ tcp6_input(struct mbuf **mp, int *offp, int proto)
ip6 = mtod(m, struct ip6_hdr *);
ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */);
if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) {
- struct ip6_hdr *ip6;
ifa_free(&ia6->ia_ifa);
- ip6 = mtod(m, struct ip6_hdr *);
icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR,
(caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
+ *mp = NULL;
return (IPPROTO_DONE);
}
if (ia6)
ifa_free(&ia6->ia_ifa);
+ *mp = m;
return (tcp_input(mp, offp, proto));
}
#endif /* INET6 */
@@ -618,15 +626,6 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
#ifdef INET6
if (isipv6) {
- /* IP6_EXTHDR_CHECK() is already done at tcp6_input(). */
-
- if (m->m_len < (sizeof(*ip6) + sizeof(*th))) {
- m = m_pullup(m, sizeof(*ip6) + sizeof(*th));
- if (m == NULL) {
- TCPSTAT_INC(tcps_rcvshort);
- return (IPPROTO_DONE);
- }
- }
ip6 = mtod(m, struct ip6_hdr *);
th = (struct tcphdr *)((caddr_t)ip6 + off0);
@@ -735,7 +734,13 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
if (off > sizeof (struct tcphdr)) {
#ifdef INET6
if (isipv6) {
- IP6_EXTHDR_CHECK(m, off0, off, IPPROTO_DONE);
+ if (m->m_len < off0 + off) {
+ m = m_pullup(m, off0 + off);
+ if (m == NULL) {
+ TCPSTAT_INC(tcps_rcvshort);
+ return (IPPROTO_DONE);
+ }
+ }
ip6 = mtod(m, struct ip6_hdr *);
th = (struct tcphdr *)((caddr_t)ip6 + off0);
}
@@ -883,8 +888,8 @@ findpcb:
* Log communication attempts to ports that are not
* in use.
*/
- if ((tcp_log_in_vain == 1 && (thflags & TH_SYN)) ||
- tcp_log_in_vain == 2) {
+ if ((V_tcp_log_in_vain == 1 && (thflags & TH_SYN)) ||
+ V_tcp_log_in_vain == 2) {
if ((s = tcp_log_vain(NULL, th, (void *)ip, ip6)))
log(LOG_INFO, "%s; %s: Connection attempt "
"to closed port\n", s, __func__);
diff --git a/freebsd/sys/netinet/tcp_output.c b/freebsd/sys/netinet/tcp_output.c
index 3e024fdb..dc75c68d 100644
--- a/freebsd/sys/netinet/tcp_output.c
+++ b/freebsd/sys/netinet/tcp_output.c
@@ -933,6 +933,20 @@ send:
if (tp->t_flags & TF_NEEDFIN)
sendalot = 1;
} else {
+ if (optlen + ipoptlen >= tp->t_maxseg) {
+ /*
+ * Since we don't have enough space to put
+ * the IP header chain and the TCP header in
+ * one packet as required by RFC 7112, don't
+ * send it. Also ensure that at least one
+ * byte of the payload can be put into the
+ * TCP segment.
+ */
+ SOCKBUF_UNLOCK(&so->so_snd);
+ error = EMSGSIZE;
+ sack_rxmit = 0;
+ goto out;
+ }
len = tp->t_maxseg - optlen - ipoptlen;
sendalot = 1;
if (dont_sendalot)
diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c
index 44ec38c7..eae696c1 100644
--- a/freebsd/sys/netinet/tcp_subr.c
+++ b/freebsd/sys/netinet/tcp_subr.c
@@ -3114,7 +3114,7 @@ tcp_log_vain(struct in_conninfo *inc, struct tcphdr *th, void *ip4hdr,
{
/* Is logging enabled? */
- if (tcp_log_in_vain == 0)
+ if (V_tcp_log_in_vain == 0)
return (NULL);
return (tcp_log_addr(inc, th, ip4hdr, ip6hdr));
diff --git a/freebsd/sys/netinet/tcp_timer.c b/freebsd/sys/netinet/tcp_timer.c
index cf6ceff5..e1b9ec59 100644
--- a/freebsd/sys/netinet/tcp_timer.c
+++ b/freebsd/sys/netinet/tcp_timer.c
@@ -127,9 +127,10 @@ SYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_slop, CTLTYPE_INT|CTLFLAG_RW,
&tcp_rexmit_slop, 0, sysctl_msec_to_ticks, "I",
"Retransmission Timer Slop");
-int tcp_always_keepalive = 1;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_RW,
- &tcp_always_keepalive , 0, "Assume SO_KEEPALIVE on all TCP connections");
+VNET_DEFINE(int, tcp_always_keepalive) = 1;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_VNET|CTLFLAG_RW,
+ &VNET_NAME(tcp_always_keepalive) , 0,
+ "Assume SO_KEEPALIVE on all TCP connections");
int tcp_fast_finwait2_recycle = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, fast_finwait2_recycle, CTLFLAG_RW,
@@ -433,7 +434,7 @@ tcp_timer_keep(void *xtp)
TCPSTAT_INC(tcps_keeptimeo);
if (tp->t_state < TCPS_ESTABLISHED)
goto dropit;
- if ((tcp_always_keepalive ||
+ if ((V_tcp_always_keepalive ||
inp->inp_socket->so_options & SO_KEEPALIVE) &&
tp->t_state <= TCPS_CLOSING) {
if (ticks - tp->t_rcvtime >= TP_KEEPIDLE(tp) + TP_MAXIDLE(tp))
diff --git a/freebsd/sys/netinet/tcp_timer.h b/freebsd/sys/netinet/tcp_timer.h
index 3e985bdf..fe3616c2 100644
--- a/freebsd/sys/netinet/tcp_timer.h
+++ b/freebsd/sys/netinet/tcp_timer.h
@@ -203,10 +203,11 @@ extern int tcp_backoff[];
extern int tcp_totbackoff;
extern int tcp_rexmit_drop_options;
-extern int tcp_always_keepalive;
extern int tcp_finwait2_timeout;
extern int tcp_fast_finwait2_recycle;
+VNET_DECLARE(int, tcp_always_keepalive);
+#define V_tcp_always_keepalive VNET(tcp_always_keepalive)
VNET_DECLARE(int, tcp_pmtud_blackhole_detect);
#define V_tcp_pmtud_blackhole_detect VNET(tcp_pmtud_blackhole_detect)
VNET_DECLARE(int, tcp_pmtud_blackhole_mss);
diff --git a/freebsd/sys/netinet/tcp_usrreq.c b/freebsd/sys/netinet/tcp_usrreq.c
index 809ea35d..eab13eeb 100644
--- a/freebsd/sys/netinet/tcp_usrreq.c
+++ b/freebsd/sys/netinet/tcp_usrreq.c
@@ -346,23 +346,25 @@ tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
int error = 0;
struct inpcb *inp;
struct tcpcb *tp = NULL;
- struct sockaddr_in6 *sin6p;
+ struct sockaddr_in6 *sin6;
+ u_char vflagsav;
- sin6p = (struct sockaddr_in6 *)nam;
- if (nam->sa_len != sizeof (*sin6p))
+ sin6 = (struct sockaddr_in6 *)nam;
+ if (nam->sa_len != sizeof (*sin6))
return (EINVAL);
/*
* Must check for multicast addresses and disallow binding
* to them.
*/
- if (sin6p->sin6_family == AF_INET6 &&
- IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
+ if (sin6->sin6_family == AF_INET6 &&
+ IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
return (EAFNOSUPPORT);
TCPDEBUG0;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL"));
INP_WLOCK(inp);
+ vflagsav = inp->inp_vflag;
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
error = EINVAL;
goto out;
@@ -374,12 +376,12 @@ tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
inp->inp_vflag |= INP_IPV6;
#ifdef INET
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6p->sin6_addr))
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
inp->inp_vflag |= INP_IPV4;
- else if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
+ else if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
struct sockaddr_in sin;
- in6_sin6_2_sin(&sin, sin6p);
+ in6_sin6_2_sin(&sin, sin6);
if (IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
error = EAFNOSUPPORT;
INP_HASH_WUNLOCK(&V_tcbinfo);
@@ -397,6 +399,8 @@ tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
error = in6_pcbbind(inp, nam, td->td_ucred);
INP_HASH_WUNLOCK(&V_tcbinfo);
out:
+ if (error != 0)
+ inp->inp_vflag = vflagsav;
TCPDEBUG2(PRU_BIND);
TCP_PROBE2(debug__user, tp, PRU_BIND);
INP_WUNLOCK(inp);
@@ -459,6 +463,7 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
int error = 0;
struct inpcb *inp;
struct tcpcb *tp = NULL;
+ u_char vflagsav;
TCPDEBUG0;
inp = sotoinpcb(so);
@@ -468,6 +473,7 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
error = EINVAL;
goto out;
}
+ vflagsav = inp->inp_vflag;
tp = intotcpcb(inp);
TCPDEBUG1();
SOCK_LOCK(so);
@@ -493,6 +499,9 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
if (IS_FASTOPEN(tp->t_flags))
tp->t_tfo_pending = tcp_fastopen_alloc_counter();
+ if (error != 0)
+ inp->inp_vflag = vflagsav;
+
out:
TCPDEBUG2(PRU_LISTEN);
TCP_PROBE2(debug__user, tp, PRU_LISTEN);
@@ -568,23 +577,27 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
int error = 0;
struct inpcb *inp;
struct tcpcb *tp = NULL;
- struct sockaddr_in6 *sin6p;
+ struct sockaddr_in6 *sin6;
+ u_int8_t incflagsav;
+ u_char vflagsav;
TCPDEBUG0;
- sin6p = (struct sockaddr_in6 *)nam;
- if (nam->sa_len != sizeof (*sin6p))
+ sin6 = (struct sockaddr_in6 *)nam;
+ if (nam->sa_len != sizeof (*sin6))
return (EINVAL);
/*
* Must disallow TCP ``connections'' to multicast addresses.
*/
- if (sin6p->sin6_family == AF_INET6
- && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
+ if (sin6->sin6_family == AF_INET6
+ && IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
return (EAFNOSUPPORT);
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL"));
INP_WLOCK(inp);
+ vflagsav = inp->inp_vflag;
+ incflagsav = inp->inp_inc.inc_flags;
if (inp->inp_flags & INP_TIMEWAIT) {
error = EADDRINUSE;
goto out;
@@ -601,7 +614,7 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
* therefore probably require the hash lock, which isn't held here.
* Is this a significant problem?
*/
- if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
+ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
struct sockaddr_in sin;
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) {
@@ -613,16 +626,16 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
goto out;
}
- in6_sin6_2_sin(&sin, sin6p);
+ in6_sin6_2_sin(&sin, sin6);
if (IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
error = EAFNOSUPPORT;
goto out;
}
- inp->inp_vflag |= INP_IPV4;
- inp->inp_vflag &= ~INP_IPV6;
if ((error = prison_remote_ip4(td->td_ucred,
&sin.sin_addr)) != 0)
goto out;
+ inp->inp_vflag |= INP_IPV4;
+ inp->inp_vflag &= ~INP_IPV6;
if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0)
goto out;
#ifdef TCP_OFFLOAD
@@ -640,11 +653,11 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
}
}
#endif
+ if ((error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr)) != 0)
+ goto out;
inp->inp_vflag &= ~INP_IPV4;
inp->inp_vflag |= INP_IPV6;
inp->inp_inc.inc_flags |= INC_ISIPV6;
- if ((error = prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr)) != 0)
- goto out;
if ((error = tcp6_connect(tp, nam, td)) != 0)
goto out;
#ifdef TCP_OFFLOAD
@@ -657,6 +670,15 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
error = tp->t_fb->tfb_tcp_output(tp);
out:
+ /*
+ * If the implicit bind in the connect call fails, restore
+ * the flags we modified.
+ */
+ if (error != 0 && inp->inp_lport == 0) {
+ inp->inp_vflag = vflagsav;
+ inp->inp_inc.inc_flags = incflagsav;
+ }
+
TCPDEBUG2(PRU_CONNECT);
TCP_PROBE2(debug__user, tp, PRU_CONNECT);
INP_WUNLOCK(inp);
@@ -912,6 +934,9 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
#ifdef INET6
int isipv6;
#endif
+ u_int8_t incflagsav;
+ u_char vflagsav;
+ bool restoreflags;
TCPDEBUG0;
/*
@@ -923,6 +948,9 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL"));
INP_WLOCK(inp);
+ vflagsav = inp->inp_vflag;
+ incflagsav = inp->inp_inc.inc_flags;
+ restoreflags = false;
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
if (control)
m_freem(control);
@@ -974,22 +1002,22 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
#ifdef INET6
case AF_INET6:
{
- struct sockaddr_in6 *sin6p;
+ struct sockaddr_in6 *sin6;
- sin6p = (struct sockaddr_in6 *)nam;
- if (sin6p->sin6_len != sizeof(struct sockaddr_in6)) {
+ sin6 = (struct sockaddr_in6 *)nam;
+ if (sin6->sin6_len != sizeof(*sin6)) {
if (m)
m_freem(m);
error = EINVAL;
goto out;
}
- if (IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
+ if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
if (m)
m_freem(m);
error = EAFNOSUPPORT;
goto out;
}
- if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
+ if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
#ifdef INET
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) {
error = EINVAL;
@@ -1003,9 +1031,10 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
m_freem(m);
goto out;
}
+ restoreflags = true;
inp->inp_vflag &= ~INP_IPV6;
sinp = &sin;
- in6_sin6_2_sin(sinp, sin6p);
+ in6_sin6_2_sin(sinp, sin6);
if (IN_MULTICAST(
ntohl(sinp->sin_addr.s_addr))) {
error = EAFNOSUPPORT;
@@ -1033,10 +1062,11 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
error = EAFNOSUPPORT;
goto out;
}
+ restoreflags = true;
inp->inp_vflag &= ~INP_IPV4;
inp->inp_inc.inc_flags |= INC_ISIPV6;
if ((error = prison_remote_ip6(td->td_ucred,
- &sin6p->sin6_addr))) {
+ &sin6->sin6_addr))) {
if (m)
m_freem(m);
goto out;
@@ -1083,6 +1113,14 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
error = tcp_connect(tp,
(struct sockaddr *)sinp, td);
#endif
+ /*
+ * The bind operation in tcp_connect succeeded. We
+ * no longer want to restore the flags if later
+ * operations fail.
+ */
+ if (error == 0 || inp->inp_lport != 0)
+ restoreflags = false;
+
if (error)
goto out;
if (IS_FASTOPEN(tp->t_flags))
@@ -1153,6 +1191,14 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
error = tcp_connect(tp,
(struct sockaddr *)sinp, td);
#endif
+ /*
+ * The bind operation in tcp_connect succeeded. We
+ * no longer want to restore the flags if later
+ * operations fail.
+ */
+ if (error == 0 || inp->inp_lport != 0)
+ restoreflags = false;
+
if (error)
goto out;
tp->snd_wnd = TTCP_CLIENT_SND_WND;
@@ -1171,6 +1217,14 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
TCP_LOG_USERSEND, error,
0, NULL, false);
out:
+ /*
+ * If the request was unsuccessful and we changed flags,
+ * restore the original flags.
+ */
+ if (error != 0 && restoreflags) {
+ inp->inp_vflag = vflagsav;
+ inp->inp_inc.inc_flags = incflagsav;
+ }
TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB :
((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
TCP_PROBE2(debug__user, tp, (flags & PRUS_OOB) ? PRU_SENDOOB :
diff --git a/freebsd/sys/netinet/tcp_var.h b/freebsd/sys/netinet/tcp_var.h
index cca8623e..13d20294 100644
--- a/freebsd/sys/netinet/tcp_var.h
+++ b/freebsd/sys/netinet/tcp_var.h
@@ -745,7 +745,8 @@ SYSCTL_DECL(_net_inet_tcp_sack);
MALLOC_DECLARE(M_TCPLOG);
#endif
-extern int tcp_log_in_vain;
+VNET_DECLARE(int, tcp_log_in_vain);
+#define V_tcp_log_in_vain VNET(tcp_log_in_vain)
/*
* Global TCP tunables shared between different stacks.
diff --git a/freebsd/sys/netinet/udp_usrreq.c b/freebsd/sys/netinet/udp_usrreq.c
index f89660d6..8462d0ee 100644
--- a/freebsd/sys/netinet/udp_usrreq.c
+++ b/freebsd/sys/netinet/udp_usrreq.c
@@ -122,9 +122,9 @@ VNET_DEFINE(int, udp_cksum) = 1;
SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(udp_cksum), 0, "compute udp checksum");
-int udp_log_in_vain = 0;
-SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW,
- &udp_log_in_vain, 0, "Log all incoming UDP packets");
+VNET_DEFINE(int, udp_log_in_vain) = 0;
+SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(udp_log_in_vain), 0, "Log all incoming UDP packets");
VNET_DEFINE(int, udp_blackhole) = 0;
SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_VNET | CTLFLAG_RW,
@@ -427,14 +427,13 @@ udp_input(struct mbuf **mp, int *offp, int proto)
/*
* Get IP and UDP header together in first mbuf.
*/
- ip = mtod(m, struct ip *);
if (m->m_len < iphlen + sizeof(struct udphdr)) {
if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == NULL) {
UDPSTAT_INC(udps_hdrops);
return (IPPROTO_DONE);
}
- ip = mtod(m, struct ip *);
}
+ ip = mtod(m, struct ip *);
uh = (struct udphdr *)((caddr_t)ip + iphlen);
cscov_partial = (proto == IPPROTO_UDPLITE) ? 1 : 0;
@@ -695,7 +694,7 @@ udp_input(struct mbuf **mp, int *offp, int proto)
ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD |
INPLOOKUP_RLOCKPCB, ifp, m);
if (inp == NULL) {
- if (udp_log_in_vain) {
+ if (V_udp_log_in_vain) {
char src[INET_ADDRSTRLEN];
char dst[INET_ADDRSTRLEN];
diff --git a/freebsd/sys/netinet/udp_var.h b/freebsd/sys/netinet/udp_var.h
index 01545582..ecca2a54 100644
--- a/freebsd/sys/netinet/udp_var.h
+++ b/freebsd/sys/netinet/udp_var.h
@@ -153,9 +153,10 @@ extern u_long udp_sendspace;
extern u_long udp_recvspace;
VNET_DECLARE(int, udp_cksum);
VNET_DECLARE(int, udp_blackhole);
+VNET_DECLARE(int, udp_log_in_vain);
#define V_udp_cksum VNET(udp_cksum)
#define V_udp_blackhole VNET(udp_blackhole)
-extern int udp_log_in_vain;
+#define V_udp_log_in_vain VNET(udp_log_in_vain)
static __inline struct inpcbinfo *
udp_get_inpcbinfo(int protocol)
diff --git a/freebsd/sys/netinet6/dest6.c b/freebsd/sys/netinet6/dest6.c
index 50a836ba..354457e2 100644
--- a/freebsd/sys/netinet6/dest6.c
+++ b/freebsd/sys/netinet6/dest6.c
@@ -66,30 +66,35 @@ __FBSDID("$FreeBSD$");
int
dest6_input(struct mbuf **mp, int *offp, int proto)
{
- struct mbuf *m = *mp;
- int off = *offp, dstoptlen, optlen;
+ struct mbuf *m;
+ int off, dstoptlen, optlen;
struct ip6_dest *dstopts;
u_int8_t *opt;
- /* validation of the length of the header */
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, sizeof(*dstopts), IPPROTO_DONE);
+ m = *mp;
+ off = *offp;
+
+ /* Validation of the length of the header. */
+ if (m->m_len < off + sizeof(*dstopts)) {
+ m = m_pullup(m, off + sizeof(*dstopts));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (IPPROTO_DONE);
+ }
+ }
dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
-#else
- IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, sizeof(*dstopts));
- if (dstopts == NULL)
- return IPPROTO_DONE;
-#endif
dstoptlen = (dstopts->ip6d_len + 1) << 3;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, dstoptlen, IPPROTO_DONE);
+ if (m->m_len < off + dstoptlen) {
+ m = m_pullup(m, off + dstoptlen);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (IPPROTO_DONE);
+ }
+ }
dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
-#else
- IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, dstoptlen);
- if (dstopts == NULL)
- return IPPROTO_DONE;
-#endif
off += dstoptlen;
dstoptlen -= sizeof(struct ip6_dest);
opt = (u_int8_t *)dstopts + sizeof(struct ip6_dest);
@@ -112,17 +117,21 @@ dest6_input(struct mbuf **mp, int *offp, int proto)
default: /* unknown option */
optlen = ip6_unknown_opt(opt, m,
opt - mtod(m, u_int8_t *));
- if (optlen == -1)
+ if (optlen == -1) {
+ *mp = NULL;
return (IPPROTO_DONE);
+ }
optlen += 2;
break;
}
}
*offp = off;
+ *mp = m;
return (dstopts->ip6d_nxt);
bad:
m_freem(m);
+ *mp = NULL;
return (IPPROTO_DONE);
}
diff --git a/freebsd/sys/netinet6/frag6.c b/freebsd/sys/netinet6/frag6.c
index 0b0c7b91..443c684a 100644
--- a/freebsd/sys/netinet6/frag6.c
+++ b/freebsd/sys/netinet6/frag6.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
+ * Copyright (c) 2019 Netflix, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,20 +41,18 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/domain.h>
+#include <sys/eventhandler.h>
#include <sys/hash.h>
+#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
-#include <sys/domain.h>
-#include <sys/eventhandler.h>
#include <sys/protosw.h>
+#include <sys/queue.h>
#include <sys/socket.h>
-#include <sys/errno.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
+#include <sys/sysctl.h>
#include <sys/syslog.h>
-#include <machine/atomic.h>
-
#include <net/if.h>
#include <net/if_var.h>
#include <net/netisr.h>
@@ -65,48 +64,85 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet/icmp6.h>
-#include <netinet/in_systm.h> /* for ECN definitions */
-#include <netinet/ip.h> /* for ECN definitions */
+#include <netinet/in_systm.h> /* For ECN definitions. */
+#include <netinet/ip.h> /* For ECN definitions. */
+#ifdef MAC
#include <security/mac/mac_framework.h>
+#endif
/*
- * Reassembly headers are stored in hash buckets.
+ * A "big picture" of how IPv6 fragment queues are all linked together.
+ *
+ * struct ip6qbucket ip6qb[...]; hashed buckets
+ * ||||||||
+ * |
+ * +--- TAILQ(struct ip6q, packets) *q6; tailq entries holding
+ * |||||||| fragmented packets
+ * | (1 per original packet)
+ * |
+ * +--- TAILQ(struct ip6asfrag, ip6q_frags) *af6; tailq entries of IPv6
+ * | *ip6af;fragment packets
+ * | for one original packet
+ * + *mbuf
*/
+
+/* Reassembly headers are stored in hash buckets. */
#define IP6REASS_NHASH_LOG2 10
#define IP6REASS_NHASH (1 << IP6REASS_NHASH_LOG2)
#define IP6REASS_HMASK (IP6REASS_NHASH - 1)
-static void frag6_enq(struct ip6asfrag *, struct ip6asfrag *,
- uint32_t bucket __unused);
-static void frag6_deq(struct ip6asfrag *, uint32_t bucket __unused);
-static void frag6_insque_head(struct ip6q *, struct ip6q *,
- uint32_t bucket);
-static void frag6_remque(struct ip6q *, uint32_t bucket);
-static void frag6_freef(struct ip6q *, uint32_t bucket);
-
+TAILQ_HEAD(ip6qhead, ip6q);
struct ip6qbucket {
- struct ip6q ip6q;
+ struct ip6qhead packets;
struct mtx lock;
int count;
};
-VNET_DEFINE_STATIC(volatile u_int, frag6_nfragpackets);
-volatile u_int frag6_nfrags = 0;
-VNET_DEFINE_STATIC(struct ip6qbucket, ip6q[IP6REASS_NHASH]);
-VNET_DEFINE_STATIC(uint32_t, ip6q_hashseed);
+struct ip6asfrag {
+ TAILQ_ENTRY(ip6asfrag) ip6af_tq;
+ struct mbuf *ip6af_m;
+ int ip6af_offset; /* Offset in ip6af_m to next header. */
+ int ip6af_frglen; /* Fragmentable part length. */
+ int ip6af_off; /* Fragment offset. */
+ bool ip6af_mff; /* More fragment bit in frag off. */
+};
+
+static MALLOC_DEFINE(M_FRAG6, "frag6", "IPv6 fragment reassembly header");
+
+#ifdef VIMAGE
+/* A flag to indicate if IPv6 fragmentation is initialized. */
+VNET_DEFINE_STATIC(bool, frag6_on);
+#define V_frag6_on VNET(frag6_on)
+#endif
+
+/* System wide (global) maximum and count of packets in reassembly queues. */
+static int ip6_maxfrags;
+static volatile u_int frag6_nfrags = 0;
+/* Maximum and current packets in per-VNET reassembly queue. */
+VNET_DEFINE_STATIC(int, ip6_maxfragpackets);
+VNET_DEFINE_STATIC(volatile u_int, frag6_nfragpackets);
+#define V_ip6_maxfragpackets VNET(ip6_maxfragpackets)
#define V_frag6_nfragpackets VNET(frag6_nfragpackets)
-#define V_ip6q VNET(ip6q)
-#define V_ip6q_hashseed VNET(ip6q_hashseed)
-#define IP6Q_LOCK(i) mtx_lock(&V_ip6q[(i)].lock)
-#define IP6Q_TRYLOCK(i) mtx_trylock(&V_ip6q[(i)].lock)
-#define IP6Q_LOCK_ASSERT(i) mtx_assert(&V_ip6q[(i)].lock, MA_OWNED)
-#define IP6Q_UNLOCK(i) mtx_unlock(&V_ip6q[(i)].lock)
-#define IP6Q_HEAD(i) (&V_ip6q[(i)].ip6q)
+/* Maximum per-VNET reassembly queues per bucket and fragments per packet. */
+VNET_DEFINE_STATIC(int, ip6_maxfragbucketsize);
+VNET_DEFINE_STATIC(int, ip6_maxfragsperpacket);
+#define V_ip6_maxfragbucketsize VNET(ip6_maxfragbucketsize)
+#define V_ip6_maxfragsperpacket VNET(ip6_maxfragsperpacket)
+
+/* Per-VNET reassembly queue buckets. */
+VNET_DEFINE_STATIC(struct ip6qbucket, ip6qb[IP6REASS_NHASH]);
+VNET_DEFINE_STATIC(uint32_t, ip6qb_hashseed);
+#define V_ip6qb VNET(ip6qb)
+#define V_ip6qb_hashseed VNET(ip6qb_hashseed)
-static MALLOC_DEFINE(M_FTABLE, "fragment", "fragment reassembly header");
+#define IP6QB_LOCK(_b) mtx_lock(&V_ip6qb[(_b)].lock)
+#define IP6QB_TRYLOCK(_b) mtx_trylock(&V_ip6qb[(_b)].lock)
+#define IP6QB_LOCK_ASSERT(_b) mtx_assert(&V_ip6qb[(_b)].lock, MA_OWNED)
+#define IP6QB_UNLOCK(_b) mtx_unlock(&V_ip6qb[(_b)].lock)
+#define IP6QB_HEAD(_b) (&V_ip6qb[(_b)].packets)
/*
* By default, limit the number of IP6 fragments across all reassembly
@@ -124,11 +160,18 @@ static MALLOC_DEFINE(M_FTABLE, "fragment", "fragment reassembly header");
#define IP6_MAXFRAGS (nmbclusters / 32)
#define IP6_MAXFRAGPACKETS (imin(IP6_MAXFRAGS, IP6REASS_NHASH * 50))
+
/*
- * Initialise reassembly queue and fragment identifier.
+ * Sysctls and helper function.
*/
-void
-frag6_set_bucketsize()
+SYSCTL_DECL(_net_inet6_ip6);
+
+SYSCTL_UINT(_net_inet6_ip6, OID_AUTO, frag6_nfrags,
+ CTLFLAG_RD, __DEVOLATILE(u_int *, &frag6_nfrags), 0,
+ "Global number of IPv6 fragments across all reassembly queues.");
+
+static void
+frag6_set_bucketsize(void)
{
int i;
@@ -136,68 +179,180 @@ frag6_set_bucketsize()
V_ip6_maxfragbucketsize = imax(i / (IP6REASS_NHASH / 2), 1);
}
+SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGS, maxfrags,
+ CTLFLAG_RW, &ip6_maxfrags, 0,
+ "Maximum allowed number of outstanding IPv6 packet fragments. "
+ "A value of 0 means no fragmented packets will be accepted, while a "
+ "a value of -1 means no limit");
+
+static int
+sysctl_ip6_maxfragpackets(SYSCTL_HANDLER_ARGS)
+{
+ int error, val;
+
+ val = V_ip6_maxfragpackets;
+ error = sysctl_handle_int(oidp, &val, 0, req);
+ if (error != 0 || !req->newptr)
+ return (error);
+ V_ip6_maxfragpackets = val;
+ frag6_set_bucketsize();
+ return (0);
+}
+SYSCTL_PROC(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS, maxfragpackets,
+ CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
+ sysctl_ip6_maxfragpackets, "I",
+ "Default maximum number of outstanding fragmented IPv6 packets. "
+ "A value of 0 means no fragmented packets will be accepted, while a "
+ "a value of -1 means no limit");
+SYSCTL_UINT(_net_inet6_ip6, OID_AUTO, frag6_nfragpackets,
+ CTLFLAG_VNET | CTLFLAG_RD,
+ __DEVOLATILE(u_int *, &VNET_NAME(frag6_nfragpackets)), 0,
+ "Per-VNET number of IPv6 fragments across all reassembly queues.");
+SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGSPERPACKET, maxfragsperpacket,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_maxfragsperpacket), 0,
+ "Maximum allowed number of fragments per packet");
+SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGBUCKETSIZE, maxfragbucketsize,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_maxfragbucketsize), 0,
+ "Maximum number of reassembly queues per hash bucket");
+
+
+/*
+ * Remove the IPv6 fragmentation header from the mbuf.
+ */
+int
+ip6_deletefraghdr(struct mbuf *m, int offset, int wait __unused)
+{
+ struct ip6_hdr *ip6;
+
+ KASSERT(m->m_len >= offset + sizeof(struct ip6_frag),
+ ("%s: ext headers not contigous in mbuf %p m_len %d >= "
+ "offset %d + %zu\n", __func__, m, m->m_len, offset,
+ sizeof(struct ip6_frag)));
+
+ /* Delete frag6 header. */
+ ip6 = mtod(m, struct ip6_hdr *);
+ bcopy(ip6, (char *)ip6 + sizeof(struct ip6_frag), offset);
+ m->m_data += sizeof(struct ip6_frag);
+ m->m_len -= sizeof(struct ip6_frag);
+ m->m_flags |= M_FRAGMENTED;
+
+ return (0);
+}
+
+/*
+ * Free a fragment reassembly header and all associated datagrams.
+ */
static void
-frag6_change(void *tag)
+frag6_freef(struct ip6q *q6, uint32_t bucket)
{
- VNET_ITERATOR_DECL(vnet_iter);
+ struct ip6_hdr *ip6;
+ struct ip6asfrag *af6;
+ struct mbuf *m;
- ip6_maxfrags = IP6_MAXFRAGS;
- VNET_LIST_RLOCK_NOSLEEP();
- VNET_FOREACH(vnet_iter) {
- CURVNET_SET(vnet_iter);
- V_ip6_maxfragpackets = IP6_MAXFRAGPACKETS;
- frag6_set_bucketsize();
- CURVNET_RESTORE();
+ IP6QB_LOCK_ASSERT(bucket);
+
+ while ((af6 = TAILQ_FIRST(&q6->ip6q_frags)) != NULL) {
+
+ m = af6->ip6af_m;
+ TAILQ_REMOVE(&q6->ip6q_frags, af6, ip6af_tq);
+
+ /*
+ * Return ICMP time exceeded error for the 1st fragment.
+ * Just free other fragments.
+ */
+ if (af6->ip6af_off == 0 && m->m_pkthdr.rcvif != NULL) {
+
+ /* Adjust pointer. */
+ ip6 = mtod(m, struct ip6_hdr *);
+
+ /* Restore source and destination addresses. */
+ ip6->ip6_src = q6->ip6q_src;
+ ip6->ip6_dst = q6->ip6q_dst;
+
+ icmp6_error(m, ICMP6_TIME_EXCEEDED,
+ ICMP6_TIME_EXCEED_REASSEMBLY, 0);
+ } else
+ m_freem(m);
+
+ free(af6, M_FRAG6);
}
- VNET_LIST_RUNLOCK_NOSLEEP();
+
+ TAILQ_REMOVE(IP6QB_HEAD(bucket), q6, ip6q_tq);
+ V_ip6qb[bucket].count--;
+ atomic_subtract_int(&frag6_nfrags, q6->ip6q_nfrag);
+#ifdef MAC
+ mac_ip6q_destroy(q6);
+#endif
+ free(q6, M_FRAG6);
+ atomic_subtract_int(&V_frag6_nfragpackets, 1);
}
-void
-frag6_init(void)
+/*
+ * Drain off all datagram fragments belonging to
+ * the given network interface.
+ */
+static void
+frag6_cleanup(void *arg __unused, struct ifnet *ifp)
{
+ struct ip6qhead *head;
struct ip6q *q6;
- int i;
+ struct ip6asfrag *af6;
+ uint32_t bucket;
- V_ip6_maxfragpackets = IP6_MAXFRAGPACKETS;
- frag6_set_bucketsize();
- for (i = 0; i < IP6REASS_NHASH; i++) {
- q6 = IP6Q_HEAD(i);
- q6->ip6q_next = q6->ip6q_prev = q6;
- mtx_init(&V_ip6q[i].lock, "ip6qlock", NULL, MTX_DEF);
- V_ip6q[i].count = 0;
- }
- V_ip6q_hashseed = arc4random();
- V_ip6_maxfragsperpacket = 64;
- if (!IS_DEFAULT_VNET(curvnet))
+ KASSERT(ifp != NULL, ("%s: ifp is NULL", __func__));
+
+ CURVNET_SET_QUIET(ifp->if_vnet);
+#ifdef VIMAGE
+ /*
+ * Skip processing if IPv6 reassembly is not initialised or
+ * torn down by frag6_destroy().
+ */
+ if (!V_frag6_on) {
+ CURVNET_RESTORE();
return;
+ }
+#endif
- ip6_maxfrags = IP6_MAXFRAGS;
- EVENTHANDLER_REGISTER(nmbclusters_change,
- frag6_change, NULL, EVENTHANDLER_PRI_ANY);
+ for (bucket = 0; bucket < IP6REASS_NHASH; bucket++) {
+ IP6QB_LOCK(bucket);
+ head = IP6QB_HEAD(bucket);
+ /* Scan fragment list. */
+ TAILQ_FOREACH(q6, head, ip6q_tq) {
+ TAILQ_FOREACH(af6, &q6->ip6q_frags, ip6af_tq) {
+
+ /* Clear no longer valid rcvif pointer. */
+ if (af6->ip6af_m->m_pkthdr.rcvif == ifp)
+ af6->ip6af_m->m_pkthdr.rcvif = NULL;
+ }
+ }
+ IP6QB_UNLOCK(bucket);
+ }
+ CURVNET_RESTORE();
}
+EVENTHANDLER_DEFINE(ifnet_departure_event, frag6_cleanup, NULL, 0);
/*
- * In RFC2460, fragment and reassembly rule do not agree with each other,
- * in terms of next header field handling in fragment header.
+ * Like in RFC2460, in RFC8200, fragment and reassembly rules do not agree with
+ * each other, in terms of next header field handling in fragment header.
* While the sender will use the same value for all of the fragmented packets,
- * receiver is suggested not to check the consistency.
+ * receiver is suggested not to check for consistency.
*
- * fragment rule (p20):
- * (2) A Fragment header containing:
- * The Next Header value that identifies the first header of
- * the Fragmentable Part of the original packet.
+ * Fragment rules (p18,p19):
+ * (2) A Fragment header containing:
+ * The Next Header value that identifies the first header
+ * after the Per-Fragment headers of the original packet.
* -> next header field is same for all fragments
*
- * reassembly rule (p21):
- * The Next Header field of the last header of the Unfragmentable
- * Part is obtained from the Next Header field of the first
+ * Reassembly rule (p20):
+ * The Next Header field of the last header of the Per-Fragment
+ * headers is obtained from the Next Header field of the first
* fragment's Fragment header.
* -> should grab it from the first fragment only
*
* The following note also contradicts with fragment rule - no one is going to
* send different fragment with different next header field.
*
- * additional note (p22):
+ * Additional note (p22) [not an error]:
* The Next Header values in the Fragment headers of different
* fragments of the same original packet may differ. Only the value
* from the Offset zero fragment packet is used for reassembly.
@@ -206,91 +361,111 @@ frag6_init(void)
* There is no explicit reason given in the RFC. Historical reason maybe?
*/
/*
- * Fragment input
+ * Fragment input.
*/
int
frag6_input(struct mbuf **mp, int *offp, int proto)
{
- struct mbuf *m = *mp, *t;
+ struct mbuf *m, *t;
struct ip6_hdr *ip6;
struct ip6_frag *ip6f;
- struct ip6q *head, *q6;
- struct ip6asfrag *af6, *ip6af, *af6dwn;
- struct in6_ifaddr *ia;
- int offset = *offp, nxt, i, next;
- int first_frag = 0;
- int fragoff, frgpartlen; /* must be larger than u_int16_t */
+ struct ip6qhead *head;
+ struct ip6q *q6;
+ struct ip6asfrag *af6, *ip6af, *af6tmp;
+ struct in6_ifaddr *ia6;
+ struct ifnet *dstifp, *srcifp;
uint32_t hashkey[(sizeof(struct in6_addr) * 2 +
sizeof(ip6f->ip6f_ident)) / sizeof(uint32_t)];
- uint32_t hash, *hashkeyp;
- struct ifnet *dstifp;
- u_int8_t ecn, ecn0;
+ uint32_t bucket, *hashkeyp;
+ int fragoff, frgpartlen; /* Must be larger than uint16_t. */
+ int nxt, offset, plen;
+ uint8_t ecn, ecn0;
+ bool only_frag;
#ifdef RSS
- struct m_tag *mtag;
struct ip6_direct_ctx *ip6dc;
+ struct m_tag *mtag;
#endif
-#if 0
- char ip6buf[INET6_ADDRSTRLEN];
-#endif
+ m = *mp;
+ offset = *offp;
+
+ M_ASSERTPKTHDR(m);
+ if (m->m_len < offset + sizeof(struct ip6_frag)) {
+ m = m_pullup(m, offset + sizeof(struct ip6_frag));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (IPPROTO_DONE);
+ }
+ }
ip6 = mtod(m, struct ip6_hdr *);
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE);
- ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset);
-#else
- IP6_EXTHDR_GET(ip6f, struct ip6_frag *, m, offset, sizeof(*ip6f));
- if (ip6f == NULL)
- return (IPPROTO_DONE);
-#endif
dstifp = NULL;
- /* find the destination interface of the packet. */
- ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */);
- if (ia != NULL) {
- dstifp = ia->ia_ifp;
- ifa_free(&ia->ia_ifa);
+ /* Find the destination interface of the packet. */
+ ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */);
+ if (ia6 != NULL) {
+ dstifp = ia6->ia_ifp;
+ ifa_free(&ia6->ia_ifa);
}
- /* jumbo payload can't contain a fragment header */
+
+ /* Jumbo payload cannot contain a fragment header. */
if (ip6->ip6_plen == 0) {
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset);
in6_ifstat_inc(dstifp, ifs6_reass_fail);
- return IPPROTO_DONE;
+ *mp = NULL;
+ return (IPPROTO_DONE);
}
/*
- * check whether fragment packet's fragment length is
- * multiple of 8 octets.
+ * Check whether fragment packet's fragment length is a
+ * multiple of 8 octets (unless it is the last one).
* sizeof(struct ip6_frag) == 8
* sizeof(struct ip6_hdr) = 40
*/
+ ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset);
if ((ip6f->ip6f_offlg & IP6F_MORE_FRAG) &&
(((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) {
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
offsetof(struct ip6_hdr, ip6_plen));
in6_ifstat_inc(dstifp, ifs6_reass_fail);
- return IPPROTO_DONE;
+ *mp = NULL;
+ return (IPPROTO_DONE);
}
IP6STAT_INC(ip6s_fragments);
in6_ifstat_inc(dstifp, ifs6_reass_reqd);
- /* offset now points to data portion */
- offset += sizeof(struct ip6_frag);
-
/*
- * RFC 6946: Handle "atomic" fragments (offset and m bit set to 0)
- * upfront, unrelated to any reassembly. Just skip the fragment header.
+ * Handle "atomic" fragments (offset and m bit set to 0) upfront,
+ * unrelated to any reassembly. We need to remove the frag hdr
+ * which is ugly.
+ * See RFC 6946 and section 4.5 of RFC 8200.
*/
if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
- /* XXX-BZ we want dedicated counters for this. */
- IP6STAT_INC(ip6s_reassembled);
+ IP6STAT_INC(ip6s_atomicfrags);
+ nxt = ip6f->ip6f_nxt;
+ /*
+ * Set nxt(-hdr field value) to the original value.
+ * We cannot just set ip6->ip6_nxt as there might be
+ * an unfragmentable part with extension headers and
+ * we must update the last one.
+ */
+ m_copyback(m, ip6_get_prevhdr(m, offset), sizeof(uint8_t),
+ (caddr_t)&nxt);
+ ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) -
+ sizeof(struct ip6_frag));
+ if (ip6_deletefraghdr(m, offset, M_NOWAIT) != 0)
+ goto dropfrag2;
+ m->m_pkthdr.len -= sizeof(struct ip6_frag);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
- *offp = offset;
- m->m_flags |= M_FRAGMENTED;
- return (ip6f->ip6f_nxt);
+ *mp = m;
+ return (nxt);
}
+ /* Offset now points to data portion. */
+ offset += sizeof(struct ip6_frag);
+
/* Get fragment length and discard 0-byte fragments. */
frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
if (frgpartlen == 0) {
@@ -298,31 +473,48 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
offsetof(struct ip6_hdr, ip6_plen));
in6_ifstat_inc(dstifp, ifs6_reass_fail);
IP6STAT_INC(ip6s_fragdropped);
- return IPPROTO_DONE;
+ *mp = NULL;
+ return (IPPROTO_DONE);
}
- hashkeyp = hashkey;
- memcpy(hashkeyp, &ip6->ip6_src, sizeof(struct in6_addr));
- hashkeyp += sizeof(struct in6_addr) / sizeof(*hashkeyp);
- memcpy(hashkeyp, &ip6->ip6_dst, sizeof(struct in6_addr));
- hashkeyp += sizeof(struct in6_addr) / sizeof(*hashkeyp);
- *hashkeyp = ip6f->ip6f_ident;
- hash = jenkins_hash32(hashkey, nitems(hashkey), V_ip6q_hashseed);
- hash &= IP6REASS_HMASK;
- head = IP6Q_HEAD(hash);
- IP6Q_LOCK(hash);
-
/*
- * Enforce upper bound on number of fragments.
+ * Enforce upper bound on number of fragments for the entire system.
* If maxfrag is 0, never accept fragments.
* If maxfrag is -1, accept all fragments without limitation.
*/
if (ip6_maxfrags < 0)
;
else if (atomic_load_int(&frag6_nfrags) >= (u_int)ip6_maxfrags)
- goto dropfrag;
+ goto dropfrag2;
+
+ /*
+ * Validate that a full header chain to the ULP is present in the
+ * packet containing the first fragment as per RFC RFC7112 and
+ * RFC 8200 pages 18,19:
+ * The first fragment packet is composed of:
+ * (3) Extension headers, if any, and the Upper-Layer header. These
+ * headers must be in the first fragment. ...
+ */
+ fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
+ /* XXX TODO. thj has D16851 open for this. */
+ /* Send ICMPv6 4,3 in case of violation. */
- for (q6 = head->ip6q_next; q6 != head; q6 = q6->ip6q_next)
+ /* Store receive network interface pointer for later. */
+ srcifp = m->m_pkthdr.rcvif;
+
+ /* Generate a hash value for fragment bucket selection. */
+ hashkeyp = hashkey;
+ memcpy(hashkeyp, &ip6->ip6_src, sizeof(struct in6_addr));
+ hashkeyp += sizeof(struct in6_addr) / sizeof(*hashkeyp);
+ memcpy(hashkeyp, &ip6->ip6_dst, sizeof(struct in6_addr));
+ hashkeyp += sizeof(struct in6_addr) / sizeof(*hashkeyp);
+ *hashkeyp = ip6f->ip6f_ident;
+ bucket = jenkins_hash32(hashkey, nitems(hashkey), V_ip6qb_hashseed);
+ bucket &= IP6REASS_HMASK;
+ IP6QB_LOCK(bucket);
+ head = IP6QB_HEAD(bucket);
+
+ TAILQ_FOREACH(q6, head, ip6q_tq)
if (ip6f->ip6f_ident == q6->ip6q_ident &&
IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &q6->ip6q_src) &&
IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &q6->ip6q_dst)
@@ -332,11 +524,11 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
)
break;
- if (q6 == head) {
- /*
- * the first fragment to arrive, create a reassembly queue.
- */
- first_frag = 1;
+ only_frag = false;
+ if (q6 == NULL) {
+
+ /* A first fragment to arrive creates a reassembly queue. */
+ only_frag = true;
/*
* Enforce upper bound on number of fragmented packets
@@ -347,30 +539,27 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
*/
if (V_ip6_maxfragpackets < 0)
;
- else if (V_ip6q[hash].count >= V_ip6_maxfragbucketsize ||
+ else if (V_ip6qb[bucket].count >= V_ip6_maxfragbucketsize ||
atomic_load_int(&V_frag6_nfragpackets) >=
(u_int)V_ip6_maxfragpackets)
goto dropfrag;
- atomic_add_int(&V_frag6_nfragpackets, 1);
- q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FTABLE,
- M_NOWAIT);
+
+ /* Allocate IPv6 fragement packet queue entry. */
+ q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FRAG6,
+ M_NOWAIT | M_ZERO);
if (q6 == NULL)
goto dropfrag;
- bzero(q6, sizeof(*q6));
#ifdef MAC
if (mac_ip6q_init(q6, M_NOWAIT) != 0) {
- free(q6, M_FTABLE);
+ free(q6, M_FRAG6);
goto dropfrag;
}
mac_ip6q_create(m, q6);
#endif
- frag6_insque_head(q6, head, hash);
+ atomic_add_int(&V_frag6_nfragpackets, 1);
- /* ip6q_nxt will be filled afterwards, from 1st fragment */
- q6->ip6q_down = q6->ip6q_up = (struct ip6asfrag *)q6;
-#ifdef notyet
- q6->ip6q_nxtp = (u_char *)nxtp;
-#endif
+ /* ip6q_nxt will be filled afterwards, from 1st fragment. */
+ TAILQ_INIT(&q6->ip6q_frags);
q6->ip6q_ident = ip6f->ip6f_ident;
q6->ip6q_ttl = IPV6_FRAGTTL;
q6->ip6q_src = ip6->ip6_src;
@@ -379,18 +568,24 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
(ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK;
q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */
- q6->ip6q_nfrag = 0;
+ /* Add the fragemented packet to the bucket. */
+ TAILQ_INSERT_HEAD(head, q6, ip6q_tq);
+ V_ip6qb[bucket].count++;
}
/*
- * If it's the 1st fragment, record the length of the
+ * If it is the 1st fragment, record the length of the
* unfragmentable part and the next header of the fragment header.
+ * Assume the first 1st fragement to arrive will be correct.
+ * We do not have any duplicate checks here yet so another packet
+ * with fragoff == 0 could come and overwrite the ip6q_unfrglen
+ * and worse, the next header, at any time.
*/
- fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
- if (fragoff == 0) {
+ if (fragoff == 0 && q6->ip6q_unfrglen == -1) {
q6->ip6q_unfrglen = offset - sizeof(struct ip6_hdr) -
sizeof(struct ip6_frag);
q6->ip6q_nxt = ip6f->ip6f_nxt;
+ /* XXX ECN? */
}
/*
@@ -401,39 +596,66 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
if (q6->ip6q_unfrglen >= 0) {
/* The 1st fragment has already arrived. */
if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
+ if (only_frag) {
+ TAILQ_REMOVE(head, q6, ip6q_tq);
+ V_ip6qb[bucket].count--;
+ atomic_subtract_int(&V_frag6_nfragpackets, 1);
+#ifdef MAC
+ mac_ip6q_destroy(q6);
+#endif
+ free(q6, M_FRAG6);
+ }
+ IP6QB_UNLOCK(bucket);
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
offset - sizeof(struct ip6_frag) +
offsetof(struct ip6_frag, ip6f_offlg));
- IP6Q_UNLOCK(hash);
+ *mp = NULL;
return (IPPROTO_DONE);
}
} else if (fragoff + frgpartlen > IPV6_MAXPACKET) {
+ if (only_frag) {
+ TAILQ_REMOVE(head, q6, ip6q_tq);
+ V_ip6qb[bucket].count--;
+ atomic_subtract_int(&V_frag6_nfragpackets, 1);
+#ifdef MAC
+ mac_ip6q_destroy(q6);
+#endif
+ free(q6, M_FRAG6);
+ }
+ IP6QB_UNLOCK(bucket);
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
offset - sizeof(struct ip6_frag) +
offsetof(struct ip6_frag, ip6f_offlg));
- IP6Q_UNLOCK(hash);
+ *mp = NULL;
return (IPPROTO_DONE);
}
+
/*
- * If it's the first fragment, do the above check for each
+ * If it is the first fragment, do the above check for each
* fragment already stored in the reassembly queue.
*/
- if (fragoff == 0) {
- for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
- af6 = af6dwn) {
- af6dwn = af6->ip6af_down;
-
- if (q6->ip6q_unfrglen + af6->ip6af_off + af6->ip6af_frglen >
- IPV6_MAXPACKET) {
- struct mbuf *merr = IP6_REASS_MBUF(af6);
+ if (fragoff == 0 && !only_frag) {
+ TAILQ_FOREACH_SAFE(af6, &q6->ip6q_frags, ip6af_tq, af6tmp) {
+
+ if (q6->ip6q_unfrglen + af6->ip6af_off +
+ af6->ip6af_frglen > IPV6_MAXPACKET) {
struct ip6_hdr *ip6err;
- int erroff = af6->ip6af_offset;
+ struct mbuf *merr;
+ int erroff;
+
+ merr = af6->ip6af_m;
+ erroff = af6->ip6af_offset;
- /* dequeue the fragment. */
- frag6_deq(af6, hash);
- free(af6, M_FTABLE);
+ /* Dequeue the fragment. */
+ TAILQ_REMOVE(&q6->ip6q_frags, af6, ip6af_tq);
+ q6->ip6q_nfrag--;
+ atomic_subtract_int(&frag6_nfrags, 1);
+ free(af6, M_FRAG6);
- /* adjust pointer. */
+ /* Set a valid receive interface pointer. */
+ merr->m_pkthdr.rcvif = srcifp;
+
+ /* Adjust pointer. */
ip6err = mtod(merr, struct ip6_hdr *);
/*
@@ -451,239 +673,182 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
}
}
- ip6af = (struct ip6asfrag *)malloc(sizeof(struct ip6asfrag), M_FTABLE,
- M_NOWAIT);
+ /* Allocate an IPv6 fragement queue entry for this fragmented part. */
+ ip6af = (struct ip6asfrag *)malloc(sizeof(struct ip6asfrag), M_FRAG6,
+ M_NOWAIT | M_ZERO);
if (ip6af == NULL)
goto dropfrag;
- bzero(ip6af, sizeof(*ip6af));
- ip6af->ip6af_mff = ip6f->ip6f_offlg & IP6F_MORE_FRAG;
+ ip6af->ip6af_mff = (ip6f->ip6f_offlg & IP6F_MORE_FRAG) ? true : false;
ip6af->ip6af_off = fragoff;
ip6af->ip6af_frglen = frgpartlen;
ip6af->ip6af_offset = offset;
- IP6_REASS_MBUF(ip6af) = m;
+ ip6af->ip6af_m = m;
- if (first_frag) {
- af6 = (struct ip6asfrag *)q6;
- goto insert;
+ if (only_frag) {
+ /*
+ * Do a manual insert rather than a hard-to-understand cast
+ * to a different type relying on data structure order to work.
+ */
+ TAILQ_INSERT_HEAD(&q6->ip6q_frags, ip6af, ip6af_tq);
+ goto postinsert;
}
+ /* Do duplicate, condition, and boundry checks. */
/*
* Handle ECN by comparing this segment with the first one;
* if CE is set, do not lose CE.
- * drop if CE and not-ECT are mixed for the same packet.
+ * Drop if CE and not-ECT are mixed for the same packet.
*/
ecn = (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK;
ecn0 = q6->ip6q_ecn;
if (ecn == IPTOS_ECN_CE) {
if (ecn0 == IPTOS_ECN_NOTECT) {
- free(ip6af, M_FTABLE);
+ free(ip6af, M_FRAG6);
goto dropfrag;
}
if (ecn0 != IPTOS_ECN_CE)
q6->ip6q_ecn = IPTOS_ECN_CE;
}
if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT) {
- free(ip6af, M_FTABLE);
+ free(ip6af, M_FRAG6);
goto dropfrag;
}
- /*
- * Find a segment which begins after this one does.
- */
- for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
- af6 = af6->ip6af_down)
+ /* Find a fragmented part which begins after this one does. */
+ TAILQ_FOREACH(af6, &q6->ip6q_frags, ip6af_tq)
if (af6->ip6af_off > ip6af->ip6af_off)
break;
-#if 0
- /*
- * If there is a preceding segment, it may provide some of
- * our data already. If so, drop the data from the incoming
- * segment. If it provides all of our data, drop us.
- */
- if (af6->ip6af_up != (struct ip6asfrag *)q6) {
- i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen
- - ip6af->ip6af_off;
- if (i > 0) {
- if (i >= ip6af->ip6af_frglen)
- goto dropfrag;
- m_adj(IP6_REASS_MBUF(ip6af), i);
- ip6af->ip6af_off += i;
- ip6af->ip6af_frglen -= i;
- }
- }
-
- /*
- * While we overlap succeeding segments trim them or,
- * if they are completely covered, dequeue them.
- */
- while (af6 != (struct ip6asfrag *)q6 &&
- ip6af->ip6af_off + ip6af->ip6af_frglen > af6->ip6af_off) {
- i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off;
- if (i < af6->ip6af_frglen) {
- af6->ip6af_frglen -= i;
- af6->ip6af_off += i;
- m_adj(IP6_REASS_MBUF(af6), i);
- break;
- }
- af6 = af6->ip6af_down;
- m_freem(IP6_REASS_MBUF(af6->ip6af_up));
- frag6_deq(af6->ip6af_up, hash);
- }
-#else
/*
* If the incoming framgent overlaps some existing fragments in
- * the reassembly queue, drop it, since it is dangerous to override
- * existing fragments from a security point of view.
- * We don't know which fragment is the bad guy - here we trust
- * fragment that came in earlier, with no real reason.
- *
- * Note: due to changes after disabling this part, mbuf passed to
- * m_adj() below now does not meet the requirement.
+ * the reassembly queue, drop both the new fragment and the
+ * entire reassembly queue. However, if the new fragment
+ * is an exact duplicate of an existing fragment, only silently
+ * drop the existing fragment and leave the fragmentation queue
+ * unchanged, as allowed by the RFC. (RFC 8200, 4.5)
*/
- if (af6->ip6af_up != (struct ip6asfrag *)q6) {
- i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen
- - ip6af->ip6af_off;
- if (i > 0) {
-#if 0 /* suppress the noisy log */
- log(LOG_ERR, "%d bytes of a fragment from %s "
- "overlaps the previous fragment\n",
- i, ip6_sprintf(ip6buf, &q6->ip6q_src));
-#endif
- free(ip6af, M_FTABLE);
+ if (af6 != NULL)
+ af6tmp = TAILQ_PREV(af6, ip6fraghead, ip6af_tq);
+ else
+ af6tmp = TAILQ_LAST(&q6->ip6q_frags, ip6fraghead);
+ if (af6tmp != NULL) {
+ if (af6tmp->ip6af_off + af6tmp->ip6af_frglen -
+ ip6af->ip6af_off > 0) {
+ if (af6tmp->ip6af_off != ip6af->ip6af_off ||
+ af6tmp->ip6af_frglen != ip6af->ip6af_frglen)
+ frag6_freef(q6, bucket);
+ free(ip6af, M_FRAG6);
goto dropfrag;
}
}
- if (af6 != (struct ip6asfrag *)q6) {
- i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off;
- if (i > 0) {
-#if 0 /* suppress the noisy log */
- log(LOG_ERR, "%d bytes of a fragment from %s "
- "overlaps the succeeding fragment",
- i, ip6_sprintf(ip6buf, &q6->ip6q_src));
-#endif
- free(ip6af, M_FTABLE);
+ if (af6 != NULL) {
+ if (ip6af->ip6af_off + ip6af->ip6af_frglen -
+ af6->ip6af_off > 0) {
+ if (af6->ip6af_off != ip6af->ip6af_off ||
+ af6->ip6af_frglen != ip6af->ip6af_frglen)
+ frag6_freef(q6, bucket);
+ free(ip6af, M_FRAG6);
goto dropfrag;
}
}
-#endif
-insert:
#ifdef MAC
- if (!first_frag)
- mac_ip6q_update(m, q6);
+ mac_ip6q_update(m, q6);
#endif
/*
- * Stick new segment in its place;
- * check for complete reassembly.
- * If not complete, check fragment limit.
- * Move to front of packet queue, as we are
- * the most recently active fragmented packet.
+ * Stick new segment in its place; check for complete reassembly.
+ * If not complete, check fragment limit. Move to front of packet
+ * queue, as we are the most recently active fragmented packet.
*/
- frag6_enq(ip6af, af6->ip6af_up, hash);
+ if (af6 != NULL)
+ TAILQ_INSERT_BEFORE(af6, ip6af, ip6af_tq);
+ else
+ TAILQ_INSERT_TAIL(&q6->ip6q_frags, ip6af, ip6af_tq);
+postinsert:
atomic_add_int(&frag6_nfrags, 1);
q6->ip6q_nfrag++;
-#if 0 /* xxx */
- if (q6 != head->ip6q_next) {
- frag6_remque(q6, hash);
- frag6_insque_head(q6, head, hash);
- }
-#endif
- next = 0;
- for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
- af6 = af6->ip6af_down) {
- if (af6->ip6af_off != next) {
+
+ plen = 0;
+ TAILQ_FOREACH(af6, &q6->ip6q_frags, ip6af_tq) {
+ if (af6->ip6af_off != plen) {
if (q6->ip6q_nfrag > V_ip6_maxfragsperpacket) {
- IP6STAT_INC(ip6s_fragdropped);
- frag6_freef(q6, hash);
+ IP6STAT_ADD(ip6s_fragdropped, q6->ip6q_nfrag);
+ frag6_freef(q6, bucket);
}
- IP6Q_UNLOCK(hash);
- return IPPROTO_DONE;
+ IP6QB_UNLOCK(bucket);
+ *mp = NULL;
+ return (IPPROTO_DONE);
}
- next += af6->ip6af_frglen;
+ plen += af6->ip6af_frglen;
}
- if (af6->ip6af_up->ip6af_mff) {
+ af6 = TAILQ_LAST(&q6->ip6q_frags, ip6fraghead);
+ if (af6->ip6af_mff) {
if (q6->ip6q_nfrag > V_ip6_maxfragsperpacket) {
- IP6STAT_INC(ip6s_fragdropped);
- frag6_freef(q6, hash);
+ IP6STAT_ADD(ip6s_fragdropped, q6->ip6q_nfrag);
+ frag6_freef(q6, bucket);
}
- IP6Q_UNLOCK(hash);
- return IPPROTO_DONE;
+ IP6QB_UNLOCK(bucket);
+ *mp = NULL;
+ return (IPPROTO_DONE);
}
- /*
- * Reassembly is complete; concatenate fragments.
- */
- ip6af = q6->ip6q_down;
- t = m = IP6_REASS_MBUF(ip6af);
- af6 = ip6af->ip6af_down;
- frag6_deq(ip6af, hash);
- while (af6 != (struct ip6asfrag *)q6) {
+ /* Reassembly is complete; concatenate fragments. */
+ ip6af = TAILQ_FIRST(&q6->ip6q_frags);
+ t = m = ip6af->ip6af_m;
+ TAILQ_REMOVE(&q6->ip6q_frags, ip6af, ip6af_tq);
+ while ((af6 = TAILQ_FIRST(&q6->ip6q_frags)) != NULL) {
m->m_pkthdr.csum_flags &=
- IP6_REASS_MBUF(af6)->m_pkthdr.csum_flags;
+ af6->ip6af_m->m_pkthdr.csum_flags;
m->m_pkthdr.csum_data +=
- IP6_REASS_MBUF(af6)->m_pkthdr.csum_data;
-
- af6dwn = af6->ip6af_down;
- frag6_deq(af6, hash);
- while (t->m_next)
- t = t->m_next;
- m_adj(IP6_REASS_MBUF(af6), af6->ip6af_offset);
- m_demote_pkthdr(IP6_REASS_MBUF(af6));
- m_cat(t, IP6_REASS_MBUF(af6));
- free(af6, M_FTABLE);
- af6 = af6dwn;
+ af6->ip6af_m->m_pkthdr.csum_data;
+
+ TAILQ_REMOVE(&q6->ip6q_frags, af6, ip6af_tq);
+ t = m_last(t);
+ m_adj(af6->ip6af_m, af6->ip6af_offset);
+ m_demote_pkthdr(af6->ip6af_m);
+ m_cat(t, af6->ip6af_m);
+ free(af6, M_FRAG6);
}
while (m->m_pkthdr.csum_data & 0xffff0000)
m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) +
(m->m_pkthdr.csum_data >> 16);
- /* adjust offset to point where the original next header starts */
+ /* Adjust offset to point where the original next header starts. */
offset = ip6af->ip6af_offset - sizeof(struct ip6_frag);
- free(ip6af, M_FTABLE);
+ free(ip6af, M_FRAG6);
ip6 = mtod(m, struct ip6_hdr *);
- ip6->ip6_plen = htons((u_short)next + offset - sizeof(struct ip6_hdr));
+ ip6->ip6_plen = htons((u_short)plen + offset - sizeof(struct ip6_hdr));
if (q6->ip6q_ecn == IPTOS_ECN_CE)
ip6->ip6_flow |= htonl(IPTOS_ECN_CE << 20);
nxt = q6->ip6q_nxt;
-#ifdef notyet
- *q6->ip6q_nxtp = (u_char)(nxt & 0xff);
-#endif
- if (ip6_deletefraghdr(m, offset, M_NOWAIT) != 0) {
- frag6_remque(q6, hash);
- atomic_subtract_int(&frag6_nfrags, q6->ip6q_nfrag);
-#ifdef MAC
- mac_ip6q_destroy(q6);
-#endif
- free(q6, M_FTABLE);
- atomic_subtract_int(&V_frag6_nfragpackets, 1);
+ TAILQ_REMOVE(head, q6, ip6q_tq);
+ V_ip6qb[bucket].count--;
+ atomic_subtract_int(&frag6_nfrags, q6->ip6q_nfrag);
- goto dropfrag;
- }
+ ip6_deletefraghdr(m, offset, M_NOWAIT);
- /*
- * Store NXT to the original.
- */
+ /* Set nxt(-hdr field value) to the original value. */
m_copyback(m, ip6_get_prevhdr(m, offset), sizeof(uint8_t),
(caddr_t)&nxt);
- frag6_remque(q6, hash);
- atomic_subtract_int(&frag6_nfrags, q6->ip6q_nfrag);
#ifdef MAC
mac_ip6q_reassemble(q6, m);
mac_ip6q_destroy(q6);
#endif
- free(q6, M_FTABLE);
+ free(q6, M_FRAG6);
atomic_subtract_int(&V_frag6_nfragpackets, 1);
if (m->m_flags & M_PKTHDR) { /* Isn't it always true? */
- int plen = 0;
+
+ plen = 0;
for (t = m; t; t = t->m_next)
plen += t->m_len;
m->m_pkthdr.len = plen;
+ /* Set a valid receive interface pointer. */
+ m->m_pkthdr.rcvif = srcifp;
}
#ifdef RSS
@@ -699,211 +864,94 @@ insert:
m_tag_prepend(m, mtag);
#endif
- IP6Q_UNLOCK(hash);
+ IP6QB_UNLOCK(bucket);
IP6STAT_INC(ip6s_reassembled);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
#ifdef RSS
- /*
- * Queue/dispatch for reprocessing.
- */
+ /* Queue/dispatch for reprocessing. */
netisr_dispatch(NETISR_IPV6_DIRECT, m);
- return IPPROTO_DONE;
+ *mp = NULL;
+ return (IPPROTO_DONE);
#endif
- /*
- * Tell launch routine the next header
- */
-
+ /* Tell launch routine the next header. */
*mp = m;
*offp = offset;
- return nxt;
+ return (nxt);
- dropfrag:
- IP6Q_UNLOCK(hash);
+dropfrag:
+ IP6QB_UNLOCK(bucket);
+dropfrag2:
in6_ifstat_inc(dstifp, ifs6_reass_fail);
IP6STAT_INC(ip6s_fragdropped);
m_freem(m);
- return IPPROTO_DONE;
-}
-
-/*
- * Free a fragment reassembly header and all
- * associated datagrams.
- */
-static void
-frag6_freef(struct ip6q *q6, uint32_t bucket)
-{
- struct ip6asfrag *af6, *down6;
-
- IP6Q_LOCK_ASSERT(bucket);
-
- for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
- af6 = down6) {
- struct mbuf *m = IP6_REASS_MBUF(af6);
-
- down6 = af6->ip6af_down;
- frag6_deq(af6, bucket);
-
- /*
- * Return ICMP time exceeded error for the 1st fragment.
- * Just free other fragments.
- */
- if (af6->ip6af_off == 0) {
- struct ip6_hdr *ip6;
-
- /* adjust pointer */
- ip6 = mtod(m, struct ip6_hdr *);
-
- /* restore source and destination addresses */
- ip6->ip6_src = q6->ip6q_src;
- ip6->ip6_dst = q6->ip6q_dst;
-
- icmp6_error(m, ICMP6_TIME_EXCEEDED,
- ICMP6_TIME_EXCEED_REASSEMBLY, 0);
- } else
- m_freem(m);
- free(af6, M_FTABLE);
- }
- frag6_remque(q6, bucket);
- atomic_subtract_int(&frag6_nfrags, q6->ip6q_nfrag);
-#ifdef MAC
- mac_ip6q_destroy(q6);
-#endif
- free(q6, M_FTABLE);
- atomic_subtract_int(&V_frag6_nfragpackets, 1);
-}
-
-/*
- * Put an ip fragment on a reassembly chain.
- * Like insque, but pointers in middle of structure.
- */
-static void
-frag6_enq(struct ip6asfrag *af6, struct ip6asfrag *up6,
- uint32_t bucket __unused)
-{
-
- IP6Q_LOCK_ASSERT(bucket);
-
- af6->ip6af_up = up6;
- af6->ip6af_down = up6->ip6af_down;
- up6->ip6af_down->ip6af_up = af6;
- up6->ip6af_down = af6;
-}
-
-/*
- * To frag6_enq as remque is to insque.
- */
-static void
-frag6_deq(struct ip6asfrag *af6, uint32_t bucket __unused)
-{
-
- IP6Q_LOCK_ASSERT(bucket);
-
- af6->ip6af_up->ip6af_down = af6->ip6af_down;
- af6->ip6af_down->ip6af_up = af6->ip6af_up;
-}
-
-static void
-frag6_insque_head(struct ip6q *new, struct ip6q *old, uint32_t bucket)
-{
-
- IP6Q_LOCK_ASSERT(bucket);
- KASSERT(IP6Q_HEAD(bucket) == old,
- ("%s: attempt to insert at head of wrong bucket"
- " (bucket=%u, old=%p)", __func__, bucket, old));
-
- new->ip6q_prev = old;
- new->ip6q_next = old->ip6q_next;
- old->ip6q_next->ip6q_prev= new;
- old->ip6q_next = new;
- V_ip6q[bucket].count++;
-}
-
-static void
-frag6_remque(struct ip6q *p6, uint32_t bucket)
-{
-
- IP6Q_LOCK_ASSERT(bucket);
-
- p6->ip6q_prev->ip6q_next = p6->ip6q_next;
- p6->ip6q_next->ip6q_prev = p6->ip6q_prev;
- V_ip6q[bucket].count--;
+ *mp = NULL;
+ return (IPPROTO_DONE);
}
/*
* IPv6 reassembling timer processing;
- * if a timer expires on a reassembly
- * queue, discard it.
+ * if a timer expires on a reassembly queue, discard it.
*/
void
frag6_slowtimo(void)
{
VNET_ITERATOR_DECL(vnet_iter);
- struct ip6q *head, *q6;
- int i;
+ struct ip6qhead *head;
+ struct ip6q *q6, *q6tmp;
+ uint32_t bucket;
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
- for (i = 0; i < IP6REASS_NHASH; i++) {
- IP6Q_LOCK(i);
- head = IP6Q_HEAD(i);
- q6 = head->ip6q_next;
- if (q6 == NULL) {
- /*
- * XXXJTL: This should never happen. This
- * should turn into an assertion.
- */
- IP6Q_UNLOCK(i);
- continue;
- }
- while (q6 != head) {
- --q6->ip6q_ttl;
- q6 = q6->ip6q_next;
- if (q6->ip6q_prev->ip6q_ttl == 0) {
- IP6STAT_INC(ip6s_fragtimeout);
+ for (bucket = 0; bucket < IP6REASS_NHASH; bucket++) {
+ IP6QB_LOCK(bucket);
+ head = IP6QB_HEAD(bucket);
+ TAILQ_FOREACH_SAFE(q6, head, ip6q_tq, q6tmp)
+ if (--q6->ip6q_ttl == 0) {
+ IP6STAT_ADD(ip6s_fragtimeout,
+ q6->ip6q_nfrag);
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(q6->ip6q_prev, i);
+ frag6_freef(q6, bucket);
}
- }
/*
* If we are over the maximum number of fragments
* (due to the limit being lowered), drain off
* enough to get down to the new limit.
* Note that we drain all reassembly queues if
* maxfragpackets is 0 (fragmentation is disabled),
- * and don't enforce a limit when maxfragpackets
+ * and do not enforce a limit when maxfragpackets
* is negative.
*/
while ((V_ip6_maxfragpackets == 0 ||
(V_ip6_maxfragpackets > 0 &&
- V_ip6q[i].count > V_ip6_maxfragbucketsize)) &&
- head->ip6q_prev != head) {
- IP6STAT_INC(ip6s_fragoverflow);
+ V_ip6qb[bucket].count > V_ip6_maxfragbucketsize)) &&
+ (q6 = TAILQ_LAST(head, ip6qhead)) != NULL) {
+ IP6STAT_ADD(ip6s_fragoverflow, q6->ip6q_nfrag);
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(head->ip6q_prev, i);
+ frag6_freef(q6, bucket);
}
- IP6Q_UNLOCK(i);
+ IP6QB_UNLOCK(bucket);
}
/*
* If we are still over the maximum number of fragmented
* packets, drain off enough to get down to the new limit.
*/
- i = 0;
+ bucket = 0;
while (V_ip6_maxfragpackets >= 0 &&
atomic_load_int(&V_frag6_nfragpackets) >
(u_int)V_ip6_maxfragpackets) {
- IP6Q_LOCK(i);
- head = IP6Q_HEAD(i);
- if (head->ip6q_prev != head) {
- IP6STAT_INC(ip6s_fragoverflow);
+ IP6QB_LOCK(bucket);
+ q6 = TAILQ_LAST(IP6QB_HEAD(bucket), ip6qhead);
+ if (q6 != NULL) {
+ IP6STAT_ADD(ip6s_fragoverflow, q6->ip6q_nfrag);
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(head->ip6q_prev, i);
+ frag6_freef(q6, bucket);
}
- IP6Q_UNLOCK(i);
- i = (i + 1) % IP6REASS_NHASH;
+ IP6QB_UNLOCK(bucket);
+ bucket = (bucket + 1) % IP6REASS_NHASH;
}
CURVNET_RESTORE();
}
@@ -911,55 +959,102 @@ frag6_slowtimo(void)
}
/*
+ * Eventhandler to adjust limits in case nmbclusters change.
+ */
+static void
+frag6_change(void *tag)
+{
+ VNET_ITERATOR_DECL(vnet_iter);
+
+ ip6_maxfrags = IP6_MAXFRAGS;
+ VNET_LIST_RLOCK_NOSLEEP();
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ V_ip6_maxfragpackets = IP6_MAXFRAGPACKETS;
+ frag6_set_bucketsize();
+ CURVNET_RESTORE();
+ }
+ VNET_LIST_RUNLOCK_NOSLEEP();
+}
+
+/*
+ * Initialise reassembly queue and fragment identifier.
+ */
+void
+frag6_init(void)
+{
+ uint32_t bucket;
+
+ V_ip6_maxfragpackets = IP6_MAXFRAGPACKETS;
+ frag6_set_bucketsize();
+ for (bucket = 0; bucket < IP6REASS_NHASH; bucket++) {
+ TAILQ_INIT(IP6QB_HEAD(bucket));
+ mtx_init(&V_ip6qb[bucket].lock, "ip6qb", NULL, MTX_DEF);
+ V_ip6qb[bucket].count = 0;
+ }
+ V_ip6qb_hashseed = arc4random();
+ V_ip6_maxfragsperpacket = 64;
+#ifdef VIMAGE
+ V_frag6_on = true;
+#endif
+ if (!IS_DEFAULT_VNET(curvnet))
+ return;
+
+ ip6_maxfrags = IP6_MAXFRAGS;
+ EVENTHANDLER_REGISTER(nmbclusters_change,
+ frag6_change, NULL, EVENTHANDLER_PRI_ANY);
+}
+
+/*
* Drain off all datagram fragments.
*/
+static void
+frag6_drain_one(void)
+{
+ struct ip6q *q6;
+ uint32_t bucket;
+
+ for (bucket = 0; bucket < IP6REASS_NHASH; bucket++) {
+ IP6QB_LOCK(bucket);
+ while ((q6 = TAILQ_FIRST(IP6QB_HEAD(bucket))) != NULL) {
+ IP6STAT_INC(ip6s_fragdropped);
+ /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
+ frag6_freef(q6, bucket);
+ }
+ IP6QB_UNLOCK(bucket);
+ }
+}
+
void
frag6_drain(void)
{
VNET_ITERATOR_DECL(vnet_iter);
- struct ip6q *head;
- int i;
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
- for (i = 0; i < IP6REASS_NHASH; i++) {
- if (IP6Q_TRYLOCK(i) == 0)
- continue;
- head = IP6Q_HEAD(i);
- while (head->ip6q_next != head) {
- IP6STAT_INC(ip6s_fragdropped);
- /* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(head->ip6q_next, i);
- }
- IP6Q_UNLOCK(i);
- }
+ frag6_drain_one();
CURVNET_RESTORE();
}
VNET_LIST_RUNLOCK_NOSLEEP();
}
-int
-ip6_deletefraghdr(struct mbuf *m, int offset, int wait)
+#ifdef VIMAGE
+/*
+ * Clear up IPv6 reassembly structures.
+ */
+void
+frag6_destroy(void)
{
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
- struct mbuf *t;
-
- /* Delete frag6 header. */
- if (m->m_len >= offset + sizeof(struct ip6_frag)) {
- /* This is the only possible case with !PULLDOWN_TEST. */
- bcopy(ip6, (char *)ip6 + sizeof(struct ip6_frag),
- offset);
- m->m_data += sizeof(struct ip6_frag);
- m->m_len -= sizeof(struct ip6_frag);
- } else {
- /* This comes with no copy if the boundary is on cluster. */
- if ((t = m_split(m, offset, wait)) == NULL)
- return (ENOMEM);
- m_adj(t, sizeof(struct ip6_frag));
- m_cat(m, t);
+ uint32_t bucket;
+
+ frag6_drain_one();
+ V_frag6_on = false;
+ for (bucket = 0; bucket < IP6REASS_NHASH; bucket++) {
+ KASSERT(V_ip6qb[bucket].count == 0,
+ ("%s: V_ip6qb[%d] (%p) count not 0 (%d)", __func__,
+ bucket, &V_ip6qb[bucket], V_ip6qb[bucket].count));
+ mtx_destroy(&V_ip6qb[bucket].lock);
}
-
- m->m_flags |= M_FRAGMENTED;
- return (0);
}
+#endif
diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c
index 6dd25e98..293ff85f 100644
--- a/freebsd/sys/netinet6/icmp6.c
+++ b/freebsd/sys/netinet6/icmp6.c
@@ -234,16 +234,13 @@ icmp6_error2(struct mbuf *m, int type, int code, int param,
if (ifp == NULL)
return;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), );
-#else
if (m->m_len < sizeof(struct ip6_hdr)) {
m = m_pullup(m, sizeof(struct ip6_hdr));
- if (m == NULL)
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
return;
+ }
}
-#endif
-
ip6 = mtod(m, struct ip6_hdr *);
if (in6_setscope(&ip6->ip6_src, ifp, NULL) != 0)
@@ -278,15 +275,13 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
}
#endif
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), );
-#else
if (m->m_len < sizeof(struct ip6_hdr)) {
m = m_pullup(m, sizeof(struct ip6_hdr));
- if (m == NULL)
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
return;
+ }
}
-#endif
oip6 = mtod(m, struct ip6_hdr *);
/*
@@ -324,17 +319,16 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
if (off >= 0 && nxt == IPPROTO_ICMPV6) {
struct icmp6_hdr *icp;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, 0, off + sizeof(struct icmp6_hdr), );
- icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
-#else
- IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off,
- sizeof(*icp));
- if (icp == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return;
+ if (m->m_len < off + sizeof(struct icmp6_hdr)) {
+ m = m_pullup(m, off + sizeof(struct icmp6_hdr));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
-#endif
+ oip6 = mtod(m, struct ip6_hdr *);
+ icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
+
if (icp->icmp6_type < ICMP6_ECHO_REQUEST ||
icp->icmp6_type == ND_REDIRECT) {
/*
@@ -351,8 +345,6 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
/* non-ICMPv6 - send the error */
}
- oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */
-
/* Finally, do rate limitation check. */
if (icmp6_ratelimit(&oip6->ip6_src, type, code)) {
ICMP6STAT_INC(icp6s_toofreq);
@@ -403,35 +395,38 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
int
icmp6_input(struct mbuf **mp, int *offp, int proto)
{
- struct mbuf *m = *mp, *n;
+ struct mbuf *m, *n;
struct ifnet *ifp;
struct ip6_hdr *ip6, *nip6;
struct icmp6_hdr *icmp6, *nicmp6;
- int off = *offp;
- int icmp6len = m->m_pkthdr.len - *offp;
- int code, sum, noff;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
- int ip6len, error;
+ int code, error, icmp6len, ip6len, noff, off, sum;
- ifp = m->m_pkthdr.rcvif;
+ m = *mp;
+ off = *offp;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_hdr), IPPROTO_DONE);
- /* m might change if M_LOOP. So, call mtod after this */
-#endif
+ if (m->m_len < off + sizeof(struct icmp6_hdr)) {
+ m = m_pullup(m, off + sizeof(struct icmp6_hdr));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (IPPROTO_DONE);
+ }
+ }
/*
* Locate icmp6 structure in mbuf, and check
* that not corrupted and of at least minimum length
*/
- ip6 = mtod(m, struct ip6_hdr *);
- ip6len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
+ icmp6len = m->m_pkthdr.len - off;
if (icmp6len < sizeof(struct icmp6_hdr)) {
ICMP6STAT_INC(icp6s_tooshort);
goto freeit;
}
+ ip6 = mtod(m, struct ip6_hdr *);
+ ifp = m->m_pkthdr.rcvif;
/*
* Check multicast group membership.
* Note: SSM filters are not applied for ICMPv6 traffic.
@@ -447,20 +442,9 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
}
}
- /*
- * calculate the checksum
- */
-#ifndef PULLDOWN_TEST
+ /* Calculate the checksum. */
icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
- if (icmp6 == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return IPPROTO_DONE;
- }
-#endif
code = icmp6->icmp6_code;
-
if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) {
nd6log((LOG_ERR,
"ICMP6 checksum error(%d|%x) %s\n",
@@ -475,6 +459,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
if (icmp6->icmp6_type < ICMP6_INFOMSG_MASK)
icmp6_ifstat_inc(ifp, ifs6_in_error);
+ ip6len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
switch (icmp6->icmp6_type) {
case ICMP6_DST_UNREACH:
icmp6_ifstat_inc(ifp, ifs6_in_dstunreach);
@@ -587,8 +572,14 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
n->m_pkthdr.len = n0len + (noff - off);
n->m_next = n0;
} else {
- IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, n, off,
- sizeof(*nicmp6));
+ if (n->m_len < off + sizeof(*nicmp6)) {
+ n = m_pullup(n, off + sizeof(*nicmp6));
+ if (n == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ break;
+ }
+ }
+ nicmp6 = (struct icmp6_hdr *)(mtod(n, caddr_t) + off);
noff = off;
}
if (n) {
@@ -621,8 +612,10 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
*/
if ((ip6->ip6_hlim != 1) || (m->m_flags & M_RTALERT_MLD) == 0)
goto freeit;
- if (mld_input(m, off, icmp6len) != 0)
+ if (mld_input(&m, off, icmp6len) != 0) {
+ *mp = NULL;
return (IPPROTO_DONE);
+ }
/* m stays. */
break;
@@ -641,10 +634,15 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
goto badlen;
if (mode == FQDN) {
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, sizeof(struct icmp6_nodeinfo),
- IPPROTO_DONE);
-#endif
+ if (m->m_len < off + sizeof(struct icmp6_nodeinfo)) {
+ m = m_pullup(m, off +
+ sizeof(struct icmp6_nodeinfo));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (IPPROTO_DONE);
+ }
+ }
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n)
n = ni6_input(n, off);
@@ -734,7 +732,14 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
if (icmp6len < sizeof(struct nd_router_solicit))
goto badlen;
if (send_sendso_input_hook != NULL) {
- IP6_EXTHDR_CHECK(m, off, icmp6len, IPPROTO_DONE);
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (IPPROTO_DONE);
+ }
+ }
error = send_sendso_input_hook(m, ifp, SND_IN, ip6len);
if (error == 0) {
m = NULL;
@@ -853,6 +858,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
deliver:
if (icmp6_notify_error(&m, off, icmp6len, code) != 0) {
/* In this case, m should've been freed. */
+ *mp = NULL;
return (IPPROTO_DONE);
}
break;
@@ -869,38 +875,40 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
/* deliver the packet to appropriate sockets */
icmp6_rip6_input(&m, *offp);
- return IPPROTO_DONE;
+ *mp = m;
+ return (IPPROTO_DONE);
freeit:
m_freem(m);
- return IPPROTO_DONE;
+ *mp = NULL;
+ return (IPPROTO_DONE);
}
static int
icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
{
- struct mbuf *m = *mp;
+ struct mbuf *m;
struct icmp6_hdr *icmp6;
struct ip6_hdr *eip6;
u_int32_t notifymtu;
struct sockaddr_in6 icmp6src, icmp6dst;
+ m = *mp;
+
if (icmp6len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr)) {
ICMP6STAT_INC(icp6s_tooshort);
goto freeit;
}
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off,
- sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr), -1);
- icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
-#else
- IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
- sizeof(*icmp6) + sizeof(struct ip6_hdr));
- if (icmp6 == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return (-1);
+
+ if (m->m_len < off + sizeof(*icmp6) + sizeof(struct ip6_hdr)) {
+ m = m_pullup(m, off + sizeof(*icmp6) + sizeof(struct ip6_hdr));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
}
-#endif
+ icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
eip6 = (struct ip6_hdr *)(icmp6 + 1);
/* Detect the upper level protocol */
@@ -924,19 +932,17 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_AH:
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, 0,
- eoff + sizeof(struct ip6_ext), -1);
- eh = (struct ip6_ext *)(mtod(m, caddr_t) + eoff);
-#else
- IP6_EXTHDR_GET(eh, struct ip6_ext *, m,
- eoff, sizeof(*eh));
- if (eh == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return (-1);
+ if (m->m_len < eoff + sizeof(struct ip6_ext)) {
+ m = m_pullup(m, eoff +
+ sizeof(struct ip6_ext));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
}
-#endif
-
+ eh = (struct ip6_ext *)
+ (mtod(m, caddr_t) + eoff);
if (nxt == IPPROTO_AH)
eoff += (eh->ip6e_len + 2) << 2;
else
@@ -952,18 +958,16 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
* information that depends on the final
* destination (e.g. path MTU).
*/
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, 0, eoff + sizeof(*rth), -1);
+ if (m->m_len < eoff + sizeof(*rth)) {
+ m = m_pullup(m, eoff + sizeof(*rth));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
+ }
rth = (struct ip6_rthdr *)
(mtod(m, caddr_t) + eoff);
-#else
- IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m,
- eoff, sizeof(*rth));
- if (rth == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return (-1);
- }
-#endif
rthlen = (rth->ip6r_len + 1) << 3;
/*
* XXX: currently there is no
@@ -977,19 +981,17 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
rth->ip6r_type == IPV6_RTHDR_TYPE_0) {
int hops;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, 0, eoff + rthlen, -1);
+ if (m->m_len < eoff + rthlen) {
+ m = m_pullup(m, eoff + rthlen);
+ if (m == NULL) {
+ IP6STAT_INC(
+ ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
+ }
rth0 = (struct ip6_rthdr0 *)
(mtod(m, caddr_t) + eoff);
-#else
- IP6_EXTHDR_GET(rth0,
- struct ip6_rthdr0 *, m,
- eoff, rthlen);
- if (rth0 == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return (-1);
- }
-#endif
/* just ignore a bogus header */
if ((rth0->ip6r0_len % 2) == 0 &&
(hops = rth0->ip6r0_len/2))
@@ -999,19 +1001,17 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
nxt = rth->ip6r_nxt;
break;
case IPPROTO_FRAGMENT:
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, 0, eoff +
- sizeof(struct ip6_frag), -1);
+ if (m->m_len < eoff + sizeof(struct ip6_frag)) {
+ m = m_pullup(m, eoff +
+ sizeof(struct ip6_frag));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
+ }
fh = (struct ip6_frag *)(mtod(m, caddr_t) +
eoff);
-#else
- IP6_EXTHDR_GET(fh, struct ip6_frag *, m,
- eoff, sizeof(*fh));
- if (fh == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return (-1);
- }
-#endif
/*
* Data after a fragment header is meaningless
* unless it is the first fragment, but
@@ -1037,16 +1037,7 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
}
}
notify:
-#ifndef PULLDOWN_TEST
icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
-#else
- IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off,
- sizeof(*icmp6) + sizeof(struct ip6_hdr));
- if (icmp6 == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return (-1);
- }
-#endif
/*
* retrieve parameters from the inner IPv6 header, and convert
@@ -1104,6 +1095,7 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
freeit:
m_freem(m);
+ *mp = NULL;
return (-1);
}
@@ -1191,15 +1183,7 @@ ni6_input(struct mbuf *m, int off)
struct in6_ifaddr *ia6 = NULL;
ip6 = mtod(m, struct ip6_hdr *);
-#ifndef PULLDOWN_TEST
ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off);
-#else
- IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6));
- if (ni6 == NULL) {
- /* m is already reclaimed */
- return (NULL);
- }
-#endif
/*
* Validate IPv6 source address.
@@ -1296,7 +1280,6 @@ ni6_input(struct mbuf *m, int off)
*
* We do not do proxy at this moment.
*/
- /* m_pulldown instead of copy? */
m_copydata(m, off + sizeof(struct icmp6_nodeinfo),
subjlen, (caddr_t)&in6_subj);
if (in6_setscope(&in6_subj, m->m_pkthdr.rcvif, NULL))
@@ -1340,10 +1323,19 @@ ni6_input(struct mbuf *m, int off)
mtx_unlock(&pr->pr_mtx);
if (!n || n->m_next || n->m_len == 0)
goto bad;
- IP6_EXTHDR_GET(subj, char *, m,
- off + sizeof(struct icmp6_nodeinfo), subjlen);
- if (subj == NULL)
- goto bad;
+ if (m->m_len < off + sizeof(struct icmp6_nodeinfo) +
+ subjlen) {
+ m = m_pullup(m, off +
+ sizeof(struct icmp6_nodeinfo) + subjlen);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ goto bad;
+ }
+ }
+ /* ip6 possibly invalid but not used after. */
+ ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off);
+ subj = (char *)(mtod(m, caddr_t) + off +
+ sizeof(struct icmp6_nodeinfo));
if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *),
n->m_len)) {
goto bad;
@@ -1906,23 +1898,15 @@ icmp6_rip6_input(struct mbuf **mp, int off)
{
struct mbuf *m = *mp;
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
- struct inpcb *in6p;
+ struct inpcb *inp;
struct inpcb *last = NULL;
struct sockaddr_in6 fromsa;
struct icmp6_hdr *icmp6;
struct epoch_tracker et;
struct mbuf *opts = NULL;
-#ifndef PULLDOWN_TEST
- /* this is assumed to be safe. */
+ /* This is assumed to be safe; icmp6_input() does a pullup. */
icmp6 = (struct icmp6_hdr *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6));
- if (icmp6 == NULL) {
- /* m is already reclaimed */
- return (IPPROTO_DONE);
- }
-#endif
/*
* XXX: the address may have embedded scope zone ID, which should be
@@ -1934,29 +1918,30 @@ icmp6_rip6_input(struct mbuf **mp, int off)
fromsa.sin6_addr = ip6->ip6_src;
if (sa6_recoverscope(&fromsa)) {
m_freem(m);
+ *mp = NULL;
return (IPPROTO_DONE);
}
INP_INFO_RLOCK_ET(&V_ripcbinfo, et);
- CK_LIST_FOREACH(in6p, &V_ripcb, inp_list) {
- if ((in6p->inp_vflag & INP_IPV6) == 0)
+ CK_LIST_FOREACH(inp, &V_ripcb, inp_list) {
+ if ((inp->inp_vflag & INP_IPV6) == 0)
continue;
- if (in6p->inp_ip_p != IPPROTO_ICMPV6)
+ if (inp->inp_ip_p != IPPROTO_ICMPV6)
continue;
- if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) &&
- !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst))
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) &&
+ !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, &ip6->ip6_dst))
continue;
- if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
- !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) &&
+ !IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &ip6->ip6_src))
continue;
- INP_RLOCK(in6p);
- if (__predict_false(in6p->inp_flags2 & INP_FREED)) {
- INP_RUNLOCK(in6p);
+ INP_RLOCK(inp);
+ if (__predict_false(inp->inp_flags2 & INP_FREED)) {
+ INP_RUNLOCK(inp);
continue;
}
if (ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type,
- in6p->in6p_icmp6filt)) {
- INP_RUNLOCK(in6p);
+ inp->in6p_icmp6filt)) {
+ INP_RUNLOCK(inp);
continue;
}
if (last != NULL) {
@@ -2017,7 +2002,7 @@ icmp6_rip6_input(struct mbuf **mp, int off)
}
INP_RUNLOCK(last);
}
- last = in6p;
+ last = inp;
}
INP_INFO_RUNLOCK_ET(&V_ripcbinfo, et);
if (last != NULL) {
@@ -2059,7 +2044,8 @@ icmp6_rip6_input(struct mbuf **mp, int off)
m_freem(m);
IP6STAT_DEC(ip6s_delivered);
}
- return IPPROTO_DONE;
+ *mp = NULL;
+ return (IPPROTO_DONE);
}
/*
@@ -2237,24 +2223,17 @@ void
icmp6_redirect_input(struct mbuf *m, int off)
{
struct ifnet *ifp;
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ struct ip6_hdr *ip6;
struct nd_redirect *nd_rd;
- int icmp6len = ntohs(ip6->ip6_plen);
- char *lladdr = NULL;
- int lladdrlen = 0;
- int is_router;
- int is_onlink;
- struct in6_addr src6 = ip6->ip6_src;
- struct in6_addr redtgt6;
- struct in6_addr reddst6;
+ struct in6_addr src6, redtgt6, reddst6;
union nd_opts ndopts;
char ip6buf[INET6_ADDRSTRLEN];
+ char *lladdr;
+ int icmp6len, is_onlink, is_router, lladdrlen;
M_ASSERTPKTHDR(m);
KASSERT(m->m_pkthdr.rcvif != NULL, ("%s: no rcvif", __func__));
- ifp = m->m_pkthdr.rcvif;
-
/* XXX if we are router, we don't update route by icmp6 redirect */
if (V_ip6_forwarding)
goto freeit;
@@ -2265,25 +2244,29 @@ icmp6_redirect_input(struct mbuf *m, int off)
if(m->m_flags & M_FRAGMENTED)
goto freeit;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, icmp6len,);
- nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len);
- if (nd_rd == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return;
+ ip6 = mtod(m, struct ip6_hdr *);
+ icmp6len = ntohs(ip6->ip6_plen);
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
-#endif
+ ip6 = mtod(m, struct ip6_hdr *);
+ nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);
+
+ ifp = m->m_pkthdr.rcvif;
redtgt6 = nd_rd->nd_rd_target;
reddst6 = nd_rd->nd_rd_dst;
- if (in6_setscope(&redtgt6, m->m_pkthdr.rcvif, NULL) ||
- in6_setscope(&reddst6, m->m_pkthdr.rcvif, NULL)) {
+ if (in6_setscope(&redtgt6, ifp, NULL) ||
+ in6_setscope(&reddst6, ifp, NULL)) {
goto freeit;
}
/* validation */
+ src6 = ip6->ip6_src;
if (!IN6_IS_ADDR_LINKLOCAL(&src6)) {
nd6log((LOG_ERR,
"ICMP6 redirect sent from %s rejected; "
@@ -2369,6 +2352,8 @@ icmp6_redirect_input(struct mbuf *m, int off)
goto freeit;
}
+ lladdr = NULL;
+ lladdrlen = 0;
if (ndopts.nd_opts_tgt_lladdr) {
lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c
index 078efe45..a42b7bf7 100644
--- a/freebsd/sys/netinet6/in6.c
+++ b/freebsd/sys/netinet6/in6.c
@@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/rmlock.h>
+#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <net/if.h>
@@ -2027,8 +2028,6 @@ in6_if2idlen(struct ifnet *ifp)
}
}
-#include <sys/sysctl.h>
-
struct in6_llentry {
struct llentry base;
};
diff --git a/freebsd/sys/netinet6/in6_mcast.c b/freebsd/sys/netinet6/in6_mcast.c
index 1ac10633..cf7c7ff2 100644
--- a/freebsd/sys/netinet6/in6_mcast.c
+++ b/freebsd/sys/netinet6/in6_mcast.c
@@ -1830,7 +1830,7 @@ ip6_getmoptions(struct inpcb *inp, struct sockopt *sopt)
* Returns NULL if no ifp could be found.
*/
static struct ifnet *
-in6p_lookup_mcast_ifp(const struct inpcb *in6p,
+in6p_lookup_mcast_ifp(const struct inpcb *inp,
const struct sockaddr_in6 *gsin6)
{
struct nhop6_basic nh6;
@@ -1838,13 +1838,13 @@ in6p_lookup_mcast_ifp(const struct inpcb *in6p,
uint32_t scopeid;
uint32_t fibnum;
- KASSERT(in6p->inp_vflag & INP_IPV6,
+ KASSERT(inp->inp_vflag & INP_IPV6,
("%s: not INP_IPV6 inpcb", __func__));
KASSERT(gsin6->sin6_family == AF_INET6,
("%s: not AF_INET6 group", __func__));
in6_splitscope(&gsin6->sin6_addr, &dst, &scopeid);
- fibnum = in6p ? in6p->inp_inc.inc_fibnum : RT_DEFAULT_FIB;
+ fibnum = inp ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB;
if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6) != 0)
return (NULL);
@@ -2111,6 +2111,7 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt)
* NOTE: Refcount from in6_joingroup_locked()
* is protecting membership.
*/
+ ip6_mfilter_insert(&imo->im6o_head, imf);
} else {
CTR1(KTR_MLD, "%s: merge inm state", __func__);
IN6_MULTI_LIST_LOCK();
@@ -2136,9 +2137,6 @@ in6p_join_group(struct inpcb *inp, struct sockopt *sopt)
}
}
- if (is_new)
- ip6_mfilter_insert(&imo->im6o_head, imf);
-
im6f_commit(imf);
imf = NULL;
@@ -2330,6 +2328,12 @@ in6p_leave_group(struct inpcb *inp, struct sockopt *sopt)
if (is_final) {
ip6_mfilter_remove(&imo->im6o_head, imf);
im6f_leave(imf);
+
+ /*
+ * Give up the multicast address record to which
+ * the membership points.
+ */
+ (void)in6_leavegroup_locked(inm, imf);
} else {
if (imf->im6f_st[0] == MCAST_EXCLUDE) {
error = EADDRNOTAVAIL;
@@ -2386,14 +2390,8 @@ in6p_leave_group(struct inpcb *inp, struct sockopt *sopt)
out_in6p_locked:
INP_WUNLOCK(inp);
- if (is_final && imf) {
- /*
- * Give up the multicast address record to which
- * the membership points.
- */
- (void)in6_leavegroup_locked(inm, imf);
+ if (is_final && imf)
ip6_mfilter_free(imf);
- }
IN6_MULTI_UNLOCK();
return (error);
diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c
index 3c89cdf4..903bc09b 100644
--- a/freebsd/sys/netinet6/in6_pcb.c
+++ b/freebsd/sys/netinet6/in6_pcb.c
@@ -816,20 +816,20 @@ in6_pcblookup_local(struct inpcbinfo *pcbinfo, struct in6_addr *laddr,
void
in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp)
{
- struct inpcb *in6p;
+ struct inpcb *inp;
struct in6_multi *inm;
struct in6_mfilter *imf;
struct ip6_moptions *im6o;
INP_INFO_WLOCK(pcbinfo);
- CK_LIST_FOREACH(in6p, pcbinfo->ipi_listhead, inp_list) {
- INP_WLOCK(in6p);
- if (__predict_false(in6p->inp_flags2 & INP_FREED)) {
- INP_WUNLOCK(in6p);
+ CK_LIST_FOREACH(inp, pcbinfo->ipi_listhead, inp_list) {
+ INP_WLOCK(inp);
+ if (__predict_false(inp->inp_flags2 & INP_FREED)) {
+ INP_WUNLOCK(inp);
continue;
}
- im6o = in6p->in6p_moptions;
- if ((in6p->inp_vflag & INP_IPV6) && im6o != NULL) {
+ im6o = inp->in6p_moptions;
+ if ((inp->inp_vflag & INP_IPV6) && im6o != NULL) {
/*
* Unselect the outgoing ifp for multicast if it
* is being detached.
@@ -853,7 +853,7 @@ restart:
goto restart;
}
}
- INP_WUNLOCK(in6p);
+ INP_WUNLOCK(inp);
}
INP_INFO_WUNLOCK(pcbinfo);
}
diff --git a/freebsd/sys/netinet6/in6_pcb.h b/freebsd/sys/netinet6/in6_pcb.h
index 2c6bcdc6..56ea6eeb 100644
--- a/freebsd/sys/netinet6/in6_pcb.h
+++ b/freebsd/sys/netinet6/in6_pcb.h
@@ -113,7 +113,7 @@ int in6_getpeeraddr(struct socket *so, struct sockaddr **nam);
int in6_getsockaddr(struct socket *so, struct sockaddr **nam);
int in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam);
int in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam);
-int in6_selecthlim(struct in6pcb *, struct ifnet *);
+int in6_selecthlim(struct inpcb *, struct ifnet *);
int in6_pcbsetport(struct in6_addr *, struct inpcb *, struct ucred *);
void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int);
#endif /* _KERNEL */
diff --git a/freebsd/sys/netinet6/in6_proto.c b/freebsd/sys/netinet6/in6_proto.c
index cf62e60c..a16818ce 100644
--- a/freebsd/sys/netinet6/in6_proto.c
+++ b/freebsd/sys/netinet6/in6_proto.c
@@ -386,10 +386,6 @@ VNET_DEFINE(int, ip6_accept_rtadv) = 0;
VNET_DEFINE(int, ip6_no_radr) = 0;
VNET_DEFINE(int, ip6_norbit_raif) = 0;
VNET_DEFINE(int, ip6_rfc6204w3) = 0;
-VNET_DEFINE(int, ip6_maxfragpackets); /* initialized in frag6.c:frag6_init() */
-int ip6_maxfrags; /* initialized in frag6.c:frag6_init() */
-VNET_DEFINE(int, ip6_maxfragbucketsize);/* initialized in frag6.c:frag6_init() */
-VNET_DEFINE(int, ip6_maxfragsperpacket); /* initialized in frag6.c:frag6_init() */
VNET_DEFINE(int, ip6_log_interval) = 5;
VNET_DEFINE(int, ip6_hdrnestlimit) = 15;/* How many header options will we
* process? */
@@ -476,20 +472,6 @@ sysctl_ip6_tempvltime(SYSCTL_HANDLER_ARGS)
return (0);
}
-static int
-sysctl_ip6_maxfragpackets(SYSCTL_HANDLER_ARGS)
-{
- int error, val;
-
- val = V_ip6_maxfragpackets;
- error = sysctl_handle_int(oidp, &val, 0, req);
- if (error != 0 || !req->newptr)
- return (error);
- V_ip6_maxfragpackets = val;
- frag6_set_bucketsize();
- return (0);
-}
-
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_FORWARDING, forwarding,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_forwarding), 0,
"Enable forwarding of IPv6 packets between interfaces");
@@ -502,12 +484,6 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFHLIM, hlim,
SYSCTL_VNET_PCPUSTAT(_net_inet6_ip6, IPV6CTL_STATS, stats, struct ip6stat,
ip6stat,
"IP6 statistics (struct ip6stat, netinet6/ip6_var.h)");
-SYSCTL_PROC(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS, maxfragpackets,
- CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
- sysctl_ip6_maxfragpackets, "I",
- "Default maximum number of outstanding fragmented IPv6 packets. "
- "A value of 0 means no fragmented packets will be accepted, while a "
- "a value of -1 means no limit");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_ACCEPT_RTADV, accept_rtadv,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_accept_rtadv), 0,
"Default value of per-interface flag for accepting ICMPv6 RA messages");
@@ -577,17 +553,6 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_PREFER_TEMPADDR, prefer_tempaddr,
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_USE_DEFAULTZONE, use_defaultzone,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_use_defzone), 0,
"Use the default scope zone when none is specified");
-SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGS, maxfrags,
- CTLFLAG_RW, &ip6_maxfrags, 0,
- "Maximum allowed number of outstanding IPv6 packet fragments. "
- "A value of 0 means no fragmented packets will be accepted, while a "
- "a value of -1 means no limit");
-SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGBUCKETSIZE, maxfragbucketsize,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_maxfragbucketsize), 0,
- "Maximum number of reassembly queues per hash bucket");
-SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGSPERPACKET, maxfragsperpacket,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_maxfragsperpacket), 0,
- "Maximum allowed number of fragments per packet");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MCAST_PMTU, mcast_pmtu,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_mcast_pmtu), 0,
"Enable path MTU discovery for multicast packets");
diff --git a/freebsd/sys/netinet6/in6_src.c b/freebsd/sys/netinet6/in6_src.c
index 170eaf18..0bd8bba4 100644
--- a/freebsd/sys/netinet6/in6_src.c
+++ b/freebsd/sys/netinet6/in6_src.c
@@ -933,21 +933,21 @@ in6_selectroute_fib(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
* 3. The system default hoplimit.
*/
int
-in6_selecthlim(struct inpcb *in6p, struct ifnet *ifp)
+in6_selecthlim(struct inpcb *inp, struct ifnet *ifp)
{
- if (in6p && in6p->in6p_hops >= 0)
- return (in6p->in6p_hops);
+ if (inp && inp->in6p_hops >= 0)
+ return (inp->in6p_hops);
else if (ifp)
return (ND_IFINFO(ifp)->chlim);
- else if (in6p && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
+ else if (inp && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
struct nhop6_basic nh6;
struct in6_addr dst;
uint32_t fibnum, scopeid;
int hlim;
- fibnum = in6p->inp_inc.inc_fibnum;
- in6_splitscope(&in6p->in6p_faddr, &dst, &scopeid);
+ fibnum = inp->inp_inc.inc_fibnum;
+ in6_splitscope(&inp->in6p_faddr, &dst, &scopeid);
if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6)==0){
hlim = ND_IFINFO(nh6.nh_ifp)->chlim;
return (hlim);
diff --git a/freebsd/sys/netinet6/ip6_forward.c b/freebsd/sys/netinet6/ip6_forward.c
index 80535efe..97a7a6c6 100644
--- a/freebsd/sys/netinet6/ip6_forward.c
+++ b/freebsd/sys/netinet6/ip6_forward.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_inet6.h>
#include <rtems/bsd/local/opt_ipsec.h>
#include <rtems/bsd/local/opt_ipstealth.h>
+#include <rtems/bsd/local/opt_sctp.h>
#include <sys/param.h>
#include <sys/systm.h>
diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c
index 25ab624c..6800d002 100644
--- a/freebsd/sys/netinet6/ip6_input.c
+++ b/freebsd/sys/netinet6/ip6_input.c
@@ -205,9 +205,6 @@ struct rmlock in6_ifaddr_lock;
RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock");
static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
-#ifdef PULLDOWN_TEST
-static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
-#endif
/*
* IP6 initialization: fill in IP6 protocol switch table.
@@ -396,6 +393,7 @@ ip6_destroy(void *unused __unused)
}
IFNET_RUNLOCK();
+ frag6_destroy();
nd6_destroy();
in6_ifattach_destroy();
@@ -406,20 +404,22 @@ VNET_SYSUNINIT(inet6, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_destroy, NULL);
#endif
static int
-ip6_input_hbh(struct mbuf *m, uint32_t *plen, uint32_t *rtalert, int *off,
+ip6_input_hbh(struct mbuf **mp, uint32_t *plen, uint32_t *rtalert, int *off,
int *nxt, int *ours)
{
+ struct mbuf *m;
struct ip6_hdr *ip6;
struct ip6_hbh *hbh;
- if (ip6_hopopts_input(plen, rtalert, &m, off)) {
+ if (ip6_hopopts_input(plen, rtalert, mp, off)) {
#if 0 /*touches NULL pointer*/
- in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
+ in6_ifstat_inc((*mp)->m_pkthdr.rcvif, ifs6_in_discard);
#endif
goto out; /* m have already been freed */
}
/* adjust pointer */
+ m = *mp;
ip6 = mtod(m, struct ip6_hdr *);
/*
@@ -441,17 +441,8 @@ ip6_input_hbh(struct mbuf *m, uint32_t *plen, uint32_t *rtalert, int *off,
(caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
goto out;
}
-#ifndef PULLDOWN_TEST
/* ip6_hopopts_input() ensures that mbuf is contiguous */
hbh = (struct ip6_hbh *)(ip6 + 1);
-#else
- IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
- sizeof(struct ip6_hbh));
- if (hbh == NULL) {
- IP6STAT_INC(ip6s_tooshort);
- goto out;
- }
-#endif
*nxt = hbh->ip6h_nxt;
/*
@@ -602,7 +593,6 @@ ip6_input(struct mbuf *m)
in6_ifstat_inc(rcvif, ifs6_in_receive);
IP6STAT_INC(ip6s_total);
-#ifndef PULLDOWN_TEST
/*
* L2 bridge code and some other code can return mbuf chain
* that does not conform to KAME requirement. too bad.
@@ -624,9 +614,6 @@ ip6_input(struct mbuf *m)
m_freem(m);
m = n;
}
- IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), /* nothing */);
-#endif
-
if (m->m_len < sizeof(struct ip6_hdr)) {
if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
IP6STAT_INC(ip6s_toosmall);
@@ -693,11 +680,10 @@ ip6_input(struct mbuf *m)
* and bypass security checks (act as if it was from 127.0.0.1 by using
* IPv6 src ::ffff:127.0.0.1). Be cautious.
*
- * This check chokes if we are in an SIIT cloud. As none of BSDs
- * support IPv4-less kernel compilation, we cannot support SIIT
- * environment at all. So, it makes more sense for us to reject any
- * malicious packets for non-SIIT environment, than try to do a
- * partial support for SIIT environment.
+ * We have supported IPv6-only kernels for a few years and this issue
+ * has not come up. The world seems to move mostly towards not using
+ * v4mapped on the wire, so it makes sense for us to keep rejecting
+ * any such packets.
*/
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
@@ -859,7 +845,7 @@ passin:
*/
plen = (u_int32_t)ntohs(ip6->ip6_plen);
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
- if (ip6_input_hbh(m, &plen, &rtalert, &off, &nxt, &ours) != 0)
+ if (ip6_input_hbh(&m, &plen, &rtalert, &off, &nxt, &ours) != 0)
return;
} else
nxt = ip6->ip6_nxt;
@@ -915,24 +901,6 @@ passin:
return;
}
- ip6 = mtod(m, struct ip6_hdr *);
-
- /*
- * Malicious party may be able to use IPv4 mapped addr to confuse
- * tcp/udp stack and bypass security checks (act as if it was from
- * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1). Be cautious.
- *
- * For SIIT end node behavior, you may want to disable the check.
- * However, you will become vulnerable to attacks using IPv4 mapped
- * source.
- */
- if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
- IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
- IP6STAT_INC(ip6s_badscope);
- in6_ifstat_inc(rcvif, ifs6_in_addrerr);
- goto bad;
- }
-
/*
* Tell launch routine the next header
*/
@@ -987,33 +955,33 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
struct ip6_hbh *hbh;
/* validation of the length of the header */
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1);
+ if (m->m_len < off + sizeof(*hbh)) {
+ m = m_pullup(m, off + sizeof(*hbh));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (-1);
+ }
+ }
hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
hbhlen = (hbh->ip6h_len + 1) << 3;
- IP6_EXTHDR_CHECK(m, off, hbhlen, -1);
- hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
-#else
- IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,
- sizeof(struct ip6_hdr), sizeof(struct ip6_hbh));
- if (hbh == NULL) {
- IP6STAT_INC(ip6s_tooshort);
- return -1;
- }
- hbhlen = (hbh->ip6h_len + 1) << 3;
- IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
- hbhlen);
- if (hbh == NULL) {
- IP6STAT_INC(ip6s_tooshort);
- return -1;
+ if (m->m_len < off + hbhlen) {
+ m = m_pullup(m, off + hbhlen);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (-1);
+ }
}
-#endif
+ hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
off += hbhlen;
hbhlen -= sizeof(struct ip6_hbh);
if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
- hbhlen, rtalertp, plenp) < 0)
+ hbhlen, rtalertp, plenp) < 0) {
+ *mp = NULL;
return (-1);
+ }
*offp = off;
*mp = m;
@@ -1198,10 +1166,9 @@ ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off)
* Create the "control" list for this pcb.
* These functions will not modify mbuf chain at all.
*
- * With KAME mbuf chain restriction:
* The routine will be called from upper layer handlers like tcp6_input().
* Thus the routine assumes that the caller (tcp6_input) have already
- * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
+ * called m_pullup() and all the extension headers are located in the
* very first mbuf on the mbuf chain.
*
* ip6_savecontrol_v4 will handle those options that are possible to be
@@ -1409,15 +1376,16 @@ ip6_savecontrol_v4(struct inpcb *inp, struct mbuf *m, struct mbuf **mp,
}
void
-ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
+ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
{
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ struct ip6_hdr *ip6;
int v4only = 0;
- mp = ip6_savecontrol_v4(in6p, m, mp, &v4only);
+ mp = ip6_savecontrol_v4(inp, m, mp, &v4only);
if (v4only)
return;
+ ip6 = mtod(m, struct ip6_hdr *);
/*
* IPV6_HOPOPTS socket option. Recall that we required super-user
* privilege for the option (see ip6_ctloutput), but it might be too
@@ -1425,7 +1393,7 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
* returned to normal user.
* See also RFC 2292 section 6 (or RFC 3542 section 8).
*/
- if ((in6p->inp_flags & IN6P_HOPOPTS) != 0) {
+ if ((inp->inp_flags & IN6P_HOPOPTS) != 0) {
/*
* Check if a hop-by-hop options header is contatined in the
* received packet, and if so, store the options as ancillary
@@ -1435,29 +1403,10 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
*/
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
struct ip6_hbh *hbh;
- int hbhlen = 0;
-#ifdef PULLDOWN_TEST
- struct mbuf *ext;
-#endif
+ int hbhlen;
-#ifndef PULLDOWN_TEST
hbh = (struct ip6_hbh *)(ip6 + 1);
hbhlen = (hbh->ip6h_len + 1) << 3;
-#else
- ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
- ip6->ip6_nxt);
- if (ext == NULL) {
- IP6STAT_INC(ip6s_tooshort);
- return;
- }
- hbh = mtod(ext, struct ip6_hbh *);
- hbhlen = (hbh->ip6h_len + 1) << 3;
- if (hbhlen != ext->m_len) {
- m_freem(ext);
- IP6STAT_INC(ip6s_tooshort);
- return;
- }
-#endif
/*
* XXX: We copy the whole header even if a
@@ -1467,17 +1416,14 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
* Note: this constraint is removed in RFC3542
*/
*mp = sbcreatecontrol((caddr_t)hbh, hbhlen,
- IS2292(in6p, IPV6_2292HOPOPTS, IPV6_HOPOPTS),
+ IS2292(inp, IPV6_2292HOPOPTS, IPV6_HOPOPTS),
IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
-#ifdef PULLDOWN_TEST
- m_freem(ext);
-#endif
}
}
- if ((in6p->inp_flags & (IN6P_RTHDR | IN6P_DSTOPTS)) != 0) {
+ if ((inp->inp_flags & (IN6P_RTHDR | IN6P_DSTOPTS)) != 0) {
int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr);
/*
@@ -1490,9 +1436,6 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
while (1) { /* is explicit loop prevention necessary? */
struct ip6_ext *ip6e = NULL;
int elen;
-#ifdef PULLDOWN_TEST
- struct mbuf *ext = NULL;
-#endif
/*
* if it is not an extension header, don't try to
@@ -1508,7 +1451,6 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
goto loopend;
}
-#ifndef PULLDOWN_TEST
if (off + sizeof(*ip6e) > m->m_len)
goto loopend;
ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + off);
@@ -1518,42 +1460,25 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
elen = (ip6e->ip6e_len + 1) << 3;
if (off + elen > m->m_len)
goto loopend;
-#else
- ext = ip6_pullexthdr(m, off, nxt);
- if (ext == NULL) {
- IP6STAT_INC(ip6s_tooshort);
- return;
- }
- ip6e = mtod(ext, struct ip6_ext *);
- if (nxt == IPPROTO_AH)
- elen = (ip6e->ip6e_len + 2) << 2;
- else
- elen = (ip6e->ip6e_len + 1) << 3;
- if (elen != ext->m_len) {
- m_freem(ext);
- IP6STAT_INC(ip6s_tooshort);
- return;
- }
-#endif
switch (nxt) {
case IPPROTO_DSTOPTS:
- if (!(in6p->inp_flags & IN6P_DSTOPTS))
+ if (!(inp->inp_flags & IN6P_DSTOPTS))
break;
*mp = sbcreatecontrol((caddr_t)ip6e, elen,
- IS2292(in6p,
+ IS2292(inp,
IPV6_2292DSTOPTS, IPV6_DSTOPTS),
IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
break;
case IPPROTO_ROUTING:
- if (!(in6p->inp_flags & IN6P_RTHDR))
+ if (!(inp->inp_flags & IN6P_RTHDR))
break;
*mp = sbcreatecontrol((caddr_t)ip6e, elen,
- IS2292(in6p, IPV6_2292RTHDR, IPV6_RTHDR),
+ IS2292(inp, IPV6_2292RTHDR, IPV6_RTHDR),
IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
@@ -1569,9 +1494,6 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
* the code just in case (nxt overwritten or
* other cases).
*/
-#ifdef PULLDOWN_TEST
- m_freem(ext);
-#endif
goto loopend;
}
@@ -1580,16 +1502,12 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
off += elen;
nxt = ip6e->ip6e_nxt;
ip6e = NULL;
-#ifdef PULLDOWN_TEST
- m_freem(ext);
- ext = NULL;
-#endif
}
loopend:
;
}
- if (in6p->inp_flags2 & INP_RECVFLOWID) {
+ if (inp->inp_flags2 & INP_RECVFLOWID) {
uint32_t flowid, flow_type;
flowid = m->m_pkthdr.flowid;
@@ -1610,7 +1528,7 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
}
#ifdef RSS
- if (in6p->inp_flags2 & INP_RECVRSSBUCKETID) {
+ if (inp->inp_flags2 & INP_RECVRSSBUCKETID) {
uint32_t flowid, flow_type;
uint32_t rss_bucketid;
@@ -1669,49 +1587,6 @@ ip6_notify_pmtu(struct inpcb *inp, struct sockaddr_in6 *dst, u_int32_t mtu)
sorwakeup(so);
}
-#ifdef PULLDOWN_TEST
-/*
- * pull single extension header from mbuf chain. returns single mbuf that
- * contains the result, or NULL on error.
- */
-static struct mbuf *
-ip6_pullexthdr(struct mbuf *m, size_t off, int nxt)
-{
- struct ip6_ext ip6e;
- size_t elen;
- struct mbuf *n;
-
-#ifdef DIAGNOSTIC
- switch (nxt) {
- case IPPROTO_DSTOPTS:
- case IPPROTO_ROUTING:
- case IPPROTO_HOPOPTS:
- case IPPROTO_AH: /* is it possible? */
- break;
- default:
- printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);
- }
-#endif
-
- m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
- if (nxt == IPPROTO_AH)
- elen = (ip6e.ip6e_len + 2) << 2;
- else
- elen = (ip6e.ip6e_len + 1) << 3;
-
- if (elen > MLEN)
- n = m_getcl(M_NOWAIT, MT_DATA, 0);
- else
- n = m_get(M_NOWAIT, MT_DATA);
- if (n == NULL)
- return NULL;
-
- m_copydata(m, off, elen, mtod(n, caddr_t));
- n->m_len = elen;
- return n;
-}
-#endif
-
/*
* Get pointer to the previous header followed by the header
* currently processed.
diff --git a/freebsd/sys/netinet6/ip6_mroute.c b/freebsd/sys/netinet6/ip6_mroute.c
index 9dee53b0..437d6da7 100644
--- a/freebsd/sys/netinet6/ip6_mroute.c
+++ b/freebsd/sys/netinet6/ip6_mroute.c
@@ -1722,12 +1722,10 @@ pim6_input(struct mbuf *m, int off, int proto, void *arg __unused)
PIM6STAT_INC(pim6s_rcv_total);
- ip6 = mtod(m, struct ip6_hdr *);
- pimlen = m->m_pkthdr.len - off;
-
/*
* Validate lengths
*/
+ pimlen = m->m_pkthdr.len - off;
if (pimlen < PIM_MINLEN) {
PIM6STAT_INC(pim6s_rcv_tooshort);
MRT6_DLOG(DEBUG_PIM, "PIM packet too short");
@@ -1749,20 +1747,15 @@ pim6_input(struct mbuf *m, int off, int proto, void *arg __unused)
* Make sure that the IP6 and PIM headers in contiguous memory, and
* possibly the PIM REGISTER header
*/
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, minlen, IPPROTO_DONE);
- /* adjust pointer */
+ if (m->m_len < off + minlen) {
+ m = m_pullup(m, off + minlen);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return (IPPROTO_DONE);
+ }
+ }
ip6 = mtod(m, struct ip6_hdr *);
-
- /* adjust mbuf to point to the PIM header */
pim = (struct pim *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(pim, struct pim *, m, off, minlen);
- if (pim == NULL) {
- PIM6STAT_INC(pim6s_rcv_tooshort);
- return (IPPROTO_DONE);
- }
-#endif
#define PIM6_CHECKSUM
#ifdef PIM6_CHECKSUM
diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c
index e941ac49..73312ca6 100644
--- a/freebsd/sys/netinet6/ip6_output.c
+++ b/freebsd/sys/netinet6/ip6_output.c
@@ -968,6 +968,7 @@ passout:
in_pcboutput_txrtlmt(inp, ifp, m);
/* stamp send tag on mbuf */
m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+ m->m_pkthdr.csum_flags |= CSUM_SND_TAG;
} else {
m->m_pkthdr.snd_tag = NULL;
}
@@ -1083,6 +1084,7 @@ sendorfree:
in_pcboutput_txrtlmt(inp, ifp, m);
/* stamp send tag on mbuf */
m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+ m->m_pkthdr.csum_flags |= CSUM_SND_TAG;
} else {
m->m_pkthdr.snd_tag = NULL;
}
@@ -1421,7 +1423,7 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
{
int optdatalen, uproto;
void *optdata;
- struct inpcb *in6p = sotoinpcb(so);
+ struct inpcb *inp = sotoinpcb(so);
int error, optval;
int level, op, optname;
int optlen;
@@ -1456,43 +1458,43 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
sopt->sopt_dir == SOPT_SET) {
switch (sopt->sopt_name) {
case SO_REUSEADDR:
- INP_WLOCK(in6p);
+ INP_WLOCK(inp);
if ((so->so_options & SO_REUSEADDR) != 0)
- in6p->inp_flags2 |= INP_REUSEADDR;
+ inp->inp_flags2 |= INP_REUSEADDR;
else
- in6p->inp_flags2 &= ~INP_REUSEADDR;
- INP_WUNLOCK(in6p);
+ inp->inp_flags2 &= ~INP_REUSEADDR;
+ INP_WUNLOCK(inp);
error = 0;
break;
case SO_REUSEPORT:
- INP_WLOCK(in6p);
+ INP_WLOCK(inp);
if ((so->so_options & SO_REUSEPORT) != 0)
- in6p->inp_flags2 |= INP_REUSEPORT;
+ inp->inp_flags2 |= INP_REUSEPORT;
else
- in6p->inp_flags2 &= ~INP_REUSEPORT;
- INP_WUNLOCK(in6p);
+ inp->inp_flags2 &= ~INP_REUSEPORT;
+ INP_WUNLOCK(inp);
error = 0;
break;
case SO_REUSEPORT_LB:
- INP_WLOCK(in6p);
+ INP_WLOCK(inp);
if ((so->so_options & SO_REUSEPORT_LB) != 0)
- in6p->inp_flags2 |= INP_REUSEPORT_LB;
+ inp->inp_flags2 |= INP_REUSEPORT_LB;
else
- in6p->inp_flags2 &= ~INP_REUSEPORT_LB;
- INP_WUNLOCK(in6p);
+ inp->inp_flags2 &= ~INP_REUSEPORT_LB;
+ INP_WUNLOCK(inp);
error = 0;
break;
case SO_SETFIB:
- INP_WLOCK(in6p);
- in6p->inp_inc.inc_fibnum = so->so_fibnum;
- INP_WUNLOCK(in6p);
+ INP_WLOCK(inp);
+ inp->inp_inc.inc_fibnum = so->so_fibnum;
+ INP_WUNLOCK(inp);
error = 0;
break;
case SO_MAX_PACING_RATE:
#ifdef RATELIMIT
- INP_WLOCK(in6p);
- in6p->inp_flags2 |= INP_RATE_LIMIT_CHANGED;
- INP_WUNLOCK(in6p);
+ INP_WLOCK(inp);
+ inp->inp_flags2 |= INP_RATE_LIMIT_CHANGED;
+ INP_WUNLOCK(inp);
error = 0;
#else
error = EOPNOTSUPP;
@@ -1526,7 +1528,7 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
error = soopt_mcopyin(sopt, m); /* XXX */
if (error != 0)
break;
- error = ip6_pcbopts(&in6p->in6p_outputopts,
+ error = ip6_pcbopts(&inp->in6p_outputopts,
m, so, sopt);
m_freem(m); /* XXX */
break;
@@ -1597,57 +1599,57 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
error = EINVAL;
else {
/* -1 = kernel default */
- in6p->in6p_hops = optval;
- if ((in6p->inp_vflag &
+ inp->in6p_hops = optval;
+ if ((inp->inp_vflag &
INP_IPV4) != 0)
- in6p->inp_ip_ttl = optval;
+ inp->inp_ip_ttl = optval;
}
break;
#define OPTSET(bit) \
do { \
- INP_WLOCK(in6p); \
+ INP_WLOCK(inp); \
if (optval) \
- in6p->inp_flags |= (bit); \
+ inp->inp_flags |= (bit); \
else \
- in6p->inp_flags &= ~(bit); \
- INP_WUNLOCK(in6p); \
+ inp->inp_flags &= ~(bit); \
+ INP_WUNLOCK(inp); \
} while (/*CONSTCOND*/ 0)
#define OPTSET2292(bit) \
do { \
- INP_WLOCK(in6p); \
- in6p->inp_flags |= IN6P_RFC2292; \
+ INP_WLOCK(inp); \
+ inp->inp_flags |= IN6P_RFC2292; \
if (optval) \
- in6p->inp_flags |= (bit); \
+ inp->inp_flags |= (bit); \
else \
- in6p->inp_flags &= ~(bit); \
- INP_WUNLOCK(in6p); \
+ inp->inp_flags &= ~(bit); \
+ INP_WUNLOCK(inp); \
} while (/*CONSTCOND*/ 0)
-#define OPTBIT(bit) (in6p->inp_flags & (bit) ? 1 : 0)
+#define OPTBIT(bit) (inp->inp_flags & (bit) ? 1 : 0)
#define OPTSET2_N(bit, val) do { \
if (val) \
- in6p->inp_flags2 |= bit; \
+ inp->inp_flags2 |= bit; \
else \
- in6p->inp_flags2 &= ~bit; \
+ inp->inp_flags2 &= ~bit; \
} while (0)
#define OPTSET2(bit, val) do { \
- INP_WLOCK(in6p); \
+ INP_WLOCK(inp); \
OPTSET2_N(bit, val); \
- INP_WUNLOCK(in6p); \
+ INP_WUNLOCK(inp); \
} while (0)
-#define OPTBIT2(bit) (in6p->inp_flags2 & (bit) ? 1 : 0)
+#define OPTBIT2(bit) (inp->inp_flags2 & (bit) ? 1 : 0)
#define OPTSET2292_EXCLUSIVE(bit) \
do { \
- INP_WLOCK(in6p); \
+ INP_WLOCK(inp); \
if (OPTBIT(IN6P_RFC2292)) { \
error = EINVAL; \
} else { \
if (optval) \
- in6p->inp_flags |= (bit); \
+ inp->inp_flags |= (bit); \
else \
- in6p->inp_flags &= ~(bit); \
+ inp->inp_flags &= ~(bit); \
} \
- INP_WUNLOCK(in6p); \
+ INP_WUNLOCK(inp); \
} while (/*CONSTCOND*/ 0)
case IPV6_RECVPKTINFO:
@@ -1663,17 +1665,17 @@ do { \
error = EINVAL;
break;
}
- INP_WLOCK(in6p);
- if (in6p->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
- INP_WUNLOCK(in6p);
+ INP_WLOCK(inp);
+ if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
+ INP_WUNLOCK(inp);
return (ECONNRESET);
}
- optp = &in6p->in6p_outputopts;
+ optp = &inp->in6p_outputopts;
error = ip6_pcbopt(IPV6_HOPLIMIT,
(u_char *)&optval, sizeof(optval),
optp, (td != NULL) ? td->td_ucred :
NULL, uproto);
- INP_WUNLOCK(in6p);
+ INP_WUNLOCK(inp);
break;
}
@@ -1724,16 +1726,16 @@ do { \
* available only prior to bind(2).
* see ipng mailing list, Jun 22 2001.
*/
- if (in6p->inp_lport ||
- !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
+ if (inp->inp_lport ||
+ !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
error = EINVAL;
break;
}
OPTSET(IN6P_IPV6_V6ONLY);
if (optval)
- in6p->inp_vflag &= ~INP_IPV4;
+ inp->inp_vflag &= ~INP_IPV4;
else
- in6p->inp_vflag |= INP_IPV4;
+ inp->inp_vflag |= INP_IPV4;
break;
case IPV6_RECVTCLASS:
/* cannot mix with RFC2292 XXX */
@@ -1757,10 +1759,10 @@ do { \
case IPV6_RSS_LISTEN_BUCKET:
if ((optval >= 0) &&
(optval < rss_getnumbuckets())) {
- INP_WLOCK(in6p);
- in6p->inp_rss_listen_bucket = optval;
+ INP_WLOCK(inp);
+ inp->inp_rss_listen_bucket = optval;
OPTSET2_N(INP_RSS_BUCKET_SET, 1);
- INP_WUNLOCK(in6p);
+ INP_WUNLOCK(inp);
} else {
error = EINVAL;
}
@@ -1783,17 +1785,17 @@ do { \
break;
{
struct ip6_pktopts **optp;
- INP_WLOCK(in6p);
- if (in6p->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
- INP_WUNLOCK(in6p);
+ INP_WLOCK(inp);
+ if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
+ INP_WUNLOCK(inp);
return (ECONNRESET);
}
- optp = &in6p->in6p_outputopts;
+ optp = &inp->in6p_outputopts;
error = ip6_pcbopt(optname,
(u_char *)&optval, sizeof(optval),
optp, (td != NULL) ? td->td_ucred :
NULL, uproto);
- INP_WUNLOCK(in6p);
+ INP_WUNLOCK(inp);
break;
}
@@ -1875,16 +1877,16 @@ do { \
break;
optlen = sopt->sopt_valsize;
optbuf = optbuf_storage;
- INP_WLOCK(in6p);
- if (in6p->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
- INP_WUNLOCK(in6p);
+ INP_WLOCK(inp);
+ if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
+ INP_WUNLOCK(inp);
return (ECONNRESET);
}
- optp = &in6p->in6p_outputopts;
+ optp = &inp->in6p_outputopts;
error = ip6_pcbopt(optname, optbuf, optlen,
optp, (td != NULL) ? td->td_ucred : NULL,
uproto);
- INP_WUNLOCK(in6p);
+ INP_WUNLOCK(inp);
break;
}
#undef OPTSET
@@ -1901,7 +1903,7 @@ do { \
case MCAST_LEAVE_GROUP:
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
- error = ip6_setmoptions(in6p, sopt);
+ error = ip6_setmoptions(inp, sopt);
break;
case IPV6_PORTRANGE:
@@ -1910,34 +1912,34 @@ do { \
if (error)
break;
- INP_WLOCK(in6p);
+ INP_WLOCK(inp);
switch (optval) {
case IPV6_PORTRANGE_DEFAULT:
- in6p->inp_flags &= ~(INP_LOWPORT);
- in6p->inp_flags &= ~(INP_HIGHPORT);
+ inp->inp_flags &= ~(INP_LOWPORT);
+ inp->inp_flags &= ~(INP_HIGHPORT);
break;
case IPV6_PORTRANGE_HIGH:
- in6p->inp_flags &= ~(INP_LOWPORT);
- in6p->inp_flags |= INP_HIGHPORT;
+ inp->inp_flags &= ~(INP_LOWPORT);
+ inp->inp_flags |= INP_HIGHPORT;
break;
case IPV6_PORTRANGE_LOW:
- in6p->inp_flags &= ~(INP_HIGHPORT);
- in6p->inp_flags |= INP_LOWPORT;
+ inp->inp_flags &= ~(INP_HIGHPORT);
+ inp->inp_flags |= INP_LOWPORT;
break;
default:
error = EINVAL;
break;
}
- INP_WUNLOCK(in6p);
+ INP_WUNLOCK(inp);
break;
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IPV6_IPSEC_POLICY:
if (IPSEC_ENABLED(ipv6)) {
- error = IPSEC_PCBCTL(ipv6, in6p, sopt);
+ error = IPSEC_PCBCTL(ipv6, inp, sopt);
break;
}
/* FALLTHROUGH */
@@ -2005,7 +2007,7 @@ do { \
break;
case IPV6_UNICAST_HOPS:
- optval = in6p->in6p_hops;
+ optval = inp->in6p_hops;
break;
case IPV6_RECVPKTINFO:
@@ -2031,7 +2033,7 @@ do { \
case IPV6_PORTRANGE:
{
int flags;
- flags = in6p->inp_flags;
+ flags = inp->inp_flags;
if (flags & INP_HIGHPORT)
optval = IPV6_PORTRANGE_HIGH;
else if (flags & INP_LOWPORT)
@@ -2057,11 +2059,11 @@ do { \
break;
case IPV6_FLOWID:
- optval = in6p->inp_flowid;
+ optval = inp->inp_flowid;
break;
case IPV6_FLOWTYPE:
- optval = in6p->inp_flowtype;
+ optval = inp->inp_flowtype;
break;
case IPV6_RECVFLOWID:
@@ -2070,8 +2072,8 @@ do { \
#ifdef RSS
case IPV6_RSSBUCKETID:
retval =
- rss_hash2bucket(in6p->inp_flowid,
- in6p->inp_flowtype,
+ rss_hash2bucket(inp->inp_flowid,
+ inp->inp_flowtype,
&rss_bucket);
if (retval == 0)
optval = rss_bucket;
@@ -2107,12 +2109,12 @@ do { \
* XXX: we dot not consider the case of source
* routing, or optional information to specify
* the outgoing interface.
- * Copy faddr out of in6p to avoid holding lock
+ * Copy faddr out of inp to avoid holding lock
* on inp during route lookup.
*/
- INP_RLOCK(in6p);
- bcopy(&in6p->in6p_faddr, &addr, sizeof(addr));
- INP_RUNLOCK(in6p);
+ INP_RLOCK(inp);
+ bcopy(&inp->in6p_faddr, &addr, sizeof(addr));
+ INP_RUNLOCK(inp);
error = ip6_getpmtu_ctl(so->so_fibnum,
&addr, &pmtu);
if (error)
@@ -2164,20 +2166,20 @@ do { \
case IPV6_DONTFRAG:
case IPV6_USE_MIN_MTU:
case IPV6_PREFER_TEMPADDR:
- error = ip6_getpcbopt(in6p, optname, sopt);
+ error = ip6_getpcbopt(inp, optname, sopt);
break;
case IPV6_MULTICAST_IF:
case IPV6_MULTICAST_HOPS:
case IPV6_MULTICAST_LOOP:
case IPV6_MSFILTER:
- error = ip6_getmoptions(in6p, sopt);
+ error = ip6_getmoptions(inp, sopt);
break;
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IPV6_IPSEC_POLICY:
if (IPSEC_ENABLED(ipv6)) {
- error = IPSEC_PCBCTL(ipv6, in6p, sopt);
+ error = IPSEC_PCBCTL(ipv6, inp, sopt);
break;
}
/* FALLTHROUGH */
@@ -2197,7 +2199,7 @@ ip6_raw_ctloutput(struct socket *so, struct sockopt *sopt)
{
int error = 0, optval, optlen;
const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum);
- struct inpcb *in6p = sotoinpcb(so);
+ struct inpcb *inp = sotoinpcb(so);
int level, op, optname;
level = sopt->sopt_level;
@@ -2240,14 +2242,14 @@ ip6_raw_ctloutput(struct socket *so, struct sockopt *sopt)
if (optval != icmp6off)
error = EINVAL;
} else
- in6p->in6p_cksum = optval;
+ inp->in6p_cksum = optval;
break;
case SOPT_GET:
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)
optval = icmp6off;
else
- optval = in6p->in6p_cksum;
+ optval = inp->in6p_cksum;
error = sooptcopyout(sopt, &optval, sizeof(optval));
break;
@@ -2346,16 +2348,16 @@ ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt,
#define GET_PKTOPT_VAR(field, lenexpr) do { \
if (pktopt && pktopt->field) { \
- INP_RUNLOCK(in6p); \
+ INP_RUNLOCK(inp); \
optdata = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK); \
malloc_optdata = true; \
- INP_RLOCK(in6p); \
- if (in6p->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { \
- INP_RUNLOCK(in6p); \
+ INP_RLOCK(inp); \
+ if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { \
+ INP_RUNLOCK(inp); \
free(optdata, M_TEMP); \
return (ECONNRESET); \
} \
- pktopt = in6p->in6p_outputopts; \
+ pktopt = inp->in6p_outputopts; \
if (pktopt && pktopt->field) { \
optdatalen = min(lenexpr, sopt->sopt_valsize); \
bcopy(&pktopt->field, optdata, optdatalen); \
@@ -2374,7 +2376,7 @@ ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt,
pktopt->field->sa_len)
static int
-ip6_getpcbopt(struct inpcb *in6p, int optname, struct sockopt *sopt)
+ip6_getpcbopt(struct inpcb *inp, int optname, struct sockopt *sopt)
{
void *optdata = NULL;
bool malloc_optdata = false;
@@ -2386,8 +2388,8 @@ ip6_getpcbopt(struct inpcb *in6p, int optname, struct sockopt *sopt)
int defpreftemp = IP6PO_TEMPADDR_SYSTEM;
struct ip6_pktopts *pktopt;
- INP_RLOCK(in6p);
- pktopt = in6p->in6p_outputopts;
+ INP_RLOCK(inp);
+ pktopt = inp->in6p_outputopts;
switch (optname) {
case IPV6_PKTINFO:
@@ -2447,10 +2449,10 @@ ip6_getpcbopt(struct inpcb *in6p, int optname, struct sockopt *sopt)
#ifdef DIAGNOSTIC
panic("ip6_getpcbopt: unexpected option\n");
#endif
- INP_RUNLOCK(in6p);
+ INP_RUNLOCK(inp);
return (ENOPROTOOPT);
}
- INP_RUNLOCK(in6p);
+ INP_RUNLOCK(inp);
error = sooptcopyout(sopt, optdata, optdatalen);
if (malloc_optdata)
@@ -3135,23 +3137,23 @@ ip6_splithdr(struct mbuf *m, struct ip6_exthdrs *exthdrs)
* Compute IPv6 extension header length.
*/
int
-ip6_optlen(struct inpcb *in6p)
+ip6_optlen(struct inpcb *inp)
{
int len;
- if (!in6p->in6p_outputopts)
+ if (!inp->in6p_outputopts)
return 0;
len = 0;
#define elen(x) \
(((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)
- len += elen(in6p->in6p_outputopts->ip6po_hbh);
- if (in6p->in6p_outputopts->ip6po_rthdr)
+ len += elen(inp->in6p_outputopts->ip6po_hbh);
+ if (inp->in6p_outputopts->ip6po_rthdr)
/* dest1 is valid with rthdr only */
- len += elen(in6p->in6p_outputopts->ip6po_dest1);
- len += elen(in6p->in6p_outputopts->ip6po_rthdr);
- len += elen(in6p->in6p_outputopts->ip6po_dest2);
+ len += elen(inp->in6p_outputopts->ip6po_dest1);
+ len += elen(inp->in6p_outputopts->ip6po_rthdr);
+ len += elen(inp->in6p_outputopts->ip6po_dest2);
return len;
#undef elen
}
diff --git a/freebsd/sys/netinet6/ip6_var.h b/freebsd/sys/netinet6/ip6_var.h
index b66f5cfb..05881f08 100644
--- a/freebsd/sys/netinet6/ip6_var.h
+++ b/freebsd/sys/netinet6/ip6_var.h
@@ -68,39 +68,27 @@
#include <sys/epoch.h>
+#ifdef _KERNEL
+struct ip6asfrag; /* frag6.c */
+TAILQ_HEAD(ip6fraghead, ip6asfrag);
+
/*
* IP6 reassembly queue structure. Each fragment
* being reassembled is attached to one of these structures.
*/
struct ip6q {
- struct ip6asfrag *ip6q_down;
- struct ip6asfrag *ip6q_up;
+ struct ip6fraghead ip6q_frags;
u_int32_t ip6q_ident;
u_int8_t ip6q_nxt;
u_int8_t ip6q_ecn;
u_int8_t ip6q_ttl;
struct in6_addr ip6q_src, ip6q_dst;
- struct ip6q *ip6q_next;
- struct ip6q *ip6q_prev;
+ TAILQ_ENTRY(ip6q) ip6q_tq;
int ip6q_unfrglen; /* len of unfragmentable part */
-#ifdef notyet
- u_char *ip6q_nxtp;
-#endif
int ip6q_nfrag; /* # of fragments */
struct label *ip6q_label;
};
-
-struct ip6asfrag {
- struct ip6asfrag *ip6af_down;
- struct ip6asfrag *ip6af_up;
- struct mbuf *ip6af_m;
- int ip6af_offset; /* offset in ip6af_m to next header */
- int ip6af_frglen; /* fragmentable part length */
- int ip6af_off; /* fragment offset */
- u_int16_t ip6af_mff; /* more fragment bit in frag off */
-};
-
-#define IP6_REASS_MBUF(ip6af) (*(struct mbuf **)&((ip6af)->ip6af_m))
+#endif /* _KERNEL */
/*
* IP6 reinjecting structure.
@@ -207,6 +195,7 @@ struct ip6stat {
uint64_t ip6s_localout; /* total ip packets generated here */
uint64_t ip6s_odropped; /* lost packets due to nobufs, etc. */
uint64_t ip6s_reassembled; /* total packets reassembled ok */
+ uint64_t ip6s_atomicfrags; /* atomic fragments */
uint64_t ip6s_fragmented; /* datagrams successfully fragmented */
uint64_t ip6s_ofragments; /* output fragments created */
uint64_t ip6s_cantfrag; /* don't fragment flag was set, etc. */
@@ -298,12 +287,6 @@ VNET_DECLARE(int, ip6_v6only);
VNET_DECLARE(struct socket *, ip6_mrouter); /* multicast routing daemon */
VNET_DECLARE(int, ip6_sendredirects); /* send IP redirects when forwarding? */
-VNET_DECLARE(int, ip6_maxfragpackets); /* Maximum packets in reassembly
- * queue */
-extern int ip6_maxfrags; /* Maximum fragments in reassembly
- * queue */
-VNET_DECLARE(int, ip6_maxfragbucketsize); /* Maximum reassembly queues per bucket */
-VNET_DECLARE(int, ip6_maxfragsperpacket); /* Maximum fragments per packet */
VNET_DECLARE(int, ip6_accept_rtadv); /* Acts as a host not a router */
VNET_DECLARE(int, ip6_no_radr); /* No defroute from RA */
VNET_DECLARE(int, ip6_norbit_raif); /* Disable R-bit in NA on RA
@@ -317,9 +300,6 @@ VNET_DECLARE(int, ip6_hdrnestlimit); /* upper limit of # of extension
VNET_DECLARE(int, ip6_dad_count); /* DupAddrDetectionTransmits */
#define V_ip6_mrouter VNET(ip6_mrouter)
#define V_ip6_sendredirects VNET(ip6_sendredirects)
-#define V_ip6_maxfragpackets VNET(ip6_maxfragpackets)
-#define V_ip6_maxfragbucketsize VNET(ip6_maxfragbucketsize)
-#define V_ip6_maxfragsperpacket VNET(ip6_maxfragsperpacket)
#define V_ip6_accept_rtadv VNET(ip6_accept_rtadv)
#define V_ip6_no_radr VNET(ip6_no_radr)
#define V_ip6_norbit_raif VNET(ip6_norbit_raif)
@@ -406,8 +386,8 @@ int ip6_fragment(struct ifnet *, struct mbuf *, int, u_char, int,
int route6_input(struct mbuf **, int *, int);
-void frag6_set_bucketsize(void);
void frag6_init(void);
+void frag6_destroy(void);
int frag6_input(struct mbuf **, int *, int);
void frag6_slowtimo(void);
void frag6_drain(void);
diff --git a/freebsd/sys/netinet6/mld6.c b/freebsd/sys/netinet6/mld6.c
index a0d045d5..e7b400ae 100644
--- a/freebsd/sys/netinet6/mld6.c
+++ b/freebsd/sys/netinet6/mld6.c
@@ -1254,20 +1254,27 @@ out_locked:
* Return IPPROTO_DONE if we freed m. Otherwise, return 0.
*/
int
-mld_input(struct mbuf *m, int off, int icmp6len)
+mld_input(struct mbuf **mp, int off, int icmp6len)
{
struct ifnet *ifp;
struct ip6_hdr *ip6;
+ struct mbuf *m;
struct mld_hdr *mld;
int mldlen;
+ m = *mp;
CTR3(KTR_MLD, "%s: called w/mbuf (%p,%d)", __func__, m, off);
ifp = m->m_pkthdr.rcvif;
- ip6 = mtod(m, struct ip6_hdr *);
-
/* Pullup to appropriate size. */
+ if (m->m_len < off + sizeof(*mld)) {
+ m = m_pullup(m, off + sizeof(*mld));
+ if (m == NULL) {
+ ICMP6STAT_INC(icp6s_badlen);
+ return (IPPROTO_DONE);
+ }
+ }
mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off);
if (mld->mld_type == MLD_LISTENER_QUERY &&
icmp6len >= sizeof(struct mldv2_query)) {
@@ -1275,11 +1282,16 @@ mld_input(struct mbuf *m, int off, int icmp6len)
} else {
mldlen = sizeof(struct mld_hdr);
}
- IP6_EXTHDR_GET(mld, struct mld_hdr *, m, off, mldlen);
- if (mld == NULL) {
- ICMP6STAT_INC(icp6s_badlen);
- return (IPPROTO_DONE);
+ if (m->m_len < off + mldlen) {
+ m = m_pullup(m, off + mldlen);
+ if (m == NULL) {
+ ICMP6STAT_INC(icp6s_badlen);
+ return (IPPROTO_DONE);
+ }
}
+ *mp = m;
+ ip6 = mtod(m, struct ip6_hdr *);
+ mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off);
/*
* Userland needs to see all of this traffic for implementing
diff --git a/freebsd/sys/netinet6/mld6_var.h b/freebsd/sys/netinet6/mld6_var.h
index 8dc2ffa4..0aedde27 100644
--- a/freebsd/sys/netinet6/mld6_var.h
+++ b/freebsd/sys/netinet6/mld6_var.h
@@ -167,7 +167,7 @@ struct mld_ifsoftc *
void mld_domifdetach(struct ifnet *);
void mld_fasttimo(void);
void mld_ifdetach(struct ifnet *, struct in6_multi_head *);
-int mld_input(struct mbuf *, int, int);
+int mld_input(struct mbuf **, int, int);
void mld_slowtimo(void);
#ifdef SYSCTL_DECL
diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c
index 140dde59..aea8168e 100644
--- a/freebsd/sys/netinet6/nd6.c
+++ b/freebsd/sys/netinet6/nd6.c
@@ -117,7 +117,6 @@ VNET_DEFINE(int, nd6_debug) = 0;
static eventhandler_tag lle_event_eh, iflladdr_event_eh;
-VNET_DEFINE(struct nd_drhead, nd_defrouter);
VNET_DEFINE(struct nd_prhead, nd_prefix);
VNET_DEFINE(struct rwlock, nd6_lock);
VNET_DEFINE(uint64_t, nd6_list_genid);
@@ -147,9 +146,11 @@ static int nd6_need_cache(struct ifnet *);
VNET_DEFINE_STATIC(struct callout, nd6_slowtimo_ch);
#define V_nd6_slowtimo_ch VNET(nd6_slowtimo_ch)
-VNET_DEFINE(struct callout, nd6_timer_ch);
+VNET_DEFINE_STATIC(struct callout, nd6_timer_ch);
#define V_nd6_timer_ch VNET(nd6_timer_ch)
+SYSCTL_DECL(_net_inet6_icmp6);
+
static void
nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
{
@@ -219,7 +220,7 @@ nd6_init(void)
rw_init(&V_nd6_lock, "nd6 list");
LIST_INIT(&V_nd_prefix);
- TAILQ_INIT(&V_nd_defrouter);
+ nd6_defrouter_init();
/* Start timers. */
callout_init(&V_nd6_slowtimo_ch, 0);
@@ -894,27 +895,15 @@ void
nd6_timer(void *arg)
{
CURVNET_SET((struct vnet *) arg);
- struct nd_drhead drq;
struct nd_prhead prl;
- struct nd_defrouter *dr, *ndr;
struct nd_prefix *pr, *npr;
struct ifnet *ifp;
struct in6_ifaddr *ia6, *nia6;
uint64_t genid;
- TAILQ_INIT(&drq);
LIST_INIT(&prl);
- ND6_WLOCK();
- TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr)
- if (dr->expire && dr->expire < time_uptime)
- defrouter_unlink(dr, &drq);
- ND6_WUNLOCK();
-
- while ((dr = TAILQ_FIRST(&drq)) != NULL) {
- TAILQ_REMOVE(&drq, dr, dr_entry);
- defrouter_del(dr);
- }
+ nd6_defrouter_timer();
/*
* expire interface addresses.
@@ -1137,34 +1126,15 @@ regen_tmpaddr(struct in6_ifaddr *ia6)
void
nd6_purge(struct ifnet *ifp)
{
- struct nd_drhead drq;
struct nd_prhead prl;
- struct nd_defrouter *dr, *ndr;
struct nd_prefix *pr, *npr;
- TAILQ_INIT(&drq);
LIST_INIT(&prl);
- /*
- * Nuke default router list entries toward ifp.
- * We defer removal of default router list entries that is installed
- * in the routing table, in order to keep additional side effects as
- * small as possible.
- */
- ND6_WLOCK();
- TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) {
- if (dr->installed)
- continue;
- if (dr->ifp == ifp)
- defrouter_unlink(dr, &drq);
- }
- TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) {
- if (!dr->installed)
- continue;
- if (dr->ifp == ifp)
- defrouter_unlink(dr, &drq);
- }
+ /* Purge default router list entries toward ifp. */
+ nd6_defrouter_purge(ifp);
+ ND6_WLOCK();
/*
* Remove prefixes on ifp. We should have already removed addresses on
* this interface, so no addresses should be referencing these prefixes.
@@ -1175,11 +1145,7 @@ nd6_purge(struct ifnet *ifp)
}
ND6_WUNLOCK();
- /* Delete the unlinked router and prefix objects. */
- while ((dr = TAILQ_FIRST(&drq)) != NULL) {
- TAILQ_REMOVE(&drq, dr, dr_entry);
- defrouter_del(dr);
- }
+ /* Delete the unlinked prefix objects. */
while ((pr = LIST_FIRST(&prl)) != NULL) {
LIST_REMOVE(pr, ndpr_entry);
nd6_prefix_del(pr);
@@ -1365,7 +1331,7 @@ restart:
* as on-link, and thus, as a neighbor.
*/
if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV &&
- TAILQ_EMPTY(&V_nd_defrouter) &&
+ nd6_defrouter_list_empty() &&
V_nd6_defifindex == ifp->if_index) {
return (1);
}
@@ -1808,22 +1774,9 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
case SIOCSRTRFLUSH_IN6:
{
/* flush all the default routers */
- struct nd_drhead drq;
- struct nd_defrouter *dr;
-
- TAILQ_INIT(&drq);
defrouter_reset();
-
- ND6_WLOCK();
- while ((dr = TAILQ_FIRST(&V_nd_defrouter)) != NULL)
- defrouter_unlink(dr, &drq);
- ND6_WUNLOCK();
- while ((dr = TAILQ_FIRST(&drq)) != NULL) {
- TAILQ_REMOVE(&drq, dr, dr_entry);
- defrouter_del(dr);
- }
-
+ nd6_defrouter_flush_all();
defrouter_select();
break;
}
@@ -2367,13 +2320,7 @@ nd6_resolve_slow(struct ifnet *ifp, int flags, struct mbuf *m,
}
}
if (lle == NULL) {
- if (!(ND_IFINFO(ifp)->flags & ND6_IFF_PERFORMNUD)) {
- m_freem(m);
- return (ENOBUFS);
- }
-
- if (m != NULL)
- m_freem(m);
+ m_freem(m);
return (ENOBUFS);
}
@@ -2616,59 +2563,6 @@ clear_llinfo_pqueue(struct llentry *ln)
ln->la_hold = NULL;
}
-static int nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS);
-static int nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS);
-
-SYSCTL_DECL(_net_inet6_icmp6);
-SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
- CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
- NULL, 0, nd6_sysctl_drlist, "S,in6_defrouter",
- "NDP default router list");
-SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist,
- CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
- NULL, 0, nd6_sysctl_prlist, "S,in6_prefix",
- "NDP prefix list");
-SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXQLEN, nd6_maxqueuelen,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1, "");
-SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_gctimer,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24), "");
-
-static int
-nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS)
-{
- struct in6_defrouter d;
- struct nd_defrouter *dr;
- int error;
-
- if (req->newptr != NULL)
- return (EPERM);
-
- error = sysctl_wire_old_buffer(req, 0);
- if (error != 0)
- return (error);
-
- bzero(&d, sizeof(d));
- d.rtaddr.sin6_family = AF_INET6;
- d.rtaddr.sin6_len = sizeof(d.rtaddr);
-
- ND6_RLOCK();
- TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
- d.rtaddr.sin6_addr = dr->rtaddr;
- error = sa6_recoverscope(&d.rtaddr);
- if (error != 0)
- break;
- d.flags = dr->raflags;
- d.rtlifetime = dr->rtlifetime;
- d.expire = dr->expire + (time_second - time_uptime);
- d.if_index = dr->ifp->if_index;
- error = SYSCTL_OUT(req, &d, sizeof(d));
- if (error != 0)
- break;
- }
- ND6_RUNLOCK();
- return (error);
-}
-
static int
nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS)
{
@@ -2742,3 +2636,11 @@ out:
ND6_RUNLOCK();
return (error);
}
+SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist,
+ CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ NULL, 0, nd6_sysctl_prlist, "S,in6_prefix",
+ "NDP prefix list");
+SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXQLEN, nd6_maxqueuelen,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1, "");
+SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_gctimer,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24), "");
diff --git a/freebsd/sys/netinet6/nd6.h b/freebsd/sys/netinet6/nd6.h
index cabfeec0..71c99b1b 100644
--- a/freebsd/sys/netinet6/nd6.h
+++ b/freebsd/sys/netinet6/nd6.h
@@ -329,7 +329,6 @@ VNET_DECLARE(int, nd6_mmaxtries);
VNET_DECLARE(int, nd6_useloopback);
VNET_DECLARE(int, nd6_maxnudhint);
VNET_DECLARE(int, nd6_gctimer);
-VNET_DECLARE(struct nd_drhead, nd_defrouter);
VNET_DECLARE(struct nd_prhead, nd_prefix);
VNET_DECLARE(int, nd6_debug);
VNET_DECLARE(int, nd6_onlink_ns_rfc4861);
@@ -340,7 +339,6 @@ VNET_DECLARE(int, nd6_onlink_ns_rfc4861);
#define V_nd6_useloopback VNET(nd6_useloopback)
#define V_nd6_maxnudhint VNET(nd6_maxnudhint)
#define V_nd6_gctimer VNET(nd6_gctimer)
-#define V_nd_defrouter VNET(nd_defrouter)
#define V_nd_prefix VNET(nd_prefix)
#define V_nd6_debug VNET(nd6_debug)
#define V_nd6_onlink_ns_rfc4861 VNET(nd6_onlink_ns_rfc4861)
@@ -470,6 +468,8 @@ void nd6_dad_stop(struct ifaddr *);
/* nd6_rtr.c */
void nd6_rs_input(struct mbuf *, int, int);
void nd6_ra_input(struct mbuf *, int, int);
+struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *);
+struct nd_defrouter *defrouter_lookup_locked(struct in6_addr *, struct ifnet *);
void defrouter_reset(void);
void defrouter_select_fib(int fibnum);
void defrouter_select(void);
@@ -478,6 +478,11 @@ void defrouter_rele(struct nd_defrouter *);
bool defrouter_remove(struct in6_addr *, struct ifnet *);
void defrouter_unlink(struct nd_defrouter *, struct nd_drhead *);
void defrouter_del(struct nd_defrouter *);
+bool nd6_defrouter_list_empty(void);
+void nd6_defrouter_flush_all(void);
+void nd6_defrouter_purge(struct ifnet *);
+void nd6_defrouter_timer(void);
+void nd6_defrouter_init(void);
int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *,
struct nd_prefix **);
void nd6_prefix_unlink(struct nd_prefix *, struct nd_prhead *);
@@ -487,8 +492,6 @@ void nd6_prefix_rele(struct nd_prefix *);
int nd6_prefix_onlink(struct nd_prefix *);
int nd6_prefix_offlink(struct nd_prefix *);
void pfxlist_onlink_check(void);
-struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *);
-struct nd_defrouter *defrouter_lookup_locked(struct in6_addr *, struct ifnet *);
struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *);
void rt6_flush(struct in6_addr *, struct ifnet *);
int nd6_setdefaultiface(int);
diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c
index 49810020..634eea06 100644
--- a/freebsd/sys/netinet6/nd6_nbr.c
+++ b/freebsd/sys/netinet6/nd6_nbr.c
@@ -122,53 +122,53 @@ VNET_DEFINE_STATIC(int, dad_maxtry) = 15; /* max # of *tries* to
void
nd6_ns_input(struct mbuf *m, int off, int icmp6len)
{
- struct ifnet *ifp = m->m_pkthdr.rcvif;
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ struct ifnet *ifp;
+ struct ip6_hdr *ip6;
struct nd_neighbor_solicit *nd_ns;
- struct in6_addr saddr6 = ip6->ip6_src;
- struct in6_addr daddr6 = ip6->ip6_dst;
- struct in6_addr taddr6;
- struct in6_addr myaddr6;
- char *lladdr = NULL;
- struct ifaddr *ifa = NULL;
- int lladdrlen = 0;
- int anycast = 0, proxy = 0, tentative = 0;
- int tlladdr;
- int rflag;
- union nd_opts ndopts;
+ struct in6_addr daddr6, myaddr6, saddr6, taddr6;
+ struct ifaddr *ifa;
struct sockaddr_dl proxydl;
+ union nd_opts ndopts;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ char *lladdr;
+ int anycast, lladdrlen, proxy, rflag, tentative, tlladdr;
+
+ ifa = NULL;
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
- rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
- if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
- rflag = 0;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, icmp6len,);
- nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
- if (nd_ns == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return;
- }
-#endif
- ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */
- taddr6 = nd_ns->nd_ns_target;
- if (in6_setscope(&taddr6, ifp, NULL) != 0)
- goto bad;
-
+ ifp = m->m_pkthdr.rcvif;
+ ip6 = mtod(m, struct ip6_hdr *);
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n",
ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
- goto bad;
+ goto bads;
}
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
+ }
+ ip6 = mtod(m, struct ip6_hdr *);
+ nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
+
+ saddr6 = ip6->ip6_src;
+ daddr6 = ip6->ip6_dst;
+ taddr6 = nd_ns->nd_ns_target;
+ if (in6_setscope(&taddr6, ifp, NULL) != 0)
+ goto bad;
+
+ rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
+ if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
+ rflag = 0;
+
if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
/* dst has to be a solicited node multicast address. */
if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
@@ -216,6 +216,8 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
goto freeit;
}
+ lladdr = NULL;
+ lladdrlen = 0;
if (ndopts.nd_opts_src_lladdr) {
lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
@@ -255,6 +257,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
/* (2) check. */
+ proxy = 0;
if (ifa == NULL) {
struct sockaddr_dl rt_gateway;
struct rt_addrinfo info;
@@ -381,6 +384,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
ip6_sprintf(ip6bufs, &daddr6)));
nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n",
ip6_sprintf(ip6bufs, &taddr6)));
+ bads:
ICMP6STAT_INC(icp6s_badns);
if (ifa != NULL)
ifa_free(ifa);
@@ -615,32 +619,32 @@ nd6_ns_output(struct ifnet *ifp, const struct in6_addr *saddr6,
void
nd6_na_input(struct mbuf *m, int off, int icmp6len)
{
- struct ifnet *ifp = m->m_pkthdr.rcvif;
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
- struct nd_neighbor_advert *nd_na;
- struct in6_addr daddr6 = ip6->ip6_dst;
- struct in6_addr taddr6;
- int flags;
- int is_router;
- int is_solicited;
- int is_override;
- char *lladdr = NULL;
- int lladdrlen = 0;
- int checklink = 0;
+ struct ifnet *ifp;
+ struct ip6_hdr *ip6;
struct ifaddr *ifa;
- struct llentry *ln = NULL;
- union nd_opts ndopts;
- struct mbuf *chain = NULL;
+ struct llentry *ln;
+ struct mbuf *chain;
+ struct nd_neighbor_advert *nd_na;
+ struct in6_addr daddr6, taddr6;
struct sockaddr_in6 sin6;
+ union nd_opts ndopts;
u_char linkhdr[LLE_MAX_LINKHDR];
- size_t linkhdrsize;
- int lladdr_off;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ char *lladdr;
+ size_t linkhdrsize;
+ int flags, is_override, is_router, is_solicited;
+ int lladdr_off, lladdrlen, checklink;
+
+ chain = NULL;
+ ln = NULL;
+ checklink = 0;
/* RFC 6980: Nodes MUST silently ignore fragments */
if(m->m_flags & M_FRAGMENTED)
goto freeit;
+ ifp = m->m_pkthdr.rcvif;
+ ip6 = mtod(m, struct ip6_hdr *);
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
"nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",
@@ -649,22 +653,20 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
goto bad;
}
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, icmp6len,);
- nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len);
- if (nd_na == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return;
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
-#endif
+ ip6 = mtod(m, struct ip6_hdr *);
+ nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off);
flags = nd_na->nd_na_flags_reserved;
is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);
is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0);
is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0);
- memset(&sin6, 0, sizeof(sin6));
taddr6 = nd_na->nd_na_target;
if (in6_setscope(&taddr6, ifp, NULL))
@@ -676,6 +678,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
ip6_sprintf(ip6bufs, &taddr6)));
goto bad;
}
+
+ daddr6 = ip6->ip6_dst;
if (IN6_IS_ADDR_MULTICAST(&daddr6))
if (is_solicited) {
nd6log((LOG_ERR,
@@ -692,6 +696,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
goto freeit;
}
+ lladdr = NULL;
+ lladdrlen = 0;
if (ndopts.nd_opts_tgt_lladdr) {
lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
@@ -889,8 +895,10 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
* rt->rt_flags &= ~RTF_REJECT;
*/
ln->la_asked = 0;
- if (ln->la_hold != NULL)
+ if (ln->la_hold != NULL) {
+ memset(&sin6, 0, sizeof(sin6));
nd6_grab_holdchain(ln, &chain, &sin6);
+ }
freeit:
if (ln != NULL)
LLE_WUNLOCK(ln);
diff --git a/freebsd/sys/netinet6/nd6_rtr.c b/freebsd/sys/netinet6/nd6_rtr.c
index a60e7c66..9dddedf4 100644
--- a/freebsd/sys/netinet6/nd6_rtr.c
+++ b/freebsd/sys/netinet6/nd6_rtr.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/errno.h>
#include <sys/rmlock.h>
#include <sys/rwlock.h>
+#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/queue.h>
@@ -74,24 +75,12 @@ __FBSDID("$FreeBSD$");
#include <netinet/icmp6.h>
#include <netinet6/scope6_var.h>
-static int rtpref(struct nd_defrouter *);
static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *);
static int prelist_update(struct nd_prefixctl *, struct nd_defrouter *,
struct mbuf *, int);
-static struct in6_ifaddr *in6_ifadd(struct nd_prefixctl *, int);
-static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *,
- struct nd_defrouter *);
-static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *);
-static void pfxrtr_del(struct nd_pfxrouter *);
-static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *);
-static void defrouter_delreq(struct nd_defrouter *);
-static void nd6_rtmsg(int, struct rtentry *);
-static int in6_init_prefix_ltimes(struct nd_prefix *);
-static void in6_init_address_ltimes(struct nd_prefix *,
- struct in6_addrlifetime *);
-
-static int rt6_deleteroute(const struct rtentry *, void *);
+VNET_DEFINE_STATIC(struct nd_drhead, nd6_defrouter);
+#define V_nd6_defrouter VNET(nd6_defrouter)
VNET_DECLARE(int, nd6_recalc_reachtm_interval);
#define V_nd6_recalc_reachtm_interval VNET(nd6_recalc_reachtm_interval)
@@ -108,6 +97,8 @@ VNET_DEFINE(u_int32_t, ip6_temp_valid_lifetime) = DEF_TEMP_VALID_LIFETIME;
VNET_DEFINE(int, ip6_temp_regen_advance) = TEMPADDR_REGEN_ADVANCE;
+SYSCTL_DECL(_net_inet6_icmp6);
+
/* RTPREF_MEDIUM has to be 0! */
#define RTPREF_HIGH 1
#define RTPREF_MEDIUM 0
@@ -115,6 +106,37 @@ VNET_DEFINE(int, ip6_temp_regen_advance) = TEMPADDR_REGEN_ADVANCE;
#define RTPREF_RESERVED (-2)
#define RTPREF_INVALID (-3) /* internal */
+void
+defrouter_ref(struct nd_defrouter *dr)
+{
+
+ refcount_acquire(&dr->refcnt);
+}
+
+void
+defrouter_rele(struct nd_defrouter *dr)
+{
+
+ if (refcount_release(&dr->refcnt))
+ free(dr, M_IP6NDP);
+}
+
+/*
+ * Remove a router from the global list and optionally stash it in a
+ * caller-supplied queue.
+ */
+void
+defrouter_unlink(struct nd_defrouter *dr, struct nd_drhead *drq)
+{
+
+ ND6_WLOCK_ASSERT();
+
+ TAILQ_REMOVE(&V_nd6_defrouter, dr, dr_entry);
+ V_nd6_list_genid++;
+ if (drq != NULL)
+ TAILQ_INSERT_TAIL(drq, dr, dr_entry);
+}
+
/*
* Receive Router Solicitation Message - just for routers.
* Router solicitation/advertisement is mostly managed by userland program
@@ -125,14 +147,16 @@ VNET_DEFINE(int, ip6_temp_regen_advance) = TEMPADDR_REGEN_ADVANCE;
void
nd6_rs_input(struct mbuf *m, int off, int icmp6len)
{
- struct ifnet *ifp = m->m_pkthdr.rcvif;
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ struct ifnet *ifp;
+ struct ip6_hdr *ip6;
struct nd_router_solicit *nd_rs;
- struct in6_addr saddr6 = ip6->ip6_src;
- char *lladdr = NULL;
- int lladdrlen = 0;
+ struct in6_addr saddr6;
union nd_opts ndopts;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
+ char *lladdr;
+ int lladdrlen;
+
+ ifp = m->m_pkthdr.rcvif;
/*
* Accept RS only when V_ip6_forwarding=1 and the interface has
@@ -146,9 +170,10 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
goto freeit;
/* Sanity checks */
+ ip6 = mtod(m, struct ip6_hdr *);
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
- "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n",
+ "%s: invalid hlim (%d) from %s to %s on %s\n", __func__,
ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
goto bad;
@@ -158,29 +183,31 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
* Don't update the neighbor cache, if src = ::.
* This indicates that the src has no IP address assigned yet.
*/
+ saddr6 = ip6->ip6_src;
if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
goto freeit;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, icmp6len,);
- nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, m, off, icmp6len);
- if (nd_rs == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return;
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
-#endif
+ ip6 = mtod(m, struct ip6_hdr *);
+ nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
icmp6len -= sizeof(*nd_rs);
nd6_option_init(nd_rs + 1, icmp6len, &ndopts);
if (nd6_options(&ndopts) < 0) {
nd6log((LOG_INFO,
- "nd6_rs_input: invalid ND option, ignored\n"));
+ "%s: invalid ND option, ignored\n", __func__));
/* nd6_options have incremented stats */
goto freeit;
}
+ lladdr = NULL;
+ lladdrlen = 0;
if (ndopts.nd_opts_src_lladdr) {
lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
@@ -188,9 +215,8 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
nd6log((LOG_INFO,
- "nd6_rs_input: lladdrlen mismatch for %s "
- "(if %d, RS packet %d)\n",
- ip6_sprintf(ip6bufs, &saddr6),
+ "%s: lladdrlen mismatch for %s (if %d, RS packet %d)\n",
+ __func__, ip6_sprintf(ip6bufs, &saddr6),
ifp->if_addrlen, lladdrlen - 2));
goto bad;
}
@@ -216,22 +242,22 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
void
nd6_ra_input(struct mbuf *m, int off, int icmp6len)
{
- struct ifnet *ifp = m->m_pkthdr.rcvif;
- struct nd_ifinfo *ndi = ND_IFINFO(ifp);
- struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ struct ifnet *ifp;
+ struct nd_ifinfo *ndi;
+ struct ip6_hdr *ip6;
struct nd_router_advert *nd_ra;
- struct in6_addr saddr6 = ip6->ip6_src;
- int mcast = 0;
- union nd_opts ndopts;
+ struct in6_addr saddr6;
struct nd_defrouter *dr;
+ union nd_opts ndopts;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
-
- dr = NULL;
+ int mcast;
/*
* We only accept RAs only when the per-interface flag
* ND6_IFF_ACCEPT_RTADV is on the receiving interface.
*/
+ ifp = m->m_pkthdr.rcvif;
+ ndi = ND_IFINFO(ifp);
if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV))
goto freeit;
@@ -239,41 +265,44 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
if(m->m_flags & M_FRAGMENTED)
goto freeit;
+ ip6 = mtod(m, struct ip6_hdr *);
if (ip6->ip6_hlim != 255) {
nd6log((LOG_ERR,
- "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
+ "%s: invalid hlim (%d) from %s to %s on %s\n", __func__,
ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
goto bad;
}
+ saddr6 = ip6->ip6_src;
if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) {
nd6log((LOG_ERR,
- "nd6_ra_input: src %s is not link-local\n",
+ "%s: src %s is not link-local\n", __func__,
ip6_sprintf(ip6bufs, &saddr6)));
goto bad;
}
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, icmp6len,);
- nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len);
- if (nd_ra == NULL) {
- ICMP6STAT_INC(icp6s_tooshort);
- return;
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
-#endif
+ ip6 = mtod(m, struct ip6_hdr *);
+ nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
icmp6len -= sizeof(*nd_ra);
nd6_option_init(nd_ra + 1, icmp6len, &ndopts);
if (nd6_options(&ndopts) < 0) {
nd6log((LOG_INFO,
- "nd6_ra_input: invalid ND option, ignored\n"));
+ "%s: invalid ND option, ignored\n", __func__));
/* nd6_options have incremented stats */
goto freeit;
}
+ mcast = 0;
+ dr = NULL;
{
struct nd_defrouter dr0;
u_int32_t advreachable = nd_ra->nd_ra_reachable;
@@ -341,26 +370,25 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
if (pi->nd_opt_pi_len != 4) {
nd6log((LOG_INFO,
- "nd6_ra_input: invalid option "
- "len %d for prefix information option, "
- "ignored\n", pi->nd_opt_pi_len));
+ "%s: invalid option len %d for prefix "
+ "information option, ignored\n", __func__,
+ pi->nd_opt_pi_len));
continue;
}
if (128 < pi->nd_opt_pi_prefix_len) {
nd6log((LOG_INFO,
- "nd6_ra_input: invalid prefix "
- "len %d for prefix information option, "
- "ignored\n", pi->nd_opt_pi_prefix_len));
+ "%s: invalid prefix len %d for prefix "
+ "information option, ignored\n", __func__,
+ pi->nd_opt_pi_prefix_len));
continue;
}
if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix)
|| IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) {
nd6log((LOG_INFO,
- "nd6_ra_input: invalid prefix "
- "%s, ignored\n",
- ip6_sprintf(ip6bufs,
+ "%s: invalid prefix %s, ignored\n",
+ __func__, ip6_sprintf(ip6bufs,
&pi->nd_opt_pi_prefix)));
continue;
}
@@ -397,8 +425,8 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
/* lower bound */
if (mtu < IPV6_MMTU) {
- nd6log((LOG_INFO, "nd6_ra_input: bogus mtu option "
- "mtu=%lu sent from %s, ignoring\n",
+ nd6log((LOG_INFO, "%s: bogus mtu option mtu=%lu sent "
+ "from %s, ignoring\n", __func__,
mtu, ip6_sprintf(ip6bufs, &ip6->ip6_src)));
goto skip;
}
@@ -416,9 +444,8 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
rt_updatemtu(ifp);
}
} else {
- nd6log((LOG_INFO, "nd6_ra_input: bogus mtu "
- "mtu=%lu sent from %s; "
- "exceeds maxmtu %lu, ignoring\n",
+ nd6log((LOG_INFO, "%s: bogus mtu=%lu sent from %s; "
+ "exceeds maxmtu %lu, ignoring\n", __func__,
mtu, ip6_sprintf(ip6bufs, &ip6->ip6_src), maxmtu));
}
}
@@ -439,8 +466,8 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
nd6log((LOG_INFO,
- "nd6_ra_input: lladdrlen mismatch for %s "
- "(if %d, RA packet %d)\n", ip6_sprintf(ip6bufs, &saddr6),
+ "%s: lladdrlen mismatch for %s (if %d, RA packet %d)\n",
+ __func__, ip6_sprintf(ip6bufs, &saddr6),
ifp->if_addrlen, lladdrlen - 2));
goto bad;
}
@@ -493,10 +520,71 @@ nd6_rtmsg(int cmd, struct rtentry *rt)
ifa_free(ifa);
}
-/*
- * default router list processing sub routines
- */
+/* PFXRTR */
+static struct nd_pfxrouter *
+pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
+{
+ struct nd_pfxrouter *search;
+
+ ND6_LOCK_ASSERT();
+
+ LIST_FOREACH(search, &pr->ndpr_advrtrs, pfr_entry) {
+ if (search->router == dr)
+ break;
+ }
+ return (search);
+}
+
+static void
+pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr)
+{
+ struct nd_pfxrouter *new;
+ bool update;
+
+ ND6_UNLOCK_ASSERT();
+
+ ND6_RLOCK();
+ if (pfxrtr_lookup(pr, dr) != NULL) {
+ ND6_RUNLOCK();
+ return;
+ }
+ ND6_RUNLOCK();
+
+ new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO);
+ if (new == NULL)
+ return;
+ defrouter_ref(dr);
+ new->router = dr;
+
+ ND6_WLOCK();
+ if (pfxrtr_lookup(pr, dr) == NULL) {
+ LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
+ update = true;
+ } else {
+ /* We lost a race to add the reference. */
+ defrouter_rele(dr);
+ free(new, M_IP6NDP);
+ update = false;
+ }
+ ND6_WUNLOCK();
+
+ if (update)
+ pfxlist_onlink_check();
+}
+
+static void
+pfxrtr_del(struct nd_pfxrouter *pfr)
+{
+
+ ND6_WLOCK_ASSERT();
+
+ LIST_REMOVE(pfr, pfr_entry);
+ defrouter_rele(pfr->router);
+ free(pfr, M_IP6NDP);
+}
+
+/* Default router list processing sub routines. */
static void
defrouter_addreq(struct nd_defrouter *new)
{
@@ -524,46 +612,6 @@ defrouter_addreq(struct nd_defrouter *new)
new->installed = 1;
}
-struct nd_defrouter *
-defrouter_lookup_locked(struct in6_addr *addr, struct ifnet *ifp)
-{
- struct nd_defrouter *dr;
-
- ND6_LOCK_ASSERT();
- TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry)
- if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) {
- defrouter_ref(dr);
- return (dr);
- }
- return (NULL);
-}
-
-struct nd_defrouter *
-defrouter_lookup(struct in6_addr *addr, struct ifnet *ifp)
-{
- struct nd_defrouter *dr;
-
- ND6_RLOCK();
- dr = defrouter_lookup_locked(addr, ifp);
- ND6_RUNLOCK();
- return (dr);
-}
-
-void
-defrouter_ref(struct nd_defrouter *dr)
-{
-
- refcount_acquire(&dr->refcnt);
-}
-
-void
-defrouter_rele(struct nd_defrouter *dr)
-{
-
- if (refcount_release(&dr->refcnt))
- free(dr, M_IP6NDP);
-}
-
/*
* Remove the default route for a given router.
* This is just a subroutine function for defrouter_select_fib(), and
@@ -595,6 +643,79 @@ defrouter_delreq(struct nd_defrouter *dr)
dr->installed = 0;
}
+void
+defrouter_del(struct nd_defrouter *dr)
+{
+ struct nd_defrouter *deldr = NULL;
+ struct nd_prefix *pr;
+ struct nd_pfxrouter *pfxrtr;
+
+ ND6_UNLOCK_ASSERT();
+
+ /*
+ * Flush all the routing table entries that use the router
+ * as a next hop.
+ */
+ if (ND_IFINFO(dr->ifp)->flags & ND6_IFF_ACCEPT_RTADV)
+ rt6_flush(&dr->rtaddr, dr->ifp);
+
+ if (dr->installed) {
+ deldr = dr;
+ defrouter_delreq(dr);
+ }
+
+ /*
+ * Also delete all the pointers to the router in each prefix lists.
+ */
+ ND6_WLOCK();
+ LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
+ if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL)
+ pfxrtr_del(pfxrtr);
+ }
+ ND6_WUNLOCK();
+
+ pfxlist_onlink_check();
+
+ /*
+ * If the router is the primary one, choose a new one.
+ * Note that defrouter_select_fib() will remove the current
+ * gateway from the routing table.
+ */
+ if (deldr)
+ defrouter_select_fib(deldr->ifp->if_fib);
+
+ /*
+ * Release the list reference.
+ */
+ defrouter_rele(dr);
+}
+
+
+struct nd_defrouter *
+defrouter_lookup_locked(struct in6_addr *addr, struct ifnet *ifp)
+{
+ struct nd_defrouter *dr;
+
+ ND6_LOCK_ASSERT();
+ TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
+ if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) {
+ defrouter_ref(dr);
+ return (dr);
+ }
+ return (NULL);
+}
+
+struct nd_defrouter *
+defrouter_lookup(struct in6_addr *addr, struct ifnet *ifp)
+{
+ struct nd_defrouter *dr;
+
+ ND6_RLOCK();
+ dr = defrouter_lookup_locked(addr, ifp);
+ ND6_RUNLOCK();
+ return (dr);
+}
+
/*
* Remove all default routes from default router list.
*/
@@ -611,14 +732,14 @@ defrouter_reset(void)
* current default router list and use that when deleting routes.
*/
ND6_RLOCK();
- TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry)
+ TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
count++;
ND6_RUNLOCK();
dra = malloc(count * sizeof(*dra), M_TEMP, M_WAITOK | M_ZERO);
ND6_RLOCK();
- TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
+ TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
if (i == count)
break;
defrouter_ref(dr);
@@ -662,67 +783,30 @@ defrouter_remove(struct in6_addr *addr, struct ifnet *ifp)
}
/*
- * Remove a router from the global list and optionally stash it in a
- * caller-supplied queue.
- *
- * The ND lock must be held.
+ * for default router selection
+ * regards router-preference field as a 2-bit signed integer
*/
-void
-defrouter_unlink(struct nd_defrouter *dr, struct nd_drhead *drq)
-{
-
- ND6_WLOCK_ASSERT();
- TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry);
- V_nd6_list_genid++;
- if (drq != NULL)
- TAILQ_INSERT_TAIL(drq, dr, dr_entry);
-}
-
-void
-defrouter_del(struct nd_defrouter *dr)
+static int
+rtpref(struct nd_defrouter *dr)
{
- struct nd_defrouter *deldr = NULL;
- struct nd_prefix *pr;
- struct nd_pfxrouter *pfxrtr;
-
- ND6_UNLOCK_ASSERT();
-
- /*
- * Flush all the routing table entries that use the router
- * as a next hop.
- */
- if (ND_IFINFO(dr->ifp)->flags & ND6_IFF_ACCEPT_RTADV)
- rt6_flush(&dr->rtaddr, dr->ifp);
-
- if (dr->installed) {
- deldr = dr;
- defrouter_delreq(dr);
- }
-
- /*
- * Also delete all the pointers to the router in each prefix lists.
- */
- ND6_WLOCK();
- LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
- if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL)
- pfxrtr_del(pfxrtr);
+ switch (dr->raflags & ND_RA_FLAG_RTPREF_MASK) {
+ case ND_RA_FLAG_RTPREF_HIGH:
+ return (RTPREF_HIGH);
+ case ND_RA_FLAG_RTPREF_MEDIUM:
+ case ND_RA_FLAG_RTPREF_RSV:
+ return (RTPREF_MEDIUM);
+ case ND_RA_FLAG_RTPREF_LOW:
+ return (RTPREF_LOW);
+ default:
+ /*
+ * This case should never happen. If it did, it would mean a
+ * serious bug of kernel internal. We thus always bark here.
+ * Or, can we even panic?
+ */
+ log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->raflags);
+ return (RTPREF_INVALID);
}
- ND6_WUNLOCK();
-
- pfxlist_onlink_check();
-
- /*
- * If the router is the primary one, choose a new one.
- * Note that defrouter_select_fib() will remove the current
- * gateway from the routing table.
- */
- if (deldr)
- defrouter_select_fib(deldr->ifp->if_fib);
-
- /*
- * Release the list reference.
- */
- defrouter_rele(dr);
+ /* NOTREACHED */
}
/*
@@ -767,7 +851,7 @@ defrouter_select_fib(int fibnum)
* Let's handle easy case (3) first:
* If default router list is empty, there's nothing to be done.
*/
- if (TAILQ_EMPTY(&V_nd_defrouter)) {
+ if (TAILQ_EMPTY(&V_nd6_defrouter)) {
ND6_RUNLOCK();
return;
}
@@ -778,7 +862,7 @@ defrouter_select_fib(int fibnum)
* the ordering rule of the list described in defrtrlist_update().
*/
selected_dr = installed_dr = NULL;
- TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
+ TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
IF_AFDATA_RLOCK(dr->ifp);
if (selected_dr == NULL && dr->ifp->if_fib == fibnum &&
(ln = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) &&
@@ -817,12 +901,12 @@ defrouter_select_fib(int fibnum)
if (selected_dr == NULL) {
if (installed_dr == NULL ||
TAILQ_NEXT(installed_dr, dr_entry) == NULL)
- dr = TAILQ_FIRST(&V_nd_defrouter);
+ dr = TAILQ_FIRST(&V_nd6_defrouter);
else
dr = TAILQ_NEXT(installed_dr, dr_entry);
/* Ensure we select a router for this FIB. */
- TAILQ_FOREACH_FROM(dr, &V_nd_defrouter, dr_entry) {
+ TAILQ_FOREACH_FROM(dr, &V_nd6_defrouter, dr_entry) {
if (dr->ifp->if_fib == fibnum) {
selected_dr = dr;
defrouter_ref(selected_dr);
@@ -872,33 +956,6 @@ defrouter_select(void)
defrouter_select_fib(RT_ALL_FIBS);
}
-/*
- * for default router selection
- * regards router-preference field as a 2-bit signed integer
- */
-static int
-rtpref(struct nd_defrouter *dr)
-{
- switch (dr->raflags & ND_RA_FLAG_RTPREF_MASK) {
- case ND_RA_FLAG_RTPREF_HIGH:
- return (RTPREF_HIGH);
- case ND_RA_FLAG_RTPREF_MEDIUM:
- case ND_RA_FLAG_RTPREF_RSV:
- return (RTPREF_MEDIUM);
- case ND_RA_FLAG_RTPREF_LOW:
- return (RTPREF_LOW);
- default:
- /*
- * This case should never happen. If it did, it would mean a
- * serious bug of kernel internal. We thus always bark here.
- * Or, can we even panic?
- */
- log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->raflags);
- return (RTPREF_INVALID);
- }
- /* NOTREACHED */
-}
-
static struct nd_defrouter *
defrtrlist_update(struct nd_defrouter *new)
{
@@ -960,7 +1017,7 @@ restart:
* The preferred router may have changed, so relocate this
* router.
*/
- TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry);
+ TAILQ_REMOVE(&V_nd6_defrouter, dr, dr_entry);
n = dr;
} else {
n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO);
@@ -981,14 +1038,14 @@ restart:
*/
/* insert at the end of the group */
- TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
+ TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
if (rtpref(n) > rtpref(dr))
break;
}
if (dr != NULL)
TAILQ_INSERT_BEFORE(dr, n, dr_entry);
else
- TAILQ_INSERT_TAIL(&V_nd_defrouter, n, dr_entry);
+ TAILQ_INSERT_TAIL(&V_nd6_defrouter, n, dr_entry);
V_nd6_list_genid++;
ND6_WUNLOCK();
@@ -997,66 +1054,154 @@ restart:
return (n);
}
-static struct nd_pfxrouter *
-pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
+static int
+in6_init_prefix_ltimes(struct nd_prefix *ndpr)
{
- struct nd_pfxrouter *search;
+ if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME)
+ ndpr->ndpr_preferred = 0;
+ else
+ ndpr->ndpr_preferred = time_uptime + ndpr->ndpr_pltime;
+ if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME)
+ ndpr->ndpr_expire = 0;
+ else
+ ndpr->ndpr_expire = time_uptime + ndpr->ndpr_vltime;
- ND6_LOCK_ASSERT();
+ return 0;
+}
- LIST_FOREACH(search, &pr->ndpr_advrtrs, pfr_entry) {
- if (search->router == dr)
- break;
+static void
+in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6)
+{
+ /* init ia6t_expire */
+ if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
+ lt6->ia6t_expire = 0;
+ else {
+ lt6->ia6t_expire = time_uptime;
+ lt6->ia6t_expire += lt6->ia6t_vltime;
+ }
+
+ /* init ia6t_preferred */
+ if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
+ lt6->ia6t_preferred = 0;
+ else {
+ lt6->ia6t_preferred = time_uptime;
+ lt6->ia6t_preferred += lt6->ia6t_pltime;
}
- return (search);
}
-static void
-pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr)
+static struct in6_ifaddr *
+in6_ifadd(struct nd_prefixctl *pr, int mcast)
{
- struct nd_pfxrouter *new;
- bool update;
+ struct ifnet *ifp = pr->ndpr_ifp;
+ struct ifaddr *ifa;
+ struct in6_aliasreq ifra;
+ struct in6_ifaddr *ia, *ib;
+ int error, plen0;
+ struct in6_addr mask;
+ int prefixlen = pr->ndpr_plen;
+ int updateflags;
+ char ip6buf[INET6_ADDRSTRLEN];
- ND6_UNLOCK_ASSERT();
+ in6_prefixlen2mask(&mask, prefixlen);
- ND6_RLOCK();
- if (pfxrtr_lookup(pr, dr) != NULL) {
- ND6_RUNLOCK();
- return;
+ /*
+ * find a link-local address (will be interface ID).
+ * Is it really mandatory? Theoretically, a global or a site-local
+ * address can be configured without a link-local address, if we
+ * have a unique interface identifier...
+ *
+ * it is not mandatory to have a link-local address, we can generate
+ * interface identifier on the fly. we do this because:
+ * (1) it should be the easiest way to find interface identifier.
+ * (2) RFC2462 5.4 suggesting the use of the same interface identifier
+ * for multiple addresses on a single interface, and possible shortcut
+ * of DAD. we omitted DAD for this reason in the past.
+ * (3) a user can prevent autoconfiguration of global address
+ * by removing link-local address by hand (this is partly because we
+ * don't have other way to control the use of IPv6 on an interface.
+ * this has been our design choice - cf. NRL's "ifconfig auto").
+ * (4) it is easier to manage when an interface has addresses
+ * with the same interface identifier, than to have multiple addresses
+ * with different interface identifiers.
+ */
+ ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0); /* 0 is OK? */
+ if (ifa)
+ ib = (struct in6_ifaddr *)ifa;
+ else
+ return NULL;
+
+ /* prefixlen + ifidlen must be equal to 128 */
+ plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL);
+ if (prefixlen != plen0) {
+ ifa_free(ifa);
+ nd6log((LOG_INFO,
+ "%s: wrong prefixlen for %s (prefix=%d ifid=%d)\n",
+ __func__, if_name(ifp), prefixlen, 128 - plen0));
+ return NULL;
}
- ND6_RUNLOCK();
- new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO);
- if (new == NULL)
- return;
- defrouter_ref(dr);
- new->router = dr;
+ /* make ifaddr */
+ in6_prepare_ifra(&ifra, &pr->ndpr_prefix.sin6_addr, &mask);
- ND6_WLOCK();
- if (pfxrtr_lookup(pr, dr) == NULL) {
- LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
- update = true;
- } else {
- /* We lost a race to add the reference. */
- defrouter_rele(dr);
- free(new, M_IP6NDP);
- update = false;
- }
- ND6_WUNLOCK();
+ IN6_MASK_ADDR(&ifra.ifra_addr.sin6_addr, &mask);
+ /* interface ID */
+ ifra.ifra_addr.sin6_addr.s6_addr32[0] |=
+ (ib->ia_addr.sin6_addr.s6_addr32[0] & ~mask.s6_addr32[0]);
+ ifra.ifra_addr.sin6_addr.s6_addr32[1] |=
+ (ib->ia_addr.sin6_addr.s6_addr32[1] & ~mask.s6_addr32[1]);
+ ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
+ (ib->ia_addr.sin6_addr.s6_addr32[2] & ~mask.s6_addr32[2]);
+ ifra.ifra_addr.sin6_addr.s6_addr32[3] |=
+ (ib->ia_addr.sin6_addr.s6_addr32[3] & ~mask.s6_addr32[3]);
+ ifa_free(ifa);
- if (update)
- pfxlist_onlink_check();
-}
+ /* lifetimes. */
+ ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime;
+ ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime;
-static void
-pfxrtr_del(struct nd_pfxrouter *pfr)
-{
+ /* XXX: scope zone ID? */
- ND6_WLOCK_ASSERT();
+ ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
- LIST_REMOVE(pfr, pfr_entry);
- defrouter_rele(pfr->router);
- free(pfr, M_IP6NDP);
+ /*
+ * Make sure that we do not have this address already. This should
+ * usually not happen, but we can still see this case, e.g., if we
+ * have manually configured the exact address to be configured.
+ */
+ ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp,
+ &ifra.ifra_addr.sin6_addr);
+ if (ifa != NULL) {
+ ifa_free(ifa);
+ /* this should be rare enough to make an explicit log */
+ log(LOG_INFO, "in6_ifadd: %s is already configured\n",
+ ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr));
+ return (NULL);
+ }
+
+ /*
+ * Allocate ifaddr structure, link into chain, etc.
+ * If we are going to create a new address upon receiving a multicasted
+ * RA, we need to impose a random delay before starting DAD.
+ * [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2]
+ */
+ updateflags = 0;
+ if (mcast)
+ updateflags |= IN6_IFAUPDATE_DADDELAY;
+ if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0) {
+ nd6log((LOG_ERR,
+ "%s: failed to make ifaddr %s on %s (errno=%d)\n", __func__,
+ ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr),
+ if_name(ifp), error));
+ return (NULL); /* ifaddr must not have been allocated. */
+ }
+
+ ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
+ /*
+ * XXXRW: Assumption of non-NULLness here might not be true with
+ * fine-grained locking -- should we validate it? Or just return
+ * earlier ifa rather than looking it up again?
+ */
+ return (ia); /* this is always non-NULL and referenced. */
}
static struct nd_prefix *
@@ -1146,8 +1291,8 @@ nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
if (new->ndpr_raf_onlink) {
ND6_ONLINK_LOCK();
if ((error = nd6_prefix_onlink(new)) != 0) {
- nd6log((LOG_ERR, "nd6_prelist_add: failed to make "
- "the prefix %s/%d on-link on %s (errno=%d)\n",
+ nd6log((LOG_ERR, "%s: failed to make the prefix %s/%d "
+ "on-link on %s (errno=%d)\n", __func__,
ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
pr->ndpr_plen, if_name(pr->ndpr_ifp), error));
/* proceed anyway. XXX: is it correct? */
@@ -1203,8 +1348,8 @@ nd6_prefix_del(struct nd_prefix *pr)
ND6_ONLINK_LOCK();
if ((e = nd6_prefix_offlink(pr)) != 0) {
nd6log((LOG_ERR,
- "nd6_prefix_del: failed to make %s/%d offlink "
- "on %s, errno=%d\n",
+ "%s: failed to make the prefix %s/%d offlink on %s "
+ "(errno=%d)\n", __func__,
ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
/* what should we do? */
@@ -1275,9 +1420,8 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
ND6_ONLINK_LOCK();
if ((error = nd6_prefix_onlink(pr)) != 0) {
nd6log((LOG_ERR,
- "prelist_update: failed to make "
- "the prefix %s/%d on-link on %s "
- "(errno=%d)\n",
+ "%s: failed to make the prefix %s/%d "
+ "on-link on %s (errno=%d)\n", __func__,
ip6_sprintf(ip6buf,
&pr->ndpr_prefix.sin6_addr),
pr->ndpr_plen, if_name(pr->ndpr_ifp),
@@ -1297,8 +1441,8 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
error = nd6_prelist_add(new, dr, &pr);
if (error != 0) {
- nd6log((LOG_NOTICE, "prelist_update: "
- "nd6_prelist_add failed for %s/%d on %s errno=%d\n",
+ nd6log((LOG_NOTICE, "%s: nd6_prelist_add() failed for "
+ "the prefix %s/%d on %s (errno=%d)\n", __func__,
ip6_sprintf(ip6buf, &new->ndpr_prefix.sin6_addr),
new->ndpr_plen, if_name(new->ndpr_ifp), error));
goto end; /* we should just give up in this case. */
@@ -1498,9 +1642,8 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
}
if (ifidlen + pr->ndpr_plen != 128) {
nd6log((LOG_INFO,
- "prelist_update: invalid prefixlen "
- "%d for %s, ignored\n",
- pr->ndpr_plen, if_name(ifp)));
+ "%s: invalid prefixlen %d for %s, ignored\n",
+ __func__, pr->ndpr_plen, if_name(ifp)));
goto end;
}
@@ -1526,10 +1669,9 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
if (V_ip6_use_tempaddr) {
int e;
if ((e = in6_tmpifadd(ia6, 1, 1)) != 0) {
- nd6log((LOG_NOTICE, "prelist_update: "
- "failed to create a temporary "
- "address, errno=%d\n",
- e));
+ nd6log((LOG_NOTICE, "%s: failed to "
+ "create a temporary address "
+ "(errno=%d)\n", __func__, e));
}
}
ifa_free(&ia6->ia_ifa);
@@ -1621,7 +1763,7 @@ pfxlist_onlink_check(void)
* that does not advertise any prefixes.
*/
if (pr == NULL) {
- TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
+ TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
struct nd_prefix *pr0;
LIST_FOREACH(pr0, &V_nd_prefix, ndpr_entry) {
@@ -1632,7 +1774,7 @@ pfxlist_onlink_check(void)
break;
}
}
- if (pr != NULL || (!TAILQ_EMPTY(&V_nd_defrouter) && pfxrtr == NULL)) {
+ if (pr != NULL || (!TAILQ_EMPTY(&V_nd6_defrouter) && pfxrtr == NULL)) {
/*
* There is at least one prefix that has a reachable router,
* or at least a router which probably does not advertise
@@ -1692,16 +1834,16 @@ restart:
if ((flags & NDPRF_ONLINK) != 0 &&
(e = nd6_prefix_offlink(pr)) != 0) {
nd6log((LOG_ERR,
- "pfxlist_onlink_check: failed to "
- "make %s/%d offlink, errno=%d\n",
+ "%s: failed to make %s/%d offlink "
+ "(errno=%d)\n", __func__,
ip6_sprintf(ip6buf,
&pr->ndpr_prefix.sin6_addr),
pr->ndpr_plen, e));
} else if ((flags & NDPRF_ONLINK) == 0 &&
(e = nd6_prefix_onlink(pr)) != 0) {
nd6log((LOG_ERR,
- "pfxlist_onlink_check: failed to "
- "make %s/%d onlink, errno=%d\n",
+ "%s: failed to make %s/%d onlink "
+ "(errno=%d)\n", __func__,
ip6_sprintf(ip6buf,
&pr->ndpr_prefix.sin6_addr),
pr->ndpr_plen, e));
@@ -1834,9 +1976,9 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
- nd6log((LOG_ERR, "nd6_prefix_onlink: failed to add "
+ nd6log((LOG_ERR, "%s: failed to add "
"route for a prefix (%s/%d) on %s, gw=%s, mask=%s, "
- "flags=%lx errno = %d\n",
+ "flags=%lx errno = %d\n", __func__,
ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
pr->ndpr_plen, if_name(pr->ndpr_ifp),
ip6_sprintf(ip6bufg, &sin6->sin6_addr),
@@ -1927,8 +2069,8 @@ nd6_prefix_onlink(struct nd_prefix *pr)
* interface. This should, of course, be rare though.
*/
nd6log((LOG_NOTICE,
- "nd6_prefix_onlink: failed to find any ifaddr"
- " to add route for a prefix(%s/%d) on %s\n",
+ "%s: failed to find any ifaddr to add route for a "
+ "prefix(%s/%d) on %s\n", __func__,
ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
pr->ndpr_plen, if_name(ifp)));
return (0);
@@ -2027,10 +2169,9 @@ restart:
ND6_RUNLOCK();
if ((e = nd6_prefix_onlink(opr)) != 0) {
nd6log((LOG_ERR,
- "nd6_prefix_offlink: failed to "
- "recover a prefix %s/%d from %s "
- "to %s (errno = %d)\n",
- ip6_sprintf(ip6buf,
+ "%s: failed to recover a prefix "
+ "%s/%d from %s to %s (errno=%d)\n",
+ __func__, ip6_sprintf(ip6buf,
&opr->ndpr_prefix.sin6_addr),
opr->ndpr_plen, if_name(ifp),
if_name(opr->ndpr_ifp), e));
@@ -2045,10 +2186,9 @@ restart:
} else {
/* XXX: can we still set the NDPRF_ONLINK flag? */
nd6log((LOG_ERR,
- "nd6_prefix_offlink: failed to delete route: "
- "%s/%d on %s (errno = %d)\n",
- ip6_sprintf(ip6buf, &sa6.sin6_addr), pr->ndpr_plen,
- if_name(ifp), error));
+ "%s: failed to delete route: %s/%d on %s (errno=%d)\n",
+ __func__, ip6_sprintf(ip6buf, &sa6.sin6_addr),
+ pr->ndpr_plen, if_name(ifp), error));
}
if (a_failure)
@@ -2058,121 +2198,6 @@ restart:
return (error);
}
-static struct in6_ifaddr *
-in6_ifadd(struct nd_prefixctl *pr, int mcast)
-{
- struct ifnet *ifp = pr->ndpr_ifp;
- struct ifaddr *ifa;
- struct in6_aliasreq ifra;
- struct in6_ifaddr *ia, *ib;
- int error, plen0;
- struct in6_addr mask;
- int prefixlen = pr->ndpr_plen;
- int updateflags;
- char ip6buf[INET6_ADDRSTRLEN];
-
- in6_prefixlen2mask(&mask, prefixlen);
-
- /*
- * find a link-local address (will be interface ID).
- * Is it really mandatory? Theoretically, a global or a site-local
- * address can be configured without a link-local address, if we
- * have a unique interface identifier...
- *
- * it is not mandatory to have a link-local address, we can generate
- * interface identifier on the fly. we do this because:
- * (1) it should be the easiest way to find interface identifier.
- * (2) RFC2462 5.4 suggesting the use of the same interface identifier
- * for multiple addresses on a single interface, and possible shortcut
- * of DAD. we omitted DAD for this reason in the past.
- * (3) a user can prevent autoconfiguration of global address
- * by removing link-local address by hand (this is partly because we
- * don't have other way to control the use of IPv6 on an interface.
- * this has been our design choice - cf. NRL's "ifconfig auto").
- * (4) it is easier to manage when an interface has addresses
- * with the same interface identifier, than to have multiple addresses
- * with different interface identifiers.
- */
- ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0); /* 0 is OK? */
- if (ifa)
- ib = (struct in6_ifaddr *)ifa;
- else
- return NULL;
-
- /* prefixlen + ifidlen must be equal to 128 */
- plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL);
- if (prefixlen != plen0) {
- ifa_free(ifa);
- nd6log((LOG_INFO, "in6_ifadd: wrong prefixlen for %s "
- "(prefix=%d ifid=%d)\n",
- if_name(ifp), prefixlen, 128 - plen0));
- return NULL;
- }
-
- /* make ifaddr */
- in6_prepare_ifra(&ifra, &pr->ndpr_prefix.sin6_addr, &mask);
-
- IN6_MASK_ADDR(&ifra.ifra_addr.sin6_addr, &mask);
- /* interface ID */
- ifra.ifra_addr.sin6_addr.s6_addr32[0] |=
- (ib->ia_addr.sin6_addr.s6_addr32[0] & ~mask.s6_addr32[0]);
- ifra.ifra_addr.sin6_addr.s6_addr32[1] |=
- (ib->ia_addr.sin6_addr.s6_addr32[1] & ~mask.s6_addr32[1]);
- ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
- (ib->ia_addr.sin6_addr.s6_addr32[2] & ~mask.s6_addr32[2]);
- ifra.ifra_addr.sin6_addr.s6_addr32[3] |=
- (ib->ia_addr.sin6_addr.s6_addr32[3] & ~mask.s6_addr32[3]);
- ifa_free(ifa);
-
- /* lifetimes. */
- ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime;
- ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime;
-
- /* XXX: scope zone ID? */
-
- ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
-
- /*
- * Make sure that we do not have this address already. This should
- * usually not happen, but we can still see this case, e.g., if we
- * have manually configured the exact address to be configured.
- */
- ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp,
- &ifra.ifra_addr.sin6_addr);
- if (ifa != NULL) {
- ifa_free(ifa);
- /* this should be rare enough to make an explicit log */
- log(LOG_INFO, "in6_ifadd: %s is already configured\n",
- ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr));
- return (NULL);
- }
-
- /*
- * Allocate ifaddr structure, link into chain, etc.
- * If we are going to create a new address upon receiving a multicasted
- * RA, we need to impose a random delay before starting DAD.
- * [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2]
- */
- updateflags = 0;
- if (mcast)
- updateflags |= IN6_IFAUPDATE_DADDELAY;
- if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0) {
- nd6log((LOG_ERR,
- "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n",
- ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr),
- if_name(ifp), error));
- return (NULL); /* ifaddr must not have been allocated. */
- }
-
- ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
- /*
- * XXXRW: Assumption of non-NULLness here might not be true with
- * fine-grained locking -- should we validate it? Or just return
- * earlier ifa rather than looking it up again?
- */
- return (ia); /* this is always non-NULL and referenced. */
-}
-
/*
* ia0 - corresponding public address
*/
@@ -2199,8 +2224,8 @@ in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen, int delay)
again:
if (in6_get_tmpifid(ifp, (u_int8_t *)randid,
(const u_int8_t *)&ia0->ia_addr.sin6_addr.s6_addr[8], forcegen)) {
- nd6log((LOG_NOTICE, "in6_tmpifadd: failed to find a good "
- "random IFID\n"));
+ nd6log((LOG_NOTICE, "%s: failed to find a good random IFID\n",
+ __func__));
return (EINVAL);
}
ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
@@ -2222,8 +2247,8 @@ in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen, int delay)
}
/* Give up. Something strange should have happened. */
- nd6log((LOG_NOTICE, "in6_tmpifadd: failed to "
- "find a unique random IFID\n"));
+ nd6log((LOG_NOTICE, "%s: failed to find a unique random IFID\n",
+ __func__));
return (EEXIST);
}
@@ -2276,8 +2301,8 @@ in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen, int delay)
newia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
if (newia == NULL) { /* XXX: can it happen? */
nd6log((LOG_ERR,
- "in6_tmpifadd: ifa update succeeded, but we got "
- "no ifaddr\n"));
+ "%s: ifa update succeeded, but we got no ifaddr\n",
+ __func__));
return (EINVAL); /* XXX */
}
newia->ia6_ndpr = ia0->ia6_ndpr;
@@ -2298,58 +2323,6 @@ in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen, int delay)
}
static int
-in6_init_prefix_ltimes(struct nd_prefix *ndpr)
-{
- if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME)
- ndpr->ndpr_preferred = 0;
- else
- ndpr->ndpr_preferred = time_uptime + ndpr->ndpr_pltime;
- if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME)
- ndpr->ndpr_expire = 0;
- else
- ndpr->ndpr_expire = time_uptime + ndpr->ndpr_vltime;
-
- return 0;
-}
-
-static void
-in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6)
-{
- /* init ia6t_expire */
- if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
- lt6->ia6t_expire = 0;
- else {
- lt6->ia6t_expire = time_uptime;
- lt6->ia6t_expire += lt6->ia6t_vltime;
- }
-
- /* init ia6t_preferred */
- if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
- lt6->ia6t_preferred = 0;
- else {
- lt6->ia6t_preferred = time_uptime;
- lt6->ia6t_preferred += lt6->ia6t_pltime;
- }
-}
-
-/*
- * Delete all the routing table entries that use the specified gateway.
- * XXX: this function causes search through all entries of routing table, so
- * it shouldn't be called when acting as a router.
- */
-void
-rt6_flush(struct in6_addr *gateway, struct ifnet *ifp)
-{
-
- /* We'll care only link-local addresses */
- if (!IN6_IS_ADDR_LINKLOCAL(gateway))
- return;
-
- /* XXX Do we really need to walk any but the default FIB? */
- rt_foreach_fib_walk_del(AF_INET6, rt6_deleteroute, (void *)gateway);
-}
-
-static int
rt6_deleteroute(const struct rtentry *rt, void *arg)
{
#define SIN6(s) ((struct sockaddr_in6 *)s)
@@ -2381,6 +2354,23 @@ rt6_deleteroute(const struct rtentry *rt, void *arg)
#undef SIN6
}
+/*
+ * Delete all the routing table entries that use the specified gateway.
+ * XXX: this function causes search through all entries of routing table, so
+ * it shouldn't be called when acting as a router.
+ */
+void
+rt6_flush(struct in6_addr *gateway, struct ifnet *ifp)
+{
+
+ /* We'll care only link-local addresses */
+ if (!IN6_IS_ADDR_LINKLOCAL(gateway))
+ return;
+
+ /* XXX Do we really need to walk any but the default FIB? */
+ rt_foreach_fib_walk_del(AF_INET6, rt6_deleteroute, (void *)gateway);
+}
+
int
nd6_setdefaultiface(int ifindex)
{
@@ -2408,3 +2398,131 @@ nd6_setdefaultiface(int ifindex)
return (error);
}
+
+bool
+nd6_defrouter_list_empty(void)
+{
+
+ return (TAILQ_EMPTY(&V_nd6_defrouter));
+}
+
+void
+nd6_defrouter_timer(void)
+{
+ struct nd_defrouter *dr, *ndr;
+ struct nd_drhead drq;
+
+ TAILQ_INIT(&drq);
+
+ ND6_WLOCK();
+ TAILQ_FOREACH_SAFE(dr, &V_nd6_defrouter, dr_entry, ndr)
+ if (dr->expire && dr->expire < time_uptime)
+ defrouter_unlink(dr, &drq);
+ ND6_WUNLOCK();
+
+ while ((dr = TAILQ_FIRST(&drq)) != NULL) {
+ TAILQ_REMOVE(&drq, dr, dr_entry);
+ defrouter_del(dr);
+ }
+}
+
+/*
+ * Nuke default router list entries toward ifp.
+ * We defer removal of default router list entries that is installed in the
+ * routing table, in order to keep additional side effects as small as possible.
+ */
+void
+nd6_defrouter_purge(struct ifnet *ifp)
+{
+ struct nd_defrouter *dr, *ndr;
+ struct nd_drhead drq;
+
+ TAILQ_INIT(&drq);
+
+ ND6_WLOCK();
+ TAILQ_FOREACH_SAFE(dr, &V_nd6_defrouter, dr_entry, ndr) {
+ if (dr->installed)
+ continue;
+ if (dr->ifp == ifp)
+ defrouter_unlink(dr, &drq);
+ }
+ TAILQ_FOREACH_SAFE(dr, &V_nd6_defrouter, dr_entry, ndr) {
+ if (!dr->installed)
+ continue;
+ if (dr->ifp == ifp)
+ defrouter_unlink(dr, &drq);
+ }
+ ND6_WUNLOCK();
+
+ /* Delete the unlinked router objects. */
+ while ((dr = TAILQ_FIRST(&drq)) != NULL) {
+ TAILQ_REMOVE(&drq, dr, dr_entry);
+ defrouter_del(dr);
+ }
+}
+
+void
+nd6_defrouter_flush_all(void)
+{
+ struct nd_defrouter *dr;
+ struct nd_drhead drq;
+
+ TAILQ_INIT(&drq);
+
+ ND6_WLOCK();
+ while ((dr = TAILQ_FIRST(&V_nd6_defrouter)) != NULL)
+ defrouter_unlink(dr, &drq);
+ ND6_WUNLOCK();
+
+ while ((dr = TAILQ_FIRST(&drq)) != NULL) {
+ TAILQ_REMOVE(&drq, dr, dr_entry);
+ defrouter_del(dr);
+ }
+}
+
+void
+nd6_defrouter_init(void)
+{
+
+ TAILQ_INIT(&V_nd6_defrouter);
+}
+
+static int
+nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS)
+{
+ struct in6_defrouter d;
+ struct nd_defrouter *dr;
+ int error;
+
+ if (req->newptr != NULL)
+ return (EPERM);
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+
+ bzero(&d, sizeof(d));
+ d.rtaddr.sin6_family = AF_INET6;
+ d.rtaddr.sin6_len = sizeof(d.rtaddr);
+
+ ND6_RLOCK();
+ TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
+ d.rtaddr.sin6_addr = dr->rtaddr;
+ error = sa6_recoverscope(&d.rtaddr);
+ if (error != 0)
+ break;
+ d.flags = dr->raflags;
+ d.rtlifetime = dr->rtlifetime;
+ d.expire = dr->expire + (time_second - time_uptime);
+ d.if_index = dr->ifp->if_index;
+ error = SYSCTL_OUT(req, &d, sizeof(d));
+ if (error != 0)
+ break;
+ }
+ ND6_RUNLOCK();
+ return (error);
+}
+SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
+ CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ NULL, 0, nd6_sysctl_drlist, "S,in6_defrouter",
+ "NDP default router list");
diff --git a/freebsd/sys/netinet6/raw_ip6.c b/freebsd/sys/netinet6/raw_ip6.c
index aa62b7e1..c33bca05 100644
--- a/freebsd/sys/netinet6/raw_ip6.c
+++ b/freebsd/sys/netinet6/raw_ip6.c
@@ -163,7 +163,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
struct ifnet *ifp;
struct mbuf *m = *mp;
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
- struct inpcb *in6p;
+ struct inpcb *inp;
struct inpcb *last = NULL;
struct mbuf *opts = NULL;
struct sockaddr_in6 fromsa;
@@ -176,18 +176,18 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
ifp = m->m_pkthdr.rcvif;
INP_INFO_RLOCK_ET(&V_ripcbinfo, et);
- CK_LIST_FOREACH(in6p, &V_ripcb, inp_list) {
+ CK_LIST_FOREACH(inp, &V_ripcb, inp_list) {
/* XXX inp locking */
- if ((in6p->inp_vflag & INP_IPV6) == 0)
+ if ((inp->inp_vflag & INP_IPV6) == 0)
continue;
- if (in6p->inp_ip_p &&
- in6p->inp_ip_p != proto)
+ if (inp->inp_ip_p &&
+ inp->inp_ip_p != proto)
continue;
- if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) &&
- !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst))
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) &&
+ !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, &ip6->ip6_dst))
continue;
- if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
- !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
+ if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) &&
+ !IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, &ip6->ip6_src))
continue;
if (last != NULL) {
struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
@@ -225,23 +225,23 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
INP_RUNLOCK(last);
last = NULL;
}
- INP_RLOCK(in6p);
- if (__predict_false(in6p->inp_flags2 & INP_FREED))
+ INP_RLOCK(inp);
+ if (__predict_false(inp->inp_flags2 & INP_FREED))
goto skip_2;
- if (jailed_without_vnet(in6p->inp_cred)) {
+ if (jailed_without_vnet(inp->inp_cred)) {
/*
* Allow raw socket in jail to receive multicast;
* assume process had PRIV_NETINET_RAW at attach,
* and fall through into normal filter path if so.
*/
if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) &&
- prison_check_ip6(in6p->inp_cred,
+ prison_check_ip6(inp->inp_cred,
&ip6->ip6_dst) != 0)
goto skip_2;
}
- if (in6p->in6p_cksum != -1) {
+ if (inp->in6p_cksum != -1) {
RIP6STAT_INC(rip6s_isum);
- if (m->m_pkthdr.len - (*offp + in6p->in6p_cksum) < 2 ||
+ if (m->m_pkthdr.len - (*offp + inp->in6p_cksum) < 2 ||
in6_cksum(m, proto, *offp,
m->m_pkthdr.len - *offp)) {
RIP6STAT_INC(rip6s_badsum);
@@ -260,7 +260,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
* should receive it, as multicast filtering is now
* the responsibility of the transport layer.
*/
- if (in6p->in6p_moptions &&
+ if (inp->in6p_moptions &&
IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
/*
* If the incoming datagram is for MLD, allow it
@@ -290,7 +290,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
mcaddr.sin6_family = AF_INET6;
mcaddr.sin6_addr = ip6->ip6_dst;
- blocked = im6o_mc_filter(in6p->in6p_moptions,
+ blocked = im6o_mc_filter(inp->in6p_moptions,
ifp,
(struct sockaddr *)&mcaddr,
(struct sockaddr *)&fromsa);
@@ -300,10 +300,10 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
goto skip_2;
}
}
- last = in6p;
+ last = inp;
continue;
skip_2:
- INP_RUNLOCK(in6p);
+ INP_RUNLOCK(inp);
}
INP_INFO_RUNLOCK_ET(&V_ripcbinfo, et);
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
@@ -396,7 +396,7 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
struct m_tag *mtag;
struct sockaddr_in6 *dstsock;
struct ip6_hdr *ip6;
- struct inpcb *in6p;
+ struct inpcb *inp;
u_int plen = m->m_pkthdr.len;
int error = 0;
struct ip6_pktopts opt, *optp;
@@ -413,18 +413,18 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
control = va_arg(ap, struct mbuf *);
va_end(ap);
- in6p = sotoinpcb(so);
- INP_WLOCK(in6p);
+ inp = sotoinpcb(so);
+ INP_WLOCK(inp);
if (control != NULL) {
if ((error = ip6_setpktopts(control, &opt,
- in6p->in6p_outputopts, so->so_cred,
+ inp->in6p_outputopts, so->so_cred,
so->so_proto->pr_protocol)) != 0) {
goto bad;
}
optp = &opt;
} else
- optp = in6p->in6p_outputopts;
+ optp = inp->in6p_outputopts;
/*
* Check and convert scope zone ID into internal form.
@@ -467,12 +467,12 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
/*
* Source address selection.
*/
- error = in6_selectsrc_socket(dstsock, optp, in6p, so->so_cred,
+ error = in6_selectsrc_socket(dstsock, optp, inp, so->so_cred,
scope_ambiguous, &in6a, &hlim);
if (error)
goto bad;
- error = prison_check_ip6(in6p->inp_cred, &in6a);
+ error = prison_check_ip6(inp->inp_cred, &in6a);
if (error != 0)
goto bad;
ip6->ip6_src = in6a;
@@ -483,18 +483,18 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
* Fill in the rest of the IPv6 header fields.
*/
ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
- (in6p->inp_flow & IPV6_FLOWINFO_MASK);
+ (inp->inp_flow & IPV6_FLOWINFO_MASK);
ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
(IPV6_VERSION & IPV6_VERSION_MASK);
/*
* ip6_plen will be filled in ip6_output, so not fill it here.
*/
- ip6->ip6_nxt = in6p->inp_ip_p;
+ ip6->ip6_nxt = inp->inp_ip_p;
ip6->ip6_hlim = hlim;
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 ||
- in6p->in6p_cksum != -1) {
+ inp->in6p_cksum != -1) {
struct mbuf *n;
int off;
u_int16_t *p;
@@ -503,7 +503,7 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)
off = offsetof(struct icmp6_hdr, icmp6_cksum);
else
- off = in6p->in6p_cksum;
+ off = inp->in6p_cksum;
if (plen < off + 2) {
error = EINVAL;
goto bad;
@@ -539,7 +539,7 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
}
}
- error = ip6_output(m, optp, NULL, 0, in6p->in6p_moptions, &oifp, in6p);
+ error = ip6_output(m, optp, NULL, 0, inp->in6p_moptions, &oifp, inp);
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
if (oifp)
icmp6_ifoutstat_inc(oifp, type, code);
@@ -558,7 +558,7 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
ip6_clearpktopts(&opt, -1);
m_freem(control);
}
- INP_WUNLOCK(in6p);
+ INP_WUNLOCK(inp);
return (error);
}
diff --git a/freebsd/sys/netinet6/route6.c b/freebsd/sys/netinet6/route6.c
index 7014daa6..908a5479 100644
--- a/freebsd/sys/netinet6/route6.c
+++ b/freebsd/sys/netinet6/route6.c
@@ -64,12 +64,16 @@ int
route6_input(struct mbuf **mp, int *offp, int proto)
{
struct ip6_hdr *ip6;
- struct mbuf *m = *mp;
+ struct mbuf *m;
struct ip6_rthdr *rh;
int off = *offp, rhlen;
#ifdef __notyet__
struct ip6aux *ip6a;
+#endif
+
+ m = *mp;
+#ifdef __notyet__
ip6a = ip6_findaux(m);
if (ip6a) {
/* XXX reject home-address option before rthdr */
@@ -81,18 +85,16 @@ route6_input(struct mbuf **mp, int *offp, int proto)
}
#endif
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE);
+ if (m->m_len < off + sizeof(*rh)) {
+ m = m_pullup(m, off + sizeof(*rh));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (IPPROTO_DONE);
+ }
+ }
ip6 = mtod(m, struct ip6_hdr *);
rh = (struct ip6_rthdr *)((caddr_t)ip6 + off);
-#else
- ip6 = mtod(m, struct ip6_hdr *);
- IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh));
- if (rh == NULL) {
- IP6STAT_INC(ip6s_tooshort);
- return IPPROTO_DONE;
- }
-#endif
/*
* While this switch may look gratuitous, leave it in
@@ -108,9 +110,11 @@ route6_input(struct mbuf **mp, int *offp, int proto)
IP6STAT_INC(ip6s_badoptions);
icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
(caddr_t)&rh->ip6r_type - (caddr_t)ip6);
+ *mp = NULL;
return (IPPROTO_DONE);
}
*offp += rhlen;
+ *mp = m;
return (rh->ip6r_nxt);
}
diff --git a/freebsd/sys/netinet6/sctp6_usrreq.c b/freebsd/sys/netinet6/sctp6_usrreq.c
index 3465f3c3..d3421894 100644
--- a/freebsd/sys/netinet6/sctp6_usrreq.c
+++ b/freebsd/sys/netinet6/sctp6_usrreq.c
@@ -107,13 +107,15 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
- ip6 = mtod(m, struct ip6_hdr *);
- IP6_EXTHDR_GET(sh, struct sctphdr *, m, iphlen,
- (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)));
- if (sh == NULL) {
- SCTP_STAT_INCR(sctps_hdrops);
- return (IPPROTO_DONE);
+ if (m->m_len < offset) {
+ m = m_pullup(m, offset);
+ if (m == NULL) {
+ SCTP_STAT_INCR(sctps_hdrops);
+ return (IPPROTO_DONE);
+ }
}
+ ip6 = mtod(m, struct ip6_hdr *);
+ sh = (struct sctphdr *)(mtod(m, caddr_t) + iphlen);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset -= sizeof(struct sctp_chunkhdr);
memset(&src, 0, sizeof(struct sockaddr_in6));
@@ -522,7 +524,6 @@ sctp_must_try_again:
static int
sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED)
{
- struct in6pcb *inp6;
int error;
struct sctp_inpcb *inp;
uint32_t vrf_id = SCTP_DEFAULT_VRFID;
@@ -544,18 +545,17 @@ sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNU
inp = (struct sctp_inpcb *)so->so_pcb;
SCTP_INP_WLOCK(inp);
inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_V6; /* I'm v6! */
- inp6 = (struct in6pcb *)inp;
- inp6->inp_vflag |= INP_IPV6;
- inp6->in6p_hops = -1; /* use kernel default */
- inp6->in6p_cksum = -1; /* just to be sure */
+ inp->ip_inp.inp.inp_vflag |= INP_IPV6;
+ inp->ip_inp.inp.in6p_hops = -1; /* use kernel default */
+ inp->ip_inp.inp.in6p_cksum = -1; /* just to be sure */
#ifdef INET
/*
* XXX: ugly!! IPv4 TTL initialization is necessary for an IPv6
* socket as well, because the socket may be bound to an IPv6
* wildcard address, which may match an IPv4-mapped IPv6 address.
*/
- inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
+ inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
#endif
SCTP_INP_WUNLOCK(inp);
return (0);
@@ -565,8 +565,8 @@ static int
sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
{
struct sctp_inpcb *inp;
- struct in6pcb *inp6;
int error;
+ u_char vflagsav;
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
@@ -597,16 +597,16 @@ sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
return (EINVAL);
}
}
- inp6 = (struct in6pcb *)inp;
- inp6->inp_vflag &= ~INP_IPV4;
- inp6->inp_vflag |= INP_IPV6;
- if ((addr != NULL) && (SCTP_IPV6_V6ONLY(inp6) == 0)) {
+ vflagsav = inp->ip_inp.inp.inp_vflag;
+ inp->ip_inp.inp.inp_vflag &= ~INP_IPV4;
+ inp->ip_inp.inp.inp_vflag |= INP_IPV6;
+ if ((addr != NULL) && (SCTP_IPV6_V6ONLY(&inp->ip_inp.inp) == 0)) {
switch (addr->sa_family) {
#ifdef INET
case AF_INET:
/* binding v4 addr to v6 socket, so reset flags */
- inp6->inp_vflag |= INP_IPV4;
- inp6->inp_vflag &= ~INP_IPV6;
+ inp->ip_inp.inp.inp_vflag |= INP_IPV4;
+ inp->ip_inp.inp.inp_vflag &= ~INP_IPV6;
break;
#endif
#ifdef INET6
@@ -617,17 +617,17 @@ sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
sin6_p = (struct sockaddr_in6 *)addr;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr)) {
- inp6->inp_vflag |= INP_IPV4;
+ inp->ip_inp.inp.inp_vflag |= INP_IPV4;
}
#ifdef INET
if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
struct sockaddr_in sin;
in6_sin6_2_sin(&sin, sin6_p);
- inp6->inp_vflag |= INP_IPV4;
- inp6->inp_vflag &= ~INP_IPV6;
+ inp->ip_inp.inp.inp_vflag |= INP_IPV4;
+ inp->ip_inp.inp.inp_vflag &= ~INP_IPV6;
error = sctp_inpcb_bind(so, (struct sockaddr *)&sin, NULL, p);
- return (error);
+ goto out;
}
#endif
break;
@@ -644,7 +644,8 @@ sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
if (addr->sa_family == AF_INET) {
/* can't bind v4 addr to v6 only socket! */
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
- return (EINVAL);
+ error = EINVAL;
+ goto out;
}
#endif
sin6_p = (struct sockaddr_in6 *)addr;
@@ -653,10 +654,14 @@ sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
/* can't bind v4-mapped addrs either! */
/* NOTE: we don't support SIIT */
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
- return (EINVAL);
+ error = EINVAL;
+ goto out;
}
}
error = sctp_inpcb_bind(so, addr, NULL, p);
+out:
+ if (error != 0)
+ inp->ip_inp.inp.inp_vflag = vflagsav;
return (error);
}
@@ -687,7 +692,6 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
struct mbuf *control, struct thread *p)
{
struct sctp_inpcb *inp;
- struct in6pcb *inp6;
#ifdef INET
struct sockaddr_in6 *sin6;
@@ -704,7 +708,6 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
- inp6 = (struct in6pcb *)inp;
/*
* For the TCP model we may get a NULL addr, if we are a connected
* socket thats ok.
@@ -724,7 +727,7 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
}
#ifdef INET
sin6 = (struct sockaddr_in6 *)addr;
- if (SCTP_IPV6_V6ONLY(inp6)) {
+ if (SCTP_IPV6_V6ONLY(inp)) {
/*
* if IPV6_V6ONLY flag, we discard datagrams destined to a
* v4 addr or v4-mapped addr
@@ -793,14 +796,10 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
struct sctp_inpcb *inp;
struct sctp_tcb *stcb;
#ifdef INET
- struct in6pcb *inp6;
struct sockaddr_in6 *sin6;
union sctp_sockstore store;
#endif
-#ifdef INET
- inp6 = (struct in6pcb *)so->so_pcb;
-#endif
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
@@ -858,7 +857,7 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
}
#ifdef INET
sin6 = (struct sockaddr_in6 *)addr;
- if (SCTP_IPV6_V6ONLY(inp6)) {
+ if (SCTP_IPV6_V6ONLY(inp)) {
/*
* if IPV6_V6ONLY flag, ignore connections destined to a v4
* addr or v4-mapped addr
@@ -1100,10 +1099,10 @@ sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
static int
sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
{
- struct in6pcb *inp6 = sotoin6pcb(so);
+ struct inpcb *inp = sotoinpcb(so);
int error;
- if (inp6 == NULL) {
+ if (inp == NULL) {
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
@@ -1136,10 +1135,10 @@ sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
static int
sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
{
- struct in6pcb *inp6 = sotoin6pcb(so);
+ struct inpcb *inp = sotoinpcb(so);
int error;
- if (inp6 == NULL) {
+ if (inp == NULL) {
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
diff --git a/freebsd/sys/netinet6/udp6_usrreq.c b/freebsd/sys/netinet6/udp6_usrreq.c
index 270b4880..845d0dc9 100644
--- a/freebsd/sys/netinet6/udp6_usrreq.c
+++ b/freebsd/sys/netinet6/udp6_usrreq.c
@@ -224,16 +224,16 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
ifp = m->m_pkthdr.rcvif;
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
+ if (m->m_len < off + sizeof(struct udphdr)) {
+ m = m_pullup(m, off + sizeof(struct udphdr));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (IPPROTO_DONE);
+ }
+ }
ip6 = mtod(m, struct ip6_hdr *);
uh = (struct udphdr *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(*uh));
- if (!uh)
- return (IPPROTO_DONE);
- ip6 = mtod(m, struct ip6_hdr *);
-#endif
UDPSTAT_INC(udps_ipackets);
@@ -396,8 +396,11 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
else
UDP_PROBE(receive, NULL, last,
ip6, last, uh);
- if (udp6_append(last, n, off, fromsa))
+ if (udp6_append(last, n, off, fromsa)) {
+ /* XXX-BZ do we leak m here? */
+ *mp = NULL;
goto inp_lost;
+ }
}
INP_RUNLOCK(last);
}
@@ -438,6 +441,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
INP_RUNLOCK(last);
inp_lost:
INP_INFO_RUNLOCK_ET(pcbinfo, et);
+ *mp = NULL;
return (IPPROTO_DONE);
}
/*
@@ -481,7 +485,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB,
m->m_pkthdr.rcvif, m);
if (inp == NULL) {
- if (udp_log_in_vain) {
+ if (V_udp_log_in_vain) {
char ip6bufs[INET6_ADDRSTRLEN];
char ip6bufd[INET6_ADDRSTRLEN];
@@ -505,6 +509,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
if (V_udp_blackhole)
goto badunlocked;
icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
+ *mp = NULL;
return (IPPROTO_DONE);
}
INP_RLOCK_ASSERT(inp);
@@ -513,6 +518,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
if (up->u_rxcslen == 0 || up->u_rxcslen > ulen) {
INP_RUNLOCK(inp);
m_freem(m);
+ *mp = NULL;
return (IPPROTO_DONE);
}
}
@@ -522,6 +528,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
UDP_PROBE(receive, NULL, inp, ip6, inp, uh);
if (udp6_append(inp, m, off, fromsa) == 0)
INP_RUNLOCK(inp);
+ *mp = NULL;
return (IPPROTO_DONE);
badheadlocked:
@@ -529,6 +536,7 @@ badheadlocked:
badunlocked:
if (m)
m_freem(m);
+ *mp = NULL;
return (IPPROTO_DONE);
}
@@ -1145,6 +1153,7 @@ udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
struct inpcb *inp;
struct inpcbinfo *pcbinfo;
int error;
+ u_char vflagsav;
pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
inp = sotoinpcb(so);
@@ -1152,6 +1161,7 @@ udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
INP_WLOCK(inp);
INP_HASH_WLOCK(pcbinfo);
+ vflagsav = inp->inp_vflag;
inp->inp_vflag &= ~INP_IPV4;
inp->inp_vflag |= INP_IPV6;
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
@@ -1179,6 +1189,8 @@ udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
#ifdef INET
out:
#endif
+ if (error != 0)
+ inp->inp_vflag = vflagsav;
INP_HASH_WUNLOCK(pcbinfo);
INP_WUNLOCK(inp);
return (error);
@@ -1225,6 +1237,7 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
struct inpcbinfo *pcbinfo;
struct sockaddr_in6 *sin6;
int error;
+ u_char vflagsav;
pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
inp = sotoinpcb(so);
@@ -1252,17 +1265,26 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
goto out;
}
in6_sin6_2_sin(&sin, sin6);
- inp->inp_vflag |= INP_IPV4;
- inp->inp_vflag &= ~INP_IPV6;
error = prison_remote_ip4(td->td_ucred, &sin.sin_addr);
if (error != 0)
goto out;
+ vflagsav = inp->inp_vflag;
+ inp->inp_vflag |= INP_IPV4;
+ inp->inp_vflag &= ~INP_IPV6;
INP_HASH_WLOCK(pcbinfo);
error = in_pcbconnect(inp, (struct sockaddr *)&sin,
td->td_ucred);
INP_HASH_WUNLOCK(pcbinfo);
+ /*
+ * If connect succeeds, mark socket as connected. If
+ * connect fails and socket is unbound, reset inp_vflag
+ * field.
+ */
if (error == 0)
soisconnected(so);
+ else if (inp->inp_laddr.s_addr == INADDR_ANY &&
+ inp->inp_lport == 0)
+ inp->inp_vflag = vflagsav;
goto out;
} else {
if ((inp->inp_vflag & INP_IPV6) == 0) {
@@ -1275,16 +1297,25 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
error = EISCONN;
goto out;
}
- inp->inp_vflag &= ~INP_IPV4;
- inp->inp_vflag |= INP_IPV6;
error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);
if (error != 0)
goto out;
+ vflagsav = inp->inp_vflag;
+ inp->inp_vflag &= ~INP_IPV4;
+ inp->inp_vflag |= INP_IPV6;
INP_HASH_WLOCK(pcbinfo);
error = in6_pcbconnect(inp, nam, td->td_ucred);
INP_HASH_WUNLOCK(pcbinfo);
+ /*
+ * If connect succeeds, mark socket as connected. If
+ * connect fails and socket is unbound, reset inp_vflag
+ * field.
+ */
if (error == 0)
soisconnected(so);
+ else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) &&
+ inp->inp_lport == 0)
+ inp->inp_vflag = vflagsav;
out:
INP_WUNLOCK(inp);
return (error);
diff --git a/freebsd/sys/netipsec/xform_ah.c b/freebsd/sys/netipsec/xform_ah.c
index 618fbd9b..afe26445 100644
--- a/freebsd/sys/netipsec/xform_ah.c
+++ b/freebsd/sys/netipsec/xform_ah.c
@@ -577,14 +577,16 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
/* Figure out header size. */
rplen = HDRSIZE(sav);
- /* XXX don't pullup, just copy header */
- IP6_EXTHDR_GET(ah, struct newah *, m, skip, rplen);
- if (ah == NULL) {
- DPRINTF(("ah_input: cannot pullup header\n"));
- AHSTAT_INC(ahs_hdrops); /*XXX*/
- error = ENOBUFS;
- goto bad;
+ if (m->m_len < skip + rplen) {
+ m = m_pullup(m, skip + rplen);
+ if (m == NULL) {
+ DPRINTF(("ah_input: cannot pullup header\n"));
+ AHSTAT_INC(ahs_hdrops); /*XXX*/
+ error = ENOBUFS;
+ goto bad;
+ }
}
+ ah = (struct newah *)(mtod(m, caddr_t) + skip);
/* Check replay window, if applicable. */
SECASVAR_LOCK(sav);
diff --git a/freebsd/sys/netipsec/xform_esp.c b/freebsd/sys/netipsec/xform_esp.c
index f5752a96..da64655d 100644
--- a/freebsd/sys/netipsec/xform_esp.c
+++ b/freebsd/sys/netipsec/xform_esp.c
@@ -309,8 +309,17 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
ESPSTAT_INC(esps_badilen);
goto bad;
}
- /* XXX don't pullup, just copy header */
- IP6_EXTHDR_GET(esp, struct newesp *, m, skip, sizeof (struct newesp));
+
+ if (m->m_len < skip + sizeof(*esp)) {
+ m = m_pullup(m, skip + sizeof(*esp));
+ if (m == NULL) {
+ DPRINTF(("%s: cannot pullup header\n", __func__));
+ ESPSTAT_INC(esps_hdrops); /*XXX*/
+ error = ENOBUFS;
+ goto bad;
+ }
+ }
+ esp = (struct newesp *)(mtod(m, caddr_t) + skip);
esph = sav->tdb_authalgxform;
espx = sav->tdb_encalgxform;
@@ -609,6 +618,13 @@ esp_input_cb(struct cryptop *crp)
}
}
+ /*
+ * RFC4303 2.6:
+ * Silently drop packet if next header field is IPPROTO_NONE.
+ */
+ if (lastthree[2] == IPPROTO_NONE)
+ goto bad;
+
/* Trim the mbuf chain to remove trailing authenticator and padding */
m_adj(m, -(lastthree[1] + 2));
diff --git a/freebsd/sys/netpfil/pf/pf.c b/freebsd/sys/netpfil/pf/pf.c
index 4f9da55b..6bc1b8c8 100644
--- a/freebsd/sys/netpfil/pf/pf.c
+++ b/freebsd/sys/netpfil/pf/pf.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_inet6.h>
#include <rtems/bsd/local/opt_bpf.h>
#include <rtems/bsd/local/opt_pf.h>
+#include <rtems/bsd/local/opt_sctp.h>
#include <sys/param.h>
#include <sys/bus.h>
@@ -105,6 +106,10 @@ __FBSDID("$FreeBSD$");
#include <netinet6/scope6_var.h>
#endif /* INET6 */
+#ifdef SCTP
+#include <netinet/sctp_crc32.h>
+#endif
+
#include <machine/in_cksum.h>
#include <security/mac/mac_framework.h>
@@ -5601,7 +5606,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
}
#ifdef SCTP
if (m0->m_pkthdr.csum_flags & CSUM_SCTP & ~ifp->if_hwassist) {
- sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
+ sctp_delayed_cksum(m0, (uint32_t)(ip->ip_hl << 2));
m0->m_pkthdr.csum_flags &= ~CSUM_SCTP;
}
#endif
diff --git a/freebsd/sys/opencrypto/cryptodev.c b/freebsd/sys/opencrypto/cryptodev.c
index 02a03034..d3f4ad1c 100644
--- a/freebsd/sys/opencrypto/cryptodev.c
+++ b/freebsd/sys/opencrypto/cryptodev.c
@@ -268,6 +268,7 @@ crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to)
struct csession {
TAILQ_ENTRY(csession) next;
crypto_session_t cses;
+ volatile u_int refs;
u_int32_t ses;
struct mtx lock; /* for op submission */
@@ -294,6 +295,7 @@ struct cryptop_data {
struct fcrypt {
TAILQ_HEAD(csessionlist, csession) csessions;
int sesn;
+ struct mtx lock;
};
static struct timeval warninterval = { .tv_sec = 60, .tv_usec = 0 };
@@ -330,8 +332,7 @@ static const rtems_filesystem_file_handlers_r cryptofops;
#endif /* __rtems__ */
static struct csession *csefind(struct fcrypt *, u_int);
-static int csedelete(struct fcrypt *, struct csession *);
-static struct csession *cseadd(struct fcrypt *, struct csession *);
+static bool csedelete(struct fcrypt *, u_int);
static struct csession *csecreate(struct fcrypt *, crypto_session_t, caddr_t,
u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *,
struct auth_hash *);
@@ -398,8 +399,6 @@ cryptof_ioctl(
struct crypt_op copc;
struct crypt_kop kopc;
#endif
- static struct timeval arc4warn, blfwarn, castwarn, deswarn, md5warn;
- static struct timeval skipwarn, tdeswarn;
switch (cmd) {
case CIOCGSESSION:
@@ -420,28 +419,18 @@ cryptof_ioctl(
case 0:
break;
case CRYPTO_DES_CBC:
- if (ratecheck(&deswarn, &warninterval))
- gone_in(13, "DES cipher via /dev/crypto");
txform = &enc_xform_des;
break;
case CRYPTO_3DES_CBC:
- if (ratecheck(&tdeswarn, &warninterval))
- gone_in(13, "3DES cipher via /dev/crypto");
txform = &enc_xform_3des;
break;
case CRYPTO_BLF_CBC:
- if (ratecheck(&blfwarn, &warninterval))
- gone_in(13, "Blowfish cipher via /dev/crypto");
txform = &enc_xform_blf;
break;
case CRYPTO_CAST_CBC:
- if (ratecheck(&castwarn, &warninterval))
- gone_in(13, "CAST128 cipher via /dev/crypto");
txform = &enc_xform_cast5;
break;
case CRYPTO_SKIPJACK_CBC:
- if (ratecheck(&skipwarn, &warninterval))
- gone_in(13, "Skipjack cipher via /dev/crypto");
txform = &enc_xform_skipjack;
break;
case CRYPTO_AES_CBC:
@@ -454,8 +443,6 @@ cryptof_ioctl(
txform = &enc_xform_null;
break;
case CRYPTO_ARC4:
- if (ratecheck(&arc4warn, &warninterval))
- gone_in(13, "ARC4 cipher via /dev/crypto");
txform = &enc_xform_arc4;
break;
case CRYPTO_CAMELLIA_CBC:
@@ -484,9 +471,6 @@ cryptof_ioctl(
case 0:
break;
case CRYPTO_MD5_HMAC:
- if (ratecheck(&md5warn, &warninterval))
- gone_in(13,
- "MD5-HMAC authenticator via /dev/crypto");
thash = &auth_hash_hmac_md5;
break;
case CRYPTO_POLY1305:
@@ -608,8 +592,8 @@ cryptof_ioctl(
if (thash) {
cria.cri_alg = thash->type;
cria.cri_klen = sop->mackeylen * 8;
- if (thash->keysize != 0 &&
- sop->mackeylen > thash->keysize) {
+ if (sop->mackeylen > thash->keysize ||
+ sop->mackeylen < 0) {
CRYPTDEB("invalid mac key length");
error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error,
@@ -692,13 +676,10 @@ bail:
break;
case CIOCFSESSION:
ses = *(u_int32_t *)data;
- cse = csefind(fcr, ses);
- if (cse == NULL) {
+ if (!csedelete(fcr, ses)) {
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
return (EINVAL);
}
- csedelete(fcr, cse);
- csefree(cse);
break;
case CIOCCRYPT:
#ifdef COMPAT_FREEBSD32
@@ -715,6 +696,7 @@ bail:
return (EINVAL);
}
error = cryptodev_op(cse, cop, active_cred, td);
+ csefree(cse);
#ifdef COMPAT_FREEBSD32
if (error == 0 && cmd == CIOCCRYPT32)
crypt_op_to_32(cop, data);
@@ -781,6 +763,7 @@ bail:
return (EINVAL);
}
error = cryptodev_aead(cse, caead, active_cred, td);
+ csefree(cse);
break;
default:
error = EINVAL;
@@ -843,6 +826,47 @@ cod_free(struct cryptop_data *cod)
free(cod, M_XDATA);
}
+static void
+cryptodev_warn(struct csession *cse)
+{
+ static struct timeval arc4warn, blfwarn, castwarn, deswarn, md5warn;
+ static struct timeval skipwarn, tdeswarn;
+
+ switch (cse->cipher) {
+ case CRYPTO_DES_CBC:
+ if (ratecheck(&deswarn, &warninterval))
+ gone_in(13, "DES cipher via /dev/crypto");
+ break;
+ case CRYPTO_3DES_CBC:
+ if (ratecheck(&tdeswarn, &warninterval))
+ gone_in(13, "3DES cipher via /dev/crypto");
+ break;
+ case CRYPTO_BLF_CBC:
+ if (ratecheck(&blfwarn, &warninterval))
+ gone_in(13, "Blowfish cipher via /dev/crypto");
+ break;
+ case CRYPTO_CAST_CBC:
+ if (ratecheck(&castwarn, &warninterval))
+ gone_in(13, "CAST128 cipher via /dev/crypto");
+ break;
+ case CRYPTO_SKIPJACK_CBC:
+ if (ratecheck(&skipwarn, &warninterval))
+ gone_in(13, "Skipjack cipher via /dev/crypto");
+ break;
+ case CRYPTO_ARC4:
+ if (ratecheck(&arc4warn, &warninterval))
+ gone_in(13, "ARC4 cipher via /dev/crypto");
+ break;
+ }
+
+ switch (cse->mac) {
+ case CRYPTO_MD5_HMAC:
+ if (ratecheck(&md5warn, &warninterval))
+ gone_in(13, "MD5-HMAC authenticator via /dev/crypto");
+ break;
+ }
+}
+
static int
cryptodev_op(
struct csession *cse,
@@ -965,6 +989,7 @@ cryptodev_op(
error = EINVAL;
goto bail;
}
+ cryptodev_warn(cse);
again:
/*
@@ -1134,6 +1159,7 @@ cryptodev_aead(
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
+ cryptodev_warn(cse);
again:
/*
* Let the dispatch run unlocked, then, interlock against the
@@ -1383,6 +1409,9 @@ cryptof_close(struct file *fp, struct thread *td)
while ((cse = TAILQ_FIRST(&fcr->csessions))) {
TAILQ_REMOVE(&fcr->csessions, cse, next);
+ KASSERT(cse->refs == 1,
+ ("%s: crypto session %p with %d refs", __func__, cse,
+ cse->refs));
csefree(cse);
}
free(fcr, M_XDATA);
@@ -1425,34 +1454,36 @@ csefind(struct fcrypt *fcr, u_int ses)
{
struct csession *cse;
- TAILQ_FOREACH(cse, &fcr->csessions, next)
- if (cse->ses == ses)
+ mtx_lock(&fcr->lock);
+ TAILQ_FOREACH(cse, &fcr->csessions, next) {
+ if (cse->ses == ses) {
+ refcount_acquire(&cse->refs);
+ mtx_unlock(&fcr->lock);
return (cse);
+ }
+ }
+ mtx_unlock(&fcr->lock);
return (NULL);
}
-static int
-csedelete(struct fcrypt *fcr, struct csession *cse_del)
+static bool
+csedelete(struct fcrypt *fcr, u_int ses)
{
struct csession *cse;
+ mtx_lock(&fcr->lock);
TAILQ_FOREACH(cse, &fcr->csessions, next) {
- if (cse == cse_del) {
+ if (cse->ses == ses) {
TAILQ_REMOVE(&fcr->csessions, cse, next);
- return (1);
+ mtx_unlock(&fcr->lock);
+ csefree(cse);
+ return (true);
}
}
- return (0);
+ mtx_unlock(&fcr->lock);
+ return (false);
}
-static struct csession *
-cseadd(struct fcrypt *fcr, struct csession *cse)
-{
- TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
- cse->ses = fcr->sesn++;
- return (cse);
-}
-
struct csession *
csecreate(struct fcrypt *fcr, crypto_session_t cses, caddr_t key, u_int64_t keylen,
caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac,
@@ -1464,6 +1495,7 @@ csecreate(struct fcrypt *fcr, crypto_session_t cses, caddr_t key, u_int64_t keyl
if (cse == NULL)
return NULL;
mtx_init(&cse->lock, "cryptodev", "crypto session lock", MTX_DEF);
+ refcount_init(&cse->refs, 1);
cse->key = key;
cse->keylen = keylen/8;
cse->mackey = mackey;
@@ -1473,7 +1505,10 @@ csecreate(struct fcrypt *fcr, crypto_session_t cses, caddr_t key, u_int64_t keyl
cse->mac = mac;
cse->txform = txform;
cse->thash = thash;
- cseadd(fcr, cse);
+ mtx_lock(&fcr->lock);
+ TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
+ cse->ses = fcr->sesn++;
+ mtx_unlock(&fcr->lock);
return (cse);
}
@@ -1481,6 +1516,8 @@ static void
csefree(struct csession *cse)
{
+ if (!refcount_release(&cse->refs))
+ return;
crypto_freesession(cse->cses);
mtx_destroy(&cse->lock);
if (cse->key)
@@ -1517,13 +1554,14 @@ cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread
switch (cmd) {
case CRIOGET:
- fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK);
+ fcr = malloc(sizeof(struct fcrypt), M_XDATA, M_WAITOK | M_ZERO);
TAILQ_INIT(&fcr->csessions);
- fcr->sesn = 0;
+ mtx_init(&fcr->lock, "fcrypt", NULL, MTX_DEF);
error = falloc(td, &f, &fd, 0);
if (error) {
+ mtx_destroy(&fcr->lock);
free(fcr, M_XDATA);
return (error);
}
diff --git a/freebsd/sys/sys/buf.h b/freebsd/sys/sys/buf.h
index a099a972..209174b4 100644
--- a/freebsd/sys/sys/buf.h
+++ b/freebsd/sys/sys/buf.h
@@ -450,7 +450,7 @@ buf_countdeps(struct buf *bp, int i)
}
static __inline void
-buf_track(struct buf *bp, const char *location)
+buf_track(struct buf *bp __unused, const char *location __unused)
{
#if defined(FULL_BUF_TRACKING)
diff --git a/freebsd/sys/sys/bus.h b/freebsd/sys/sys/bus.h
index 1ac476a4..48babb3a 100644
--- a/freebsd/sys/sys/bus.h
+++ b/freebsd/sys/sys/bus.h
@@ -563,6 +563,7 @@ int bus_child_present(device_t child);
int bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen);
int bus_child_location_str(device_t child, char *buf, size_t buflen);
void bus_enumerate_hinted_children(device_t bus);
+int bus_delayed_attach_children(device_t bus);
static __inline struct resource *
bus_alloc_resource_any(device_t dev, int type, int *rid, u_int flags)
diff --git a/freebsd/sys/sys/conf.h b/freebsd/sys/sys/conf.h
index 4ace162f..d6215ba9 100644
--- a/freebsd/sys/sys/conf.h
+++ b/freebsd/sys/sys/conf.h
@@ -66,7 +66,7 @@ struct cdev {
#define SI_ETERNAL 0x0001 /* never destroyed */
#define SI_ALIAS 0x0002 /* carrier of alias name */
#define SI_NAMED 0x0004 /* make_dev{_alias} has been called */
-#define SI_CHEAPCLONE 0x0008 /* can be removed_dev'ed when vnode reclaims */
+#define SI_UNUSED1 0x0008 /* unused */
#define SI_CHILD 0x0010 /* child of another struct cdev **/
#define SI_DUMPDEV 0x0080 /* is kernel dumpdev */
#define SI_CLONELIST 0x0200 /* on a clone list */
diff --git a/freebsd/sys/sys/kernel.h b/freebsd/sys/sys/kernel.h
index 41a5233a..fb9ad6ac 100644
--- a/freebsd/sys/sys/kernel.h
+++ b/freebsd/sys/sys/kernel.h
@@ -475,6 +475,8 @@ struct tunable_str {
#define TUNABLE_LONG_FETCH(path, var)
#define TUNABLE_ULONG(path, var)
#define TUNABLE_ULONG_FETCH(path, var)
+#define TUNABLE_UINT64(path, var)
+#define TUNABLE_UINT64_FETCH(path, var)
#define TUNABLE_QUAD(path, var)
#define TUNABLE_QUAD_FETCH(path, var)
#define TUNABLE_STR(path, var, size)
diff --git a/freebsd/sys/sys/linker.h b/freebsd/sys/sys/linker.h
index 8aae31d9..10baaa03 100644
--- a/freebsd/sys/sys/linker.h
+++ b/freebsd/sys/sys/linker.h
@@ -97,6 +97,11 @@ struct linker_file {
*/
int nenabled; /* number of enabled probes. */
int fbt_nentries; /* number of fbt entries created. */
+
+#ifdef __arm__
+ caddr_t exidx_addr; /* Unwind data index table start */
+ size_t exidx_size; /* Unwind data index table size */
+#endif
};
/*
diff --git a/freebsd/sys/sys/malloc.h b/freebsd/sys/sys/malloc.h
index 83510329..56b17f36 100644
--- a/freebsd/sys/sys/malloc.h
+++ b/freebsd/sys/sys/malloc.h
@@ -185,7 +185,11 @@ void *contigmalloc_domainset(unsigned long size, struct malloc_type *type,
unsigned long alignment, vm_paddr_t boundary)
__malloc_like __result_use_check __alloc_size(1) __alloc_align(7);
void free(void *addr, struct malloc_type *type);
+#ifndef __rtems__
void free_domain(void *addr, struct malloc_type *type);
+#else /* __rtems__ */
+#define free_domain(addr, type) free(addr, type)
+#endif /* __rtems__ */
#ifndef __rtems__
void *malloc(size_t size, struct malloc_type *type, int flags) __malloc_like
__result_use_check __alloc_size(1);
@@ -250,9 +254,13 @@ void *_bsd_malloc(size_t size, struct malloc_type *type, int flags)
_malloc_item; \
})
+#ifndef __rtems__
void *malloc_domainset(size_t size, struct malloc_type *type,
struct domainset *ds, int flags) __malloc_like __result_use_check
__alloc_size(1);
+#else /* __rtems__ */
+#define malloc_domainset(size, type, ds, flags) malloc(size, type, flags)
+#endif /* __rtems__ */
void *mallocarray(size_t nmemb, size_t size, struct malloc_type *type,
int flags) __malloc_like __result_use_check
__alloc_size2(1, 2);
diff --git a/freebsd/sys/sys/mbuf.h b/freebsd/sys/sys/mbuf.h
index 634f7d9e..badc7eef 100644
--- a/freebsd/sys/sys/mbuf.h
+++ b/freebsd/sys/sys/mbuf.h
@@ -521,6 +521,8 @@ struct mbuf {
#define CSUM_L5_VALID 0x20000000 /* checksum is correct */
#define CSUM_COALESCED 0x40000000 /* contains merged segments */
+#define CSUM_SND_TAG 0x80000000 /* Packet header has send tag */
+
/*
* CSUM flag description for use with printf(9) %b identifier.
*/
@@ -530,7 +532,7 @@ struct mbuf {
"\12CSUM_IP6_UDP\13CSUM_IP6_TCP\14CSUM_IP6_SCTP\15CSUM_IP6_TSO" \
"\16CSUM_IP6_ISCSI" \
"\31CSUM_L3_CALC\32CSUM_L3_VALID\33CSUM_L4_CALC\34CSUM_L4_VALID" \
- "\35CSUM_L5_CALC\36CSUM_L5_VALID\37CSUM_COALESCED"
+ "\35CSUM_L5_CALC\36CSUM_L5_VALID\37CSUM_COALESCED\40CSUM_SND_TAG"
/* CSUM flags compatibility mappings. */
#define CSUM_IP_CHECKED CSUM_L3_CALC
diff --git a/freebsd/sys/sys/mount.h b/freebsd/sys/sys/mount.h
index dabb506d..698716f5 100644
--- a/freebsd/sys/sys/mount.h
+++ b/freebsd/sys/sys/mount.h
@@ -396,6 +396,7 @@ void __mnt_vnode_markerfree_active(struct vnode **mvp, struct mount *);
#define MNTK_UNMAPPED_BUFS 0x00002000
#define MNTK_USES_BCACHE 0x00004000 /* FS uses the buffer cache. */
#define MNTK_TEXT_REFS 0x00008000 /* Keep use ref for text */
+#define MNTK_VMSETSIZE_BUG 0x00010000
#define MNTK_NOASYNC 0x00800000 /* disable async */
#define MNTK_UNMOUNT 0x01000000 /* unmount in progress */
#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */
diff --git a/freebsd/sys/sys/pcpu.h b/freebsd/sys/sys/pcpu.h
index 0ce30af7..7812c3d8 100644
--- a/freebsd/sys/sys/pcpu.h
+++ b/freebsd/sys/sys/pcpu.h
@@ -221,10 +221,6 @@ extern struct cpuhead cpuhead;
extern struct pcpu *cpuid_to_pcpu[];
#define curcpu PCPU_GET(cpuid)
-#define curproc (curthread->td_proc)
-#ifndef curthread
-#define curthread PCPU_GET(curthread)
-#endif
#define curvidata PCPU_GET(vidata)
#ifndef __rtems__
@@ -233,20 +229,12 @@ extern struct pcpu *cpuid_to_pcpu[];
#define UMA_PCPU_ALLOC_SIZE (PAGE_SIZE / 32)
#endif /* __rtems__ */
-#ifndef __rtems__
-#ifdef CTASSERT
-#if defined(__i386__) || defined(__amd64__)
-/* Required for counters(9) to work on x86. */
-CTASSERT(sizeof(struct pcpu) == UMA_PCPU_ALLOC_SIZE);
-#else
-/*
- * To minimize memory waste in per-cpu UMA zones, size of struct pcpu
- * should be denominator of PAGE_SIZE.
- */
-CTASSERT((PAGE_SIZE / sizeof(struct pcpu)) * sizeof(struct pcpu) == PAGE_SIZE);
-#endif /* UMA_PCPU_ALLOC_SIZE && x86 */
-#endif /* CTASSERT */
-#endif /* __rtems__ */
+#include <machine/pcpu_aux.h>
+
+#ifndef curthread
+#define curthread PCPU_GET(curthread)
+#endif
+#define curproc (curthread->td_proc)
/* Accessor to elements allocated via UMA_ZONE_PCPU zone. */
static inline void *
diff --git a/freebsd/sys/sys/proc.h b/freebsd/sys/sys/proc.h
index 01cf3963..04a0e430 100644
--- a/freebsd/sys/sys/proc.h
+++ b/freebsd/sys/sys/proc.h
@@ -1057,6 +1057,8 @@ struct fork_req {
int *fr_pd_fd;
int fr_pd_flags;
struct filecaps *fr_pd_fcaps;
+ int fr_flags2;
+#define FR2_DROPSIG_CAUGHT 0x00001 /* Drop caught non-DFL signals */
};
/*
@@ -1185,6 +1187,7 @@ void cpu_thread_swapin(struct thread *);
void cpu_thread_swapout(struct thread *);
struct thread *thread_alloc(int pages);
int thread_alloc_stack(struct thread *, int pages);
+int thread_check_susp(struct thread *td, bool sleep);
void thread_cow_get_proc(struct thread *newtd, struct proc *p);
void thread_cow_get(struct thread *newtd, struct thread *td);
void thread_cow_free(struct thread *td);
diff --git a/freebsd/sys/sys/signalvar.h b/freebsd/sys/sys/signalvar.h
index aafbc0f8..70dd8fa3 100644
--- a/freebsd/sys/sys/signalvar.h
+++ b/freebsd/sys/sys/signalvar.h
@@ -382,6 +382,7 @@ void sigacts_copy(struct sigacts *dest, struct sigacts *src);
void sigacts_free(struct sigacts *ps);
struct sigacts *sigacts_hold(struct sigacts *ps);
int sigacts_shared(struct sigacts *ps);
+void sig_drop_caught(struct proc *p);
void sigexit(struct thread *td, int sig) __dead2;
int sigev_findtd(struct proc *p, struct sigevent *sigev, struct thread **);
int sig_ffs(sigset_t *set);
diff --git a/freebsd/sys/sys/smp.h b/freebsd/sys/sys/smp.h
index aa0c3119..22b7dcd5 100644
--- a/freebsd/sys/sys/smp.h
+++ b/freebsd/sys/sys/smp.h
@@ -168,8 +168,10 @@ extern cpuset_t logical_cpus_mask;
#ifndef __rtems__
extern u_int mp_maxid;
extern int mp_maxcpus;
+extern int mp_ncores;
extern int mp_ncpus;
extern volatile int smp_started;
+extern int smp_threads_per_core;
extern cpuset_t all_cpus;
extern cpuset_t cpuset_domain[MAXMEMDOM]; /* CPUs in each NUMA domain. */
diff --git a/freebsd/sys/sys/sysctl.h b/freebsd/sys/sys/sysctl.h
index b2ae7f97..c21f19d3 100644
--- a/freebsd/sys/sys/sysctl.h
+++ b/freebsd/sys/sys/sysctl.h
@@ -888,7 +888,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
/*
* Top-level identifiers
*/
-#define CTL_UNSPEC 0 /* unused */
+#define CTL_SYSCTL 0 /* "magic" numbers */
#define CTL_KERN 1 /* "high kernel": proc, limits */
#define CTL_VM 2 /* virtual memory */
#define CTL_VFS 3 /* filesystem, mount type is next */
@@ -900,6 +900,17 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define CTL_P1003_1B 9 /* POSIX 1003.1B */
/*
+ * CTL_SYSCTL identifiers
+ */
+#define CTL_SYSCTL_DEBUG 0 /* printf all nodes */
+#define CTL_SYSCTL_NAME 1 /* string name of OID */
+#define CTL_SYSCTL_NEXT 2 /* next OID */
+#define CTL_SYSCTL_NAME2OID 3 /* int array of name */
+#define CTL_SYSCTL_OIDFMT 4 /* OID's kind and format */
+#define CTL_SYSCTL_OIDDESCR 5 /* OID's description */
+#define CTL_SYSCTL_OIDLABEL 6 /* aggregation label */
+
+/*
* CTL_KERN identifiers
*/
#define KERN_OSTYPE 1 /* string: system version */
@@ -1085,6 +1096,7 @@ SYSCTL_DECL(_hw_bus);
SYSCTL_DECL(_hw_bus_devices);
SYSCTL_DECL(_hw_bus_info);
SYSCTL_DECL(_machdep);
+SYSCTL_DECL(_machdep_mitigations);
SYSCTL_DECL(_user);
SYSCTL_DECL(_compat);
SYSCTL_DECL(_regression);
diff --git a/freebsd/sys/sys/systm.h b/freebsd/sys/sys/systm.h
index a52cde01..aae31704 100644
--- a/freebsd/sys/sys/systm.h
+++ b/freebsd/sys/sys/systm.h
@@ -634,9 +634,14 @@ int poll_no_poll(int events);
void DELAY(int usec);
/* Root mount holdback API */
-struct root_hold_token;
+struct root_hold_token {
+ int flags;
+ const char *who;
+ TAILQ_ENTRY(root_hold_token) list;
+};
struct root_hold_token *root_mount_hold(const char *identifier);
+void root_mount_hold_token(const char *identifier, struct root_hold_token *h);
void root_mount_rel(struct root_hold_token *h);
int root_mounted(void);
diff --git a/freebsd/sys/sys/taskqueue.h b/freebsd/sys/sys/taskqueue.h
index 4af1e0a3..3f7ff1f5 100644
--- a/freebsd/sys/sys/taskqueue.h
+++ b/freebsd/sys/sys/taskqueue.h
@@ -42,6 +42,7 @@
struct taskqueue;
struct taskqgroup;
+struct proc;
struct thread;
struct timeout_task {
@@ -75,7 +76,9 @@ struct taskqueue *taskqueue_create(const char *name, int mflags,
taskqueue_enqueue_fn enqueue,
void *context);
int taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
- const char *name, ...) __printflike(4, 5);
+ const char *name, ...) __printflike(4, 5);
+int taskqueue_start_threads_in_proc(struct taskqueue **tqp, int count,
+ int pri, struct proc *p, const char *name, ...) __printflike(5, 6);
int taskqueue_start_threads_cpuset(struct taskqueue **tqp, int count,
int pri, cpuset_t *mask, const char *name, ...) __printflike(5, 6);
int taskqueue_enqueue(struct taskqueue *queue, struct task *task);
diff --git a/freebsd/sys/sys/unpcb.h b/freebsd/sys/sys/unpcb.h
index 7d7a20ac..3ea20b1d 100644
--- a/freebsd/sys/sys/unpcb.h
+++ b/freebsd/sys/sys/unpcb.h
@@ -160,7 +160,7 @@ struct xunpcb {
char xu_dummy2[256];
};
struct xsocket xu_socket;
-} __aligned(8);
+} __aligned(MAX(8, sizeof(void *)));
struct xunpgen {
ksize_t xug_len;
diff --git a/freebsd/sys/sys/vnode.h b/freebsd/sys/sys/vnode.h
index c1235a79..f3cdf8a5 100644
--- a/freebsd/sys/sys/vnode.h
+++ b/freebsd/sys/sys/vnode.h
@@ -247,6 +247,7 @@ struct xvnode {
#define VV_NOSYNC 0x0004 /* unlinked, stop syncing */
#define VV_ETERNALDEV 0x0008 /* device that is never destroyed */
#define VV_CACHEDLABEL 0x0010 /* Vnode has valid cached MAC label */
+#define VV_VMSIZEVNLOCK 0x0020 /* object size check requires vnode lock */
#define VV_COPYONWRITE 0x0040 /* vnode is doing copy-on-write */
#define VV_SYSTEM 0x0080 /* vnode being used by kernel */
#define VV_PROCDEP 0x0100 /* vnode is process dependent */
@@ -577,6 +578,7 @@ typedef void vop_getpages_iodone_t(void *, vm_page_t *, int, int);
#define VN_OPEN_NOAUDIT 0x00000001
#define VN_OPEN_NOCAPCHECK 0x00000002
#define VN_OPEN_NAMECACHE 0x00000004
+#define VN_OPEN_INVFS 0x00000008
/*
* Public vnode manipulation functions.
@@ -920,6 +922,8 @@ int vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
void vn_fsid(struct vnode *vp, struct vattr *va);
+int vn_dir_check_exec(struct vnode *vp, struct componentname *cnp);
+
#endif /* _KERNEL */
#endif /* __rtems__ */
diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c
index 7738c5d2..8c3a84b4 100644
--- a/freebsd/sys/vm/uma_core.c
+++ b/freebsd/sys/vm/uma_core.c
@@ -189,8 +189,14 @@ SYSCTL_ULONG(_vm, OID_AUTO, uma_kmem_total, CTLFLAG_RD, &uma_kmem_total, 0,
#ifndef __rtems__
/* Is the VM done starting up? */
-static enum { BOOT_COLD = 0, BOOT_STRAPPED, BOOT_PAGEALLOC, BOOT_BUCKETS,
- BOOT_RUNNING } booted = BOOT_COLD;
+static enum {
+ BOOT_COLD,
+ BOOT_STRAPPED,
+ BOOT_PAGEALLOC,
+ BOOT_BUCKETS,
+ BOOT_RUNNING,
+ BOOT_SHUTDOWN,
+} booted = BOOT_COLD;
#endif /* __rtems__ */
/*
@@ -311,6 +317,9 @@ static int hash_expand(struct uma_hash *, struct uma_hash *);
static void hash_free(struct uma_hash *hash);
static void uma_timeout(void *);
static void uma_startup3(void);
+#ifndef __rtems__
+static void uma_shutdown(void);
+#endif /* __rtems__ */
static void *zone_alloc_item(uma_zone_t, void *, int, int);
static void zone_free_item(uma_zone_t, void *, void *, enum zfreeskip);
static void bucket_enable(void);
@@ -1255,8 +1264,7 @@ startup_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag,
case BOOT_PAGEALLOC:
if (keg->uk_ppera > 1)
break;
- case BOOT_BUCKETS:
- case BOOT_RUNNING:
+ default:
#ifdef UMA_MD_SMALL_ALLOC
keg->uk_allocf = (keg->uk_ppera > 1) ?
page_alloc : uma_small_alloc;
@@ -2259,10 +2267,6 @@ uma_startup2(void)
}
#endif /* __rtems__ */
-/*
- * Initialize our callout handle
- *
- */
static void
uma_startup3(void)
{
@@ -2278,9 +2282,21 @@ uma_startup3(void)
callout_reset(&uma_callout, UMA_TIMEOUT * hz, uma_timeout, NULL);
#ifndef __rtems__
booted = BOOT_RUNNING;
+
+ EVENTHANDLER_REGISTER(shutdown_post_sync, uma_shutdown, NULL,
+ EVENTHANDLER_PRI_FIRST);
#endif /* __rtems__ */
}
+#ifndef __rtems__
+static void
+uma_shutdown(void)
+{
+
+ booted = BOOT_SHUTDOWN;
+}
+#endif /* __rtems__ */
+
static uma_keg_t
uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini,
int align, uint32_t flags)
@@ -2518,6 +2534,16 @@ void
uma_zdestroy(uma_zone_t zone)
{
+#ifndef __rtems__
+ /*
+ * Large slabs are expensive to reclaim, so don't bother doing
+ * unnecessary work if we're shutting down.
+ */
+ if (booted == BOOT_SHUTDOWN &&
+ zone->uz_fini == NULL &&
+ zone->uz_release == (uma_release)zone_release)
+ return;
+#endif /* __rtems__ */
sx_slock(&uma_drain_lock);
zone_free_item(zones, zone, NULL, SKIP_NONE);
sx_sunlock(&uma_drain_lock);
diff --git a/freebsd/sys/vm/vm_extern.h b/freebsd/sys/vm/vm_extern.h
index 52884357..0d17f8af 100644
--- a/freebsd/sys/vm/vm_extern.h
+++ b/freebsd/sys/vm/vm_extern.h
@@ -85,19 +85,18 @@ void kmeminit(void);
int kernacc(void *, int, int);
int useracc(void *, int, int);
-int vm_fault(vm_map_t, vm_offset_t, vm_prot_t, int);
+int vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
+ int fault_flags, vm_page_t *m_hold);
void vm_fault_copy_entry(vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t,
vm_ooffset_t *);
int vm_fault_disable_pagefaults(void);
void vm_fault_enable_pagefaults(int save);
#ifndef __rtems__
-int vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
- int fault_flags, vm_page_t *m_hold);
int vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len,
vm_prot_t prot, vm_page_t *ma, int max_count);
+int vm_fault_trap(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
+ int fault_flags, int *signo, int *ucode);
#endif /* __rtems__ */
-void vm_fault_unwire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t);
-int vm_fault_wire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t);
int vm_forkproc(struct thread *, struct proc *, struct thread *,
struct vmspace *, int);
void vm_waitproc(struct proc *);
diff --git a/freebsd/usr.bin/netstat/inet.c b/freebsd/usr.bin/netstat/inet.c
index 73d3ec65..785d928f 100644
--- a/freebsd/usr.bin/netstat/inet.c
+++ b/freebsd/usr.bin/netstat/inet.c
@@ -662,8 +662,8 @@ tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
"{N:/discarded for bad header offset field%s}\n");
p1a(tcps_rcvshort, "\t\t{:discard-too-short/%ju} "
"{N:discarded because packet too short}\n");
- p1a(tcps_rcvmemdrop, "\t\t{:discard-memory-problems/%ju} "
- "{N:discarded due to memory problems}\n");
+ p1a(tcps_rcvreassfull, "\t\t{:discard-reassembly-queue-full/%ju} "
+ "{N:discarded due to full reassembly queue}\n");
p(tcps_connattempt, "\t{:connection-requests/%ju} "
"{N:/connection request%s}\n");
p(tcps_accepts, "\t{:connections-accepts/%ju} "
@@ -1255,10 +1255,12 @@ igmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
if (igmpstat.igps_version != IGPS_VERSION_3) {
xo_warnx("%s: version mismatch (%d != %d)", __func__,
igmpstat.igps_version, IGPS_VERSION_3);
+ return;
}
if (igmpstat.igps_len != IGPS_VERSION3_LEN) {
xo_warnx("%s: size mismatch (%d != %d)", __func__,
igmpstat.igps_len, IGPS_VERSION3_LEN);
+ return;
}
xo_open_container(name);
diff --git a/freebsd/usr.bin/netstat/inet6.c b/freebsd/usr.bin/netstat/inet6.c
index 9954a89f..452d37d7 100644
--- a/freebsd/usr.bin/netstat/inet6.c
+++ b/freebsd/usr.bin/netstat/inet6.c
@@ -403,6 +403,8 @@ ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
"{N:/fragment%s dropped after timeout}\n");
p(ip6s_fragoverflow, "\t{:dropped-fragments-overflow/%ju} "
"{N:/fragment%s that exceeded limit}\n");
+ p(ip6s_atomicfrags, "\t{:atomic-fragments/%ju} "
+ "{N:/atomic fragment%s}\n");
p(ip6s_reassembled, "\t{:reassembled-packets/%ju} "
"{N:/packet%s reassembled ok}\n");
p(ip6s_delivered, "\t{:received-local-packets/%ju} "
@@ -1320,7 +1322,7 @@ inet6print(const char *container, struct in6_addr *in6, int port,
*/
char *
-inet6name(struct in6_addr *in6p)
+inet6name(struct in6_addr *ia6)
{
struct sockaddr_in6 sin6;
char hbuf[NI_MAXHOST], *cp;
@@ -1329,7 +1331,7 @@ inet6name(struct in6_addr *in6p)
static int first = 1;
int flags, error;
- if (IN6_IS_ADDR_UNSPECIFIED(in6p)) {
+ if (IN6_IS_ADDR_UNSPECIFIED(ia6)) {
strcpy(line, "*");
return (line);
}
@@ -1342,9 +1344,9 @@ inet6name(struct in6_addr *in6p)
domain[0] = 0;
}
memset(&sin6, 0, sizeof(sin6));
- memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p));
+ memcpy(&sin6.sin6_addr, ia6, sizeof(*ia6));
sin6.sin6_family = AF_INET6;
- /* XXX: in6p.s6_addr[2] can contain scopeid. */
+ /* XXX: ia6.s6_addr[2] can contain scopeid. */
in6_fillscopeid(&sin6);
flags = (numeric_addr) ? NI_NUMERICHOST : 0;
error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
diff --git a/freebsd/usr.bin/netstat/main.c b/freebsd/usr.bin/netstat/main.c
index c47bd826..b3d09aef 100644
--- a/freebsd/usr.bin/netstat/main.c
+++ b/freebsd/usr.bin/netstat/main.c
@@ -579,6 +579,9 @@ main(int argc, char *argv[])
if (rflag) {
xo_open_container("statistics");
if (sflag) {
+ if (live) {
+ kresolve_list(nl);
+ }
rt_stats();
} else
routepr(fib, af);
diff --git a/freebsd/usr.bin/netstat/mroute.c b/freebsd/usr.bin/netstat/mroute.c
index f2937e30..bd19dfa1 100644
--- a/freebsd/usr.bin/netstat/mroute.c
+++ b/freebsd/usr.bin/netstat/mroute.c
@@ -426,16 +426,14 @@ mrt_stats()
mstaddr = nl[N_MRTSTAT].n_value;
+ if (fetch_stats("net.inet.ip.mrtstat", mstaddr, &mrtstat,
+ sizeof(mrtstat), kread_counters) != 0) {
#ifndef __rtems__
- if (mstaddr == 0) {
- fprintf(stderr, "No IPv4 MROUTING kernel support.\n");
- return;
- }
+ if ((live && errno == ENOENT) || (!live && mstaddr == 0))
+ fprintf(stderr, "No IPv4 MROUTING kernel support.\n");
#endif /* __rtems__ */
-
- if (fetch_stats("net.inet.ip.mrtstat", mstaddr, &mrtstat,
- sizeof(mrtstat), kread_counters) != 0)
return;
+ }
xo_emit("{T:IPv4 multicast forwarding}:\n");
diff --git a/freebsd/usr.sbin/arp/arp.c b/freebsd/usr.sbin/arp/arp.c
index 0b9c497d..c3109d9d 100644
--- a/freebsd/usr.sbin/arp/arp.c
+++ b/freebsd/usr.sbin/arp/arp.c
@@ -678,8 +678,7 @@ print_entry(struct sockaddr_dl *sdl,
} else
xo_emit("{d:/(incomplete)}{en:incomplete/true}");
- for (p = ifnameindex; p && ifnameindex->if_index &&
- ifnameindex->if_name; p++) {
+ for (p = ifnameindex; p && p->if_index && p->if_name; p++) {
if (p->if_index == sdl->sdl_index) {
xo_emit(" on {:interface/%s}", p->if_name);
break;
diff --git a/libbsd.py b/libbsd.py
index ec30a442..e00496dd 100644
--- a/libbsd.py
+++ b/libbsd.py
@@ -1725,7 +1725,6 @@ class net(builder.Module):
'sys/net/if_mib.h',
'sys/net/if_sppp.h',
'sys/net/if_tap.h',
- 'sys/net/if_tapvar.h',
'sys/net/if_tun.h',
'sys/net/if_types.h',
'sys/net/if_var.h',
@@ -1771,8 +1770,7 @@ class net(builder.Module):
'sys/net/if_mib.c',
'sys/net/if_spppfr.c',
'sys/net/if_spppsubr.c',
- 'sys/net/if_tap.c',
- 'sys/net/if_tun.c',
+ 'sys/net/if_tuntap.c',
'sys/net/if_vlan.c',
'sys/net/pfil.c',
'sys/net/radix.c',
@@ -1840,7 +1838,6 @@ class netinet(builder.Module):
'sys/netinet/sctp_constants.h',
'sys/netinet/sctp_crc32.h',
'sys/netinet/sctp_dtrace_declare.h',
- 'sys/netinet/sctp_dtrace_define.h',
'sys/netinet/sctp.h',
'sys/netinet/sctp_header.h',
'sys/netinet/sctp_indata.h',
@@ -4162,9 +4159,11 @@ class contrib_libpcap(builder.Module):
def generate(self):
mm = self.manager
cflags = ['-D__FreeBSD__=1',
+ '-D_GNU_SOURCE=1',
'-DBSD=1',
'-D_U_=__attribute__((unused))',
'-DPACKAGE_VERSION="libbsd"',
+ '-DHAVE_ASPRINTF=1',
'-DHAVE_LIMITS_H=1',
'-DHAVE_INTTYPES=1',
'-DHAVE_STDINT=1',
@@ -4203,6 +4202,7 @@ class contrib_libpcap(builder.Module):
'contrib/libpcap/pcap/pcap.h',
'contrib/libpcap/pcap/pcap-inttypes.h',
'contrib/libpcap/pcap/sll.h',
+ 'contrib/libpcap/pcap/socket.h',
'contrib/libpcap/pcap-types.h',
'contrib/libpcap/pcap/usb.h',
'contrib/libpcap/portability.h',
diff --git a/rtemsbsd/include/machine/pcpu_aux.h b/rtemsbsd/include/machine/pcpu_aux.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/rtemsbsd/include/machine/pcpu_aux.h
diff --git a/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h b/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
index 82b00eb5..3300b3fd 100644
--- a/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
+++ b/rtemsbsd/include/machine/rtems-bsd-kernel-namespace.h
@@ -401,6 +401,7 @@
#define bus_data_generation_check _bsd_bus_data_generation_check
#define bus_data_generation_update _bsd_bus_data_generation_update
#define bus_deactivate_resource _bsd_bus_deactivate_resource
+#define bus_delayed_attach_children _bsd_bus_delayed_attach_children
#define bus_delete_resource _bsd_bus_delete_resource
#define bus_describe_intr _bsd_bus_describe_intr
#define busdma_lock_mutex _bsd_busdma_lock_mutex
@@ -417,7 +418,6 @@
#define bus_dma_tag_create _bsd_bus_dma_tag_create
#define bus_dma_tag_destroy _bsd_bus_dma_tag_destroy
#define bus_enumerate_hinted_children _bsd_bus_enumerate_hinted_children
-#define bus_free_resource _bsd_bus_free_resource
#define bus_generic_activate_resource _bsd_bus_generic_activate_resource
#define bus_generic_add_child _bsd_bus_generic_add_child
#define bus_generic_adjust_resource _bsd_bus_generic_adjust_resource
@@ -740,6 +740,7 @@
#define device_has_quiet_children _bsd_device_has_quiet_children
#define device_is_alive _bsd_device_is_alive
#define device_is_attached _bsd_device_is_attached
+#define device_is_devclass_fixed _bsd_device_is_devclass_fixed
#define device_is_enabled _bsd_device_is_enabled
#define device_is_quiet _bsd_device_is_quiet
#define device_is_suspended _bsd_device_is_suspended
@@ -1097,6 +1098,7 @@
#define e1000_write_vfta_generic _bsd_e1000_write_vfta_generic
#define e1000_write_vfta_i350 _bsd_e1000_write_vfta_i350
#define e1000_write_xmdio_reg _bsd_e1000_write_xmdio_reg
+#define early_counter _bsd_early_counter
#define edid_is_valid _bsd_edid_is_valid
#define edid_nproducts _bsd_edid_nproducts
#define edid_nvendors _bsd_edid_nvendors
@@ -1146,6 +1148,7 @@
#define epoch_init _bsd_epoch_init
#define epoch_wait _bsd_epoch_wait
#define epoch_wait_preempt _bsd_epoch_wait_preempt
+#define errno2iic _bsd_errno2iic
#define esp_enable _bsd_esp_enable
#define esp_hdrsiz _bsd_esp_hdrsiz
#define espstat _bsd_espstat
@@ -1352,6 +1355,8 @@
#define gpiobus_init_softc _bsd_gpiobus_init_softc
#define gpiobus_release_pin _bsd_gpiobus_release_pin
#define gpio_check_flags _bsd_gpio_check_flags
+#define gpio_pin_get_by_bus_pinnum _bsd_gpio_pin_get_by_bus_pinnum
+#define gpio_pin_get_by_child_index _bsd_gpio_pin_get_by_child_index
#define gpio_pin_get_by_ofw_idx _bsd_gpio_pin_get_by_ofw_idx
#define gpio_pin_get_by_ofw_name _bsd_gpio_pin_get_by_ofw_name
#define gpio_pin_get_by_ofw_property _bsd_gpio_pin_get_by_ofw_property
@@ -1880,6 +1885,8 @@
#define ifa_ifwithroute _bsd_ifa_ifwithroute
#define if_allmulti _bsd_if_allmulti
#define if_alloc _bsd_if_alloc
+#define if_alloc_dev _bsd_if_alloc_dev
+#define if_alloc_domain _bsd_if_alloc_domain
#define ifaof_ifpforaddr _bsd_ifaof_ifpforaddr
#define ifa_preferred _bsd_ifa_preferred
#define ifa_ref _bsd_ifa_ref
@@ -1892,6 +1899,7 @@
#define ifc_free_unit _bsd_ifc_free_unit
#define if_clearhwassist _bsd_if_clearhwassist
#define if_clone_addgroup _bsd_if_clone_addgroup
+#define if_clone_addif _bsd_if_clone_addif
#define if_clone_advanced _bsd_if_clone_advanced
#define if_clone_create _bsd_if_clone_create
#define if_clone_destroy _bsd_if_clone_destroy
@@ -2184,11 +2192,13 @@
#define in_domifdetach _bsd_in_domifdetach
#define inet6ctlerrmap _bsd_inet6ctlerrmap
#define inet6domain _bsd_inet6domain
+#define inet6_pfil_head _bsd_inet6_pfil_head
#define inet6_pfil_hook _bsd_inet6_pfil_hook
#define inet6sw _bsd_inet6sw
#define inetctlerrmap _bsd_inetctlerrmap
#define inetdomain _bsd_inetdomain
#define inet_ntoa_r _bsd_inet_ntoa_r
+#define inet_pfil_head _bsd_inet_pfil_head
#define inet_pfil_hook _bsd_inet_pfil_hook
#define inetsw _bsd_inetsw
#define in_getpeeraddr _bsd_in_getpeeraddr
@@ -2290,8 +2300,6 @@
#define in_sockaddr _bsd_in_sockaddr
#define intr_event_add_handler _bsd_intr_event_add_handler
#define intr_event_create _bsd_intr_event_create
-#define intr_event_resume_handler _bsd_intr_event_resume_handler
-#define intr_event_suspend_handler _bsd_intr_event_suspend_handler
#define ip4_ah_net_deflev _bsd_ip4_ah_net_deflev
#define ip4_ah_trans_deflev _bsd_ip4_ah_trans_deflev
#define ip4_esp_net_deflev _bsd_ip4_esp_net_deflev
@@ -2705,6 +2713,7 @@
#define link_alloc_sdl _bsd_link_alloc_sdl
#define link_free_sdl _bsd_link_free_sdl
#define link_init_sdl _bsd_link_init_sdl
+#define link_pfil_head _bsd_link_pfil_head
#define link_pfil_hook _bsd_link_pfil_hook
#define lla_rt_output _bsd_lla_rt_output
#define llentry_alloc _bsd_llentry_alloc
@@ -2770,8 +2779,10 @@
#define maxpipekva _bsd_maxpipekva
#define mb_dupcl _bsd_mb_dupcl
#define mb_free_ext _bsd_mb_free_ext
+#define mb_free_notready _bsd_mb_free_notready
#define M_BPF _bsd_M_BPF
#define M_BPFJIT _bsd_M_BPFJIT
+#define mb_use_ext_pgs _bsd_mb_use_ext_pgs
#define M_CAMSIM _bsd_M_CAMSIM
#define m_cat _bsd_m_cat
#define m_catpkt _bsd_m_catpkt
@@ -2874,6 +2885,7 @@
#define mmc_wait_for_cmd _bsd_mmc_wait_for_cmd
#define m_megapullup _bsd_m_megapullup
#define m_move_pkthdr _bsd_m_move_pkthdr
+#define M_NVME _bsd_M_NVME
#define module_lookupbyname _bsd_module_lookupbyname
#define module_register _bsd_module_register
#define module_register_init _bsd_module_register_init
@@ -2894,6 +2906,8 @@
#define mrt_ioctl _bsd_mrt_ioctl
#define M_RTWN_PRIV _bsd_M_RTWN_PRIV
#define m_sanity _bsd_m_sanity
+#define m_snd_tag_destroy _bsd_m_snd_tag_destroy
+#define m_snd_tag_init _bsd_m_snd_tag_init
#define M_SONAME _bsd_M_SONAME
#define m_split _bsd_m_split
#define m_striphdr _bsd_m_striphdr
@@ -2927,6 +2941,7 @@
#define mtx_trylock_flags_ _bsd_mtx_trylock_flags_
#define _mtx_unlock_flags _bsd__mtx_unlock_flags
#define m_uiotombuf _bsd_m_uiotombuf
+#define m_unmappedtouio _bsd_m_unmappedtouio
#define m_unshare _bsd_m_unshare
#define murmur3_32_hash _bsd_murmur3_32_hash
#define murmur3_32_hash32 _bsd_murmur3_32_hash32
@@ -2947,10 +2962,16 @@
#define nd6_dad_start _bsd_nd6_dad_start
#define nd6_dad_stop _bsd_nd6_dad_stop
#define nd6_defifindex _bsd_nd6_defifindex
+#define nd6_defrouter_flush_all _bsd_nd6_defrouter_flush_all
+#define nd6_defrouter_init _bsd_nd6_defrouter_init
+#define nd6_defrouter_list_empty _bsd_nd6_defrouter_list_empty
+#define nd6_defrouter_purge _bsd_nd6_defrouter_purge
+#define nd6_defrouter_timer _bsd_nd6_defrouter_timer
#define nd6_flush_holdchain _bsd_nd6_flush_holdchain
#define nd6_grab_holdchain _bsd_nd6_grab_holdchain
#define nd6_ifattach _bsd_nd6_ifattach
#define nd6_ifdetach _bsd_nd6_ifdetach
+#define nd6_ifnet_link_event _bsd_nd6_ifnet_link_event
#define nd6_ifptomac _bsd_nd6_ifptomac
#define nd6_init _bsd_nd6_init
#define nd6_ioctl _bsd_nd6_ioctl
@@ -3017,6 +3038,89 @@
#define null_class _bsd_null_class
#define null_filtops _bsd_null_filtops
#define nullop _bsd_nullop
+#define nvme_admin_qpair_destroy _bsd_nvme_admin_qpair_destroy
+#define nvme_admin_qpair_disable _bsd_nvme_admin_qpair_disable
+#define nvme_admin_qpair_enable _bsd_nvme_admin_qpair_enable
+#define nvme_attach _bsd_nvme_attach
+#define nvme_completion_poll_cb _bsd_nvme_completion_poll_cb
+#define nvme_consumer _bsd_nvme_consumer
+#define nvme_ctrlr_cmd_abort _bsd_nvme_ctrlr_cmd_abort
+#define nvme_ctrlr_cmd_create_io_cq _bsd_nvme_ctrlr_cmd_create_io_cq
+#define nvme_ctrlr_cmd_create_io_sq _bsd_nvme_ctrlr_cmd_create_io_sq
+#define nvme_ctrlr_cmd_delete_io_cq _bsd_nvme_ctrlr_cmd_delete_io_cq
+#define nvme_ctrlr_cmd_delete_io_sq _bsd_nvme_ctrlr_cmd_delete_io_sq
+#define nvme_ctrlr_cmd_get_error_page _bsd_nvme_ctrlr_cmd_get_error_page
+#define nvme_ctrlr_cmd_get_feature _bsd_nvme_ctrlr_cmd_get_feature
+#define nvme_ctrlr_cmd_get_firmware_page _bsd_nvme_ctrlr_cmd_get_firmware_page
+#define nvme_ctrlr_cmd_get_health_information_page _bsd_nvme_ctrlr_cmd_get_health_information_page
+#define nvme_ctrlr_cmd_get_log_page _bsd_nvme_ctrlr_cmd_get_log_page
+#define nvme_ctrlr_cmd_identify_controller _bsd_nvme_ctrlr_cmd_identify_controller
+#define nvme_ctrlr_cmd_identify_namespace _bsd_nvme_ctrlr_cmd_identify_namespace
+#define nvme_ctrlr_cmd_set_async_event_config _bsd_nvme_ctrlr_cmd_set_async_event_config
+#define nvme_ctrlr_cmd_set_feature _bsd_nvme_ctrlr_cmd_set_feature
+#define nvme_ctrlr_cmd_set_interrupt_coalescing _bsd_nvme_ctrlr_cmd_set_interrupt_coalescing
+#define nvme_ctrlr_cmd_set_num_queues _bsd_nvme_ctrlr_cmd_set_num_queues
+#define nvme_ctrlr_construct _bsd_nvme_ctrlr_construct
+#define nvme_ctrlr_destruct _bsd_nvme_ctrlr_destruct
+#define nvme_ctrlr_get_data _bsd_nvme_ctrlr_get_data
+#define nvme_ctrlr_get_device _bsd_nvme_ctrlr_get_device
+#define nvme_ctrlr_hw_reset _bsd_nvme_ctrlr_hw_reset
+#define nvme_ctrlr_intx_handler _bsd_nvme_ctrlr_intx_handler
+#define nvme_ctrlr_passthrough_cmd _bsd_nvme_ctrlr_passthrough_cmd
+#define nvme_ctrlr_poll _bsd_nvme_ctrlr_poll
+#define nvme_ctrlr_post_failed_request _bsd_nvme_ctrlr_post_failed_request
+#define nvme_ctrlr_reset _bsd_nvme_ctrlr_reset
+#define nvme_ctrlr_resume _bsd_nvme_ctrlr_resume
+#define nvme_ctrlr_shutdown _bsd_nvme_ctrlr_shutdown
+#define nvme_ctrlr_start_config_hook _bsd_nvme_ctrlr_start_config_hook
+#define nvme_ctrlr_submit_admin_request _bsd_nvme_ctrlr_submit_admin_request
+#define nvme_ctrlr_submit_io_request _bsd_nvme_ctrlr_submit_io_request
+#define nvme_ctrlr_suspend _bsd_nvme_ctrlr_suspend
+#define nvme_detach _bsd_nvme_detach
+#define nvme_devclass _bsd_nvme_devclass
+#define nvme_dump_command _bsd_nvme_dump_command
+#define nvme_dump_completion _bsd_nvme_dump_completion
+#define nvme_io_qpair_destroy _bsd_nvme_io_qpair_destroy
+#define nvme_io_qpair_disable _bsd_nvme_io_qpair_disable
+#define nvme_io_qpair_enable _bsd_nvme_io_qpair_enable
+#define nvme_notify_async_consumers _bsd_nvme_notify_async_consumers
+#define nvme_notify_fail_consumers _bsd_nvme_notify_fail_consumers
+#define nvme_notify_new_controller _bsd_nvme_notify_new_controller
+#define nvme_notify_ns _bsd_nvme_notify_ns
+#define nvme_ns_cmd_deallocate _bsd_nvme_ns_cmd_deallocate
+#define nvme_ns_cmd_flush _bsd_nvme_ns_cmd_flush
+#define nvme_ns_cmd_read _bsd_nvme_ns_cmd_read
+#define nvme_ns_cmd_read_iov _bsd_nvme_ns_cmd_read_iov
+#define nvme_ns_cmd_write _bsd_nvme_ns_cmd_write
+#define nvme_ns_cmd_write_iov _bsd_nvme_ns_cmd_write_iov
+#define nvme_ns_construct _bsd_nvme_ns_construct
+#define nvme_ns_destruct _bsd_nvme_ns_destruct
+#define nvme_ns_dump _bsd_nvme_ns_dump
+#define nvme_ns_get_data _bsd_nvme_ns_get_data
+#define nvme_ns_get_flags _bsd_nvme_ns_get_flags
+#define nvme_ns_get_max_io_xfer_size _bsd_nvme_ns_get_max_io_xfer_size
+#define nvme_ns_get_model_number _bsd_nvme_ns_get_model_number
+#define nvme_ns_get_num_sectors _bsd_nvme_ns_get_num_sectors
+#define nvme_ns_get_sector_size _bsd_nvme_ns_get_sector_size
+#define nvme_ns_get_serial_number _bsd_nvme_ns_get_serial_number
+#define nvme_ns_get_size _bsd_nvme_ns_get_size
+#define nvme_ns_get_stripesize _bsd_nvme_ns_get_stripesize
+#define nvme_ns_ioctl_process _bsd_nvme_ns_ioctl_process
+#define nvme_qpair_construct _bsd_nvme_qpair_construct
+#define nvme_qpair_fail _bsd_nvme_qpair_fail
+#define nvme_qpair_manual_complete_request _bsd_nvme_qpair_manual_complete_request
+#define nvme_qpair_process_completions _bsd_nvme_qpair_process_completions
+#define nvme_qpair_reset _bsd_nvme_qpair_reset
+#define nvme_qpair_submit_request _bsd_nvme_qpair_submit_request
+#define nvme_qpair_submit_tracker _bsd_nvme_qpair_submit_tracker
+#define nvme_register_consumer _bsd_nvme_register_consumer
+#define nvme_request_zone _bsd_nvme_request_zone
+#define nvme_retry_count _bsd_nvme_retry_count
+#define nvme_shutdown _bsd_nvme_shutdown
+#define nvme_sysctl_initialize_ctrlr _bsd_nvme_sysctl_initialize_ctrlr
+#define nvme_unregister_consumer _bsd_nvme_unregister_consumer
+#define nvme_use_nvd _bsd_nvme_use_nvd
+#define nvme_verbose_cmd_dump _bsd_nvme_verbose_cmd_dump
#define OF_call_method _bsd_OF_call_method
#define OF_canon _bsd_OF_canon
#define OF_child _bsd_OF_child
@@ -3132,6 +3236,7 @@
#define pci_alloc_multi_resource _bsd_pci_alloc_multi_resource
#define pci_alloc_resource _bsd_pci_alloc_resource
#define pci_assign_interrupt_method _bsd_pci_assign_interrupt_method
+#define pci_attach _bsd_pci_attach
#define pci_attach_common _bsd_pci_attach_common
#define pcib_alloc_msi _bsd_pcib_alloc_msi
#define pcib_alloc_msix _bsd_pcib_alloc_msix
@@ -3170,6 +3275,7 @@
#define pci_child_pnpinfo_str_method _bsd_pci_child_pnpinfo_str_method
#define pci_deactivate_resource _bsd_pci_deactivate_resource
#define pci_delete_resource _bsd_pci_delete_resource
+#define pci_detach _bsd_pci_detach
#define pci_devq _bsd_pci_devq
#define pci_disable_busmaster_method _bsd_pci_disable_busmaster_method
#define pci_disable_io_method _bsd_pci_disable_io_method
@@ -3248,6 +3354,7 @@
#define pci_write_ivar _bsd_pci_write_ivar
#define pcpu_entry_epair_dpcpu _bsd_pcpu_entry_epair_dpcpu
#define pcpu_zone_64 _bsd_pcpu_zone_64
+#define pcpu_zone_int _bsd_pcpu_zone_int
#define pcpu_zone_ptr _bsd_pcpu_zone_ptr
#define pf_addr_cmp _bsd_pf_addr_cmp
#define pf_addrcpy _bsd_pf_addrcpy
@@ -3309,6 +3416,8 @@
#define pf_free_rule _bsd_pf_free_rule
#define pf_free_src_nodes _bsd_pf_free_src_nodes
#define pf_free_state _bsd_pf_free_state
+#define pf_frent_previous _bsd_pf_frent_previous
+#define pf_frent_remove _bsd_pf_frent_remove
#define pf_get_mtag _bsd_pf_get_mtag
#define pf_get_ruleset_number _bsd_pf_get_ruleset_number
#define pf_get_translation _bsd_pf_get_translation
@@ -3351,7 +3460,9 @@
#define pfil_head_list _bsd_pfil_head_list
#define pfil_head_register _bsd_pfil_head_register
#define pfil_head_unregister _bsd_pfil_head_unregister
+#define pfil_link _bsd_pfil_link
#define pfil_lock _bsd_pfil_lock
+#define pfil_realloc _bsd_pfil_realloc
#define pfil_remove_hook _bsd_pfil_remove_hook
#define pfil_remove_hook_flags _bsd_pfil_remove_hook_flags
#define pfil_rlock _bsd_pfil_rlock
@@ -3760,6 +3871,8 @@
#define rc4_init _bsd_rc4_init
#define read_dsfield _bsd_read_dsfield
#define read_machclk _bsd_read_machclk
+#define refcount_release_last _bsd_refcount_release_last
+#define refcount_sleep _bsd_refcount_sleep
#define registered_toedevs _bsd_registered_toedevs
#define register_tcp_functions _bsd_register_tcp_functions
#define register_tcp_functions_as_name _bsd_register_tcp_functions_as_name
@@ -4068,7 +4181,9 @@
#define sbuf_len _bsd_sbuf_len
#define sbuf_new _bsd_sbuf_new
#define sbuf_new_for_sysctl _bsd_sbuf_new_for_sysctl
+#define sbuf_nl_terminate _bsd_sbuf_nl_terminate
#define sbuf_printf _bsd_sbuf_printf
+#define sbuf_printf_drain _bsd_sbuf_printf_drain
#define sbuf_printf_uuid _bsd_sbuf_printf_uuid
#define sbuf_putbuf _bsd_sbuf_putbuf
#define sbuf_putc _bsd_sbuf_putc
@@ -4569,8 +4684,6 @@
#define Skein_512_Output _bsd_Skein_512_Output
#define Skein_512_Process_Block _bsd_Skein_512_Process_Block
#define Skein_512_Update _bsd_Skein_512_Update
-#define Skein_Get64_LSB_First _bsd_Skein_Get64_LSB_First
-#define Skein_Put64_LSB_First _bsd_Skein_Put64_LSB_First
#define skipjack_backwards _bsd_skipjack_backwards
#define skipjack_forwards _bsd_skipjack_forwards
#define sl_compress_init _bsd_sl_compress_init
@@ -4772,6 +4885,7 @@
#define sysctl___hw _bsd_sysctl___hw
#define sysctl___hw_bus _bsd_sysctl___hw_bus
#define sysctl___hw_fdt _bsd_sysctl___hw_fdt
+#define sysctl___hw_nvme _bsd_sysctl___hw_nvme
#define sysctl___hw_pci _bsd_sysctl___hw_pci
#define sysctl___hw_sdhci _bsd_sysctl___hw_sdhci
#define sysctl___hw_usb _bsd_sysctl___hw_usb
@@ -4785,6 +4899,7 @@
#define sysctl___kern_features _bsd_sysctl___kern_features
#define sysctl___kern_ipc _bsd_sysctl___kern_ipc
#define sysctl_move_oid _bsd_sysctl_move_oid
+#define sysctl_msec_to_sbintime _bsd_sysctl_msec_to_sbintime
#define sysctl_msec_to_ticks _bsd_sysctl_msec_to_ticks
#define sysctl___net _bsd_sysctl___net
#define sysctl___net_accf _bsd_sysctl___net_accf
@@ -4835,6 +4950,7 @@
#define sysctl___security _bsd_sysctl___security
#define sysctl___sysctl _bsd_sysctl___sysctl
#define sysctl_unregister_oid _bsd_sysctl_unregister_oid
+#define sysctl_usec_to_sbintime _bsd_sysctl_usec_to_sbintime
#define sysctl___vm _bsd_sysctl___vm
#define sysctl_wire_old_buffer _bsd_sysctl_wire_old_buffer
#define sysctl_wlock _bsd_sysctl_wlock
@@ -4869,6 +4985,7 @@
#define tcp_clean_dsack_blocks _bsd_tcp_clean_dsack_blocks
#define tcp_clean_sackreport _bsd_tcp_clean_sackreport
#define tcp_close _bsd_tcp_close
+#define tcp_compute_initwnd _bsd_tcp_compute_initwnd
#define tcp_compute_pipe _bsd_tcp_compute_pipe
#define tcp_ctlinput _bsd_tcp_ctlinput
#define tcp_ctloutput _bsd_tcp_ctloutput
@@ -4907,6 +5024,12 @@
#define tcp_init _bsd_tcp_init
#define tcp_initcwnd_segments _bsd_tcp_initcwnd_segments
#define tcp_inpinfo_lock_del _bsd_tcp_inpinfo_lock_del
+#define tcp_inp_lro_compressed _bsd_tcp_inp_lro_compressed
+#define tcp_inp_lro_direct_queue _bsd_tcp_inp_lro_direct_queue
+#define tcp_inp_lro_locks_taken _bsd_tcp_inp_lro_locks_taken
+#define tcp_inp_lro_sack_wake _bsd_tcp_inp_lro_sack_wake
+#define tcp_inp_lro_single_push _bsd_tcp_inp_lro_single_push
+#define tcp_inp_lro_wokeup_queue _bsd_tcp_inp_lro_wokeup_queue
#define tcp_inptoxtp _bsd_tcp_inptoxtp
#define tcp_input _bsd_tcp_input
#define tcp_insecure_rst _bsd_tcp_insecure_rst
@@ -4921,6 +5044,7 @@
#define tcp_log_addrs _bsd_tcp_log_addrs
#define tcp_log_in_vain _bsd_tcp_log_in_vain
#define tcp_log_vain _bsd_tcp_log_vain
+#define tcp_lro_dereg_mbufq _bsd_tcp_lro_dereg_mbufq
#define tcp_lro_flush _bsd_tcp_lro_flush
#define tcp_lro_flush_all _bsd_tcp_lro_flush_all
#define tcp_lro_flush_inactive _bsd_tcp_lro_flush_inactive
@@ -4928,6 +5052,7 @@
#define tcp_lro_init _bsd_tcp_lro_init
#define tcp_lro_init_args _bsd_tcp_lro_init_args
#define tcp_lro_queue_mbuf _bsd_tcp_lro_queue_mbuf
+#define tcp_lro_reg_mbufq _bsd_tcp_lro_reg_mbufq
#define tcp_lro_rx _bsd_tcp_lro_rx
#define tcp_maxmtu _bsd_tcp_maxmtu
#define tcp_maxmtu6 _bsd_tcp_maxmtu6
@@ -5107,6 +5232,7 @@
#define ttyoutq_write _bsd_ttyoutq_write
#define ttyoutq_write_nofrag _bsd_ttyoutq_write_nofrag
#define tty_putchar _bsd_tty_putchar
+#define tty_putstrn _bsd_tty_putstrn
#define tty_rel_gone _bsd_tty_rel_gone
#define tty_rel_pgrp _bsd_tty_rel_pgrp
#define tty_rel_sess _bsd_tty_rel_sess
@@ -5176,8 +5302,14 @@
#define uether_rxmbuf _bsd_uether_rxmbuf
#define uether_start _bsd_uether_start
#define ugen_do_request _bsd_ugen_do_request
+#define uhub_attach _bsd_uhub_attach
+#define uhub_child_location_string _bsd_uhub_child_location_string
#define uhub_count_active_host_ports _bsd_uhub_count_active_host_ports
+#define uhub_detach _bsd_uhub_detach
+#define uhub_driver _bsd_uhub_driver
#define uhub_explore_handle_re_enumerate _bsd_uhub_explore_handle_re_enumerate
+#define uhub_find_iface_index _bsd_uhub_find_iface_index
+#define uhub_probe _bsd_uhub_probe
#define uhub_query_info _bsd_uhub_query_info
#define uhub_root_intr _bsd_uhub_root_intr
#define uhub_tt_buffer_reset_async_locked _bsd_uhub_tt_buffer_reset_async_locked
@@ -5211,6 +5343,7 @@
#define uma_zone_exhausted_nolock _bsd_uma_zone_exhausted_nolock
#define uma_zone_get_cur _bsd_uma_zone_get_cur
#define uma_zone_get_max _bsd_uma_zone_get_max
+#define uma_zone_reclaim _bsd_uma_zone_reclaim
#define uma_zone_reserve _bsd_uma_zone_reserve
#define uma_zone_set_allocf _bsd_uma_zone_set_allocf
#define uma_zone_set_fini _bsd_uma_zone_set_fini
@@ -5218,6 +5351,7 @@
#define uma_zone_set_init _bsd_uma_zone_set_init
#define uma_zone_set_max _bsd_uma_zone_set_max
#define uma_zone_set_maxaction _bsd_uma_zone_set_maxaction
+#define uma_zone_set_maxcache _bsd_uma_zone_set_maxcache
#define uma_zone_set_warning _bsd_uma_zone_set_warning
#define uma_zone_set_zfini _bsd_uma_zone_set_zfini
#define uma_zone_set_zinit _bsd_uma_zone_set_zinit
@@ -5559,6 +5693,7 @@
#define z_free _bsd_z_free
#define zone_clust _bsd_zone_clust
#define zone_drain _bsd_zone_drain
+#define zone_extpgs _bsd_zone_extpgs
#define zone_jumbo16 _bsd_zone_jumbo16
#define zone_jumbo9 _bsd_zone_jumbo9
#define zone_jumbop _bsd_zone_jumbop
diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs.h b/rtemsbsd/include/rtems/bsd/local/usbdevs.h
index 1909e626..fca51836 100644
--- a/rtemsbsd/include/rtems/bsd/local/usbdevs.h
+++ b/rtemsbsd/include/rtems/bsd/local/usbdevs.h
@@ -1789,6 +1789,7 @@
#define USB_PRODUCT_DISPLAYLINK_SWDVI 0x024c /* SUNWEIT DVI */
#define USB_PRODUCT_DISPLAYLINK_NBDOCK 0x0215 /* VideoHome NBdock1920 */
#define USB_PRODUCT_DISPLAYLINK_LUM70 0x02a9 /* Lilliput UM-70 */
+#define USB_PRODUCT_DISPLAYLINK_DVI_19 0x0360 /* USB to DVI-19 */
#define USB_PRODUCT_DISPLAYLINK_UM7X0 0x401a /* nanovision MiMo */
#define USB_PRODUCT_DISPLAYLINK_LT1421 0x03e0 /* Lenovo ThinkVision LT1421 */
#define USB_PRODUCT_DISPLAYLINK_POLARIS2 0x0117 /* Polaris2 USB dock */
@@ -4343,6 +4344,7 @@
#define USB_PRODUCT_SILABS_MMB_ZIGBEE 0x88a4 /* MMB Networks ZigBee */
#define USB_PRODUCT_SILABS_INGENI_ZIGBEE 0x88a5 /* Planet Innovation Ingeni ZigBee */
#define USB_PRODUCT_SILABS_HUBZ 0x8a2a /* HubZ dual ZigBee and Z-Wave */
+#define USB_PRODUCT_SILABS_BV_AV2010_10 0x8b34 /* Bitron Video AV2010/10 ZigBee USB Stick */
#define USB_PRODUCT_SILABS_CP2102 0xea60 /* SILABS USB UART */
#define USB_PRODUCT_SILABS_CP210X_2 0xea61 /* CP210x Serial */
#define USB_PRODUCT_SILABS_CP210X_3 0xea70 /* CP210x Serial */
diff --git a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
index e7cc4655..9833c8f1 100644
--- a/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
+++ b/rtemsbsd/include/rtems/bsd/local/usbdevs_data.h
@@ -4214,6 +4214,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"Lilliput UM-70",
},
{
+ USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_DVI_19,
+ 0,
+ "DisplayLink",
+ "USB to DVI-19",
+ },
+ {
USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_UM7X0,
0,
"DisplayLink",
@@ -16502,6 +16508,12 @@ const struct usb_knowndev usb_knowndevs[] = {
"HubZ dual ZigBee and Z-Wave",
},
{
+ USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BV_AV2010_10,
+ 0,
+ "Silicon Labs",
+ "Bitron Video AV2010/10 ZigBee USB Stick",
+ },
+ {
USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2102,
0,
"Silicon Labs",