Full Code of luigirizzo/dummynet for AI

master e717cdd4bef7 cached
120 files
1.1 MB
346.6k tokens
1239 symbols
1 requests
Download .txt
Showing preview only (1,142K chars total). Download the full file or copy to clipboard to get everything.
Repository: luigirizzo/dummynet
Branch: master
Commit: e717cdd4bef7
Files: 120
Total size: 1.1 MB

Directory structure:
gitextract_r3ojrber/

├── 020-mips-hz1000.patch
├── Makefile
├── Makefile.inc
├── Makefile.openwrt
├── NOTES
├── README
├── binary/
│   ├── README.txt
│   ├── ipfw.sys
│   ├── netipfw.inf
│   ├── netipfw_m.inf
│   └── testme.bat
├── binary64/
│   └── ipfw.sys
├── configuration/
│   ├── README
│   ├── change_rules.sh
│   ├── change_rules_linux.sh
│   ├── ipfw.conf
│   ├── ipfw.rules
│   └── rc.firewall
├── glue.h
├── ipfw/
│   ├── Makefile
│   ├── add_rules
│   ├── dummynet.c
│   ├── expand_number.c
│   ├── glue.c
│   ├── humanize_number.c
│   ├── include/
│   │   ├── alias.h
│   │   ├── net/
│   │   │   ├── if_dl.h
│   │   │   └── pfvar.h
│   │   └── timeconv.h
│   ├── ipfw.8
│   ├── ipfw2.c
│   ├── ipfw2.h
│   ├── ipv6.c
│   ├── main.c
│   ├── qsort.c
│   ├── qsort_r.c
│   ├── rule_test.sh
│   └── ws2_32.def
├── kipfw/
│   ├── Makefile
│   ├── bsd_compat.c
│   ├── debug.c
│   ├── ipfw2_mod.c
│   ├── md_win.c
│   ├── missing.h
│   ├── mysetenv.sh
│   ├── netipfw.inf
│   ├── netipfw_m.inf
│   ├── sources
│   ├── win-passthru.diff
│   └── winmissing.h
├── kmod-ipfw3_2.4.35.4-brcm-2.4-1_mipsel.ipk
├── planetlab/
│   ├── Makefile.planetlab
│   ├── check_planetlab_sync
│   ├── ipfw
│   ├── ipfw.cron
│   ├── ipfwroot.spec
│   ├── ipfwslice.spec
│   ├── netconfig
│   ├── planetlab-tags.mk
│   ├── planetlab.mk
│   └── sample_hook
├── sys/
│   ├── net/
│   │   ├── if.h
│   │   ├── pfil.h
│   │   ├── radix.c
│   │   └── radix.h
│   ├── netgraph/
│   │   └── ng_ipfw.h
│   ├── netinet/
│   │   ├── in_cksum.c
│   │   ├── ip.h
│   │   ├── ip6.h
│   │   ├── ip_dummynet.h
│   │   ├── ip_fw.h
│   │   ├── ip_icmp.h
│   │   ├── ipfw/
│   │   │   ├── dn_heap.c
│   │   │   ├── dn_heap.h
│   │   │   ├── dn_sched.h
│   │   │   ├── dn_sched_fifo.c
│   │   │   ├── dn_sched_prio.c
│   │   │   ├── dn_sched_qfq.c
│   │   │   ├── dn_sched_rr.c
│   │   │   ├── dn_sched_wf2q.c
│   │   │   ├── ip_dn_glue.c
│   │   │   ├── ip_dn_io.c
│   │   │   ├── ip_dn_private.h
│   │   │   ├── ip_dummynet.c
│   │   │   ├── ip_fw2.c
│   │   │   ├── ip_fw_dynamic.c
│   │   │   ├── ip_fw_log.c
│   │   │   ├── ip_fw_lookup.c
│   │   │   ├── ip_fw_nat.c
│   │   │   ├── ip_fw_pfil.c
│   │   │   ├── ip_fw_private.h
│   │   │   ├── ip_fw_sockopt.c
│   │   │   └── ip_fw_table.c
│   │   ├── tcp.h
│   │   ├── tcp_var.h
│   │   └── udp.h
│   └── sys/
│       ├── cdefs.h
│       ├── kernel.h
│       ├── malloc.h
│       ├── mbuf.h
│       ├── module.h
│       ├── param.h
│       ├── queue.h
│       ├── syslog.h
│       ├── systm.h
│       └── taskqueue.h
├── tcc_glue.h
└── test/
    ├── Makefile
    ├── basic_ipfw.sh
    ├── dn_test.h
    ├── dynrules.sh
    ├── interpolation.c
    ├── main.c
    ├── memory_leak.sh
    ├── mylist.h
    ├── profile_bench1
    ├── profile_bench2
    ├── profile_bench3
    ├── test_dn_heap.c
    └── test_dn_sched.c

================================================
FILE CONTENTS
================================================

================================================
FILE: 020-mips-hz1000.patch
================================================
--- include/asm-mips/param_orig.h	2010-02-23 12:45:58.000000000 +0100
+++ include/asm-mips/param.h	2010-02-23 12:00:31.000000000 +0100
@@ -41,7 +41,7 @@
    counter is increasing.  This value is independent from the external value
    and can be changed in order to suit the hardware and application
    requirements.  */
-#  define HZ 100
+#  define HZ 1000
 #  define hz_to_std(a) (a)
 
 #endif /* Not a DECstation  */


================================================
FILE: Makefile
================================================
# $Id: Makefile 11689 2012-08-12 21:07:34Z luigi $
#
# Top level makefile for building ipfw/dummynet (kernel and userspace).
# You can run it manually or also under the Planetlab build.
# Planetlab wants also the 'install' target.
#
# To build on system with non standard Kernel sources or userland files,
# you should run this with
#
#	make KERNELPATH=/path/to/linux-2.x.y.z USRDIR=/path/to/usr
#
# We assume that $(USRDIR) contains include/ and lib/ used to build userland.
#

include Makefile.inc

DATE ?= $(shell date +%Y%m%d)
SNAPSHOT_NAME=$(DATE)-ipfw3.tgz
BINDIST=$(DATE)-dummynet-linux.tgz
WINDIST=$(DATE)-dummynet-windows.zip

DISTFILES= Makefile Makefile.inc README binary* ipfw kipfw *.h sys

.PHONY: ipfw kipfw

###########################################
#  windows x86 and x64 specific variables #
###########################################
#  DRIVE must be the hard drive letter where DDK is installed
#  DDKDIR must be the path to the DDK root directory, without drive letter
#  TARGETOS (x64 only) must be one of the following:
#  wnet   -> windows server 2003
#  wlh    -> windows vista and windows server 2008
#  win7   -> windows 7
#  future version must be added here
DRIVE ?= C:
DDKDIR ?= /WinDDK/7600.16385.1
DDK = $(DRIVE)$(DDKDIR)
TARGETOS=win7

export WIN64
export DDK
export DRIVE
export DDKDIR

_all: all

clean distclean:
	-@(cd ipfw && $(MAKE) $(@) )
	-@rm -rf kipfw-mod binary64/[A-hj-z]*

all: kipfw ipfw
	@# -- windows only
ifeq ($(OSARCH),Windows)	# copy files
ifeq ($(WIN64),)
	-@ cp ipfw/ipfw.exe kipfw-mod/$(OBJDIR)/ipfw.sys binary/
	-@ cp kipfw/*.inf binary/
else
	-@ cp binary/* kipfw/*.inf binary64/
	-@ cp ipfw/ipfw.exe kipfw-mod/objchk_win7_amd64/amd64/ipfw.sys binary64/
endif	# WIN64
endif	# Windows

win64:
	$(MAKE) WIN64=1

# kipfw-src prepares the sources for the kernel part.
# The windows files (passthru etc.) are modified version of the
# examples found in the $(DDK)/src/network/ndis/passthru/driver/
# They can be re-created using the 'ndis-glue' target
# # We need a sed trick to remove newlines from the patchfile.

ndis-glue:
	-@mkdir -p kipfw-mod
	cp $(DDK)/src/network/ndis/passthru/driver/*.[ch] kipfw-mod
	(cd kipfw-mod; for i in  `find . -type f`; do sed -i.tmp "s/$$(printf '\r')//g" $$i; done )
	cat kipfw/win-passthru.diff | sed "s/$$(printf '\r')//g" | (cd kipfw-mod; patch )

kipfw-src:
	-@rm -rf kipfw-mod
	-@mkdir -p kipfw-mod
	-@cp -Rp kipfw/* kipfw-mod
	-@cp `find sys -name \*.c` kipfw-mod
	-@(cd kipfw-mod && $(MAKE) include_e)
ifeq ($(OSARCH),Windows)
	make ndis-glue
endif

snapshot:
	$(MAKE) distclean
	(tar cvzhf /tmp/$(SNAPSHOT_NAME) -s':^:ipfw3-2012/:' $(DISTFILES) )

bindist:
	$(MAKE) clean
	$(MAKE) all
	tar cvzf /tmp/$(BINDIST) ipfw/ipfw ipfw/ipfw.8 kipfw-mod/ipfw_mod.ko

windist:
	$(MAKE) clean
	-$(MAKE) all
	-rm /tmp/$(WINDIST)
	zip -r /tmp/$(WINDIST) binary -x \*.svn\*


ipfw:
	@(cd ipfw && $(MAKE) $(@) )

kipfw: kipfw-src
ifeq ($(WIN64),)	# linux or windows 32 bit
	@(cd kipfw-mod && $(MAKE) $(@) )
else	#--- windows 64 bit, we use build.exe and nmake
	rm -f kipfw-mod/Makefile
	mkdir kipfw-mod/tmpbuild		# check mysetenv.sh
	bash kipfw/mysetenv.sh $(DRIVE) $(DDKDIR) $(TARGETOS)
endif

openwrt_release:
	# create a temporary directory
	$(eval TMPDIR := $(shell mktemp -d -p /tmp/ ipfw3_openwrt_XXXXX))
	# create the source destination directory
	$(eval IPFWDIR := ipfw3-$(DATE))
	$(eval DSTDIR := $(TMPDIR)/$(IPFWDIR))
	mkdir $(DSTDIR)
	# copy the package, clean objects and svn info
	cp -r ./ipfw ./kipfw-mod glue.h Makefile ./configuration README $(DSTDIR)
	(cd $(DSTDIR); make -s distclean; find . -name .svn | xargs rm -rf)
	(cd $(TMPDIR); tar czf $(IPFWDIR).tar.gz $(IPFWDIR))

	# create the port files in /tmp/ipfw3-port
	$(eval PORTDIR := $(TMPDIR)/ipfw3)
	mkdir -p $(PORTDIR)/patches
	# generate the Makefile, PKG_VERSION and PKG_MD5SUM
	md5sum $(DSTDIR).tar.gz | cut -d ' ' -f 1 > $(TMPDIR)/md5sum
	cat ./OPENWRT/Makefile | \
		sed s/PKG_VERSION:=/PKG_VERSION:=$(DATE)/ | \
		sed s/PKG_MD5SUM:=/PKG_MD5SUM:=`cat $(TMPDIR)/md5sum`/ \
		> $(PORTDIR)/Makefile

	@echo ""
	@echo "The openwrt port is in $(TMPDIR)/ipfw3-port"
	@echo "The source file should be copied to the public server:"
	@echo "scp $(DSTDIR).tar.gz marta@info.iet.unipi.it:~marta/public_html/dummynet"
	@echo "after this the temporary directory $(TMPDIR) can be removed."

install:

diff:
	-@(diff -upr $(BSD_HEAD)/sbin/ipfw ipfw)
	-@(diff -upr $(BSD_HEAD)/sys sys)



================================================
FILE: Makefile.inc
================================================
# $Id$
# GNU makefile header for ipfw/kipfw building
BSD_HEAD ?= ~/FreeBSD/head
OSARCH := $(shell uname)
OSARCH := $(findstring $(OSARCH),FreeBSD Linux Darwin)
ifeq ($(OSARCH),)
    OSARCH := Windows
endif
OBJDIR=mia

KSRC ?= /lib/modules/$(shell uname -r)/build
ifneq ($V,1) # no echo
    MSG=@echo
    HIDE=@
else
    MSG=@\#
    HIDE=
endif

.c.o:
	$(MSG) "   CC $<"
	$(HIDE) $(CC) $(CFLAGS) -c $< -o $@



================================================
FILE: Makefile.openwrt
================================================
# Makefile to build the package in openwrt.
# goes into package/network/utils/ipfw3/Makefile
#
# Edit IPFW_DIR to point to the directory with the sources for ipfw

IPFW_DIR := $(TOPDIR)/../qemu-misc/ipfw3

include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=ipfw3
PKG_RELEASE:=1

# MV is undefined, we use it in the internal Makefiles
MV ?= mv

include $(INCLUDE_DIR)/package.mk

#Stuff depending on kernel version
$(warning --- openwrt kernel version $(KERNEL) linux dir $(LINUX_DIR) -------)

ifeq ($(KERNEL),2.4)
    VERS:=openwrt
    CFLAGS_WRT:=-DSYSCTL_NODE -DEMULATE_SYSCTL
    IPFW_MOD:=ipfw_mod.o
    IPFW_SRC_DIR:=SUBDIRS
else
    #VERS:=2.6
    IPFW_MOD:=ipfw_mod.ko
    IPFW_SRC_DIR:=M
endif

define Package/ipfw3
  SECTION:=utils
  CATEGORY:=Utilities
  TITLE := /sbin/ipfw
  DEPENDS := +libc +libgcc
  FILES := $(PKG_BUILD_DIR)/ipfw/ipfw
  $(warning --- build dir is $(PKG_BUILD_DIR) ---)
endef

define Package/ipfw3/description
  Control program for ipfw and dummynet
endef

# XXX not entirely clear why the install entry for userland works,
# given that /sbin/ipfw is in KernelPackage/ipfw3

define Package/ipfw3/install
	$(INSTALL_DIR) $(1) /sbin
endef

# Description for the package.
# The names KernelPackage/ipfw3 must match the arguments to the
# call $(eval $(call KernelPackage,ipfw3)) used to build it

define KernelPackage/ipfw3
  SUBMENU:=Other modules
  TITLE:= IPFW and dummynet
  # FILES is what makes up the module, both kernel and userland
  # It must be in the KernelPackage section XXX
  FILES := $(PKG_BUILD_DIR)/kipfw-mod/$(IPFW_MOD)
  # AUTOLOAD:=$(call AutoLoad,80,ipfw_mod)
endef

define KernelPackage/kmod-ipfw3/description
  ipfw and dummynet kernel module
endef

# Standard entries for the openwrt builds: Build/Prepare and Build/Compile
# Remember that commands must start with a tab

# 'prepare' instructions for both kernel and userland
# We copy the entire subtree, then build include_e/ which
# contains empty headers used by the kernel sources.
define Build/Prepare
  # $(warning --- Preparing ipfw sources ---)
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) -Rp $(IPFW_DIR)/* $(PKG_BUILD_DIR)/
	# The kernel sources are spread in multiple places,
	# so we put everything in kipfw-mod
	mkdir -p $(PKG_BUILD_DIR)/kipfw-mod
	cp -Rp $(IPFW_DIR)/kipfw/* $(PKG_BUILD_DIR)/kipfw-mod
	cp `find $(IPFW_DIR)/sys -name \*.c` $(PKG_BUILD_DIR)/kipfw-mod
	# we do not need cross parameters
	(cd $(PKG_BUILD_DIR)/ipfw && $(MAKE) include_e )
	(cd $(PKG_BUILD_DIR)/kipfw-mod && $(MAKE) include_e )
endef

define Build/Compile
	# XXX check whether we need all linux_dir etc.
	$(warning --- compile the user part for ipfw/openwrt ---)
	$(MAKE) -C $(PKG_BUILD_DIR)/ipfw \
		LINUX_DIR=$(LINUX_DIR) \
		$(TARGET_CONFIGURE_OPTS) \
		CFLAGS="$(TARGET_CFLAGS) $(CFLAGS_WRT) -I./include_e -I./include -include ../glue.h -DNO_ALTQ -D__BSD_VISIBLE" \
		_VER=$(VERS) all
	$(warning --- compile the kernel part for ipfw/openwrt ---)
	$(MAKE) -C "$(LINUX_DIR)" \
		CROSS_COMPILE="$(TARGET_CROSS)" \
		LINUX_DIR=$(LINUX_DIR) \
		KERNELPATH=$(LINUX_DIR) \
		ARCH="$(LINUX_KARCH)" \
		$(IPFW_SRC_DIR)="$(PKG_BUILD_DIR)/kipfw-mod" \
		IPFW3_ROOT="$(PKG_BUILD_DIR)" \
		_VER=$(VERS) modules
	$(warning +++ done compile the kernel part for ipfw/openwrt ---)
endef


$(eval $(call BuildPackage,ipfw3))
$(eval $(call KernelPackage,ipfw3))


================================================
FILE: NOTES
================================================
#
# $Id: NOTES 6552 2010-06-15 11:24:59Z svn_panicucci $
#

---------------------------------------------------------------------
---  DEVELOPER NOTES ------------------------------------------------

Both the client and the kernel code use almost unmodified sources
from FreeBSD (just a very small number of sections #ifdef'ed out
for features not relevant or not implemented).

In both cases we provide two set of headers:
 - one set is made of empty files, automatically generated, to replace
   FreeBSD headers not available or conflicting on the ported platforms.
 - one set is made of custom files, sometimes copied verbatim
   from FreeBSD, sometimes containing only the minimal set of
   macros/ struct/ prototypes required by the port.

Additionally, we have a small set of .c files providing functions not
available in the port platforms, and hooks for the sockopt/packet
data.


TODO 20100205:
+ use an appropriate identifier instead of LINUX24
+ find the discharging module hook, in order to force a queue flush
+ better matching on interface names (case insensitive etc ?)
+ match by interface address
+ verify path
+ send keepalives (20100301 marta: implemented)
+ pullup of data in external buffers
+ O_TAG
+ O_DIVERT
+ O_TEE
+ O_SETFIB
+ kmem_cache_alloc 

TODO (OpenWRT) 20090622
+ add a module compilation for 2.6

TODO (FreeBSD, general)
+ New features related to the forthcoming IPv6 are missing, as the IPv6
support for lookup tables that currently support IPv4 addresses only.
One of the goal of this project is to add the tables feature to the
IPv6 protocol.

+ The current code implements rules listing requests as a single
request returning both static and dynamic rules as a whole block. This
operation requires a lock to be held for the time needed to get the
full list of rules, regardless of the requested rules.  I propose to
break up the rule request in two parts, for static and dynamic rules, in
order to avoid to lock the whole struct for a subset of rules required.

+ At last, due to improvement and contribution to the code, the tool
significantly grown over the time with new functionalities and features,
leaving the general view aside. An example of this will be the use of
dispatching table instead some very long switch case, making the resulting
code more readable and hopefully a faster execution.

+ XXX can't find the ipfw_* indirection...

DETAILED PORTING INFO

--- ipfw (userland) on linux ---

The port is relatively trivial. Communication with the kernel occurs
through a raw socket using [gs]etsockopt(), and all is needed is the
availability of ip_fw.h and ip_dummynet.h headers to describe the
relevant data structures.

--- kernel ipfw on linux ---

Sources are mostly unmodified, except for commenting out
unsupported features (tables, in-kernel nat...).
The port requires a rather large number of empty headers.
Other porting issues are in ipfw2_mod.c

--- build as an Openwrt package

------ WINDOWS PORT ------

We started from the wipfw port available at [WIPFW] , but
most of the port is done from scratch using the most recent
version of ipfw+dummynet from HEAD/RELENG_7 as of March 2009

# WIPFW: wipfw.sourceforge.net
#binary:
http://downloads.sourceforge.net/wipfw/wipfw-0.3.2b.zip?use_mirror=mesh
http://downloads.sourceforge.net/wipfw/wipfw-0.2.8-source.zip

--- DEVELOPMENT TOOLS:

At least initially, to build the code you need a pc with
windows installed and the [WINDDK] from the microsoft site.
Other tools like the new WDK should work as well.

The 'standard' way used by WDK/WINDDK is to run a 'build'
script which in turn calls nmake and then the microsoft
compiler [CL] and linker [LINK]. See the documentation for
command line switches for these tools, they are similar but
not the same as the equivalent gcc switches. In particular,
a / is often used to replace - though both forms are accepted.

The steps to do in order to launch the build environment follows:

 + download winddk from microsoft.com 
 + install 
 + run the Free Build Enviroment from:

	Start -> All Program -> WINDDK ->
	[NT|XP|2000] -> Free Build Environment

 + change dir to .src and type `build' in command line

For our purposes, however, it is much more convenient to use
cygwin [CYGWIN] and invoke CL and LINK using gmake

A debugging tools is:
	http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx
it simply display the kernel-mode debug output.
Use the DbgPrint() function, that is something similar to printk().
Can be lauched with dbgview.exe.

After a succesfully compilation and link, you can launch the program
in user space simply executing the binary file, while for the kernel
space you need to do the following steps:

cp ipfw.sys /cygdrive/c/WINDOWS/system32/drivers/
ipfw install_drv System32\DRIVERS\ip_fw.sys
net start ip_fw


=======
--- ARCHITECTURE ---

The main part of the userland program mostly work as the
unix equivalent, the only issue is to provide empty
header files to replace those not available in Windows,
and include the winsock2 headers to access some network
related functions and headers.

Communication with the kernel module does not use a raw IP socket
as in the unix version. Instead, we inherit the same method
used in ipfw -- a replacement for socket() creates a handle
to access the control structure, and setsockopt/getsockopt
replacements are also used to communicate with the kernel
side. This is implemented in win32.c

In order to load the module and activate it, we also use
the same technique suggested in wipfw -- the main() is
extended (with a wrapper) so that it can handle additional
commands to install/control/deinstall the service and
call the appropriate actions. See svcmain.c for details.

--- PORTING ISSUES:

Most of the unix hierarchy of headers is not available so we
have to replicate them.

gcc attributes are also not present.

C99 types are not present, remapped in <sys/cdefs.h>
Also, we don't have C99 initializers which sometimes gives trouble.

--- USEFUL LINKS:

[WIPFW]
	http://wipfw.sourceforge.net/

[WINDDK]
	http://www.microsoft.com/whdc/devtools/ddk/default.mspx

[CL]
	http://msdn.microsoft.com/en-us/library/610ecb4h.aspx
	command line syntax

[CYGWIN]
	http://www.cygwin.com/setup.exe
Windows Driver Kit
http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx

Debug Symbols for WinXP SP3
http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx#d

DbgView
http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx

Cygwin
http://www.cygwin.com/
(installazione pacchetti di default + categoria devel)

Winrar (il WDK e' distribuito in un file .iso)
http://www.rarlab.com/download.htm

puttycyg (terminale per cygwin)
http://code.google.com/p/puttycyg/

Tortoise SVN
http://tortoisesvn.net/downloads

EditPlus
http://www.editplus.com/

---------------------------------------------------------------------
--- OPEN ISSUES/TODO ------------------------------------------------

- Fix the build on OpenWRT for linux 2.6
  [Forum: https://forum.openwrt.org/viewtopic.php?id=24990]
- Compilation on 2.6 OpenWRT (target is MIPS Artheros 71xx) gives compilation
  errors; [Send updates to: https://forum.openwrt.org/viewtopic.php?id=24990]
- Windows stack corruption [a tricky bug in dummynet]
- Windows ipv6 port [RE: Windows port of ipv6 in ipfw+dummynet]

NOTE:
- To allow compilation on OpenWRT with kernel 2.6 only the Makefile.opewrt
  is modified to guess the kernel version (2.4/2.6)
- ipfw3 Makefile is not modified.
- Also compile on bigendian, but not tested yet...
- Little changes in source code.



================================================
FILE: README
================================================
#
# $Id: README 11691 2012-08-12 21:32:37Z luigi $
#

This directory contains a port of ipfw and dummynet to Linux and Windows.
This version of ipfw and dummynet is called "ipfw3" as it is the
third major rewrite of the code.  The source code here comes straight
from FreeBSD (roughly the version in HEAD as of February 2010),
plus some glue code and headers written from scratch.  Unless
specified otherwise, all the code here is under a BSD license.

Specific build instructions are below, and in general produce

	a kernel module,	ipfw_mod.ko (ipfw.sys on windows)
	a userland program,	/sbin/ipfw (ipfw.exe on windows)

which you need to install on your system.

CREDITS:
    Luigi Rizzo (main design and development)
    Marta Carbone (Linux and Planetlab ports)
    Riccardo Panicucci (modular scheduler support)
    Francesco Magno (Windows port)
    Fabio Checconi (the QFQ scheduler)
    Funding from Universita` di Pisa (NETOS project),
	European Commission (ONELAB2 project)
	ACM SIGCOMM (Sigcomm Community Projects Award, April 2012)
    
------ INSTALL/REMOVE INSTRUCTIONS ------

Linux
    INSTALL:
	# Do the following as root
	insmod ./dummynet2/ipfw_mod.ko
	cp ipfw/ipfw /usr/local/sbin
    REMOVE:
	rmmod ipfw_mod.ko

OpenWRT
    INSTALL:	# use the correct name for your system
	opkg install  kmod-ipfw3_2.4.35.4-brcm-2.4-1_mipsel.ipk #install
	ls -l ls -l /lib/modules/2.4.35.4/ipfw*     # check
	insmod /lib/modules/2.4.35.4/ipfw_mod.o     # load the module
	/lib/modules/2.4.35.4/ipfw show             # launch the userspace tool
    REMOVE:
	rmmod ipfw_mod.o                            # remove the module

Windows:
    A pre-built version is in binary/ and binary64/ directories.

    INSTALL THE NDIS DRIVER
	- open the configuration panel for the network card in use
	  (right click on the icon on the SYSTRAY, or go to
	  Control Panel -> Network and select one card)
	- click on Properties->Install->Service->Add
	- click on 'Driver Disk' and select 'netipfw.inf' in this folder
	- select 'ipfw+dummynet' which is the only service you should see
	- click accept on the warnings for the installation of an unsigned
	  driver (roughly twice per existing network card)

	Now you are ready to use the emulator. To configure it, open a 'cmd'
	window (REMEMBER to run it as Administrator)
	and you can use the ipfw command from the command line.
	Otherwise click on the 'TESTME.bat' which is a batch program that
	runs various tests.
	REMEMBER: you need to run ipfw as administrator.

    REMOVE:
	- select a network card as above.
	- click on Properties
	- select 'ipfw+dummynet'
	- click on 'Remove'


------ BUILD INSTRUCTIONS ------

+ Windows 32 bit and 64 bit (XP, Windows7)

    To build your own version of the package you need:
	- cygwin, http://www.cygwin.com/ with base packages, make,
	  c compiler, possibly an editor and subversion.
	  This is used to build the userspace control program, ipfw.exe

	- Microsoft Windows Driver Kit Version 7.1.0, available from
	    http://www.microsoft.com/en-us/download/details.aspx?id=11800
	    (ISO image, GRMWDK_EN_7600_1.ISO)
	  This is used to build the kernel module.

	- optionally, DbgView if you want to see diagnostics coming from
	  the kernel module. You can find it at

	    http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx

    Check the Makefile in the root directory to make sure that the WDK is
    installed in the place indicated by DRIVE and DDKDIR variables
    (otherwise pass the correct values to the Makefile).
    Open a shell from cygwin, move to this directory, and run "make" for
    the 32-bit version, "make win64" for the 64 bit version.
    This will produce in the binary/ or binary64/ directory the
    following files:
	ipfw.exe (you also need cygwin1.dll)
	ipfw.sys (an NDIS intermediate filter driver)
	netipfw.inf and netipfw_m.inf (installer files)

    Cross compilation of the userland side under FreeBSD is possible with
	gmake TCC=`pwd`/tcc-0.9.25-bsd/win32 CC=`pwd`/tcc-0.9.25-bsd/win32/bin/wintcc
    (wintcc is a custom version of tcc which produces Windows code)

    NOTE: the 64-bit version is compiled as a 32-bit executable for userspace,
	with appropriate changes to produce 64-bit pointers.
	The kernel module is built using the MSC 'build' utility instead
	of 'make'. THE MODULE IS NOT SIGNED.
    IMPORTANT: Windows 64-bit will not load unsigned kernel modules unless
	you boot with 'F8' and disable checks for signed modules.

***** Linux 2.6 and above ******

	make [KSRC=/path/to/linux USRDIR=/path/to/usr]

    where the two variables are optional an point to the linux kernel
    sources and the /usr directory. Defaults are USRDIR=/usr and
    KSRC=/lib/modules/`uname -r`/build 	--- XXX check ?

    NOTE: make sure CONFIG_NETFILTER is enabled in the kernel
    configuration file. You need the ncurses devel library,
    that can be installed according your distro with:
	apt-get install ncurses-dev	# for debian based distro
	yum -y install ncurses-dev	# for fedora based distro
    You can enable CONFIG_NETFILTER by doing:
    
	"(cd ${KSRC}; make menuconfig)"

    and enabling the option listed below:

        Networking --->
	    Networking options  --->
              [*] Network packet filtering framework (Netfilter)

    If you have not yet compiled your kernel source, you need to
    prepare the build environment:

	(cd $(KSRC); make oldconfig; make prepare; make scripts)

***** Linux 2.4.x *****

    Almost as above, with an additional VER=2.4

	make VER=2.4 KSRC=...

    For 2.4, if KSRC is not specified then we use
    	KSRC ?= /usr/src/`uname -r`/build

    You need to follow the same instruction for the 2.6 kernel, enabling
    netfilter in the kernel options:

    Networking options  --->
      [*] Network packet filtering (replaces ipchains)

***** Openwrt package *****

    (Tested with kamikaze_8.09.1 and Linux 2.4)

    + Download and extract the OpenWrt package, e.g.

	wget http://downloads.openwrt.org/kamikaze/8.09.1/kamikaze_8.09.1_source.tar.bz2
	tar xvjf kamikaze_8.09.1_source.tar.bz2

    + move to the directory with the OpenWrt sources (the one that
      contains Config.in, rules.mk ...)

	cd kamikaze_8.09.1

    + Optional: Add support for 1ms resolution.

	By default OpenWRT kernel is compiled with HZ=100; this implies
        that all timeouts are rounded to 10ms, too coarse for dummynet.
        The file 020-mips-hz1000.patch contains a kernel patch to build
	a kernel with HZ=1000 (i.e. 1ms resolution) as in Linux/FreeBSD.
        To apply this patch, go in the kernel source directory and
        patch the kernel

		cd build_dir/linux-brcm-2.4/linux-2.4.35.4
		cat $IPFW3_SOURCES/020-mips-hz1000.patch | patch -p0

	where IPFW3_SOURCES contains the ipfw3 source code.
	Now, the next kernel recompilation will use the right HZ value

    + Optional: to be sure that the tools are working, make a first
      build as follows:

	- run "make menuconfig" and set the correct target device,
	  drivers, and so on;
	- run "make" to do the build

    + Add ipfw3 to the openwrt package, as follows:

      - copy the code from this directory to the place used for the build:

		cp -Rp /path_to_ipfw3 ../ipfw3; 

	If you want, you can fetch a newer version from the web
	(cd ..; rm -rf ipfw3; \
	wget http://info.iet.unipi.it/~luigi/dummynet/ipfw3-latest.tgz;\
	tar xvzf ipfw3-latest.tgz)

      - run the following commands:
	(mkdir package/ipfw3; \
	cp ../ipfw3/Makefile.openwrt package/ipfw3/Makefile)

	to create the package/ipfw3 directory in the OpenWrt source
	directory, and copy Makefile.openwrt to package/ipfw3/Makefile ;

      - if necessary, edit package/ipfw3/Makefile and set IPFW_DIR to point to
	the directory ipfw3, which contains the sources;

      - run "make menuconfig" and select kmod-ipfw3 as a module <M> in
	    Kernel Modules -> Other modules -> kmod-ipfw3 

      - run "make" to build the package, "make V=99" for verbose build.

      - to modify the code, assuming you are in directory "kamikaze_8.09.1"
	
	(cd ../ipfw3 && vi ...the files you are interested in )
	rm -rf build_dir/linux-brcm-2.4/kmod-ipfw3
	make package/ipfw3/compile V=99

    The resulting package is located in bin/packages/mipsel/kmod-ipfw3*,
    upload the file and install on the target system, as follows:

    opkg install  kmod-ipfw3_2.4.35.4-brcm-2.4-1_mipsel.ipk #install
    ls -l ls -l /lib/modules/2.4.35.4/ipfw*     # check
    insmod /lib/modules/2.4.35.4/ipfw_mod.o     # load the module
    /lib/modules/2.4.35.4/ipfw show             # launch the userspace tool
    rmmod ipfw_mod.o                            # remove the module

***** PLANETLAB BUILD (within a slice) *****
These instruction can be used by PlanetLab developers to compile
the dummynet module on a node. To install the module on the node
users need root access in root context.  PlanetLab users that want
to use the dummynet package should ask to PlanetLab support for
nodes with dummynet emulation capabilities.

    Follow the instructions below. You can just cut&paste

	# install the various tools if not available
	sudo yum -y install subversion rpm-build rpm-devel m4 redhat-rpm-config make gcc
	# new build installation requires the gnupg package
	sudo yum -y install gnupg
	# the linux kernel and the ipfw source can be fetched by git
	sudo yum -y install git

	# create and move to a work directory
	mkdir -p test
	# extract a planetlab distribution to directory XYZ
	(cd test; git clone git://git.onelab.eu/build ./XYZ)
	# download the specfiles and do some patching.
	# Results are into SPEC/ (takes 5 minutes)
	(cd test/XYZ; make stage1=true PLDISTRO=onelab)
	# Building the slice code is fast, the root code takes longer
	# as it needs to rebuild the whole kernel
	(cd test/XYZ; sudo make ipfwslice PLDISTRO=onelab)
	(cd test/XYZ; sudo make ipfwroot PLDISTRO=onelab)

    The kernel dependency phase is a bit time consuming, but does not
    need to be redone if we are changing the ipfw sources only.
    To clean up the code do
	(cd test/XYZ; sudo make ipfwroot-clean ipfwslice-clean)
    then after you have updated the repository again
	(cd test/XYZ; sudo make ipfwslice ipfwroot)

--- References
[1] https://svn.planet-lab.org/wiki/VserverCentos
[2] http://wiki.linux-vserver.org/Installation_on_CentOS
[3] http://mirror.centos.org/centos/5/isos/
[4] More information are in /build/README* files 


================================================
FILE: binary/README.txt
================================================
This directory contains the binaries to install and use IPFW and
DUMMYNET on a Windows Machine. The kernel part is an NDIS module,
whereas the user interface is a command line program.

1. INSTALL THE NDIS DRIVER

- open the configuration panel for the network card in use
  (either right click on the icon on the SYSTRAY, or go to
  Control Panel -> Network and select one card)

- click on Properties->Install->Service->Add
- click on 'Driver Disk' and select 'netipfw.inf' in this folder
- select 'ipfw+dummynet' which is the only service you should see
- click accept on the warnings for the installation of an unknown
  driver (roughly twice per existing network card)

Now you are ready to use the emulator. To configure it, open a 'cmd'
window and you can use the ipfw command from the command line.
Otherwise click on the 'TESTME.bat' which is a batch program that
runs various tests.

2. UNINSTALL THE DRIVER

- select a network card as above.
- click on Properties
- select 'ipfw+dummynet'
- click on 'Remove'


================================================
FILE: binary/netipfw.inf
================================================
; version section
[Version]
Signature  = "$Windows NT$"
Class      = NetService
ClassGUID  = {4D36E974-E325-11CE-BFC1-08002BE10318}
Provider   = %Unipi%
DriverVer  = 26/02/2010,3.0.0.1

; manufacturer section
[Manufacturer]
%Unipi% = UNIPI,NTx86,NTamd64

; control flags section
; optional, unused in netipfw.inf inf, used in netipfw_m.inf
[ControlFlags]

; models section
[UNIPI] ; Win2k
%Desc% = Ipfw.ndi, unipi_ipfw
[UNIPI.NTx86] ;For WinXP and later
%Desc% = Ipfw.ndi, unipi_ipfw
[UNIPI.NTamd64] ;For x64
%Desc% = Ipfw.ndi, unipi_ipfw

; ddinstall section
[Ipfw.ndi]
AddReg          = Ipfw.ndi.AddReg, Ipfw.AddReg
Characteristics = 0x4410 ;  NCF_FILTER | NCF_NDIS_PROTOCOL !--Filter Specific--!!
CopyFiles       = Ipfw.Files.Sys
CopyInf         = netipfw_m.inf

; remove section
[Ipfw.ndi.Remove]
DelFiles = Ipfw.Files.Sys

;ddinstall.services section
[Ipfw.ndi.Services]
AddService = Ipfw,,Ipfw.AddService

[Ipfw.AddService]
DisplayName    = %ServiceDesc%
ServiceType    = 1 ;SERVICE_KERNEL_DRIVER
StartType      = 3 ;SERVICE_DEMAND_START
ErrorControl   = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\ipfw.sys
AddReg         = Ipfw.AddService.AddReg

[Ipfw.AddService.AddReg]

;file copy related sections
[SourceDisksNames]
1=%DiskDescription%,"",,

[SourceDisksFiles]
ipfw.sys=1

[DestinationDirs]
DefaultDestDir = 12
Ipfw.Files.Sys   = 12   ; %windir%\System32\drivers

; ddinstall->copyfiles points here
[Ipfw.Files.Sys]
ipfw.sys,,,2

; ddinstall->addreg points here
[Ipfw.ndi.AddReg]
HKR, Ndi,            HelpText,            , %HELP% ; this is displayed at the bottom of the General page of the Connection Properties dialog box
HKR, Ndi,            FilterClass,         , failover
HKR, Ndi,            FilterDeviceInfId,   , unipi_ipfwmp
HKR, Ndi,            Service,             , Ipfw
HKR, Ndi\Interfaces, UpperRange,          , noupper
HKR, Ndi\Interfaces, LowerRange,          , nolower
HKR, Ndi\Interfaces, FilterMediaTypes,    , "ethernet, tokenring, fddi, wan"

;strings section
[Strings]
Unipi = "Unipi"
DiskDescription = "Ipfw Driver Disk"
Desc = "ipfw+dummynet"
HELP = "This is ipfw and dummynet network emulator, developed by unipi.it"
ServiceDesc = "ipfw service"


================================================
FILE: binary/netipfw_m.inf
================================================
; version section
[Version]
Signature  = "$Windows NT$"
Class      = Net
ClassGUID  = {4D36E972-E325-11CE-BFC1-08002BE10318}
Provider   = %Unipi%
DriverVer  = 26/02/2010,3.0.0.1

; control flags section
; optional, unused in netipfw.inf inf, used in netipfw_m.inf
[ControlFlags]
ExcludeFromSelect = unipi_ipfwmp

; destinationdirs section, optional
[DestinationDirs]
DefaultDestDir=12
; No files to copy 

; manufacturer section
[Manufacturer]
%Unipi% = UNIPI,NTx86,NTamd64

; models section
[UNIPI] ; Win2k
%Desc% = IpfwMP.ndi, unipi_ipfwmp
[UNIPI.NTx86] ;For WinXP and later
%Desc% = IpfwMP.ndi, unipi_ipfwmp
[UNIPI.NTamd64] ;For x64
%Desc% = IpfwMP.ndi, unipi_ipfwmp

; ddinstall section
[IpfwMP.ndi]
AddReg  = IpfwMP.ndi.AddReg
Characteristics = 0x29 ;NCF_NOT_USER_REMOVABLE | NCF_VIRTUAL | NCF_HIDDEN

; ddinstall->addreg points here
[IpfwMP.ndi.AddReg]
HKR, Ndi, Service,  0,  IpfwMP

;ddinstall.services section
[IpfwMP.ndi.Services]
AddService = IpfwMP,0x2, IpfwMP.AddService

[IpfwMP.AddService]
ServiceType    = 1 ;SERVICE_KERNEL_DRIVER
StartType      = 3 ;SERVICE_DEMAND_START
ErrorControl   = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\ipfw.sys
AddReg         = IpfwMP.AddService.AddReg

[IpfwMP.AddService.AddReg]
; None

[Strings]
Unipi = "Unipi"
Desc = "Ipfw Miniport"

================================================
FILE: binary/testme.bat
================================================
@echo on
@set CYGWIN=nodosfilewarning

@ipfw -q flush
@ipfw -q pipe flush
@echo ######################################################################
@echo ## Setting delay to 100ms for both incoming and outgoing ip packets ##
@echo ## and sending 4 echo request to Google                             ##
@echo ######################################################################
ipfw pipe 3 config delay 100ms
ipfw add pipe 3 ip from any to any
ipfw pipe show
ping -n 4 www.google.it

@echo ##############################################
@echo ## Raising delay to 300ms and pinging again ##
@echo ##############################################
ipfw pipe 3 config delay 300ms
ipfw pipe show
ping -n 4 www.google.com

@echo ##################################
@echo ## Shaping bandwidth to 500kbps ##
@echo ##################################
ipfw pipe 3 config bw 500Kbit/s
ipfw pipe show
wget http://info.iet.unipi.it/~luigi/1m
@del 1m

@echo ###################################
@echo ## Lowering bandwidth to 250kbps ##
@echo ###################################
ipfw pipe 3 config bw 250Kbit/s
ipfw pipe show
wget http://info.iet.unipi.it/~luigi/1m
@del 1m

@echo ###################################################################
@echo ## Simulating 50 percent packet loss and sending 15 echo request ##
@echo ###################################################################
@ipfw -q flush
@ipfw -q pipe flush
ipfw add prob 0.5 deny proto icmp in
ping -n 15 -w 300 www.google.it
@ipfw -q flush

@echo ##############################
@echo ## Showing SYSCTL variables ##
@echo ##############################
ipfw sysctl -a

@echo #############################################
@echo ## Inserting rules to test command parsing ##
@echo #############################################
@echo -- dropping all packets of a specific protocol --
ipfw add deny proto icmp
@echo -- dropping packets of all protocols except a specific one --
ipfw add deny not proto tcp
@echo -- dropping all packets from IP x to IP y --
ipfw add deny src-ip 1.2.3.4 dst-ip 5.6.7.8
@echo -- dropping all ssh outgoing connections --
ipfw add deny out dst-port 22
@echo -- allowing already opened browser connections --
@echo -- but preventing new ones from being opened   --
ipfw add deny out proto tcp dst-port 80 tcpflags syn
@echo -- another way to do the same thing --
ipfw add allow out proto tcp dst-port 80 established
ipfw add deny out proto tcp dst-port 80 setup
@echo -- checking what rules have been inserted --
ipfw -c show
@ipfw -q flush

@echo #################
@echo ## Cleaning up ##
@echo #################
ipfw -q flush
ipfw -q pipe flush

pause


================================================
FILE: configuration/README
================================================
This directorty contains some ipfw configurations and a scripts 
to safely change the firewall rules.

The firewall configuration comes from the FreeBSD initial script.
The change_rules_linux.sh allows to change the ipfw rules and
in case os a misconfiguration which prevents to reach the remote
host, to restore the old ruleset.

To configure the firewall behavior, edit the ipfw.conf file and 
execute the ./change_rules_linux.sh script.

The ipfw program executable should be located in /sbin (XXX)

XXX seems we use something which is not compatible with dash


================================================
FILE: configuration/change_rules.sh
================================================
#!/bin/sh
#
# Copyright (c) 2000 Alexandre Peixoto
# 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.
#
# $FreeBSD: src/share/examples/ipfw/change_rules.sh,v 1.6 2003/09/07 07:52:56 jmg Exp $

# Change ipfw(8) rules with safety guarantees for remote operation
#
# Invoke this script to edit ${firewall_script}. It will call ${EDITOR},
# or vi(1) if the environment variable is not set, for you to edit
# ${firewall_script}, ask for confirmation, and then run
# ${firewall_script}. You can then examine the output of ipfw list and
# confirm whether you want the new version or not.
#
# If no answer is received in 30 seconds, the previous
# ${firewall_script} is run, restoring the old rules (this assumes ipfw
# flush is present in it).
#
# If the new rules are confirmed, they'll replace ${firewall_script} and
# the previous ones will be copied to ${firewall_script}.{date}. Mail
# will also be sent to root with a unified diff of the rule change.
#
# Unapproved rules are kept in ${firewall_script}.new, and you are
# offered the option of changing them instead of the present rules when
# you call this script.
#
# This script could be improved by using version control
# software.

# XXX on linux /etc/rc.conf defines:
# firewall_type and firewall_script

if [ -r /etc/defaults/rc.conf ]; then
	. /etc/defaults/rc.conf
	source_rc_confs
elif [ -r /etc/rc.conf ]; then
	. /etc/rc.conf
fi

EDITOR=${EDITOR:-/usr/bin/vi}
PAGER=${PAGER:-/usr/bin/more}

# on linux the default mktemp invocation behavior
# is different, we should change the temporary file creation
tempfoo=`basename $0`
#TMPFILE=`mktemp -t ${tempfoo}` || exit 1
TMPFILE=`mktemp -t ${tempfoo}.XXXXX` || exit 1

get_yes_no() {
	while true
	do
		echo -n "$1 (Y/N) ? " 
		read -t 30 a
		if [ $? != 0 ]; then
			a="No";
		        return;
		fi
		case $a in
			[Yy]) a="Yes";
			      return;;
			[Nn]) a="No";
			      return;;
			*);;
		esac
	done
}

restore_rules() {
	nohup sh ${firewall_script} </dev/null >/dev/null 2>&1
	rm ${TMPFILE}
	exit 1
}

case "${firewall_type}" in
[Cc][Ll][Ii][Ee][Nn][Tt]|\
[Cc][Ll][Oo][Ss][Ee][Dd]|\
[Oo][Pp][Ee][Nn]|\
[Ss][Ii][Mm][Pp][Ll][Ee]|\
[Uu][Nn][Kk][Nn][Oo][Ww][Nn])
	edit_file="${firewall_script}"
	rules_edit=no
	;;
*)
	if [ -r "${firewall_type}" ]; then
		edit_file="${firewall_type}"
		rules_edit=yes
	fi
	;;
esac

if [ -f ${edit_file}.new ]; then
	get_yes_no "A new rules file already exists, do you want to use it"
	[ $a = 'No' ] && cp ${edit_file} ${edit_file}.new
else 
	cp ${edit_file} ${edit_file}.new
fi

trap restore_rules SIGHUP

${EDITOR} ${edit_file}.new

get_yes_no "Do you want to install the new rules"

[ $a = 'No' ] && exit 1

cat <<!
The rules will be changed now. If the message 'Type y to keep the new
rules' does not appear on the screen or the y key is not pressed in 30
seconds, the original rules will be restored.
The TCP/IP connections might be broken during the change. If so, restore
the ssh/telnet connection being used.
!

if [ ${rules_edit} = yes ]; then
	nohup sh ${firewall_script} ${firewall_type}.new \
	    < /dev/null > ${TMPFILE} 2>&1
else
	nohup sh ${firewall_script}.new \
	    < /dev/null > ${TMPFILE} 2>&1
fi
sleep 2;
get_yes_no "Would you like to see the resulting new rules"
[ $a = 'Yes' ] && ${PAGER} ${TMPFILE}
get_yes_no "Type y to keep the new rules"
[ $a != 'Yes' ] && restore_rules

DATE=`date "+%Y%m%d%H%M"`
cp ${edit_file} ${edit_file}.$DATE
mv ${edit_file}.new ${edit_file} 
cat <<!
The new rules are now installed. The previous rules have been preserved in
the file ${edit_file}.$DATE
!
diff -F "^# .*[A-Za-z]" -u ${edit_file}.$DATE ${edit_file} \
    | mail -s "`hostname` Firewall rule change" root
rm ${TMPFILE}
exit 0


================================================
FILE: configuration/change_rules_linux.sh
================================================
#!/bin/sh
#
# marta
# linux wrapper for the FreeBSD change rules program
# This file load the linux configuration and calls the
# original change rules program

if [ -r ./ipfw.conf ]; then
	. ./ipfw.conf
fi

. ./change_rules.sh


================================================
FILE: configuration/ipfw.conf
================================================
# ipfw and dummynet configuration file for linux
# XXX TO BE TESTED ON LINUX

# The firewall_type variable is used to configure the firewall behavior.
# A detailed description on how a following type works is in rc.firewall
#
#   open        - will allow anyone in
#   client      - will try to protect just this machine
#   simple      - will try to protect a whole network
#   closed      - totally disables IP services except via lo0 interface
#   workstation - will try to protect just this machine using statefull
#                 firewalling. See below for rc.conf variables used
#   UNKNOWN     - disables the loading of firewall rules.
#   filename    - will load the rules in the given filename (full path required)

# firewall_type=open

# The following file is an example on how to use a filename to define a firewall
# and how to configure a simple dummynet pipe to ... XXX shape traffic... etc...
firewall_type=/home/marta/SVN/ports-luigi/dummynet-branches/ipfw3/configuration/ipfw.rules

# Environment variables expected by the change rules script
EDITOR=/usr/bin/vi
PAGER=/bin/more

# The following variable should point to the rc.firewall script
# XXX TEST
#firewall_script=`echo "please edit the firewall_script variable in ipfw.conf"`;
firewall_script="/home/marta/SVN/ports-luigi/dummynet-branches/ipfw3/configuration/rc.firewall"


================================================
FILE: configuration/ipfw.rules
================================================
# This is a simple configuration file
# add dummynet pipes and a firewall section

# flush all rules ...
# flush

# dummynet configuration

# firewall configuration
add 1 allow all from any to any
# ...
add 65000 deny all from any to any


================================================
FILE: configuration/rc.firewall
================================================
#!/bin/sh -
# Copyright (c) 1996  Poul-Henning Kamp
# 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.
#
# $FreeBSD: src/etc/rc.firewall,v 1.52.4.1 2008/01/29 00:22:32 dougb Exp $
#

#
# Setup system for ipfw(4) firewall service.
#

# Suck in the configuration variables.
if [ -z "${source_rc_confs_defined}" ]; then
	if [ -r /etc/defaults/rc.conf ]; then
		. /etc/defaults/rc.conf
		source_rc_confs
	elif [ -r /etc/rc.conf ]; then
		. /etc/rc.conf
	fi
fi

############
# Define the firewall type in /etc/rc.conf.  Valid values are:
#   open        - will allow anyone in
#   client      - will try to protect just this machine
#   simple      - will try to protect a whole network
#   closed      - totally disables IP services except via lo0 interface
#   workstation - will try to protect just this machine using statefull
#		  firewalling. See below for rc.conf variables used
#   UNKNOWN     - disables the loading of firewall rules.
#   filename    - will load the rules in the given filename (full path required)
#
# For ``client'' and ``simple'' the entries below should be customized
# appropriately.

############
#
# If you don't know enough about packet filtering, we suggest that you
# take time to read this book:
#
#	Building Internet Firewalls, 2nd Edition
#	Brent Chapman and Elizabeth Zwicky
#
#	O'Reilly & Associates, Inc
#	ISBN 1-56592-871-7
#	http://www.ora.com/
#	http://www.oreilly.com/catalog/fire2/
#
# For a more advanced treatment of Internet Security read:
#
#	Firewalls and Internet Security: Repelling the Wily Hacker, 2nd Edition
#	William R. Cheswick, Steven M. Bellowin, Aviel D. Rubin
#
#	Addison-Wesley / Prentice Hall
#	ISBN 0-201-63466-X
#	http://www.pearsonhighered.com/
#	http://www.pearsonhighered.com/educator/academic/product/0,3110,020163466X,00.html
#

setup_loopback () {
	############
	# Only in rare cases do you want to change these rules
	#
	${fwcmd} add 100 pass all from any to any via lo0
	${fwcmd} add 200 deny all from any to 127.0.0.0/8
	${fwcmd} add 300 deny ip from 127.0.0.0/8 to any
}

if [ -n "${1}" ]; then
	firewall_type="${1}"
fi

############
# Set quiet mode if requested
#
case ${firewall_quiet} in
[Yy][Ee][Ss])
	fwcmd="/sbin/ipfw -q"
	;;
*)
	fwcmd="/sbin/ipfw"
	;;
esac

############
# Flush out the list before we begin.
#
${fwcmd} -f flush

setup_loopback

############
# Network Address Translation.  All packets are passed to natd(8)
# before they encounter your remaining rules.  The firewall rules
# will then be run again on each packet after translation by natd
# starting at the rule number following the divert rule.
#
# For ``simple'' firewall type the divert rule should be put to a
# different place to not interfere with address-checking rules.
#
case ${firewall_type} in
[Oo][Pp][Ee][Nn]|[Cc][Ll][Ii][Ee][Nn][Tt])
	case ${natd_enable} in
	[Yy][Ee][Ss])
		if [ -n "${natd_interface}" ]; then
			${fwcmd} add 50 divert natd ip4 from any to any via ${natd_interface}
		fi
		;;
	esac
	case ${firewall_nat_enable} in
	[Yy][Ee][Ss])
		if [ -n "${firewall_nat_interface}" ]; then
			${fwcmd} nat 123 config if ${firewall_nat_interface} log
			${fwcmd} add 50 nat 123 ip4 from any to any via ${firewall_nat_interface}
		fi
		;;
	esac
esac

############
# If you just configured ipfw in the kernel as a tool to solve network
# problems or you just want to disallow some particular kinds of traffic
# then you will want to change the default policy to open.  You can also
# do this as your only action by setting the firewall_type to ``open''.
#
# ${fwcmd} add 65000 pass all from any to any


# Prototype setups.
#
case ${firewall_type} in
[Oo][Pp][Ee][Nn])
	${fwcmd} add 65000 pass all from any to any
	;;

[Cc][Ll][Ii][Ee][Nn][Tt])
	############
	# This is a prototype setup that will protect your system somewhat
	# against people from outside your own network.
	############

	# set these to your network and netmask and ip
	net="192.0.2.0"
	mask="255.255.255.0"
	ip="192.0.2.1"

	# Allow any traffic to or from my own net.
	${fwcmd} add pass all from ${ip} to ${net}:${mask}
	${fwcmd} add pass all from ${net}:${mask} to ${ip}

	# Allow TCP through if setup succeeded
	${fwcmd} add pass tcp from any to any established

	# Allow IP fragments to pass through
	${fwcmd} add pass all from any to any frag

	# Allow setup of incoming email
	${fwcmd} add pass tcp from any to me 25 setup

	# Allow setup of outgoing TCP connections only
	${fwcmd} add pass tcp from me to any setup

	# Disallow setup of all other TCP connections
	${fwcmd} add deny tcp from any to any setup

	# Allow DNS queries out in the world
	${fwcmd} add pass udp from me to any 53 keep-state

	# Allow NTP queries out in the world
	${fwcmd} add pass udp from me to any 123 keep-state

	# Everything else is denied by default, unless the
	# IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
	# config file.
	;;

[Ss][Ii][Mm][Pp][Ll][Ee])
	############
	# This is a prototype setup for a simple firewall.  Configure this
	# machine as a DNS and NTP server, and point all the machines
	# on the inside at this machine for those services.
	############

	# set these to your outside interface network and netmask and ip
	oif="ed0"
	onet="192.0.2.0"
	omask="255.255.255.240"
	oip="192.0.2.1"

	# set these to your inside interface network and netmask and ip
	iif="ed1"
	inet="192.0.2.16"
	imask="255.255.255.240"
	iip="192.0.2.17"

	# Stop spoofing
	${fwcmd} add deny all from ${inet}:${imask} to any in via ${oif}
	${fwcmd} add deny all from ${onet}:${omask} to any in via ${iif}

	# Stop RFC1918 nets on the outside interface
	${fwcmd} add deny all from any to 10.0.0.0/8 via ${oif}
	${fwcmd} add deny all from any to 172.16.0.0/12 via ${oif}
	${fwcmd} add deny all from any to 192.168.0.0/16 via ${oif}

	# Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1,
	# DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E)
	# on the outside interface
	${fwcmd} add deny all from any to 0.0.0.0/8 via ${oif}
	${fwcmd} add deny all from any to 169.254.0.0/16 via ${oif}
	${fwcmd} add deny all from any to 192.0.2.0/24 via ${oif}
	${fwcmd} add deny all from any to 224.0.0.0/4 via ${oif}
	${fwcmd} add deny all from any to 240.0.0.0/4 via ${oif}

	# Network Address Translation.  This rule is placed here deliberately
	# so that it does not interfere with the surrounding address-checking
	# rules.  If for example one of your internal LAN machines had its IP
	# address set to 192.0.2.1 then an incoming packet for it after being
	# translated by natd(8) would match the `deny' rule above.  Similarly
	# an outgoing packet originated from it before being translated would
	# match the `deny' rule below.
	case ${natd_enable} in
	[Yy][Ee][Ss])
		if [ -n "${natd_interface}" ]; then
			${fwcmd} add divert natd all from any to any via ${natd_interface}
		fi
		;;
	esac

	# Stop RFC1918 nets on the outside interface
	${fwcmd} add deny all from 10.0.0.0/8 to any via ${oif}
	${fwcmd} add deny all from 172.16.0.0/12 to any via ${oif}
	${fwcmd} add deny all from 192.168.0.0/16 to any via ${oif}

	# Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1,
	# DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E)
	# on the outside interface
	${fwcmd} add deny all from 0.0.0.0/8 to any via ${oif}
	${fwcmd} add deny all from 169.254.0.0/16 to any via ${oif}
	${fwcmd} add deny all from 192.0.2.0/24 to any via ${oif}
	${fwcmd} add deny all from 224.0.0.0/4 to any via ${oif}
	${fwcmd} add deny all from 240.0.0.0/4 to any via ${oif}

	# Allow TCP through if setup succeeded
	${fwcmd} add pass tcp from any to any established

	# Allow IP fragments to pass through
	${fwcmd} add pass all from any to any frag

	# Allow setup of incoming email
	${fwcmd} add pass tcp from any to ${oip} 25 setup

	# Allow access to our DNS
	${fwcmd} add pass tcp from any to ${oip} 53 setup
	${fwcmd} add pass udp from any to ${oip} 53
	${fwcmd} add pass udp from ${oip} 53 to any

	# Allow access to our WWW
	${fwcmd} add pass tcp from any to ${oip} 80 setup

	# Reject&Log all setup of incoming connections from the outside
	${fwcmd} add deny log tcp from any to any in via ${oif} setup

	# Allow setup of any other TCP connection
	${fwcmd} add pass tcp from any to any setup

	# Allow DNS queries out in the world
	${fwcmd} add pass udp from ${oip} to any 53 keep-state

	# Allow NTP queries out in the world
	${fwcmd} add pass udp from ${oip} to any 123 keep-state

	# Everything else is denied by default, unless the
	# IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
	# config file.
	;;

[Ww][Oo][Rr][Kk][Ss][Tt][Aa][Tt][Ii][Oo][Nn])
	# Configuration:
	#  firewall_myservices:		List of TCP ports on which this host
	#			 	 offers services.
	#  firewall_allowservices:	List of IPs which has access to
	#				 $firewall_myservices.
	#  firewall_trusted:		List of IPs which has full access 
	#				 to this host. Be very carefull 
	#				 when setting this. This option can
	#				 seriously degrade the level of 
	#				 protection provided by the firewall.
	#  firewall_logdeny:		Boolean (YES/NO) specifying if the
	#				 default denied packets should be
	#				 logged (in /var/log/security).
	#  firewall_nologports:		List of TCP/UDP ports for which
	#				 denied incomming packets are not
	#				 logged.
	
	# Allow packets for which a state has been built.
	${fwcmd} add check-state

	# For services permitted below.
	${fwcmd} add pass tcp  from me to any established

	# Allow any connection out, adding state for each.
	${fwcmd} add pass tcp  from me to any setup keep-state
	${fwcmd} add pass udp  from me to any       keep-state
	${fwcmd} add pass icmp from me to any       keep-state

	# Allow DHCP.
	${fwcmd} add pass udp  from 0.0.0.0 68 to 255.255.255.255 67 out
	${fwcmd} add pass udp  from any 67     to me 68 in
	${fwcmd} add pass udp  from any 67     to 255.255.255.255 68 in
	# Some servers will ping the IP while trying to decide if it's 
	# still in use.
	${fwcmd} add pass icmp from any to any icmptype 8

	# Allow "mandatory" ICMP in.
	${fwcmd} add pass icmp from any to any icmptype 3,4,11
	
	# Add permits for this workstations published services below
	# Only IPs and nets in firewall_allowservices is allowed in.
	# If you really wish to let anyone use services on your 
	# workstation, then set "firewall_allowservices='any'" in /etc/rc.conf
	#
	# Note: We don't use keep-state as that would allow DoS of
	#       our statetable. 
	#       You can add 'keep-state' to the lines for slightly
	#       better performance if you fell that DoS of your
	#       workstation won't be a problem.
	#
	for i in ${firewall_allowservices} ; do
	  for j in ${firewall_myservices} ; do
	    ${fwcmd} add pass tcp from $i to me $j
	  done
	done

	# Allow all connections from trusted IPs.
	# Playing with the content of firewall_trusted could seriously
	# degrade the level of protection provided by the firewall.
	for i in ${firewall_trusted} ; do
	  ${fwcmd} add pass ip from $i to me
	done
	
	${fwcmd} add 65000 count ip from any to any

	# Drop packets to ports where we don't want logging
	for i in ${firewall_nologports} ; do
	  ${fwcmd} add deny { tcp or udp } from any to any $i in
	done

	# Broadcasts and muticasts
	${fwcmd} add deny ip  from any to 255.255.255.255
	${fwcmd} add deny ip  from any to 224.0.0.0/24 in	# XXX

	# Noise from routers
	${fwcmd} add deny udp from any to any 520 in

	# Noise from webbrowsing.
	# The statefull filter is a bit agressive, and will cause some
	#  connection teardowns to be logged.
	${fwcmd} add deny tcp from any 80,443 to any 1024-65535 in

	# Deny and (if wanted) log the rest unconditionally.
	log=""
	if [ ${firewall_logdeny:-x} = "YES" -o ${firewall_logdeny:-x} = "yes" ] ; then
	  log="log logamount 500"	# The default of 100 is too low.
	  sysctl net.inet.ip.fw.verbose=1 >/dev/null
	fi
	${fwcmd} add deny $log ip from any to any
	;;

[Cc][Ll][Oo][Ss][Ee][Dd])
	${fwcmd} add 65000 deny ip from any to any
	;;
[Uu][Nn][Kk][Nn][Oo][Ww][Nn])
	;;
*)
	if [ -r "${firewall_type}" ]; then
		${fwcmd} ${firewall_flags} ${firewall_type}
	fi
	;;
esac


================================================
FILE: glue.h
================================================
/*
 * Copyright (c) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa
 *
 * 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.
 */
/*
 * $Id: glue.h 12501 2014-01-10 01:09:14Z luigi $
 *
 * glue code to adapt the FreeBSD version to linux and windows,
 * userland and kernel.
 * This is included before any other headers, so we do not have
 * a chance to override any #define that should appear in other
 * headers.
 * First handle headers for userland and kernel. Then common code
 * (including headers that require a specific order of inclusion),
 * then the user- and kernel- specific parts.
 */
 
#if defined __FreeBSD__
#define _GLUE_H
#endif /* __FreeBSD__ */
#ifndef _GLUE_H
#define	_GLUE_H


/*
 * common definitions to allow portability
 */
#ifndef __FBSDID
#define __FBSDID(x)
#endif  /* FBSDID */

#ifndef KERNEL_MODULE	/* Userland headers */

#if defined(__CYGWIN32__) || defined(__CYGWIN__)
#if !defined(_WIN32)                                   
#define _WIN32                                                                  
#endif                                                                          
#endif                                                                          

#if defined(TCC) && defined(_WIN32)
#include <tcc_glue.h>
#endif /* TCC */

#include <stdint.h>	/* linux needs it in addition to sys/types.h */
#include <sys/types.h>	/* for size_t */
#include <sys/ioctl.h>
#include <time.h>
#include <errno.h>
#ifdef __linux__
#include <netinet/ether.h>	/* linux only 20111031 */
#endif

#else /* KERNEL_MODULE, kernel headers */

#define	INET		# want inet support
#ifdef __linux__

#include <linux/version.h>

#define ifnet		net_device	/* remap */
#define	_KERNEL		# make kernel structure visible
#define	KLD_MODULE	# add the module glue

#include <linux/stddef.h>	/* linux kernel */
#include <linux/types.h>	/* linux kernel */

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)	// or 2.4.x
#include <linux/linkage.h>	/* linux/msg.h require this */
#include <linux/netdevice.h>	/* just MAX_ADDR_LEN 8 on 2.4 32 on 2.6, also brings in byteorder */
#endif

/* on 2.6.22, msg.h requires spinlock_types.h */
/* XXX spinlock_type.h was introduced in 2.6.14 */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) && \
	LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
#include <linux/spinlock_types.h>
#endif
/* XXX m_type define conflict with include/sys/mbuf.h,
 * so early include msg.h (to be solved)
*/
#include <linux/msg.h>	

#include <linux/list.h>
#include <linux/in.h>		/* struct in_addr */
#include <linux/in6.h>		/* struct in6_addr */
#include <linux/icmp.h>
/*
 * LIST_HEAD in queue.h conflict with linux/list.h
 * some previous linux include need list.h definition
 */
#undef LIST_HEAD

#define	IF_NAMESIZE	(16)
typedef	uint32_t	in_addr_t;

#define printf(fmt, arg...) printk(KERN_ERR fmt, ##arg)
#endif	/* __linux__ */

#endif /* KERNEL_MODULE end of kernel headers */


/*
 * Part 2: common userland and kernel definitions
 */

#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN (6+0)       /* length of an Ethernet address */
#endif

#define ICMP6_DST_UNREACH_NOROUTE       0       /* no route to destination */
#define ICMP6_DST_UNREACH_ADMIN         1       /* administratively prohibited */
#define ICMP6_DST_UNREACH_ADDR          3       /* address unreachable */
#define ICMP6_DST_UNREACH_NOPORT        4       /* port unreachable */

/*
 * linux: sysctl are mapped into /sys/module/ipfw_mod parameters
 * windows: they are emulated via get/setsockopt
 */
#define CTLFLAG_RD		1
#define CTLFLAG_RDTUN	1
#define CTLFLAG_RW		2
#define CTLFLAG_SECURE3	0 // unsupported
#define CTLFLAG_VNET    0	/* unsupported */

/* if needed, queue.h must be included here after list.h */

/*
 * struct thread is used in linux and windows kernel.
 * In windows, we need to emulate the sockopt interface
 * so also the userland needs to have the struct sockopt defined.
 * In order to achieve 64 bit compatibility, padding has been inserted.
 */
struct thread {
        void *sopt_td;
        void *td_ucred;
};

enum sopt_dir { SOPT_GET, SOPT_SET };

struct  sockopt {
        enum    sopt_dir sopt_dir; /* is this a get or a set? */
        int     sopt_level;     /* second arg of [gs]etsockopt */
        int     sopt_name;      /* third arg of [gs]etsockopt */
#ifdef _X64EMU
		void* pad1;
		void* pad2;
#endif
		void   *sopt_val;       /* fourth arg of [gs]etsockopt */
		size_t  sopt_valsize;   /* (almost) fifth arg of [gs]etsockopt */
#ifdef _X64EMU
		void* pad3;
		void* pad4;
#endif
		struct  thread *sopt_td; /* calling thread or null if kernel */
};


#define INET_ADDRSTRLEN		(16)	/* missing in netinet/in.h */

/*
 * List of values used for set/getsockopt options.
 * The base value on FreeBSD is defined as a macro,
 * if not available we will use our own enum.
 * The TABLE_BASE value is used in the kernel.
 */
#ifndef IP_FW_TABLE_ADD
#define _IPFW_SOCKOPT_BASE	100	/* 40 on freebsd */
enum ipfw_msg_type {
	IP_FW_TABLE_ADD		= _IPFW_SOCKOPT_BASE,
	IP_FW_TABLE_DEL,
	IP_FW_TABLE_FLUSH,
	IP_FW_TABLE_GETSIZE,
	IP_FW_TABLE_LIST,
	IP_FW_DYN_GET,		/* new addition */

	/* IP_FW3 and IP_DUMMYNET3 are the new API */
	IP_FW3			= _IPFW_SOCKOPT_BASE + 8,
	IP_DUMMYNET3,

	IP_FW_ADD		= _IPFW_SOCKOPT_BASE + 10,
	IP_FW_DEL,
	IP_FW_FLUSH,
	IP_FW_ZERO,
	IP_FW_GET,
	IP_FW_RESETLOG,

	IP_FW_NAT_CFG,
	IP_FW_NAT_DEL,
	IP_FW_NAT_GET_CONFIG,
	IP_FW_NAT_GET_LOG,

	IP_DUMMYNET_CONFIGURE,
	IP_DUMMYNET_DEL	,
	IP_DUMMYNET_FLUSH,
	/* 63 is missing */
	IP_DUMMYNET_GET		= _IPFW_SOCKOPT_BASE + 24,
	_IPFW_SOCKOPT_END
};
#endif /* IP_FW_TABLE_ADD */

/*
 * Part 3: userland stuff
 */

#ifndef KERNEL_MODULE

/*
 * internal names in struct in6_addr (netinet/in6.h) differ,
 * so we remap the FreeBSD names to the platform-specific ones.
 */
#ifndef _WIN32
#define __u6_addr	in6_u
#define __u6_addr32	u6_addr32
#define in6_u __in6_u	/* missing type for ipv6 (linux 2.6.28) */
#else	/* _WIN32 uses different naming */
#define __u6_addr	__u6
#define __u6_addr32	__s6_addr32
#endif	/* _WIN32 */

/* missing in linux netinet/ip.h */
#define IPTOS_ECN_ECT0	0x02    /* ECN-capable transport (0) */
#define IPTOS_ECN_CE	0x03    /* congestion experienced */

/* defined in freebsd netinet/icmp6.h */
#define ICMP6_MAXTYPE	201

/* on freebsd sys/socket.h pf specific */
#define NET_RT_IFLIST	3               /* survey interface list */

#if defined(__linux__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
/* on freebsd net/if.h XXX used */
struct if_data {
	/* ... */
        u_long ifi_mtu;	/* maximum transmission unit */
};

/*
 * Message format for use in obtaining information about interfaces
 * from getkerninfo and the routing socket.
 * This is used in nat.c
 */
struct if_msghdr {
        u_short ifm_msglen;     /* to skip over unknown messages */
        u_char  ifm_version;    /* future binary compatibility */
        u_char  ifm_type;       /* message type */
        int     ifm_addrs;      /* like rtm_addrs */
        int     ifm_flags;      /* value of if_flags */
        u_short ifm_index;      /* index for associated ifp */
        struct  if_data ifm_data;/* stats and other ifdata */
};

/*
 * Message format for use in obtaining information about interface
 * addresses from getkerninfo and the routing socket
 */
struct ifa_msghdr {
        u_short ifam_msglen;    /* to skip over unknown messages */
        u_char  ifam_version;   /* future binary compatibility */
        u_char  ifam_type;      /* message type */
        int     ifam_addrs;     /* like rtm_addrs */
        int     ifam_flags;     /* value of ifa_flags */
        u_short ifam_index;     /* index for associated ifp */
        int     ifam_metric;    /* value of ifa_metric */
};

#ifndef NO_RTM	/* conflicting with netlink */
/* missing in net/route.h */
#define RTM_VERSION     5       /* Up the ante and ignore older versions */
#define RTM_IFINFO      0xe     /* iface going up/down etc. */
#define RTM_NEWADDR     0xc     /* address being added to iface */
#define RTA_IFA         0x20    /* interface addr sockaddr present */
#endif	/* NO_RTM */

/* SA_SIZE is used in the userland nat.c modified */
#define SA_SIZE(sa)                                             \
    (  (!(sa) ) ?      \
        sizeof(long)            :                               \
        1 + ( (sizeof(struct sockaddr) - 1) | (sizeof(long) - 1) ) )

/* sys/time.h */
/*
 * Getkerninfo clock information structure
 */
struct clockinfo {
        int     hz;             /* clock frequency */
        int     tick;           /* micro-seconds per hz tick */
        int     spare;
        int     stathz;         /* statistics clock frequency */
        int     profhz;         /* profiling clock frequency */
};

/* no sin_len in sockaddr, we only remap in userland */
#define	sin_len	sin_zero[0]

#endif /* Linux/Win */

/*
 * linux does not have a reentrant version of qsort,
 * so we the FreeBSD stdlib version.
 */
void qsort_r(void *a, size_t n, size_t es, void *thunk,
	int cmp_t(void *, const void *, const void *));

/* prototypes from libutil */
/* humanize_number(3) */
#define HN_DECIMAL              0x01
#define HN_NOSPACE              0x02
#define HN_B                    0x04
#define HN_DIVISOR_1000         0x08

#define HN_GETSCALE             0x10
#define HN_AUTOSCALE            0x20

int     humanize_number(char *_buf, size_t _len, int64_t _number,
            const char *_suffix, int _scale, int _flags);
int     expand_number(const char *_buf, int64_t *_num);

#define setprogname(x)	/* not present in linux */

extern int optreset;	/* not present in linux */

size_t strlcpy(char * dst, const char * src, size_t siz);
long long int strtonum(const char *nptr, long long minval,
	long long maxval, const char **errstr);
 
int sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
	void *newp, size_t newlen);
 

#else /* KERNEL_MODULE */

/*
 * Part 4: kernel stuff
 */

/* linux and windows kernel do not have bcopy ? */
#define bcopy(_s, _d, _l)	memcpy(_d, _s, _l)
/* definitions useful for the kernel side */
struct route_in6 {
	int dummy;
};

#ifdef __linux__

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)	// or 2.4.x
#include <linux/in6.h>
#endif

/* skb_dst() and skb_dst_set() was introduced from linux 2.6.31 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst);
struct dst_entry *skb_dst(const struct sk_buff *skb);
#endif

/* The struct flowi changed */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)	// check boundaries
#define flow_daddr fl.u.ip4
#else
#define flow_daddr fl.nl_u.ip4_u
#endif

#endif /* __linux__ */

/* 
 * Do not load prio_heap.h header because of conflicting names
 * with our heap functions defined in include/netinet/ipfw/dn_heap.h
 * However do define struct ptr_heap used in linux 3.12.7 etc.
 */
#define _LINUX_PRIO_HEAP_H
struct ptr_heap;

/* 
 * The following define prevent the ipv6.h header to be loaded.
 * Starting from the 2.6.38 kernel the ipv6.h file, which is included
 * by include/net/inetpeer.h in turn included by net/route.h
 * include the system tcp.h file while we want to include 
 * our include/net/tcp.h instead.
 */
#ifndef _NET_IPV6_H
#define _NET_IPV6_H
static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
{
        memcpy(a1, a2, sizeof(struct in6_addr));
}
#endif /* _NET_IPV6_H */

#endif	/* KERNEL_MODULE */

/*
 * Part 5: windows specific stuff
 */

#ifdef _WIN32
#ifndef KERNEL_MODULE
#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)

#define METHOD_BUFFERED                 0
#define METHOD_IN_DIRECT                1
#define METHOD_OUT_DIRECT               2
#define METHOD_NEITHER                  3
#define FILE_ANY_ACCESS                 0
#define FILE_READ_DATA            ( 0x0001 )    // file & pipe
#define FILE_WRITE_DATA           ( 0x0002 )    // file & pipe
#endif /* !KERNEL_MODULE */

#define FILE_DEVICE_IPFW		0x00654324
#define IP_FW_BASE_CTL			0x840
#define IP_FW_SETSOCKOPT \
	CTL_CODE(FILE_DEVICE_IPFW, IP_FW_BASE_CTL + 1, METHOD_BUFFERED, FILE_WRITE_DATA)
#define IP_FW_GETSOCKOPT \
	CTL_CODE(FILE_DEVICE_IPFW, IP_FW_BASE_CTL + 2, METHOD_BUFFERED, FILE_ANY_ACCESS)

/*********************************
* missing declarations in altq.c *
**********************************/

#define _IOWR(x,y,t) _IOW(x,y,t)

/**********************************
* missing declarations in ipfw2.c *
***********************************/

#define	ICMP_UNREACH_NET		0	/* bad net */
#define	ICMP_UNREACH_HOST		1	/* bad host */
#define	ICMP_UNREACH_PROTOCOL		2	/* bad protocol */
#define	ICMP_UNREACH_PORT		3	/* bad port */
#define	ICMP_UNREACH_NEEDFRAG		4	/* IP_DF caused drop */
#define	ICMP_UNREACH_SRCFAIL		5	/* src route failed */
#define	ICMP_UNREACH_NET_UNKNOWN	6	/* unknown net */
#define	ICMP_UNREACH_HOST_UNKNOWN	7	/* unknown host */
#define	ICMP_UNREACH_ISOLATED		8	/* src host isolated */
#define	ICMP_UNREACH_NET_PROHIB		9	/* prohibited access */
#define	ICMP_UNREACH_HOST_PROHIB	10	/* ditto */
#define	ICMP_UNREACH_TOSNET		11	/* bad tos for net */
#define	ICMP_UNREACH_TOSHOST		12	/* bad tos for host */
#define	ICMP_UNREACH_FILTER_PROHIB	13	/* admin prohib */
#define	ICMP_UNREACH_HOST_PRECEDENCE	14	/* host prec vio. */
#define	ICMP_UNREACH_PRECEDENCE_CUTOFF	15	/* prec cutoff */


struct ether_addr;
struct ether_addr * ether_aton(const char *a);

/*********************************
* missing declarations in ipv6.c *
**********************************/

struct hostent* gethostbyname2(const char *name, int af);

#define strcasecmp strcmp // windows XXX ip_dummynet.c

/********************
* windows wrappings *
*********************/

int my_socket(int domain, int ty, int proto);
#define socket(_a, _b, _c)	my_socket(_a, _b, _c)

#endif /* _WIN32 */
/*******************
* SYSCTL emulation *
********************/
#if defined (_WIN32) || defined (EMULATE_SYSCTL)
#define STRINGIFY(x) #x

/* flag is set with the last 2 bits for access, as defined in glue.h
 * and the rest for type
 */
enum {
	SYSCTLTYPE_INT = 0,
	SYSCTLTYPE_UINT,
	SYSCTLTYPE_SHORT,
	SYSCTLTYPE_USHORT,
	SYSCTLTYPE_LONG,
	SYSCTLTYPE_ULONG,
	SYSCTLTYPE_STRING,
};

struct sysctlhead {
	uint32_t blocklen; //total size of the entry
	uint32_t namelen; //strlen(name) + '\0'
	uint32_t flags; //type and access
	uint32_t datalen;
};

#ifdef _KERNEL

#ifdef SYSCTL_NODE
#undef SYSCTL_NODE
#endif
#define SYSCTL_NODE(a,b,c,d,e,f)
#define SYSCTL_DECL(a)
#define SYSCTL_VNET_PROC(a,b,c,d,e,f,g,h,i)

#define GST_HARD_LIMIT 100

/* In the module, GST is implemented as an array of
 * sysctlentry, but while passing data to the userland
 * pointers are useless, the buffer is actually made of:
 * - sysctlhead (fixed size, containing lengths)
 * - data (typically 32 bit)
 * - name (zero-terminated and padded to mod4)
 */

struct sysctlentry {
	struct sysctlhead head;
	char* name;
	void* data;
};

struct sysctltable {
	int count; //number of valid tables
	int totalsize; //total size of valid entries of al the valid tables
	void* namebuffer; //a buffer for all chained names
	struct sysctlentry entry[GST_HARD_LIMIT];
};

#ifdef SYSBEGIN
#undef SYSBEGIN
#endif
#define SYSBEGIN(x) void sysctl_addgroup_##x() {
#ifdef SYSEND
#undef SYSEND
#endif
#define SYSEND }

/* XXX remove duplication */
#define SYSCTL_INT(a,b,c,d,e,f,g) 				\
	sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,	\
		(d) | (SYSCTLTYPE_INT << 2), sizeof(*e), e)

#define SYSCTL_VNET_INT(a,b,c,d,e,f,g)				\
	sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,	\
		(d) | (SYSCTLTYPE_INT << 2), sizeof(*e), e)

#define SYSCTL_UINT(a,b,c,d,e,f,g)				\
	sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,	\
		(d) | (SYSCTLTYPE_UINT << 2), sizeof(*e), e)

#define SYSCTL_VNET_UINT(a,b,c,d,e,f,g)				\
	sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,	\
		(d) | (SYSCTLTYPE_UINT << 2), sizeof(*e), e)

#define SYSCTL_LONG(a,b,c,d,e,f,g)				\
	sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,	\
		(d) | (SYSCTLTYPE_LONG << 2), sizeof(*e), e)

#define SYSCTL_ULONG(a,b,c,d,e,f,g)				\
	sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,	\
		(d) | (SYSCTLTYPE_ULONG << 2), sizeof(*e), e)
#define TUNABLE_INT(a,b)

void keinit_GST(void);
void keexit_GST(void);
int kesysctl_emu_set(void* p, int l);
int kesysctl_emu_get(struct sockopt* sopt);
void sysctl_pushback(char* name, int flags, int datalen, void* data);

#endif /* _KERNEL */

int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
         size_t newlen);
#endif /* _WIN32" || EMULATE_SYSCTL */
#ifdef _WIN32
int do_cmd(int optname, void *optval, uintptr_t optlen);

#endif /* _WIN32 */

#define __PAST_END(v, idx)      v[idx]
#endif /* !_GLUE_H */


================================================
FILE: ipfw/Makefile
================================================
#
# $Id: Makefile 11688 2012-08-12 20:58:26Z luigi $
#
# GNUMakefile to build the userland part of ipfw on Linux and Windows
#
# Do not set with = or := so we can inherit from the caller

include ../Makefile.inc
TARGET := ipfw

all: $(TARGET)

#TCC=c:/path/to/tcc

# common flags
EXTRA_CFLAGS += -O1
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -include ../glue.h
EXTRA_CFLAGS += -I ./include_e -I ./include

ifneq ($(VER),openwrt)
ifeq ($(OSARCH),Linux)
    EXTRA_CFLAGS += -D__BSD_VISIBLE
    EXTRA_CFLAGS += -Werror
    # Required by GCC 4.6
    EXTRA_CFLAGS += -Wno-unused-but-set-variable
endif
ifeq ($(OSARCH),FreeBSD)
    EXTRA_CFLAGS += -D__BSD_VISIBLE
    EXTRA_CFLAGS += -Werror
endif
ifeq ($(OSARCH),Darwin)
    EXTRA_CFLAGS += -D__BSD_VISIBLE
    EXTRA_CFLAGS += -Werror
endif

ifeq ($(OSARCH),Windows)
# we only support Cygwin and tcc as compilers.
ifeq ($(WIN64),1)
    EXTRA_CFLAGS += -D_X64EMU
endif

ifeq ($(TCC),)	# cygwin
    EXTRA_CFLAGS += -I/cygdrive/c/$(DDKDIR)/inc/ddk
    EXTRA_CFLAGS += -I .
    EXTRA_CFLAGS += -pipe -Wall
else		#-- build with tcc
    # TCC points to the root of tcc tree
    CC=$(TCC)/tcc.exe
    EXTRA_CFLAGS += -DTCC -I..
    EXTRA_CFLAGS += -I$(TCC)/include/winapi -I$(TCC)/include
    EXTRA_CFLAGS += -nostdinc

    EFILES_. += err.h grp.h netdb.h pwd.h sysexits.h
    EFILES_arpa += inet.h
    EFILES_net += if.h
    EFILES_netinet += in.h in_systm.h ip.h ip_icmp.h
    EFILES_sys += cdefs.h wait.h ioctl.h socket.h

endif
    # EXTRA_CFLAGS += -D_WIN32 # see who defines it
    EXTRA_CFLAGS += -Dsetsockopt=wnd_setsockopt
    EXTRA_CFLAGS += -Dgetsockopt=wnd_getsockopt
    EXTRA_CFLAGS += -DEMULATE_SYSCTL
    EFILES_net += ethernet.h route.h
    EFILES_netinet += ether.h icmp6.h
    EFILES_sys += sysctl.h
    TARGET = ipfw.exe
ipfw: $(TARGET)
endif # windows
endif # !openwrt

CFLAGS += $(EXTRA_CFLAGS)
# Location of OS headers and libraries. After our stuff.
USRDIR?= /usr
ifeq ($(TCC),)
    CFLAGS += -I$(USRDIR)/include
    LDFLAGS += -L$(USRDIR)/lib
else
    LDFLAGS += -L. -L$(TCC)/lib -lws2_32
endif

OBJS = ipfw2.o dummynet.o main.o ipv6.o qsort_r.o
OBJS += expand_number.o humanize_number.o glue.o

# we don't use ALTQ
CFLAGS += -DNO_ALTQ
#OBJS += altq.o


$(TARGET): $(OBJS)
	$(MSG) "   LD  $@"
	$(HIDE)$(CC) $(LDFLAGS) -o $@ $^

$(OBJS) : ipfw2.h ../glue.h include_e

# support to create empty dirs and files in include_e/
# EDIRS is the list of directories, EFILES is the list of files.
EFILES_sys  += sockio.h
EFILES_.    += libutil.h
EFILES_netinet += __emtpy.h

M ?= $(shell pwd)

# first make a list of directories from variable names
EDIRS= $(subst EFILES_,,$(filter EFILES_%,$(.VARIABLES)))
# then prepend the directory name to individual files.
#       $(empty) serves to interpret the following space literally,
#       and the ":  = " substitution packs spaces into one.
EFILES = $(foreach i,$(EDIRS),$(subst $(empty) , $(i)/, $(EFILES_$(i):  = )))

include_e:
	$(MSG) "building include_e in $M"
	-@rm -rf $(M)/include_e opt_*
	-@mkdir -p $(M)/include_e
	-@(cd $(M)/include_e; mkdir -p $(EDIRS); touch $(EFILES) )
	-@(cd $(M)/include_e/netinet; \
		for i in ip_fw.h ip_dummynet.h tcp.h; do \
		cp ../../../sys/netinet/$$i .; done; )

clean distclean:
	-@rm -rf $(OBJS) $(TARGET) include_e

diff:
	-@(diff -upr $(BSD_HEAD)/sbin/ipfw .)



================================================
FILE: ipfw/add_rules
================================================
#!/bin/bash
#
# A test script to add rules

PRG=./ipfw

myfun() {
	$PRG add 10 count icmp from any to 131.114.9.128
	$PRG add 20 count icmp from 131.114.9.128 to any
	$PRG add 20 count icmp from any to 131.114.9.130
	$PRG add 30 count icmp from 131.114.9.130 to any
	$PRG add 40 count icmp from any to 131.114.9.129
	$PRG add 50 count icmp from 131.114.9.129 to any
	$PRG add 60 count icmp from 131.114.9.236 to any
	sleep 1
	$PRG del 10
	$PRG del 20
	$PRG del 20
	$PRG del 30
	$PRG del 40
	$PRG del 50
	$PRG del 60
}

for ((i=0;i<100;i++)) ; do
	myfun
done


================================================
FILE: ipfw/dummynet.c
================================================
/*
 * Copyright (c) 2002-2003,2010 Luigi Rizzo
 *
 * Redistribution and use in source forms, with and without modification,
 * are permitted provided that this entire comment appears intact.
 *
 * Redistribution in binary form may occur without any restrictions.
 * Obviously, it would be nice if you gave credit where credit is due
 * but requiring it would be too onerous.
 *
 * This software is provided ``AS IS'' without any warranties of any kind.
 *
 * $FreeBSD: head/sbin/ipfw/dummynet.c 206843 2010-04-19 15:11:45Z luigi $
 *
 * dummynet support
 */

#include <sys/types.h>
#include <sys/socket.h>
/* XXX there are several sysctl leftover here */
#include <sys/sysctl.h>

#include "ipfw2.h"

#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <libutil.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>

#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
#include <arpa/inet.h>	/* inet_ntoa */


static struct _s_x dummynet_params[] = {
	{ "plr",		TOK_PLR },
	{ "noerror",		TOK_NOERROR },
	{ "buckets",		TOK_BUCKETS },
	{ "dst-ip",		TOK_DSTIP },
	{ "src-ip",		TOK_SRCIP },
	{ "dst-port",		TOK_DSTPORT },
	{ "src-port",		TOK_SRCPORT },
	{ "proto",		TOK_PROTO },
	{ "weight",		TOK_WEIGHT },
	{ "lmax",		TOK_LMAX },
	{ "maxlen",		TOK_LMAX },
	{ "all",		TOK_ALL },
	{ "mask",		TOK_MASK }, /* alias for both */
	{ "sched_mask",		TOK_SCHED_MASK },
	{ "flow_mask",		TOK_FLOW_MASK },
	{ "droptail",		TOK_DROPTAIL },
	{ "red",		TOK_RED },
	{ "gred",		TOK_GRED },
	{ "bw",			TOK_BW },
	{ "bandwidth",		TOK_BW },
	{ "delay",		TOK_DELAY },
	{ "link",		TOK_LINK },
	{ "pipe",		TOK_PIPE },
	{ "queue",		TOK_QUEUE },
	{ "flowset",		TOK_FLOWSET },
	{ "sched",		TOK_SCHED },
	{ "pri",		TOK_PRI },
	{ "priority",		TOK_PRI },
	{ "type",		TOK_TYPE },
	{ "flow-id",		TOK_FLOWID},
	{ "dst-ipv6",		TOK_DSTIP6},
	{ "dst-ip6",		TOK_DSTIP6},
	{ "src-ipv6",		TOK_SRCIP6},
	{ "src-ip6",		TOK_SRCIP6},
	{ "profile",		TOK_PROFILE},
	{ "burst",		TOK_BURST},
	{ "dummynet-params",	TOK_NULL },
	{ NULL, 0 }	/* terminator */
};

#define O_NEXT(p, len) ((void *)((char *)p + len))

static void
oid_fill(struct dn_id *oid, int len, int type, uintptr_t id)
{
	oid->len = len;
	oid->type = type;
	oid->subtype = 0;
	oid->id = id;
}

/* make room in the buffer and move the pointer forward */
static void *
o_next(struct dn_id **o, int len, int type)
{
	struct dn_id *ret = *o;
	oid_fill(ret, len, type, 0);
	*o = O_NEXT(*o, len);
	return ret;
}

/* handle variable length structures moving back the pointer and fixing length */
static void *
o_compact(struct dn_id **o, int len, int real_length, int type)
{
        struct dn_id *ret = *o;

        ret = O_NEXT(*o, -len);
        oid_fill(ret, real_length, type, 0);
        *o = O_NEXT(ret, real_length);
        return ret;
}

#if 0
static int
sort_q(void *arg, const void *pa, const void *pb)
{
	int rev = (co.do_sort < 0);
	int field = rev ? -co.do_sort : co.do_sort;
	long long res = 0;
	const struct dn_flow_queue *a = pa;
	const struct dn_flow_queue *b = pb;

	switch (field) {
	case 1: /* pkts */
		res = a->len - b->len;
		break;
	case 2: /* bytes */
		res = a->len_bytes - b->len_bytes;
		break;

	case 3: /* tot pkts */
		res = a->tot_pkts - b->tot_pkts;
		break;

	case 4: /* tot bytes */
		res = a->tot_bytes - b->tot_bytes;
		break;
	}
	if (res < 0)
		res = -1;
	if (res > 0)
		res = 1;
	return (int)(rev ? res : -res);
}
#endif

/* print a mask and header for the subsequent list of flows */
static void
print_mask(struct ipfw_flow_id *id)
{
	if (!IS_IP6_FLOW_ID(id)) {
		printf("    "
		    "mask: %s 0x%02x 0x%08x/0x%04x -> 0x%08x/0x%04x\n",
		    id->extra ? "queue," : "",
		    id->proto,
		    id->src_ip, id->src_port,
		    id->dst_ip, id->dst_port);
	} else {
		char buf[255];
		printf("\n        mask: %sproto: 0x%02x, flow_id: 0x%08x,  ",
		    id->extra ? "queue," : "",
		    id->proto, id->flow_id6);
		inet_ntop(AF_INET6, &(id->src_ip6), buf, sizeof(buf));
		printf("%s/0x%04x -> ", buf, id->src_port);
		inet_ntop(AF_INET6, &(id->dst_ip6), buf, sizeof(buf));
		printf("%s/0x%04x\n", buf, id->dst_port);
	}
}

static void
print_header(struct ipfw_flow_id *id)
{
	if (!IS_IP6_FLOW_ID(id))
		printf("BKT Prot ___Source IP/port____ "
		    "____Dest. IP/port____ "
		    "Tot_pkt/bytes Pkt/Byte Drp\n");
	else
		printf("BKT ___Prot___ _flow-id_ "
		    "______________Source IPv6/port_______________ "
		    "_______________Dest. IPv6/port_______________ "
		    "Tot_pkt/bytes Pkt/Byte Drp\n");
}

static void
list_flow(struct dn_flow *ni, int *print)
{
	char buff[255];
	struct protoent *pe = NULL;
	struct in_addr ina;
	struct ipfw_flow_id *id = &ni->fid;

	if (*print) {
		print_header(&ni->fid);
		*print = 0;
	}
	pe = getprotobynumber(id->proto);
		/* XXX: Should check for IPv4 flows */
	printf("%3u%c", (ni->oid.id) & 0xff,
		id->extra ? '*' : ' ');
	if (!IS_IP6_FLOW_ID(id)) {
		if (pe)
			printf("%-4s ", pe->p_name);
		else
			printf("%4u ", id->proto);
		ina.s_addr = htonl(id->src_ip);
		printf("%15s/%-5d ",
		    inet_ntoa(ina), id->src_port);
		ina.s_addr = htonl(id->dst_ip);
		printf("%15s/%-5d ",
		    inet_ntoa(ina), id->dst_port);
	} else {
		/* Print IPv6 flows */
		if (pe != NULL)
			printf("%9s ", pe->p_name);
		else
			printf("%9u ", id->proto);
		printf("%7d  %39s/%-5d ", id->flow_id6,
		    inet_ntop(AF_INET6, &(id->src_ip6), buff, sizeof(buff)),
		    id->src_port);
		printf(" %39s/%-5d ",
		    inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)),
		    id->dst_port);
	}
	pr_u64(&ni->tot_pkts, 4);
	pr_u64(&ni->tot_bytes, 8);
	printf("%2u %4u %3u\n",
	    ni->length, ni->len_bytes, ni->drops);
}

static void
print_flowset_parms(struct dn_fs *fs, char *prefix)
{
	int l;
	char qs[30];
	char plr[30];
	char red[90];	/* Display RED parameters */

	l = fs->qsize;
	if (fs->flags & DN_QSIZE_BYTES) {
		if (l >= 8192)
			sprintf(qs, "%d KB", l / 1024);
		else
			sprintf(qs, "%d B", l);
	} else
		sprintf(qs, "%3d sl.", l);
	if (fs->plr)
		sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff));
	else
		plr[0] = '\0';

	if (fs->flags & DN_IS_RED)	/* RED parameters */
		sprintf(red,
		    "\n\t %cRED w_q %f min_th %d max_th %d max_p %f",
		    (fs->flags & DN_IS_GENTLE_RED) ? 'G' : ' ',
		    1.0 * fs->w_q / (double)(1 << SCALE_RED),
		    fs->min_th,
		    fs->max_th,
		    1.0 * fs->max_p / (double)(1 << SCALE_RED));
	else
		sprintf(red, "droptail");

	if (prefix[0]) {
	    printf("%s %s%s %d queues (%d buckets) %s\n",
		prefix, qs, plr, fs->oid.id, fs->buckets, red);
	    prefix[0] = '\0';
	} else {
	    printf("q%05d %s%s %d flows (%d buckets) sched %d "
			"weight %d lmax %d pri %d %s\n",
		fs->fs_nr, qs, plr, fs->oid.id, fs->buckets,
		fs->sched_nr, fs->par[0], fs->par[1], fs->par[2], red);
	    if (fs->flags & DN_HAVE_MASK)
		print_mask(&fs->flow_mask);
	}
}

static void
print_extra_delay_parms(struct dn_profile *p)
{
	double loss;
	if (p->samples_no <= 0)
		return;

	loss = p->loss_level;
	loss /= p->samples_no;
	printf("\t profile: name \"%s\" loss %f samples %d\n",
		p->name, loss, p->samples_no);
}

static void
flush_buf(char *buf)
{
	if (buf[0])
		printf("%s\n", buf);
	buf[0] = '\0';
}

/*
 * generic list routine. We expect objects in a specific order, i.e.
 * PIPES AND SCHEDULERS:
 *	link; scheduler; internal flowset if any; instances
 * we can tell a pipe from the number.
 *
 * FLOWSETS:
 *	flowset; queues;
 * link i (int queue); scheduler i; si(i) { flowsets() : queues }
 */
static void
list_pipes(struct dn_id *oid, struct dn_id *end)
{
    char buf[160];	/* pending buffer */
    int toPrint = 1;	/* print header */

    buf[0] = '\0';
    for (; oid != end; oid = O_NEXT(oid, oid->len)) {
	if (oid->len < sizeof(*oid))
		errx(1, "invalid oid len %d\n", oid->len);

	switch (oid->type) {
	default:
	    flush_buf(buf);
	    printf("unrecognized object %d size %d\n", oid->type, oid->len);
	    break;
	case DN_TEXT: /* list of attached flowsets */
	    {
		int i, l;
		struct {
			struct dn_id id;
			uint32_t p[0];
		} *d = (void *)oid;
		l = (oid->len - sizeof(*oid))/sizeof(d->p[0]);
		if (l == 0)
		    break;
		printf("   Children flowsets: ");
		for (i = 0; i < l; i++)
			printf("%u ", d->p[i]);
		printf("\n");
		break;
	    }
	case DN_CMD_GET:
	    if (co.verbose)
		printf("answer for cmd %d, len %d\n", oid->type, oid->id);
	    break;
	case DN_SCH: {
	    struct dn_sch *s = (struct dn_sch *)oid;
	    flush_buf(buf);
	    printf(" sched %d type %s flags 0x%x %d buckets %d active\n",
			s->sched_nr,
			s->name, s->flags, s->buckets, s->oid.id);
	    if (s->flags & DN_HAVE_MASK)
		print_mask(&s->sched_mask);
	    }
	    break;

	case DN_FLOW:
	    list_flow((struct dn_flow *)oid, &toPrint);
	    break;

	case DN_LINK: {
	    struct dn_link *p = (struct dn_link *)oid;
	    double b = p->bandwidth;
	    char bwbuf[30];
	    char burst[5 + 7];

	    /* This starts a new object so flush buffer */
	    flush_buf(buf);
	    /* data rate */
	    if (b == 0)
		sprintf(bwbuf, "unlimited     ");
	    else if (b >= 1000000)
		sprintf(bwbuf, "%7.3f Mbit/s", b/1000000);
	    else if (b >= 1000)
		sprintf(bwbuf, "%7.3f Kbit/s", b/1000);
	    else
		sprintf(bwbuf, "%7.3f bit/s ", b);

	    if (humanize_number(burst, sizeof(burst), p->burst,
		    "", HN_AUTOSCALE, 0) < 0 || co.verbose)
		sprintf(burst, "%d", (int)p->burst);
	    sprintf(buf, "%05d: %s %4d ms burst %s",
		p->link_nr % DN_MAX_ID, bwbuf, p->delay, burst);
	    }
	    break;

	case DN_FS:
	    print_flowset_parms((struct dn_fs *)oid, buf);
	    break;
	case DN_PROFILE:
	    flush_buf(buf);
	    print_extra_delay_parms((struct dn_profile *)oid);
	}
	flush_buf(buf); // XXX does it really go here ?
    }
}

/*
 * Delete pipe, queue or scheduler i
 */
int
ipfw_delete_pipe(int do_pipe, int i)
{
	struct {
		struct dn_id oid;
		uintptr_t a[1];	/* add more if we want a list */
	} cmd;
	oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION);
	cmd.oid.subtype = (do_pipe == 1) ? DN_LINK :
		( (do_pipe == 2) ? DN_FS : DN_SCH);
	cmd.a[0] = i;
	i = do_cmd(IP_DUMMYNET3, &cmd, cmd.oid.len);
	if (i) {
		i = 1;
		warn("rule %u: setsockopt(IP_DUMMYNET_DEL)", i);
	}
	return i;
}

/*
 * Code to parse delay profiles.
 *
 * Some link types introduce extra delays in the transmission
 * of a packet, e.g. because of MAC level framing, contention on
 * the use of the channel, MAC level retransmissions and so on.
 * From our point of view, the channel is effectively unavailable
 * for this extra time, which is constant or variable depending
 * on the link type. Additionally, packets may be dropped after this
 * time (e.g. on a wireless link after too many retransmissions).
 * We can model the additional delay with an empirical curve
 * that represents its distribution.
 *
 *      cumulative probability
 *      1.0 ^
 *          |
 *      L   +-- loss-level          x
 *          |                 ******
 *          |                *
 *          |           *****
 *          |          *
 *          |        **
 *          |       *
 *          +-------*------------------->
 *                      delay
 *
 * The empirical curve may have both vertical and horizontal lines.
 * Vertical lines represent constant delay for a range of
 * probabilities; horizontal lines correspond to a discontinuty
 * in the delay distribution: the link will use the largest delay
 * for a given probability.
 *
 * To pass the curve to dummynet, we must store the parameters
 * in a file as described below, and issue the command
 *
 *      ipfw pipe <n> config ... bw XXX profile <filename> ...
 *
 * The file format is the following, with whitespace acting as
 * a separator and '#' indicating the beginning a comment:
 *
 *	samples N
 *		the number of samples used in the internal
 *		representation (2..1024; default 100);
 *
 *	loss-level L
 *		The probability above which packets are lost.
 *	       (0.0 <= L <= 1.0, default 1.0 i.e. no loss);
 *
 *	name identifier
 *		Optional a name (listed by "ipfw pipe show")
 *		to identify the distribution;
 *
 *	"delay prob" | "prob delay"
 *		One of these two lines is mandatory and defines
 *		the format of the following lines with data points.
 *
 *	XXX YYY
 *		2 or more lines representing points in the curve,
 *		with either delay or probability first, according
 *		to the chosen format.
 *		The unit for delay is milliseconds.
 *
 * Data points does not need to be ordered or equal to the number
 * specified in the "samples" line. ipfw will sort and interpolate
 * the curve as needed.
 *
 * Example of a profile file:

	name    bla_bla_bla
	samples 100
	loss-level    0.86
	prob    delay
	0       200	# minimum overhead is 200ms
	0.5     200
	0.5     300
	0.8     1000
	0.9     1300
	1       1300

 * Internally, we will convert the curve to a fixed number of
 * samples, and when it is time to transmit a packet we will
 * model the extra delay as extra bits in the packet.
 *
 */

#define ED_MAX_LINE_LEN	256+ED_MAX_NAME_LEN
#define ED_TOK_SAMPLES	"samples"
#define ED_TOK_LOSS	"loss-level"
#define ED_TOK_NAME	"name"
#define ED_TOK_DELAY	"delay"
#define ED_TOK_PROB	"prob"
#define ED_TOK_BW	"bw"
#define ED_SEPARATORS	" \t\n"
#define ED_MIN_SAMPLES_NO	2

/*
 * returns 1 if s is a non-negative number, with at least one '.'
 */
static int
is_valid_number(const char *s)
{
	int i, dots_found = 0;
	int len = strlen(s);

	for (i = 0; i<len; ++i)
		if (!isdigit(s[i]) && (s[i] !='.' || ++dots_found > 1))
			return 0;
	return 1;
}

/*
 * Take as input a string describing a bandwidth value
 * and return the numeric bandwidth value.
 * set clocking interface or bandwidth value
 */
static void
read_bandwidth(char *arg, int *bandwidth, char *if_name, int namelen)
{
	if (*bandwidth != -1)
		warnx("duplicate token, override bandwidth value!");

	if (arg[0] >= 'a' && arg[0] <= 'z') {
		if (!if_name) {
			errx(1, "no if support");
		}
		if (namelen >= IFNAMSIZ)
			warn("interface name truncated");
		namelen--;
		/* interface name */
		strncpy(if_name, arg, namelen);
		if_name[namelen] = '\0';
		*bandwidth = 0;
	} else {	/* read bandwidth value */
		int bw;
		char *end = NULL;

		bw = strtoul(arg, &end, 0);
		if (*end == 'K' || *end == 'k') {
			end++;
			bw *= 1000;
		} else if (*end == 'M' || *end == 'm') {
			end++;
			bw *= 1000000;
		}
		if ((*end == 'B' &&
			_substrcmp2(end, "Bi", "Bit/s") != 0) ||
		    _substrcmp2(end, "by", "bytes") == 0)
			bw *= 8;

		if (bw < 0)
			errx(EX_DATAERR, "bandwidth too large");

		*bandwidth = bw;
		if (if_name)
			if_name[0] = '\0';
	}
}

struct point {
	double prob;
	double delay;
};

static int
compare_points(const void *vp1, const void *vp2)
{
	const struct point *p1 = vp1;
	const struct point *p2 = vp2;
	double res = 0;

	res = p1->prob - p2->prob;
	if (res == 0)
		res = p1->delay - p2->delay;
	if (res < 0)
		return -1;
	else if (res > 0)
		return 1;
	else
		return 0;
}

#define ED_EFMT(s) EX_DATAERR,"error in %s at line %d: "#s,filename,lineno

/*
 * Interpolate a set of proability-value tuples.
 *
 * This function takes as input a tuple of values <prob, value>
 * and samples the interpolated curve described from the tuples.
 *
 * The user defined points are stored in the ponts structure.
 * The number of points is stored in points_no.
 * The user defined sampling value is stored in samples_no.
 * The resulting samples are in the "samples" pointer.
 *
 *       We assume that The last point for the '1' value of the
 *       probability should be defined. (XXX add checks for this)
 *
 * The input data are points and points_no.
 * The output data are s (the array of s_no samples)
 * and s_no (the number of samples)
 *
 */
static void
interpolate_samples(struct point *p, int points_no,
		int *samples, int samples_no, const char *filename)
{
	double dy;		/* delta on the y axis */
	double y;		/* current value of y */
	double x;		/* current value of x */
	double m;		/* the y slope */
	int i;			/* samples index */
	int curr;		/* points current index */

        /* make sure that there are enough points. */
        /* XXX Duplicated should be removed */
        if (points_no < 3)
            errx(EX_DATAERR, "%s too few samples, need at least %d",
                filename, 3);

        qsort(p, points_no, sizeof(struct point), compare_points);

	dy = 1.0/samples_no;
	y = 0;

	for (i=0, curr = 0; i < samples_no; i++, y+=dy) {
		/* This statment move the curr pointer to the next point
		 * skipping the points with the same x value. We are
		 * guaranteed to exit from the loop because the
		 * last possible value of y is stricly less than 1
		 * and the last possible value of the y points is 1 */
		while ( y >= p[curr+1].prob ) curr++;

		/* compute the slope of the curve */
		m = (p[curr+1].delay - p[curr].delay) / (p[curr+1].prob - p[curr].prob);
		/* compute the x value starting from the current point */
		x = p[curr].delay + (y - p[curr].prob) * m;
		samples[i] = x;
	}

	/* add the last sample */
	samples[i] = p[curr+1].delay;
}

/*
 * p is the link (old pipe)
 * pf is the profile
 */
static void
load_extra_delays(const char *filename, struct dn_profile *p,
	struct dn_link *link)
{
	char    line[ED_MAX_LINE_LEN];
	FILE    *f;
	int     lineno = 0;

	int     samples = -1;
	double  loss = -1.0;
	char    profile_name[ED_MAX_NAME_LEN];
	int     delay_first = -1;
	int     do_points = 0;
	struct point    points[ED_MAX_SAMPLES_NO];
	int     points_no = 0;

	/* XXX link never NULL? */
	p->link_nr = link->link_nr;

	profile_name[0] = '\0';
	f = fopen(filename, "r");
	if (f == NULL)
		err(EX_UNAVAILABLE, "fopen: %s", filename);

	while (fgets(line, ED_MAX_LINE_LEN, f)) {	 /* read commands */
		char *s, *cur = line, *name = NULL, *arg = NULL;

		++lineno;

		/* parse the line */
		while (cur) {
			s = strsep(&cur, ED_SEPARATORS);
			if (s == NULL || *s == '#')
				break;
			if (*s == '\0')
				continue;
			if (arg)
				errx(ED_EFMT("too many arguments"));
			if (name == NULL)
				name = s;
			else
				arg = s;
		}

		if ((name == NULL) || (*name == '#'))   /* empty line */
			continue;
		if (arg == NULL)
			errx(ED_EFMT("missing arg for %s"), name);

		if (!strcasecmp(name, ED_TOK_SAMPLES)) {
		    if (samples > 0)
			errx(ED_EFMT("duplicate ``samples'' line"));
		    if (atoi(arg) <=0)
			errx(ED_EFMT("invalid number of samples"));
		    samples = atoi(arg);
		    if (samples>=ED_MAX_SAMPLES_NO-1)
			    errx(ED_EFMT("too many samples, maximum is %d"),
				ED_MAX_SAMPLES_NO-1);
		    do_points = 0;
		} else if (!strcasecmp(name, ED_TOK_BW)) {
		    char buf[IFNAMSIZ];
		    read_bandwidth(arg, &link->bandwidth, buf, sizeof(buf));
		    p->bandwidth = link->bandwidth;
		} else if (!strcasecmp(name, ED_TOK_LOSS)) {
		    if (loss != -1.0)
			errx(ED_EFMT("duplicated token: %s"), name);
		    if (!is_valid_number(arg))
			errx(ED_EFMT("invalid %s"), arg);
		    loss = atof(arg);
		    if (loss > 1)
			errx(ED_EFMT("%s greater than 1.0"), name);
		    do_points = 0;
		} else if (!strcasecmp(name, ED_TOK_NAME)) {
		    if (profile_name[0] != '\0')
			errx(ED_EFMT("duplicated token: %s"), name);
		    strncpy(profile_name, arg, sizeof(profile_name) - 1);
		    profile_name[sizeof(profile_name)-1] = '\0';
		    do_points = 0;
		} else if (!strcasecmp(name, ED_TOK_DELAY)) {
		    if (do_points)
			errx(ED_EFMT("duplicated token: %s"), name);
		    delay_first = 1;
		    do_points = 1;
		} else if (!strcasecmp(name, ED_TOK_PROB)) {
		    if (do_points)
			errx(ED_EFMT("duplicated token: %s"), name);
		    delay_first = 0;
		    do_points = 1;
		} else if (do_points) {
		    if (!is_valid_number(name) || !is_valid_number(arg))
			errx(ED_EFMT("invalid point found"));
		    if (delay_first) {
			points[points_no].delay = atof(name);
			points[points_no].prob = atof(arg);
		    } else {
			points[points_no].delay = atof(arg);
			points[points_no].prob = atof(name);
		    }
		    if (points[points_no].prob > 1.0)
			errx(ED_EFMT("probability greater than 1.0"));
		    ++points_no;
		} else {
		    errx(ED_EFMT("unrecognised command '%s'"), name);
		}
	}

	fclose (f);

	if (samples == -1) {
	    warnx("'%s' not found, assuming 100", ED_TOK_SAMPLES);
	    samples = 100;
	}

	if (loss == -1.0) {
	    warnx("'%s' not found, assuming no loss", ED_TOK_LOSS);
	    loss = 1;
	}

	interpolate_samples(points, points_no, p->samples, samples, filename);

	p->samples_no = samples++;
	p->loss_level = loss * samples;
	strncpy(p->name, profile_name, sizeof(p->name));
}

/*
 * configuration of pipes, schedulers, flowsets.
 * When we configure a new scheduler, an empty pipe is created, so:
 *
 * do_pipe = 1 -> "pipe N config ..." only for backward compatibility
 *	sched N+Delta type fifo sched_mask ...
 *	pipe N+Delta <parameters>
 *	flowset N+Delta pipe N+Delta (no parameters)
 *	sched N type wf2q+ sched_mask ...
 *	pipe N <parameters>
 *
 * do_pipe = 2 -> flowset N config
 *	flowset N parameters
 *
 * do_pipe = 3 -> sched N config
 *	sched N parameters (default no pipe)
 *	optional Pipe N config ...
 * pipe ==>
 */
void
ipfw_config_pipe(int ac, char **av)
{
	int i;
	u_int j;
	char *end;
	void *par = NULL;
	struct dn_id *buf, *base;
	struct dn_sch *sch = NULL;
	struct dn_link *p = NULL;
	struct dn_fs *fs = NULL;
	struct dn_profile *pf = NULL;
	struct ipfw_flow_id *mask = NULL;
	int lmax;
	uint32_t _foo = 0, *flags = &_foo , *buckets = &_foo;
	size_t max_pf_size = sizeof(struct dn_profile) + ED_MAX_SAMPLES_NO * sizeof(int);

	/*
	 * allocate space for 1 header,
	 * 1 scheduler, 1 link, 1 flowset, 1 profile
	 */
	lmax = sizeof(struct dn_id);	/* command header */
	lmax += sizeof(struct dn_sch) + sizeof(struct dn_link) +
		sizeof(struct dn_fs);
	lmax += max_pf_size;

	av++; ac--;
	/* Pipe number */
	if (ac && isdigit(**av)) {
		i = atoi(*av); av++; ac--;
	} else
		i = -1;
	if (i <= 0)
		errx(EX_USAGE, "need a pipe/flowset/sched number");
	base = buf = safe_calloc(1, lmax);
	/* all commands start with a 'CONFIGURE' and a version */
	o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG);
	base->id = DN_API_VERSION;

	switch (co.do_pipe) {
	case 1: /* "pipe N config ..." */
		/* Allocate space for the WF2Q+ scheduler, its link
		 * and the FIFO flowset. Set the number, but leave
		 * the scheduler subtype and other parameters to 0
		 * so the kernel will use appropriate defaults.
		 * XXX todo: add a flag to record if a parameter
		 * is actually configured.
		 * If we do a 'pipe config' mask -> sched_mask.
		 * The FIFO scheduler and link are derived from the
		 * WF2Q+ one in the kernel.
		 */
		sch = o_next(&buf, sizeof(*sch), DN_SCH);
		p = o_next(&buf, sizeof(*p), DN_LINK);
		fs = o_next(&buf, sizeof(*fs), DN_FS);

		sch->sched_nr = i;
		sch->oid.subtype = 0;	/* defaults to WF2Q+ */
		mask = &sch->sched_mask;
		flags = &sch->flags;
		buckets = &sch->buckets;
		*flags |= DN_PIPE_CMD;

		p->link_nr = i;

		/* This flowset is only for the FIFO scheduler */
		fs->fs_nr = i + 2*DN_MAX_ID;
		fs->sched_nr = i + DN_MAX_ID;
		break;

	case 2: /* "queue N config ... " */
		fs = o_next(&buf, sizeof(*fs), DN_FS);
		fs->fs_nr = i;
		mask = &fs->flow_mask;
		flags = &fs->flags;
		buckets = &fs->buckets;
		break;

	case 3: /* "sched N config ..." */
		sch = o_next(&buf, sizeof(*sch), DN_SCH);
		fs = o_next(&buf, sizeof(*fs), DN_FS);
		sch->sched_nr = i;
		mask = &sch->sched_mask;
		flags = &sch->flags;
		buckets = &sch->buckets;
		/* fs is used only with !MULTIQUEUE schedulers */
		fs->fs_nr = i + DN_MAX_ID;
		fs->sched_nr = i;
		break;
	}
	/* set to -1 those fields for which we want to reuse existing
	 * values from the kernel.
	 * Also, *_nr and subtype = 0 mean reuse the value from the kernel.
	 * XXX todo: support reuse of the mask.
	 */
	if (p)
		p->bandwidth = -1;
	for (j = 0; j < sizeof(fs->par)/sizeof(fs->par[0]); j++)
		fs->par[j] = -1;
	while (ac > 0) {
		double d;
		int tok = match_token(dummynet_params, *av);
		ac--; av++;

		switch(tok) {
		case TOK_NOERROR:
			NEED(fs, "noerror is only for pipes");
			fs->flags |= DN_NOERROR;
			break;

		case TOK_PLR:
			NEED(fs, "plr is only for pipes");
			NEED1("plr needs argument 0..1\n");
			d = strtod(av[0], NULL);
			if (d > 1)
				d = 1;
			else if (d < 0)
				d = 0;
			fs->plr = (int)(d*0x7fffffff);
			ac--; av++;
			break;

		case TOK_QUEUE:
			NEED(fs, "queue is only for pipes or flowsets");
			NEED1("queue needs queue size\n");
			end = NULL;
			fs->qsize = strtoul(av[0], &end, 0);
			if (*end == 'K' || *end == 'k') {
				fs->flags |= DN_QSIZE_BYTES;
				fs->qsize *= 1024;
			} else if (*end == 'B' ||
			    _substrcmp2(end, "by", "bytes") == 0) {
				fs->flags |= DN_QSIZE_BYTES;
			}
			ac--; av++;
			break;

		case TOK_BUCKETS:
			NEED(fs, "buckets is only for pipes or flowsets");
			NEED1("buckets needs argument\n");
			*buckets = strtoul(av[0], NULL, 0);
			ac--; av++;
			break;

		case TOK_FLOW_MASK:
		case TOK_SCHED_MASK:
		case TOK_MASK:
			NEED(mask, "tok_mask");
			NEED1("mask needs mask specifier\n");
			/*
			 * per-flow queue, mask is dst_ip, dst_port,
			 * src_ip, src_port, proto measured in bits
			 */
			par = NULL;

			bzero(mask, sizeof(*mask));
			end = NULL;

			while (ac >= 1) {
			    uint32_t *p32 = NULL;
			    uint16_t *p16 = NULL;
			    uint32_t *p20 = NULL;
			    struct in6_addr *pa6 = NULL;
			    uint32_t a;

			    tok = match_token(dummynet_params, *av);
			    ac--; av++;
			    switch(tok) {
			    case TOK_ALL:
				    /*
				     * special case, all bits significant
				     * except 'extra' (the queue number)
				     */
				    mask->dst_ip = ~0;
				    mask->src_ip = ~0;
				    mask->dst_port = ~0;
				    mask->src_port = ~0;
				    mask->proto = ~0;
				    n2mask(&mask->dst_ip6, 128);
				    n2mask(&mask->src_ip6, 128);
				    mask->flow_id6 = ~0;
				    *flags |= DN_HAVE_MASK;
				    goto end_mask;

			    case TOK_QUEUE:
				    mask->extra = ~0;
				    *flags |= DN_HAVE_MASK;
				    goto end_mask;

			    case TOK_DSTIP:
				    mask->addr_type = 4;
				    p32 = &mask->dst_ip;
				    break;

			    case TOK_SRCIP:
				    mask->addr_type = 4;
				    p32 = &mask->src_ip;
				    break;

			    case TOK_DSTIP6:
				    mask->addr_type = 6;
				    pa6 = &mask->dst_ip6;
				    break;

			    case TOK_SRCIP6:
				    mask->addr_type = 6;
				    pa6 = &mask->src_ip6;
				    break;

			    case TOK_FLOWID:
				    mask->addr_type = 6;
				    p20 = &mask->flow_id6;
				    break;

			    case TOK_DSTPORT:
				    p16 = &mask->dst_port;
				    break;

			    case TOK_SRCPORT:
				    p16 = &mask->src_port;
				    break;

			    case TOK_PROTO:
				    break;

			    default:
				    ac++; av--; /* backtrack */
				    goto end_mask;
			    }
			    if (ac < 1)
				    errx(EX_USAGE, "mask: value missing");
			    if (*av[0] == '/') {
				    a = strtoul(av[0]+1, &end, 0);
				    if (pa6 == NULL)
					    a = (a == 32) ? ~0 : (1 << a) - 1;
			    } else
				    a = strtoul(av[0], &end, 0);
			    if (p32 != NULL)
				    *p32 = a;
			    else if (p16 != NULL) {
				    if (a > 0xFFFF)
					    errx(EX_DATAERR,
						"port mask must be 16 bit");
				    *p16 = (uint16_t)a;
			    } else if (p20 != NULL) {
				    if (a > 0xfffff)
					errx(EX_DATAERR,
					    "flow_id mask must be 20 bit");
				    *p20 = (uint32_t)a;
			    } else if (pa6 != NULL) {
				    if (a > 128)
					errx(EX_DATAERR,
					    "in6addr invalid mask len");
				    else
					n2mask(pa6, a);
			    } else {
				    if (a > 0xFF)
					    errx(EX_DATAERR,
						"proto mask must be 8 bit");
				    mask->proto = (uint8_t)a;
			    }
			    if (a != 0)
				    *flags |= DN_HAVE_MASK;
			    ac--; av++;
			} /* end while, config masks */
end_mask:
			break;

		case TOK_RED:
		case TOK_GRED:
			NEED1("red/gred needs w_q/min_th/max_th/max_p\n");
			fs->flags |= DN_IS_RED;
			if (tok == TOK_GRED)
				fs->flags |= DN_IS_GENTLE_RED;
			/*
			 * the format for parameters is w_q/min_th/max_th/max_p
			 */
			if ((end = strsep(&av[0], "/"))) {
			    double w_q = strtod(end, NULL);
			    if (w_q > 1 || w_q <= 0)
				errx(EX_DATAERR, "0 < w_q <= 1");
			    fs->w_q = (int) (w_q * (1 << SCALE_RED));
			}
			if ((end = strsep(&av[0], "/"))) {
			    fs->min_th = strtoul(end, &end, 0);
			    if (*end == 'K' || *end == 'k')
				fs->min_th *= 1024;
			}
			if ((end = strsep(&av[0], "/"))) {
			    fs->max_th = strtoul(end, &end, 0);
			    if (*end == 'K' || *end == 'k')
				fs->max_th *= 1024;
			}
			if ((end = strsep(&av[0], "/"))) {
			    double max_p = strtod(end, NULL);
			    if (max_p > 1 || max_p <= 0)
				errx(EX_DATAERR, "0 < max_p <= 1");
			    fs->max_p = (int)(max_p * (1 << SCALE_RED));
			}
			ac--; av++;
			break;

		case TOK_DROPTAIL:
			NEED(fs, "droptail is only for flowsets");
			fs->flags &= ~(DN_IS_RED|DN_IS_GENTLE_RED);
			break;

		case TOK_BW:
			NEED(p, "bw is only for links");
			NEED1("bw needs bandwidth or interface\n");
			read_bandwidth(av[0], &p->bandwidth, NULL, 0);
			ac--; av++;
			break;

		case TOK_DELAY:
			NEED(p, "delay is only for links");
			NEED1("delay needs argument 0..10000ms\n");
			p->delay = strtoul(av[0], NULL, 0);
			ac--; av++;
			break;

		case TOK_TYPE: {
			int l;
			NEED(sch, "type is only for schedulers");
			NEED1("type needs a string");
			l = strlen(av[0]);
			if (l == 0 || l > 15)
				errx(1, "type %s too long\n", av[0]);
			strcpy(sch->name, av[0]);
			sch->oid.subtype = 0; /* use string */
			ac--; av++;
			break;
		    }

		case TOK_WEIGHT:
			NEED(fs, "weight is only for flowsets");
			NEED1("weight needs argument\n");
			fs->par[0] = strtol(av[0], &end, 0);
			ac--; av++;
			break;

		case TOK_LMAX:
			NEED(fs, "lmax is only for flowsets");
			NEED1("lmax needs argument\n");
			fs->par[1] = strtol(av[0], &end, 0);
			ac--; av++;
			break;

		case TOK_PRI:
			NEED(fs, "priority is only for flowsets");
			NEED1("priority needs argument\n");
			fs->par[2] = strtol(av[0], &end, 0);
			ac--; av++;
			break;

		case TOK_SCHED:
		case TOK_PIPE:
			NEED(fs, "pipe/sched");
			NEED1("pipe/link/sched needs number\n");
			fs->sched_nr = strtoul(av[0], &end, 0);
			ac--; av++;
			break;

		case TOK_PROFILE:
		    {
			size_t real_length;

			NEED((!pf), "profile already set");
			NEED(p, "profile");
			NEED1("extra delay needs the file name\n");

			/* load the profile structure using the DN_API */
			pf = o_next(&buf, max_pf_size, DN_PROFILE);
			load_extra_delays(av[0], pf, p); //XXX can't fail?

			/* compact the dn_id structure */
			real_length = sizeof(struct dn_profile) +
				pf->samples_no * sizeof(int);
			o_compact(&buf, max_pf_size, real_length, DN_PROFILE);
			--ac; ++av;
		    }
			break;

		case TOK_BURST:
			NEED(p, "burst");
			NEED1("burst needs argument\n");
			errno = 0;
			if (expand_number(av[0], (int64_t *)&p->burst) < 0)
				if (errno != ERANGE)
					errx(EX_DATAERR,
					    "burst: invalid argument");
			if (errno || p->burst > (1ULL << 48) - 1)
				errx(EX_DATAERR,
				    "burst: out of range (0..2^48-1)");
			ac--; av++;
			break;

		default:
			errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]);
		}
	}

	/* check validity of parameters */
	if (p) {
		if (p->delay > 10000)
			errx(EX_DATAERR, "delay must be < 10000");
		if (p->bandwidth == -1)
			p->bandwidth = 0;
	}
	if (fs) {
		/* XXX accept a 0 scheduler to keep the default */
	    if (fs->flags & DN_QSIZE_BYTES) {
		size_t len;
		long limit;

		len = sizeof(limit);
		if (sysctlbyname("net.inet.ip.dummynet.pipe_byte_limit",
			&limit, &len, NULL, 0) == -1)
			limit = 1024*1024;
		if (fs->qsize > limit)
			errx(EX_DATAERR, "queue size must be < %ldB", limit);
	    } else {
		size_t len;
		long limit;

		len = sizeof(limit);
		if (sysctlbyname("net.inet.ip.dummynet.pipe_slot_limit",
			&limit, &len, NULL, 0) == -1)
			limit = 100;
		if (fs->qsize > limit)
			errx(EX_DATAERR, "2 <= queue size <= %ld", limit);
	    }

	    if (fs->flags & DN_IS_RED) {
		size_t len;
		int lookup_depth, avg_pkt_size;
		double w_q;

		if (fs->min_th >= fs->max_th)
		    errx(EX_DATAERR, "min_th %d must be < than max_th %d",
			fs->min_th, fs->max_th);
		if (fs->max_th == 0)
		    errx(EX_DATAERR, "max_th must be > 0");

		len = sizeof(int);
		if (sysctlbyname("net.inet.ip.dummynet.red_lookup_depth",
			&lookup_depth, &len, NULL, 0) == -1)
			lookup_depth = 256;
		if (lookup_depth == 0)
		    errx(EX_DATAERR, "net.inet.ip.dummynet.red_lookup_depth"
			" must be greater than zero");

		len = sizeof(int);
		if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size",
			&avg_pkt_size, &len, NULL, 0) == -1)
			avg_pkt_size = 512;

		if (avg_pkt_size == 0)
			errx(EX_DATAERR,
			    "net.inet.ip.dummynet.red_avg_pkt_size must"
			    " be greater than zero");

		/*
		 * Ticks needed for sending a medium-sized packet.
		 * Unfortunately, when we are configuring a WF2Q+ queue, we
		 * do not have bandwidth information, because that is stored
		 * in the parent pipe, and also we have multiple queues
		 * competing for it. So we set s=0, which is not very
		 * correct. But on the other hand, why do we want RED with
		 * WF2Q+ ?
		 */
#if 0
		if (p.bandwidth==0) /* this is a WF2Q+ queue */
			s = 0;
		else
			s = (double)ck.hz * avg_pkt_size * 8 / p.bandwidth;
#endif
		/*
		 * max idle time (in ticks) before avg queue size becomes 0.
		 * NOTA:  (3/w_q) is approx the value x so that
		 * (1-w_q)^x < 10^-3.
		 */
		w_q = ((double)fs->w_q) / (1 << SCALE_RED);
#if 0 // go in kernel
		idle = s * 3. / w_q;
		fs->lookup_step = (int)idle / lookup_depth;
		if (!fs->lookup_step)
			fs->lookup_step = 1;
		weight = 1 - w_q;
		for (t = fs->lookup_step; t > 1; --t)
			weight *= 1 - w_q;
		fs->lookup_weight = (int)(weight * (1 << SCALE_RED));
#endif /* code moved in the kernel */
	    }
	}

	i = do_cmd(IP_DUMMYNET3, base, (char *)buf - (char *)base);

	if (i)
		err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE");
}

void
dummynet_flush(void)
{
	struct dn_id oid;
	oid_fill(&oid, sizeof(oid), DN_CMD_FLUSH, DN_API_VERSION);
	do_cmd(IP_DUMMYNET3, &oid, oid.len);
}

/* Parse input for 'ipfw [pipe|sched|queue] show [range list]'
 * Returns the number of ranges, and possibly stores them
 * in the array v of size len.
 */
static int
parse_range(int ac, char *av[], uint32_t *v, int len)
{
	int n = 0;
	char *endptr, *s;
	uint32_t base[2];

	if (v == NULL || len < 2) {
		v = base;
		len = 2;
	}

	for (s = *av; s != NULL; av++, ac--) {
		v[0] = strtoul(s, &endptr, 10);
		v[1] = (*endptr != '-') ? v[0] :
			 strtoul(endptr+1, &endptr, 10);
		if (*endptr == '\0') { /* prepare for next round */
			s = (ac > 0) ? *(av+1) : NULL;
		} else {
			if (*endptr != ',') {
				warn("invalid number: %s", s);
				s = ++endptr;
				continue;
			}
			/* continue processing from here */
			s = ++endptr;
			ac++;
			av--;
		}
		if (v[1] < v[0] ||
			v[1] >= DN_MAX_ID-1 ||
			v[1] >= DN_MAX_ID-1) {
			continue; /* invalid entry */
		}
		n++;
		/* translate if 'pipe list' */
		if (co.do_pipe == 1) {
			v[0] += DN_MAX_ID;
			v[1] += DN_MAX_ID;
		}
		v = (n*2 < len) ? v + 2 : base;
	}
	return n;
}

/* main entry point for dummynet list functions. co.do_pipe indicates
 * which function we want to support.
 * av may contain filtering arguments, either individual entries
 * or ranges, or lists (space or commas are valid separators).
 * Format for a range can be n1-n2 or n3 n4 n5 ...
 * In a range n1 must be <= n2, otherwise the range is ignored.
 * A number 'n4' is translate in a range 'n4-n4'
 * All number must be > 0 and < DN_MAX_ID-1
 */
void
dummynet_list(int ac, char *av[], int show_counters)
{
	struct dn_id *oid, *x = NULL;
	int ret, i;
	int n; 		/* # of ranges */
	u_int buflen, l;
	u_int max_size;	/* largest obj passed up */

	(void)show_counters;	// XXX unused, but we should use it.
	ac--;
	av++; 		/* skip 'list' | 'show' word */

	n = parse_range(ac, av, NULL, 0);	/* Count # of ranges. */

	/* Allocate space to store ranges */
	l = sizeof(*oid) + sizeof(uint32_t) * n * 2;
	oid = safe_calloc(1, l);
	oid_fill(oid, l, DN_CMD_GET, DN_API_VERSION);

	if (n > 0)	/* store ranges in idx */
		parse_range(ac, av, (uint32_t *)(oid + 1), n*2);
	/*
	 * Compute the size of the largest object returned. If the
	 * response leaves at least this much spare space in the
	 * buffer, then surely the response is complete; otherwise
	 * there might be a risk of truncation and we will need to
	 * retry with a larger buffer.
	 * XXX don't bother with smaller structs.
	 */
	max_size = sizeof(struct dn_fs);
	if (max_size < sizeof(struct dn_sch))
		max_size = sizeof(struct dn_sch);
	if (max_size < sizeof(struct dn_flow))
		max_size = sizeof(struct dn_flow);

	switch (co.do_pipe) {
	case 1:
		oid->subtype = DN_LINK;	/* list pipe */
		break;
	case 2:
		oid->subtype = DN_FS;	/* list queue */
		break;
	case 3:
		oid->subtype = DN_SCH;	/* list sched */
		break;
	}

	/*
	 * Ask the kernel an estimate of the required space (result
	 * in oid.id), unless we are requesting a subset of objects,
	 * in which case the kernel does not give an exact answer.
	 * In any case, space might grow in the meantime due to the
	 * creation of new queues, so we must be prepared to retry.
	 */
	if (n > 0) {
		buflen = 4*1024;
	} else {
		ret = do_cmd(-IP_DUMMYNET3, oid, (uintptr_t)&l);
		if (ret != 0 || oid->id <= sizeof(*oid))
			goto done;
		buflen = oid->id + max_size;
		oid->len = sizeof(*oid); /* restore */
	}
	/* Try a few times, until the buffer fits */
	for (i = 0; i < 20; i++) {
		l = buflen;
		x = safe_realloc(x, l);
		bcopy(oid, x, oid->len);
		ret = do_cmd(-IP_DUMMYNET3, x, (uintptr_t)&l);
		if (ret != 0 || x->id <= sizeof(*oid))
			goto done; /* no response */
		if (l + max_size <= buflen)
			break; /* ok */
		buflen *= 2;	 /* double for next attempt */
	}
	list_pipes(x, O_NEXT(x, l));
done:
	if (x)
		free(x);
	free(oid);
}


================================================
FILE: ipfw/expand_number.c
================================================
/*-
 * Copyright (c) 2007 Eric Anderson <anderson@FreeBSD.org>
 * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
 * 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 AUTHORS 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 AUTHORS 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: src/lib/libutil/expand_number.c,v 1.2.4.2 2009/06/10 14:52:34 des Exp $");

#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
//#include <libutil.h>
#include <stdint.h>

/*
 * Convert an expression of the following forms to a int64_t.
 * 	1) A positive decimal number.
 *	2) A positive decimal number followed by a 'b' or 'B' (mult by 1).
 *	3) A positive decimal number followed by a 'k' or 'K' (mult by 1 << 10).
 *	4) A positive decimal number followed by a 'm' or 'M' (mult by 1 << 20).
 *	5) A positive decimal number followed by a 'g' or 'G' (mult by 1 << 30).
 *	6) A positive decimal number followed by a 't' or 'T' (mult by 1 << 40).
 *	7) A positive decimal number followed by a 'p' or 'P' (mult by 1 << 50).
 *	8) A positive decimal number followed by a 'e' or 'E' (mult by 1 << 60).
 */
int
expand_number(const char *buf, int64_t *num)
{
	static const char unit[] = "bkmgtpe";
	char *endptr, s;
	int64_t number;
	int i;

	number = strtoimax(buf, &endptr, 0);

	if (endptr == buf) {
		/* No valid digits. */
		errno = EINVAL;
		return (-1);
	}

	if (*endptr == '\0') {
		/* No unit. */
		*num = number;
		return (0);
	}

	s = tolower(*endptr);
	switch (s) {
	case 'b':
	case 'k':
	case 'm':
	case 'g':
	case 't':
	case 'p':
	case 'e':
		break;
	default:
		/* Unrecognized unit. */
		errno = EINVAL;
		return (-1);
	}

	for (i = 0; unit[i] != '\0'; i++) {
		if (s == unit[i])
			break;
		if ((number < 0 && (number << 10) > number) ||
		    (number >= 0 && (number << 10) < number)) {
			errno = ERANGE;
			return (-1);
		}
		number <<= 10;
	}

	*num = number;
	return (0);
}


================================================
FILE: ipfw/glue.c
================================================
/*
 * Copyright (C) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa
 *
 * 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.
 */

/*
 * $Id: glue.c 12264 2013-04-27 20:21:06Z luigi $
 *
 * Userland functions missing in linux/Windows
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef _WIN32
#include <netdb.h>
#include <windows.h>
#endif /* _WIN32 */

#ifndef HAVE_NAT
/* dummy nat functions */
void
ipfw_show_nat(int ac, char **av)
{
	fprintf(stderr, "%s unsupported\n", __FUNCTION__);
}

void
ipfw_config_nat(int ac, char **av)
{
	fprintf(stderr, "%s unsupported\n", __FUNCTION__);
}
#endif

#ifdef __linux__
int optreset;	/* missing in linux */
#endif

/*
 * not implemented in linux.
 * taken from /usr/src/lib/libc/string/strlcpy.c
 */
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
        char *d = dst;
        const char *s = src;
        size_t n = siz;

        /* Copy as many bytes as will fit */
        if (n != 0 && --n != 0) {
                do {
                        if ((*d++ = *s++) == 0)
                                break;
                } while (--n != 0);
        }

        /* Not enough room in dst, add NUL and traverse rest of src */
        if (n == 0) {
                if (siz != 0)
                        *d = '\0';              /* NUL-terminate dst */
                while (*s++)
                        ;
        }

        return(s - src - 1);    /* count does not include NUL */
}


/* missing in linux and windows */
long long int
strtonum(const char *nptr, long long minval, long long maxval,
         const char **errstr)
{
	long long ret;
	int errno_c = errno;	/* save actual errno */

	errno = 0;
#ifdef TCC
	ret = strtol(nptr, (char **)errstr, 0);
#else
	ret = strtoll(nptr, (char **)errstr, 0);
#endif
	/* We accept only a string that represent exactly a number (ie. start
	 * and end with a digit).
	 * FreeBSD version wants errstr==NULL if no error occurs, otherwise
	 * errstr should point to an error string.
	 * For our purspose, we implement only the invalid error, ranges
	 * error aren't checked
	 */
	if (errno != 0 || nptr == *errstr || **errstr != '\0')
		*errstr = "invalid";
	else  {
		*errstr = NULL;
		errno = errno_c;
	}
	return ret;
}

#if defined (_WIN32) || defined (EMULATE_SYSCTL)
//XXX missing prerequisites
#include <net/if.h> 		//openwrt
#include <netinet/ip.h> 	//openwrt
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
#endif

/*
 * set or get system information
 * XXX lock acquisition/serialize calls
 *
 * we export this as sys/module/ipfw_mod/parameters/___
 * This function get or/and set the value of the sysctl passed by
 * the name parameter. If the old value is not desired,
 * oldp and oldlenp should be set to NULL.
 *
 * XXX
 * I do not know how this works in FreeBSD in the case
 * where there are no write permission on the sysctl var.
 * We read the value and set return variables in any way
 * but returns -1 on write failures, regardless the
 * read success.
 *
 * Since there is no information on types, in the following
 * code we assume a length of 4 is a int.
 *
 * Returns 0 on success, -1 on errors.
 */
int
sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
         size_t newlen)
{
#if defined (_WIN32) || defined (EMULATE_SYSCTL)
	/*
	 * we embed the sysctl request in the usual sockopt mechanics.
	 * the sockopt buffer il filled with a dn_id with IP_DUMMYNET3
	 * command, and the special DN_SYSCTL_GET and DN_SYSCTL_SET
	 * subcommands.
	 * the syntax of this function is fully compatible with
	 * POSIX sysctlby name:
	 * if newp and newlen are != 0 => this is a set
	 * else if oldp and oldlen are != 0 => this is a get
	 *		to avoid too much overhead in the module, the whole
	 *		sysctltable is returned, and the parsing is done in userland,
	 *		a probe request is done to retrieve the size needed to
	 *		transfer the table, before the real request
	 * if both old and new params = 0 => this is a print
	 *		this is a special request, done only by main()
	 *		to implement the extension './ipfw sysctl',
	 *		a command that bypasses the normal getopt, and that
	 *		is available on those platforms that use this
	 *		sysctl emulation.
	 *		in this case, a negative oldlen signals that *oldp
	 *		is actually a FILE* to print somewhere else than stdout
	 */

	int l;
	int ret;
	struct dn_id* oid;
	struct sysctlhead* entry;
	char* pstring;
	char* pdata;
	FILE* fp;

	if((oldlenp != NULL) && (*oldlenp < 0))
		fp = (FILE*)oldp;
	else
		fp = stdout;
	if(newp != NULL && newlen != 0)
	{
		//this is a set
		l = sizeof(struct dn_id) + sizeof(struct sysctlhead) + strlen(name)+1 + newlen;
		oid = malloc(l);
		if (oid == NULL)
			return -1;
		oid->len = l;
		oid->type = DN_SYSCTL_SET;
		oid->id = DN_API_VERSION;

		entry = (struct sysctlhead*)(oid+1);
		pdata = (char*)(entry+1);
		pstring = pdata + newlen;

		entry->blocklen = ((sizeof(struct sysctlhead) + strlen(name)+1 + newlen) + 3) & ~3;
		entry->namelen = strlen(name)+1;
		entry->flags = 0;
		entry->datalen = newlen;

		bcopy(newp, pdata, newlen);
		bcopy(name, pstring, strlen(name)+1);

		ret = do_cmd(IP_DUMMYNET3, oid, (uintptr_t)l);
		if (ret != 0)
			return -1;
	}
	else
	{
		//this is a get or a print
		l = sizeof(struct dn_id);
		oid = malloc(l);
		if (oid == NULL)
			return -1;
		oid->len = l;
		oid->type = DN_SYSCTL_GET;
		oid->id = DN_API_VERSION;

		ret = do_cmd(-IP_DUMMYNET3, oid, (uintptr_t)&l);
		if (ret != 0)
			return -1;

		l=oid->id;
		free(oid);
		oid = malloc(l);
		if (oid == NULL)
			return -1;
		oid->len = l;
		oid->type = DN_SYSCTL_GET;
		oid->id = DN_API_VERSION;

		ret = do_cmd(-IP_DUMMYNET3, oid, (uintptr_t)&l);
		if (ret != 0)
			return -1;

		entry = (struct sysctlhead*)(oid+1);
		while(entry->blocklen != 0)
		{
			pdata = (char*)(entry+1);
			pstring = pdata+entry->datalen;

			//time to check if this is a get or a print
			if(name != NULL && oldp != NULL && *oldlenp > 0)
			{
				//this is a get
				if(strcmp(name,pstring) == 0)
				{
					//match found, sanity chech on len
					if(*oldlenp < entry->datalen)
					{
						printf("%s error: buffer too small\n",__FUNCTION__);
						return -1;
					}
					*oldlenp = entry->datalen;
					bcopy(pdata, oldp, *oldlenp);
					return 0;
				}
			}
			else
			{
				//this is a print
				if( name == NULL )
					goto print;
				if ( (strncmp(pstring,name,strlen(name)) == 0) && ( pstring[strlen(name)]=='\0' || pstring[strlen(name)]=='.' ) )
						goto print;
				else
						goto skip;
print:
				fprintf(fp, "%s: ",pstring);
				switch( entry->flags >> 2 )
				{
					case SYSCTLTYPE_LONG:
						fprintf(fp, "%li ", *(long*)(pdata));
						break;
					case SYSCTLTYPE_UINT:
						fprintf(fp, "%u ", *(unsigned int*)(pdata));
						break;
					case SYSCTLTYPE_ULONG:
						fprintf(fp, "%lu ", *(unsigned long*)(pdata));
						break;
					case SYSCTLTYPE_INT:
					default:
						fprintf(fp, "%i ", *(int*)(pdata));
				}
				if( (entry->flags & 0x00000003) == CTLFLAG_RD )
					fprintf(fp, "\t(read only)\n");
				else
					fprintf(fp, "\n");
skip:			;
			}
			entry = (struct sysctlhead*)((unsigned char*)entry + entry->blocklen);
		}
		free(oid);
		return 0;
	}
	//fallback for invalid options
	return -1;

#else /* __linux__ */
	FILE *fp;
	char *basename = "/sys/module/ipfw_mod/parameters/";
	char filename[256];	/* full filename */
	char *varp;
	int ret = 0;		/* return value */
	long d;

	if (name == NULL) /* XXX set errno */
		return -1;

	/* locate the filename */
	varp = strrchr(name, '.');
	if (varp == NULL) /* XXX set errno */
		return -1;

	snprintf(filename, sizeof(filename), "%s%s", basename, varp+1);

	/*
	 * XXX we could open the file here, in rw mode
	 * but need to check if a file have write
	 * permissions.
	 */

	/* check parameters */
	if (oldp && oldlenp) { /* read mode */
		fp = fopen(filename, "r");
		if (fp == NULL) {
			fprintf(stderr, "%s fopen error reading filename %s\n", __FUNCTION__, filename);
			return -1;
		}
		if (fscanf(fp, "%ld", &d) != 1) {
			ret = -1;
		} else if (*oldlenp == sizeof(int)) {
			int dst = d;
			memcpy(oldp, &dst, *oldlenp);
		} else if (*oldlenp == sizeof(long)) {
			memcpy(oldp, &d, *oldlenp);
		} else {
			fprintf(stderr, "unknown paramerer len %d\n",
				(int)*oldlenp);
		}
		fclose(fp);
	}

	if (newp && newlen) { /* write */
		fp = fopen(filename, "w");
		if (fp == NULL) {
			fprintf(stderr, "%s fopen error writing filename %s\n", __FUNCTION__, filename);
			return -1;
		}
		if (newlen == sizeof(int)) {
			if (fprintf(fp, "%d", *(int *)newp) < 1)
				ret = -1;
		} else if (newlen == sizeof(long)) {
			if (fprintf(fp, "%ld", *(long *)newp) < 1)
				ret = -1;
		} else {
			fprintf(stderr, "unknown paramerer len %d\n",
				(int)newlen);
		}

		fclose(fp);
	}

	return ret;
#endif /* __linux__ */
}

#ifdef _WIN32
/*
 * On windows, set/getsockopt are mapped to DeviceIoControl()
 */
int
wnd_setsockopt(int s, int level, int sopt_name, const void *optval,
                socklen_t optlen)
{
    size_t len = sizeof (struct sockopt) + optlen;
    struct sockopt *sock;
    DWORD n;
    BOOL result;
    HANDLE _dev_h = (HANDLE)s;

    /* allocate a data structure for communication */
    sock = malloc(len);
    if (sock == NULL)
        return -1;

    sock->sopt_dir = SOPT_SET;
    sock->sopt_name = sopt_name;
    sock->sopt_valsize = optlen;
    sock->sopt_val = (void *)(sock+1);

    memcpy(sock->sopt_val, optval, optlen);
    result = DeviceIoControl (_dev_h, IP_FW_SETSOCKOPT, sock, len,
		NULL, 0, &n, NULL);
    free (sock);

    return (result ? 0 : -1);
}

int
wnd_getsockopt(int s, int level, int sopt_name, void *optval,
                socklen_t *optlen)
{
    size_t len = sizeof (struct sockopt) + *optlen;
    struct sockopt *sock;
    DWORD n;
    BOOL result;
    HANDLE _dev_h = (HANDLE)s;

    sock = malloc(len);
    if (sock == NULL)
        return -1;

    sock->sopt_dir = SOPT_GET;
    sock->sopt_name = sopt_name;
    sock->sopt_valsize = *optlen;
    sock->sopt_val = (void *)(sock+1);

    memcpy (sock->sopt_val, optval, *optlen);

    result = DeviceIoControl (_dev_h, IP_FW_GETSOCKOPT, sock, len,
		sock, len, &n, NULL);
	//printf("len = %i, returned = %u, valsize = %i\n",len,n,sock->sopt_valsize);
    *optlen = sock->sopt_valsize;
    memcpy (optval, sock->sopt_val, *optlen);
    free (sock);
    return (result ? 0 : -1);
}

int
my_socket(int domain, int ty, int proto)
{
    TCHAR *pcCommPort = TEXT("\\\\.\\Ipfw");
    HANDLE _dev_h = INVALID_HANDLE_VALUE;

    /* Special Handling For Accessing Device On Windows 2000 Terminal Server
       See Microsoft KB Article 259131 */
    if (_dev_h == INVALID_HANDLE_VALUE) {
        _dev_h = CreateFile (pcCommPort,
		GENERIC_READ | GENERIC_WRITE,
		0, NULL,
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    }
    if (_dev_h == INVALID_HANDLE_VALUE) {
	printf("%s failed %u, cannot talk to kernel module\n",
		__FUNCTION__, (unsigned)GetLastError());
        return -1;
    }
    return (int)_dev_h;
}

struct hostent* gethostbyname2(const char *name, int af)
{
	return gethostbyname(name);
}

struct ether_addr* ether_aton(const char *a)
{
	fprintf(stderr, "%s empty\n", __FUNCTION__);
	return NULL;
}

#ifdef TCC
int     opterr = 1,             /* if error message should be printed */
        optind = 1,             /* index into parent argv vector */
        optopt,                 /* character checked for validity */
        optreset;               /* reset getopt */
char    *optarg;                /* argument associated with option */

#define BADCH   (int)'?'
#define BADARG  (int)':'
#define EMSG    ""

#define PROGNAME	"ipfw"
/*
 * getopt --
 *      Parse argc/argv argument vector.
 */
int
getopt(nargc, nargv, ostr)
        int nargc;
        char * const nargv[];
        const char *ostr;
{
        static char *place = EMSG;              /* option letter processing */
        char *oli;                              /* option letter list index */

        if (optreset || *place == 0) {          /* update scanning pointer */
                optreset = 0;
                place = nargv[optind];
                if (optind >= nargc || *place++ != '-') {
                        /* Argument is absent or is not an option */
                        place = EMSG;
                        return (-1);
                }
                optopt = *place++;
                if (optopt == '-' && *place == 0) {
                        /* "--" => end of options */
                        ++optind;
                        place = EMSG;
                        return (-1);
                }
                if (optopt == 0) {
                        /* Solitary '-', treat as a '-' option
                           if the program (eg su) is looking for it. */
                        place = EMSG;
                        if (strchr(ostr, '-') == NULL)
                                return (-1);
                        optopt = '-';
                }
        } else
                optopt = *place++;

        /* See if option letter is one the caller wanted... */
        if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
                if (*place == 0)
                        ++optind;
                if (opterr && *ostr != ':')
                        (void)fprintf(stderr,
                            "%s: illegal option -- %c\n", PROGNAME,
                            optopt);
                return (BADCH);
        }

        /* Does this option need an argument? */
        if (oli[1] != ':') {
                /* don't need argument */
                optarg = NULL;
                if (*place == 0)
                        ++optind;
        } else {
                /* Option-argument is either the rest of this argument or the
                   entire next argument. */
                if (*place)
                        optarg = place;
                else if (nargc > ++optind)
                        optarg = nargv[optind];
                else {
                        /* option-argument absent */
                        place = EMSG;
                        if (*ostr == ':')
                                return (BADARG);
                        if (opterr)
                                (void)fprintf(stderr,
                                    "%s: option requires an argument -- %c\n",
                                    PROGNAME, optopt);
                        return (BADCH);
                }
                place = EMSG;
                ++optind;
        }
        return (optopt);                        /* return option letter */
}

//static FILE *err_file = stderr;
void
verrx(int ex, int eval, const char *fmt, va_list ap)
{
        fprintf(stderr, "%s: ", PROGNAME);
        if (fmt != NULL)
                vfprintf(stderr, fmt, ap);
        fprintf(stderr, "\n");
	if (ex)
		exit(eval);
}
void
errx(int eval, const char *fmt, ...)
{
        va_list ap;
        va_start(ap, fmt);
        verrx(1, eval, fmt, ap);
        va_end(ap);
}

void
warnx(const char *fmt, ...)
{
        va_list ap;
        va_start(ap, fmt);
	verrx(0, 0, fmt, ap);
        va_end(ap);
}

char *
strsep(char **stringp, const char *delim)
{
        char *s;
        const char *spanp;
        int c, sc;
        char *tok;

        if ((s = *stringp) == NULL)
                return (NULL);
        for (tok = s;;) {
                c = *s++;
                spanp = delim;
                do {
                        if ((sc = *spanp++) == c) {
                                if (c == 0)
                                        s = NULL;
                                else
                                        s[-1] = 0;
                                *stringp = s;
                                return (tok);
                        }
                } while (sc != 0);
        }
        /* NOTREACHED */
}

static unsigned char
tolower(unsigned char c)
{
	return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
}

static int isdigit(unsigned char c)
{
	return (c >= '0' && c <= '9');
}

static int isxdigit(unsigned char c)
{
	return (strchr("0123456789ABCDEFabcdef", c) ? 1 : 0);
}

static int isspace(unsigned char c)
{
	return (strchr(" \t\n\r", c) ? 1 : 0);
}

static int isascii(unsigned char c)
{
	return (c < 128);
}

static int islower(unsigned char c)
{
	return (c >= 'a' && c <= 'z');
}

int
strcasecmp(const char *s1, const char *s2)
{
        const unsigned char
                        *us1 = (const unsigned char *)s1,
                        *us2 = (const unsigned char *)s2;

        while (tolower(*us1) == tolower(*us2++))
                if (*us1++ == '\0')
                        return (0);
        return (tolower(*us1) - tolower(*--us2));
}

intmax_t
strtoimax(const char * restrict nptr, char ** restrict endptr, int base)
{
	return strtol(nptr, endptr,base);
}

void
setservent(int a)
{
}

#define NS_INADDRSZ 128

int
inet_pton(int af, const char *src, void *dst)
{
        static const char digits[] = "0123456789";
        int saw_digit, octets, ch;
        u_char tmp[NS_INADDRSZ], *tp;

	if (af != AF_INET) {
		errno = EINVAL;
		return -1;
	}

        saw_digit = 0;
        octets = 0;
        *(tp = tmp) = 0;
        while ((ch = *src++) != '\0') {
                const char *pch;

                if ((pch = strchr(digits, ch)) != NULL) {
                        u_int new = *tp * 10 + (pch - digits);

                        if (saw_digit && *tp == 0)
                                return (0);
                        if (new > 255)
                                return (0);
                        *tp = new;
                        if (!saw_digit) {
                                if (++octets > 4)
                                        return (0);
                                saw_digit = 1;
                        }
                } else if (ch == '.' && saw_digit) {
                        if (octets == 4)
                                return (0);
                        *++tp = 0;
                        saw_digit = 0;
                } else
                        return (0);
        }
        if (octets < 4)
                return (0);
        memcpy(dst, tmp, NS_INADDRSZ);
        return (1);
}

const char *
inet_ntop(int af, const void *_src, char *dst, socklen_t size)
{
        static const char fmt[] = "%u.%u.%u.%u";
        char tmp[sizeof "255.255.255.255"];
	const u_char *src = _src;
        int l;
	if (af != AF_INET) {
		errno = EINVAL;
		return NULL;
	}

        l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
        if (l <= 0 || (socklen_t) l >= size) {
                errno = ENOSPC;
                return (NULL);
        }
        strlcpy(dst, tmp, size);
        return (dst);
}

/*%
 * Check whether "cp" is a valid ascii representation
 * of an Internet address and convert to a binary address.
 * Returns 1 if the address is valid, 0 if not.
 * This replaces inet_addr, the return value from which
 * cannot distinguish between failure and a local broadcast address.
 */
int
inet_aton(const char *cp, struct in_addr *addr) {
        u_long val;
        int base, n;
        char c;
        u_int8_t parts[4];
        u_int8_t *pp = parts;
        int digit;

        c = *cp;
        for (;;) {
                /*
                 * Collect number up to ``.''.
                 * Values are specified as for C:
                 * 0x=hex, 0=octal, isdigit=decimal.
                 */
                if (!isdigit((unsigned char)c))
                        return (0);
                val = 0; base = 10; digit = 0;
                if (c == '0') {
                        c = *++cp;
                        if (c == 'x' || c == 'X')
                                base = 16, c = *++cp;
                        else {
                                base = 8;
                                digit = 1 ;
                        }
                }
                for (;;) {
                        if (isascii(c) && isdigit((unsigned char)c)) {
                                if (base == 8 && (c == '8' || c == '9'))
                                        return (0);
                                val = (val * base) + (c - '0');
                                c = *++cp;
                                digit = 1;
                        } else if (base == 16 && isascii(c) &&
                                   isxdigit((unsigned char)c)) {
                                val = (val << 4) |
                                        (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
                                c = *++cp;
                                digit = 1;
                        } else
                                break;
                }
                if (c == '.') {
                        /*
                         * Internet format:
                         *      a.b.c.d
                         *      a.b.c   (with c treated as 16 bits)
                         *      a.b     (with b treated as 24 bits)
                         */
                        if (pp >= parts + 3 || val > 0xffU)
                                return (0);
                        *pp++ = val;
                        c = *++cp;
                } else
                        break;
        }
        /*
         * Check for trailing characters.
         */
        if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c)))
                return (0);
        /*
         * Did we get a valid digit?
         */
        if (!digit)
                return (0);
        /*
         * Concoct the address according to
         * the number of parts specified.
         */
        n = pp - parts + 1;
        switch (n) {
        case 1:                         /*%< a -- 32 bits */
                break;

        case 2:                         /*%< a.b -- 8.24 bits */
                if (val > 0xffffffU)
                        return (0);
                val |= parts[0] << 24;
                break;

        case 3:                         /*%< a.b.c -- 8.8.16 bits */
                if (val > 0xffffU)
                        return (0);
                val |= (parts[0] << 24) | (parts[1] << 16);
                break;

        case 4:                         /*%< a.b.c.d -- 8.8.8.8 bits */
                if (val > 0xffU)
                        return (0);
                val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
                break;
        }
        if (addr != NULL)
                addr->s_addr = htonl(val);
        return (1);
}

#endif /* TCC */

#endif /* _WIN32 */


================================================
FILE: ipfw/humanize_number.c
================================================
/*	$NetBSD: humanize_number.c,v 1.13 2007/12/14 17:26:19 christos Exp $	*/

/*
 * Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
 * NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson.
 *
 * 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 NetBSD
 *      Foundation, Inc. and its contributors.
 * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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: src/lib/libutil/humanize_number.c,v 1.2.10.1 2008/04/20 16:29:01 antoine Exp $");

#include <sys/types.h>
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include <locale.h>
//#include <libutil.h>

int
humanize_number(char *buf, size_t len, int64_t bytes,
    const char *suffix, int scale, int flags)
{
	const char *prefixes, *sep;
	int	b, i, r, maxscale, s1, s2, sign;
	int64_t	divisor, max;
	size_t	baselen;

	assert(buf != NULL);
	assert(suffix != NULL);
	assert(scale >= 0);

	if (flags & HN_DIVISOR_1000) {
		/* SI for decimal multiplies */
		divisor = 1000;
		if (flags & HN_B)
			prefixes = "B\0k\0M\0G\0T\0P\0E";
		else
			prefixes = "\0\0k\0M\0G\0T\0P\0E";
	} else {
		/*
		 * binary multiplies
		 * XXX IEC 60027-2 recommends Ki, Mi, Gi...
		 */
		divisor = 1024;
		if (flags & HN_B)
			prefixes = "B\0K\0M\0G\0T\0P\0E";
		else
			prefixes = "\0\0K\0M\0G\0T\0P\0E";
	}

#define	SCALE2PREFIX(scale)	(&prefixes[(scale) << 1])
	maxscale = 7;

	if (scale >= maxscale &&
	    (scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
		return (-1);

	if (buf == NULL || suffix == NULL)
		return (-1);

	if (len > 0)
		buf[0] = '\0';
	if (bytes < 0) {
		sign = -1;
		bytes *= -100;
		baselen = 3;		/* sign, digit, prefix */
	} else {
		sign = 1;
		bytes *= 100;
		baselen = 2;		/* digit, prefix */
	}
	if (flags & HN_NOSPACE)
		sep = "";
	else {
		sep = " ";
		baselen++;
	}
	baselen += strlen(suffix);

	/* Check if enough room for `x y' + suffix + `\0' */
	if (len < baselen + 1)
		return (-1);

	if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
		/* See if there is additional columns can be used. */
		for (max = 100, i = len - baselen; i-- > 0;)
			max *= 10;

		/*
		 * Divide the number until it fits the given column.
		 * If there will be an overflow by the rounding below,
		 * divide once more.
		 */
		for (i = 0; bytes >= max - 50 && i < maxscale; i++)
			bytes /= divisor;

		if (scale & HN_GETSCALE)
			return (i);
	} else
		for (i = 0; i < scale && i < maxscale; i++)
			bytes /= divisor;

	/* If a value <= 9.9 after rounding and ... */
	if (bytes < 995 && i > 0 && flags & HN_DECIMAL) {
		/* baselen + \0 + .N */
		if (len < baselen + 1 + 2)
			return (-1);
		b = ((int)bytes + 5) / 10;
		s1 = b / 10;
		s2 = b % 10;
		r = snprintf(buf, len, "%d%s%d%s%s%s",
		    sign * s1, ".", s2,
		    sep, SCALE2PREFIX(i), suffix);
	} else
		r = snprintf(buf, len, "%" PRId64 "%s%s%s",
		    sign * ((bytes + 50) / 100),
		    sep, SCALE2PREFIX(i), suffix);

	return (r);
}


================================================
FILE: ipfw/include/alias.h
================================================
#ifndef _ALIAS_H_
#define	_ALIAS_H_

#define LIBALIAS_BUF_SIZE 128

/*
 * If PKT_ALIAS_LOG is set, a message will be printed to /var/log/alias.log
 * every time a link is created or deleted.  This is useful for debugging.
 */
#define	PKT_ALIAS_LOG			0x01

/*
 * If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g. to ftp,
 * telnet or web servers will be prevented by the aliasing mechanism.
 */
#define	PKT_ALIAS_DENY_INCOMING		0x02

/*
 * If PKT_ALIAS_SAME_PORTS is set, packets will be attempted sent from the
 * same port as they originated on.  This allows e.g. rsh to work *99% of the
 * time*, but _not_ 100% (it will be slightly flakey instead of not working
 * at all).  This mode bit is set by PacketAliasInit(), so it is a default
 * mode of operation.
 */
#define	PKT_ALIAS_SAME_PORTS		0x04

/*
 * If PKT_ALIAS_USE_SOCKETS is set, then when partially specified links (e.g.
 * destination port and/or address is zero), the packet aliasing engine will
 * attempt to allocate a socket for the aliasing port it chooses.  This will
 * avoid interference with the host machine.  Fully specified links do not
 * require this.  This bit is set after a call to PacketAliasInit(), so it is
 * a default mode of operation.
 */
#ifndef	NO_USE_SOCKETS
#define	PKT_ALIAS_USE_SOCKETS		0x08
#endif
/*-
 * If PKT_ALIAS_UNREGISTERED_ONLY is set, then only packets with
 * unregistered source addresses will be aliased.  Private
 * addresses are those in the following ranges:
 *
 *		10.0.0.0     ->   10.255.255.255
 *		172.16.0.0   ->   172.31.255.255
 *		192.168.0.0  ->   192.168.255.255
 */
#define	PKT_ALIAS_UNREGISTERED_ONLY	0x10

/*
 * If PKT_ALIAS_RESET_ON_ADDR_CHANGE is set, then the table of dynamic
 * aliasing links will be reset whenever PacketAliasSetAddress() changes the
 * default aliasing address.  If the default aliasing address is left
 * unchanged by this function call, then the table of dynamic aliasing links
 * will be left intact.  This bit is set after a call to PacketAliasInit().
 */
#define	PKT_ALIAS_RESET_ON_ADDR_CHANGE	0x20


/*
 * If PKT_ALIAS_PROXY_ONLY is set, then NAT will be disabled and only
 * transparent proxying is performed.
 */
#define	PKT_ALIAS_PROXY_ONLY		0x40

/*
 * If PKT_ALIAS_REVERSE is set, the actions of PacketAliasIn() and
 * PacketAliasOut() are reversed.
 */
#define	PKT_ALIAS_REVERSE		0x80

#endif				/* !_ALIAS_H_ */


================================================
FILE: ipfw/include/net/if_dl.h
================================================
/*-
 * Copyright (c) 1990, 1993
 *	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.
 * 4. Neither the name of the University 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 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.
 *
 *	@(#)if_dl.h	8.1 (Berkeley) 6/10/93
 * $FreeBSD: src/sys/net/if_dl.h,v 1.14 2005/01/07 01:45:34 imp Exp $
 */

#ifndef _NET_IF_DL_H_
#define _NET_IF_DL_H_

/*
 * A Link-Level Sockaddr may specify the interface in one of two
 * ways: either by means of a system-provided index number (computed
 * anew and possibly differently on every reboot), or by a human-readable
 * string such as "il0" (for managerial convenience).
 *
 * Census taking actions, such as something akin to SIOCGCONF would return
 * both the index and the human name.
 *
 * High volume transactions (such as giving a link-level ``from'' address
 * in a recvfrom or recvmsg call) may be likely only to provide the indexed
 * form, (which requires fewer copy operations and less space).
 *
 * The form and interpretation  of the link-level address is purely a matter
 * of convention between the device driver and its consumers; however, it is
 * expected that all drivers for an interface of a given if_type will agree.
 */

/*
 * Structure of a Link-Level sockaddr:
 */
struct sockaddr_dl {
	u_char	sdl_len;	/* Total length of sockaddr */
	u_char	sdl_family;	/* AF_LINK */
	u_short	sdl_index;	/* if != 0, system given index for interface */
	u_char	sdl_type;	/* interface type */
	u_char	sdl_nlen;	/* interface name length, no trailing 0 reqd. */
	u_char	sdl_alen;	/* link level address length */
	u_char	sdl_slen;	/* link layer selector length */
	char	sdl_data[46];	/* minimum work area, can be larger;
				   contains both if name and ll address */
};

#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))

#ifndef _KERNEL

#include <sys/cdefs.h>

__BEGIN_DECLS
void	link_addr(const char *, struct sockaddr_dl *);
char	*link_ntoa(const struct sockaddr_dl *);
__END_DECLS

#endif /* !_KERNEL */

#endif


================================================
FILE: ipfw/include/net/pfvar.h
================================================
#ifndef _PF_VAR_H_
#define _PF_VAR_H_

/*
 * replacement for FreeBSD's pfqueue.h
 */
#include <sys/queue.h>

#define DIOCSTARTALTQ   _IO  ('D', 42)
#define DIOCSTOPALTQ    _IO  ('D', 43)

struct pf_altq {
	TAILQ_ENTRY(pf_altq)     entries;
	/* ... */
        u_int32_t                qid;           /* return value */

#define PF_QNAME_SIZE            64
        char                     qname[PF_QNAME_SIZE];  /* queue name */

};

struct pfioc_altq {
        u_int32_t        action;
        u_int32_t        ticket;
        u_int32_t        nr;
        struct pf_altq   altq;
};

#define DIOCGETALTQS    _IOWR('D', 47, struct pfioc_altq)
#define DIOCGETALTQ    _IOWR('D', 48, struct pfioc_altq)

#endif /* !_PF_VAR_H */


================================================
FILE: ipfw/include/timeconv.h
================================================
/*
 * simple override for _long_to_time()
 */
#ifndef _TIMECONV_H_
#define _TIMECONV_H_
static __inline time_t
_long_to_time(long tlong)
{
    if (sizeof(long) == sizeof(__int32_t))
        return((time_t)(__int32_t)(tlong));
    return((time_t)tlong);
}

#endif /* _TIMECONV_H_ */


================================================
FILE: ipfw/ipfw.8
================================================
.\"
.\" $FreeBSD$
.\"
.Dd October 25, 2012
.Dt IPFW 8
.Os
.Sh NAME
.Nm ipfw
.Nd User interface for firewall, traffic shaper, packet scheduler,
in-kernel NAT.
.Sh SYNOPSIS
.Ss FIREWALL CONFIGURATION
.Nm
.Op Fl cq
.Cm add
.Ar rule
.Nm
.Op Fl acdefnNStT
.Op Cm set Ar N
.Brq Cm list | show
.Op Ar rule | first-last ...
.Nm
.Op Fl f | q
.Op Cm set Ar N
.Cm flush
.Nm
.Op Fl q
.Op Cm set Ar N
.Brq Cm delete | zero | resetlog
.Op Ar number ...
.Pp
.Nm
.Cm set Oo Cm disable Ar number ... Oc Op Cm enable Ar number ...
.Nm
.Cm set move
.Op Cm rule
.Ar number Cm to Ar number
.Nm
.Cm set swap Ar number number
.Nm
.Cm set show
.Ss SYSCTL SHORTCUTS
.Nm
.Cm enable
.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
.Nm
.Cm disable
.Brq Cm firewall | altq | one_pass | debug | verbose | dyn_keepalive
.Ss LOOKUP TABLES
.Nm
.Cm table Ar number Cm add Ar addr Ns Oo / Ns Ar masklen Oc Op Ar value
.Nm
.Cm table Ar number Cm delete Ar addr Ns Op / Ns Ar masklen
.Nm
.Cm table
.Brq Ar number | all
.Cm flush
.Nm
.Cm table
.Brq Ar number | all
.Cm list
.Ss DUMMYNET CONFIGURATION (TRAFFIC SHAPER AND PACKET SCHEDULER)
.Nm
.Brq Cm pipe | queue | sched
.Ar number
.Cm config
.Ar config-options
.Nm
.Op Fl s Op Ar field
.Brq Cm pipe | queue | sched
.Brq Cm delete | list | show
.Op Ar number ...
.Ss IN-KERNEL NAT
.Nm
.Op Fl q
.Cm nat
.Ar number
.Cm config
.Ar config-options
.Pp
.Nm
.Op Fl cfnNqS
.Oo
.Fl p Ar preproc
.Oo
.Ar preproc-flags
.Oc
.Oc
.Ar pathname
.Sh DESCRIPTION
The
.Nm
utility is the user interface for controlling the
.Xr ipfw 4
firewall, the
.Xr dummynet 4
traffic shaper/packet scheduler, and the
in-kernel NAT services.
.Pp
A firewall configuration, or
.Em ruleset ,
is made of a list of
.Em rules
numbered from 1 to 65535.
Packets are passed to the firewall
from a number of different places in the protocol stack
(depending on the source and destination of the packet,
it is possible for the firewall to be
invoked multiple times on the same packet).
The packet passed to the firewall is compared
against each of the rules in the
.Em ruleset ,
in rule-number order
(multiple rules with the same number are permitted, in which case
they are processed in order of insertion).
When a match is found, the action corresponding to the
matching rule is performed.
.Pp
Depending on the action and certain system settings, packets
can be reinjected into the firewall at some rule after the
matching one for further processing.
.Pp
A ruleset always includes a
.Em default
rule (numbered 65535) which cannot be modified or deleted,
and matches all packets.
The action associated with the
.Em default
rule can be either
.Cm deny
or
.Cm allow
depending on how the kernel is configured.
.Pp
If the ruleset includes one or more rules with the
.Cm keep-state
or
.Cm limit
option,
the firewall will have a
.Em stateful
behaviour, i.e., upon a match it will create
.Em dynamic rules ,
i.e., rules that match packets with the same 5-tuple
(protocol, source and destination addresses and ports)
as the packet which caused their creation.
Dynamic rules, which have a limited lifetime, are checked
at the first occurrence of a
.Cm check-state ,
.Cm keep-state
or
.Cm limit
rule, and are typically used to open the firewall on-demand to
legitimate traffic only.
See the
.Sx STATEFUL FIREWALL
and
.Sx EXAMPLES
Sections below for more information on the stateful behaviour of
.Nm .
.Pp
All rules (including dynamic ones) have a few associated counters:
a packet count, a byte count, a log count and a timestamp
indicating the time of the last match.
Counters can be displayed or reset with
.Nm
commands.
.Pp
Each rule belongs to one of 32 different
.Em sets
, and there are
.Nm
commands to atomically manipulate sets, such as enable,
disable, swap sets, move all rules in a set to another
one, delete all rules in a set.
These can be useful to
install temporary configurations, or to test them.
See Section
.Sx SETS OF RULES
for more information on
.Em sets .
.Pp
Rules can be added with the
.Cm add
command; deleted individually or in groups with the
.Cm delete
command, and globally (except those in set 31) with the
.Cm flush
command; displayed, optionally with the content of the
counters, using the
.Cm show
and
.Cm list
commands.
Finally, counters can be reset with the
.Cm zero
and
.Cm resetlog
commands.
.Pp
.Ss COMMAND OPTIONS
The following general options are available when invoking
.Nm :
.Bl -tag -width indent
.It Fl a
Show counter values when listing rules.
The
.Cm show
command implies this option.
.It Fl b
Only show the action and the comment, not the body of a rule.
Implies
.Fl c .
.It Fl c
When entering or showing rules, print them in compact form,
i.e., omitting the "ip from any to any" string
when this does not carry any additional information.
.It Fl d
When listing, show dynamic rules in addition to static ones.
.It Fl e
When listing and
.Fl d
is specified, also show expired dynamic rules.
.It Fl f
Do not ask for confirmation for commands that can cause problems
if misused, i.e.,
.Cm flush .
If there is no tty associated with the process, this is implied.
.It Fl i
When listing a table (see the
.Sx LOOKUP TABLES
section below for more information on lookup tables), format values
as IP addresses.
By default, values are shown as integers.
.It Fl n
Only check syntax of the command strings, without actually passing
them to the kernel.
.It Fl N
Try to resolve addresses and service names in output.
.It Fl q
Be quiet when executing the
.Cm add ,
.Cm nat ,
.Cm zero ,
.Cm resetlog
or
.Cm flush
commands;
(implies
.Fl f ) .
This is useful when updating rulesets by executing multiple
.Nm
commands in a script
(e.g.,
.Ql sh\ /etc/rc.firewall ) ,
or by processing a file with many
.Nm
rules across a remote login session.
It also stops a table add or delete
from failing if the entry already exists or is not present.
.Pp
The reason why this option may be important is that
for some of these actions,
.Nm
may print a message; if the action results in blocking the
traffic to the remote client,
the remote login session will be closed
and the rest of the ruleset will not be processed.
Access to the console would then be required to recover.
.It Fl S
When listing rules, show the
.Em set
each rule belongs to.
If this flag is not specified, disabled rules will not be
listed.
.It Fl s Op Ar field
When listing pipes, sort according to one of the four
counters (total or current packets or bytes).
.It Fl t
When listing, show last match timestamp converted with ctime().
.It Fl T
When listing, show last match timestamp as seconds from the epoch.
This form can be more convenient for postprocessing by scripts.
.El
.Ss LIST OF RULES AND PREPROCESSING
To ease configuration, rules can be put into a file which is
processed using
.Nm
as shown in the last synopsis line.
An absolute
.Ar pathname
must be used.
The file will be read line by line and applied as arguments to the
.Nm
utility.
.Pp
Optionally, a preprocessor can be specified using
.Fl p Ar preproc
where
.Ar pathname
is to be piped through.
Useful preprocessors include
.Xr cpp 1
and
.Xr m4 1 .
If
.Ar preproc
does not start with a slash
.Pq Ql /
as its first character, the usual
.Ev PATH
name search is performed.
Care should be taken with this in environments where not all
file systems are mounted (yet) by the time
.Nm
is being run (e.g.\& when they are mounted over NFS).
Once
.Fl p
has been specified, any additional arguments are passed on to the preprocessor
for interpretation.
This allows for flexible configuration files (like conditionalizing
them on the local hostname) and the use of macros to centralize
frequently required arguments like IP addresses.
.Ss TRAFFIC SHAPER CONFIGURATION
The
.Nm
.Cm pipe , queue
and
.Cm sched
commands are used to configure the traffic shaper and packet scheduler.
See the
.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
Section below for details.
.Pp
If the world and the kernel get out of sync the
.Nm
ABI may break, preventing you from being able to add any rules.
This can adversely affect the booting process.
You can use
.Nm
.Cm disable
.Cm firewall
to temporarily disable the firewall to regain access to the network,
allowing you to fix the problem.
.Sh PACKET FLOW
A packet is checked against the active ruleset in multiple places
in the protocol stack, under control of several sysctl variables.
These places and variables are shown below, and it is important to
have this picture in mind in order to design a correct ruleset.
.Bd -literal -offset indent
       ^    to upper layers    V
       |                       |
       +----------->-----------+
       ^                       V
 [ip(6)_input]           [ip(6)_output]     net.inet(6).ip(6).fw.enable=1
       |                       |
       ^                       V
 [ether_demux]        [ether_output_frame]  net.link.ether.ipfw=1
       |                       |
       +-->--[bdg_forward]-->--+            net.link.bridge.ipfw=1
       ^                       V
       |      to devices       |
.Ed
.Pp
The number of
times the same packet goes through the firewall can
vary between 0 and 4 depending on packet source and
destination, and system configuration.
.Pp
Note that as packets flow through the stack, headers can be
stripped or added to it, and so they may or may not be available
for inspection.
E.g., incoming packets will include the MAC header when
.Nm
is invoked from
.Cm ether_demux() ,
but the same packets will have the MAC header stripped off when
.Nm
is invoked from
.Cm ip_input()
or
.Cm ip6_input() .
.Pp
Also note that each packet is always checked against the complete ruleset,
irrespective of the place where the check occurs, or the source of the packet.
If a rule contains some match patterns or actions which are not valid
for the place of invocation (e.g.\& trying to match a MAC header within
.Cm ip_input
or
.Cm ip6_input ),
the match pattern will not match, but a
.Cm not
operator in front of such patterns
.Em will
cause the pattern to
.Em always
match on those packets.
It is thus the responsibility of
the programmer, if necessary, to write a suitable ruleset to
differentiate among the possible places.
.Cm skipto
rules can be useful here, as an example:
.Bd -literal -offset indent
# packets from ether_demux or bdg_forward
ipfw add 10 skipto 1000 all from any to any layer2 in
# packets from ip_input
ipfw add 10 skipto 2000 all from any to any not layer2 in
# packets from ip_output
ipfw add 10 skipto 3000 all from any to any not layer2 out
# packets from ether_output_frame
ipfw add 10 skipto 4000 all from any to any layer2 out
.Ed
.Pp
(yes, at the moment there is no way to differentiate between
ether_demux and bdg_forward).
.Sh SYNTAX
In general, each keyword or argument must be provided as
a separate command line argument, with no leading or trailing
spaces.
Keywords are case-sensitive, whereas arguments may
or may not be case-sensitive depending on their nature
(e.g.\& uid's are, hostnames are not).
.Pp
Some arguments (e.g., port or address lists) are comma-separated
lists of values.
In this case, spaces after commas ',' are allowed to make
the line more readable.
You can also put the entire
command (including flags) into a single argument.
E.g., the following forms are equivalent:
.Bd -literal -offset indent
ipfw -q add deny src-ip 10.0.0.0/24,127.0.0.1/8
ipfw -q add deny src-ip 10.0.0.0/24, 127.0.0.1/8
ipfw "-q add deny src-ip 10.0.0.0/24, 127.0.0.1/8"
.Ed
.Sh RULE FORMAT
The format of firewall rules is the following:
.Bd -ragged -offset indent
.Bk -words
.Op Ar rule_number
.Op Cm set Ar set_number
.Op Cm prob Ar match_probability
.Ar action
.Op Cm log Op Cm logamount Ar number
.Op Cm altq Ar queue
.Oo
.Bro Cm tag | untag
.Brc Ar number
.Oc
.Ar body
.Ek
.Ed
.Pp
where the body of the rule specifies which information is used
for filtering packets, among the following:
.Pp
.Bl -tag -width "Source and dest. addresses and ports" -offset XXX -compact
.It Layer-2 header fields
When available
.It IPv4 and IPv6 Protocol
TCP, UDP, ICMP, etc.
.It Source and dest. addresses and ports
.It Direction
See Section
.Sx PACKET FLOW
.It Transmit and receive interface
By name or address
.It Misc. IP header fields
Version, type of service, datagram length, identification,
fragment flag (non-zero IP offset),
Time To Live
.It IP options
.It IPv6 Extension headers
Fragmentation, Hop-by-Hop options,
Routing Headers, Source routing rthdr0, Mobile IPv6 rthdr2, IPSec options.
.It IPv6 Flow-ID
.It Misc. TCP header fields
TCP flags (SYN, FIN, ACK, RST, etc.),
sequence number, acknowledgment number,
window
.It TCP options
.It ICMP types
for ICMP packets
.It ICMP6 types
for ICMP6 packets
.It User/group ID
When the packet can be associated with a local socket.
.It Divert status
Whether a packet came from a divert socket (e.g.,
.Xr natd 8 ) .
.It Fib annotation state
Whether a packet has been tagged for using a specific FIB (routing table)
in future forwarding decisions.
.El
.Pp
Note that some of the above information, e.g.\& source MAC or IP addresses and
TCP/UDP ports, can be easily spoofed, so filtering on those fields
alone might not guarantee the desired results.
.Bl -tag -width indent
.It Ar rule_number
Each rule is associated with a
.Ar rule_number
in the range 1..65535, with the latter reserved for the
.Em default
rule.
Rules are checked sequentially by rule number.
Multiple rules can have the same number, in which case they are
checked (and listed) according to the order in which they have
been added.
If a rule is entered without specifying a number, the kernel will
assign one in such a way that the rule becomes the last one
before the
.Em default
rule.
Automatic rule numbers are assigned by incrementing the last
non-default rule number by the value of the sysctl variable
.Ar net.inet.ip.fw.autoinc_step
which defaults to 100.
If this is not possible (e.g.\& because we would go beyond the
maximum allowed rule number), the number of the last
non-default value is used instead.
.It Cm set Ar set_number
Each rule is associated with a
.Ar set_number
in the range 0..31.
Sets can be individually disabled and enabled, so this parameter
is of fundamental importance for atomic ruleset manipulation.
It can be also used to simplify deletion of groups of rules.
If a rule is entered without specifying a set number,
set 0 will be used.
.br
Set 31 is special in that it cannot be disabled,
and rules in set 31 are not deleted by the
.Nm ipfw flush
command (but you can delete them with the
.Nm ipfw delete set 31
command).
Set 31 is also used for the
.Em default
rule.
.It Cm prob Ar match_probability
A match is only declared with the specified probability
(floating point number between 0 and 1).
This can be useful for a number of applications such as
random packet drop or
(in conjunction with
.Nm dummynet )
to simulate the effect of multiple paths leading to out-of-order
packet delivery.
.Pp
Note: this condition is checked before any other condition, including
ones such as keep-state or check-state which might have side effects.
.It Cm log Op Cm logamount Ar number
Packets matching a rule with the
.Cm log
keyword will be made available for logging in two ways:
if the sysctl variable
.Va net.inet.ip.fw.verbose
is set to 0 (default), one can use
.Xr bpf 4
attached to the
.Li ipfw0
pseudo interface.
This pseudo interface can be created after a boot
manually by using the following command:
.Bd -literal -offset indent
# ifconfig ipfw0 create
.Ed
.Pp
Or, automatically at boot time by adding the following
line to the
.Xr rc.conf 5
file:
.Bd -literal -offset indent
firewall_logif="YES"
.Ed
.Pp
There is no overhead if no
.Xr bpf 4
is attached to the pseudo interface.
.Pp
If
.Va net.inet.ip.fw.verbose
is set to 1, packets will be logged to
.Xr syslogd 8
with a
.Dv LOG_SECURITY
facility up to a maximum of
.Cm logamount
packets.
If no
.Cm logamount
is specified, the limit is taken from the sysctl variable
.Va net.inet.ip.fw.verbose_limit .
In both cases, a value of 0 means unlimited logging.
.Pp
Once the limit is reached, logging can be re-enabled by
clearing the logging counter or the packet counter for that entry, see the
.Cm resetlog
command.
.Pp
Note: logging is done after all other packet matching conditions
have been successfully verified, and before performing the final
action (accept, deny, etc.) on the packet.
.It Cm tag Ar number
When a packet matches a rule with the
.Cm tag
keyword, the numeric tag for the given
.Ar number
in the range 1..65534 will be attached to the packet.
The tag acts as an internal marker (it is not sent out over
the wire) that can be used to identify these packets later on.
This can be used, for example, to provide trust between interfaces
and to start doing policy-based filtering.
A packet can have multiple tags at the same time.
Tags are "sticky", meaning once a tag is applied to a packet by a
matching rule it exists until explicit removal.
Tags are kept with the packet everywhere within the kernel, but are
lost when packet leaves the kernel, for example, on transmitting
packet out to the network or sending packet to a
.Xr divert 4
socket.
.Pp
To check for previously applied tags, use the
.Cm tagged
rule option.
To delete previously applied tag, use the
.Cm untag
keyword.
.Pp
Note: since tags are kept with the packet everywhere in kernelspace,
they can be set and unset anywhere in the kernel network subsystem
(using the
.Xr mbuf_tags 9
facility), not only by means of the
.Xr ipfw 4
.Cm tag
and
.Cm untag
keywords.
For example, there can be a specialized
.Xr netgraph 4
node doing traffic analyzing and tagging for later inspecting
in firewall.
.It Cm untag Ar number
When a packet matches a rule with the
.Cm untag
keyword, the tag with the number
.Ar number
is searched among the tags attached to this packet and,
if found, removed from it.
Other tags bound to packet, if present, are left untouched.
.It Cm altq Ar queue
When a packet matches a rule with the
.Cm altq
keyword, the ALTQ identifier for the given
.Ar queue
(see
.Xr altq 4 )
will be attached.
Note that this ALTQ tag is only meaningful for packets going "out" of IPFW,
and not being rejected or going to divert sockets.
Note that if there is insufficient memory at the time the packet is
processed, it will not be tagged, so it is wise to make your ALTQ
"default" queue policy account for this.
If multiple
.Cm altq
rules match a single packet, only the first one adds the ALTQ classification
tag.
In doing so, traffic may be shaped by using
.Cm count Cm altq Ar queue
rules for classification early in the ruleset, then later applying
the filtering decision.
For example,
.Cm check-state
and
.Cm keep-state
rules may come later and provide the actual filtering decisions in
addition to the fallback ALTQ tag.
.Pp
You must run
.Xr pfctl 8
to set up the queues before IPFW will be able to look them up by name,
and if the ALTQ disciplines are rearranged, the rules in containing the
queue identifiers in the kernel will likely have gone stale and need
to be reloaded.
Stale queue identifiers will probably result in misclassification.
.Pp
All system ALTQ processing can be turned on or off via
.Nm
.Cm enable Ar altq
and
.Nm
.Cm disable Ar altq .
The usage of
.Va net.inet.ip.fw.one_pass
is irrelevant to ALTQ traffic shaping, as the actual rule action is followed
always after adding an ALTQ tag.
.El
.Ss RULE ACTIONS
A rule can be associated with one of the following actions, which
will be executed when the packet matches the body of the rule.
.Bl -tag -width indent
.It Cm allow | accept | pass | permit
Allow packets that match rule.
The search terminates.
.It Cm check-state
Checks the packet against the dynamic ruleset.
If a match is found, execute the action associated with
the rule which generated this dynamic rule, otherwise
move to the next rule.
.br
.Cm Check-state
rules do not have a body.
If no
.Cm check-state
rule is found, the dynamic ruleset is checked at the first
.Cm keep-state
or
.Cm limit
rule.
.It Cm count
Update counters for all packets that match rule.
The search continues with the next rule.
.It Cm deny | drop
Discard packets that match this rule.
The search terminates.
.It Cm divert Ar port
Divert packets that match this rule to the
.Xr divert 4
socket bound to port
.Ar port .
The search terminates.
.It Cm fwd | forward Ar ipaddr | tablearg Ns Op , Ns Ar port
Change the next-hop on matching packets to
.Ar ipaddr ,
which can be an IP address or a host name.
For IPv4, the next hop can also be supplied by the last table
looked up for the packet by using the
.Cm tablearg
keyword instead of an explicit address.
The search terminates if this rule matches.
.Pp
If
.Ar ipaddr
is a local address, then matching packets will be forwarded to
.Ar port
(or the port number in the packet if one is not specified in the rule)
on the local machine.
.br
If
.Ar ipaddr
is not a local address, then the port number
(if specified) is ignored, and the packet will be
forwarded to the remote address, using the route as found in
the local routing table for that IP.
.br
A
.Ar fwd
rule will not match layer-2 packets (those received
on ether_input, ether_output, or bridged).
.br
The
.Cm fwd
action does not change the contents of the packet at all.
In particular, the destination address remains unmodified, so
packets forwarded to another system will usually be rejected by that system
unless there is a matching rule on that system to capture them.
For packets forwarded locally,
the local address of the socket will be
set to the original destination address of the packet.
This makes the
.Xr netstat 1
entry look rather weird but is intended for
use with transparent proxy servers.
.It Cm nat Ar nat_nr | tablearg
Pass packet to a
nat instance
(for network address translation, address redirect, etc.):
see the
.Sx NETWORK ADDRESS TRANSLATION (NAT)
Section for further information.
.It Cm pipe Ar pipe_nr
Pass packet to a
.Nm dummynet
.Dq pipe
(for bandwidth limitation, delay, etc.).
See the
.Sx TRAFFIC SHAPER (DUMMYNET) CONFIGURATION
Section for further information.
The search terminates; however, on exit from the pipe and if
the
.Xr sysctl 8
variable
.Va net.inet.ip.fw.one_pass
is not set, the packet is passed again to the firewall code
starting from the next rule.
.It Cm queue Ar queue_nr
Pass packet to a
.Nm dummynet
.Dq queue
(for bandwidth limitation using WF2Q+).
.It Cm reject
(Deprecated).
Synonym for
.Cm unreach host .
.It Cm reset
Discard packets that match this rule, and if the
packet is a TCP packet, try to send a TCP reset (RST) notice.
The search terminates.
.It Cm reset6
Discard packets that match this rule, and if the
packet is a TCP packet, try to send a TCP reset (RST) notice.
The search terminates.
.It Cm skipto Ar number | tablearg
Skip all subsequent rules numbered less than
.Ar number .
The search continues with the first rule numbered
.Ar number
or higher.
It is possible to use the
.Cm tablearg
keyword with a skipto for a
.Em computed
skipto, but care should be used, as no destination caching
is possible in this case so the rules are always walked to find it,
starting from the
.Cm skipto .
.It Cm call Ar number | tablearg
The current rule number is saved in the internal stack and
ruleset processing continues with the first rule numbered
.Ar number
or higher.
If later a rule with the
.Cm return
action is encountered, the processing returns to the first rule
with number of this
.Cm call
rule plus one or higher
(the same behaviour as with packets returning from
.Xr divert 4
socket after a
.Cm divert
action).
This could be used to make somewhat like an assembly language
.Dq subroutine
calls to rules with common checks for different interfaces, etc.
.Pp
Rule with any number could be called, not just forward jumps as with
.Cm skipto .
So, to prevent endless loops in case of mistakes, both
.Cm call
and
.Cm return
actions don't do any jumps and simply go to the next rule if memory
cannot be allocated or stack overflowed/underflowed.
.Pp
Internally stack for rule numbers is implemented using
.Xr mbuf_tags 9
facility and currently has size of 16 entries.
As mbuf tags are lost when packet leaves the kernel,
.Cm divert
should not be used in subroutines to avoid endless loops
and other undesired effects.
.It Cm return
Takes rule number saved to internal stack by the last
.Cm call
action and returns ruleset processing to the first rule
with number greater than number of corresponding
.Cm call
rule.
See description of the
.Cm call
action for more details.
.Pp
Note that
.Cm return
rules usually end a
.Dq subroutine
and thus are unconditional, but
.Nm
command-line utility currently requires every action except
.Cm check-state
to have body.
While it is sometimes useful to return only on some packets,
usually you want to print just
.Dq return
for readability.
A workaround for this is to use new syntax and
.Fl c
switch:
.Bd -literal -offset indent
# Add a rule without actual body
ipfw add 2999 return via any

# List rules without "from any to any" part
ipfw -c list
.Ed
.Pp
This cosmetic annoyance may be fixed in future releases.
.It Cm tee Ar port
Send a copy of packets matching this rule to the
.Xr divert 4
socket bound to port
.Ar port .
The search continues with the next rule.
.It Cm unreach Ar code
Discard packets that match this rule, and try to send an ICMP
unreachable notice with code
.Ar code ,
where
.Ar code
is a number from 0 to 255, or one of these aliases:
.Cm net , host , protocol , port ,
.Cm needfrag , srcfail , net-unknown , host-unknown ,
.Cm isolated , net-prohib , host-prohib , tosnet ,
.Cm toshost , filter-prohib , host-precedence
or
.Cm precedence-cutoff .
The search terminates.
.It Cm unreach6 Ar code
Discard packets that match this rule, and try to send an ICMPv6
unreachable notice with code
.Ar code ,
where
.Ar code
is a number from 0, 1, 3 or 4, or one of these aliases:
.Cm no-route, admin-prohib, address
or
.Cm port .
The search terminates.
.It Cm netgraph Ar cookie
Divert packet into netgraph with given
.Ar cookie .
The search terminates.
If packet is later returned from netgraph it is either
accepted or continues with the next rule, depending on
.Va net.inet.ip.fw.one_pass
sysctl variable.
.It Cm ngtee Ar cookie
A copy of packet is diverted into netgraph, original
packet continues with the next rule.
See
.Xr ng_ipfw 4
for more information on
.Cm netgraph
and
.Cm ngtee
actions.
.It Cm setfib Ar fibnum | tablearg
The packet is tagged so as to use the FIB (routing table)
.Ar fibnum
in any subsequent forwarding decisions.
In the current implementation, this is limited to the values 0 through 15, see
.Xr setfib 2 .
Processing continues at the next rule.
It is possible to use the
.Cm tablearg
keyword with setfib.
If the tablearg value is not within the compiled range of fibs,
the packet's fib is set to 0.
.It Cm setdscp Ar DSCP | number | tablearg
Set specified DiffServ codepoint for an IPv4/IPv6 packet.
Processing continues at the next rule.
Supported values are:
.Pp
.Cm CS0
.Pq Dv 000000 ,
.Cm CS1
.Pq Dv 001000 ,
.Cm CS2
.Pq Dv 010000 ,
.Cm CS3
.Pq Dv 011000 ,
.Cm CS4
.Pq Dv 100000 ,
.Cm CS5
.Pq Dv 101000 ,
.Cm CS6
.Pq Dv 110000 ,
.Cm CS7
.Pq Dv 111000 ,
.Cm AF11
.Pq Dv 001010 ,
.Cm AF12
.Pq Dv 001100 ,
.Cm AF13
.Pq Dv 001110 ,
.Cm AF21
.Pq Dv 010010 ,
.Cm AF22
.Pq Dv 010100 ,
.Cm AF23
.Pq Dv 010110 ,
.Cm AF31
.Pq Dv 011010 ,
.Cm AF32
.Pq Dv 011100 ,
.Cm AF33
.Pq Dv 011110 ,
.Cm AF41
.Pq Dv 100010 ,
.Cm AF42
.Pq Dv 100100 ,
.Cm AF43
.Pq Dv 100110 ,
.Cm EF
.Pq Dv 101110 ,
.Cm BE
.Pq Dv 000000 .
Additionally, DSCP value can be specified by number (0..64).
It is also possible to use the
.Cm tablearg
keyword with setdscp.
If the tablearg value is not within the 0..64 range, lower 6 bits of supplied
value are used.
.It Cm reass
Queue and reassemble IP fragments.
If the packet is not fragmented, counters are updated and
processing continues with the next rule.
If the packet is the last logical fragment, the packet is reassembled and, if
.Va net.inet.ip.fw.one_pass
is set to 0, processing continues with the next rule.
Otherwise, the packet is allowed to pass and the search terminates.
If the packet is a fragment in the middle of a logical group of fragments,
it is consumed and
processing stops immediately.
.Pp
Fragment handling can be tuned via
.Va net.inet.ip.maxfragpackets
and
.Va net.inet.ip.maxfragsperpacket
which limit, respectively, the maximum number of processable
fragments (default: 800) and
the maximum number of fragments per packet (default: 16).
.Pp
NOTA BENE: since fragments do not contain port numbers,
they should be avoided with the
.Nm reass
rule.
Alternatively, direction-based (like
.Nm in
/
.Nm out
) and source-based (like
.Nm via
) match patterns can be used to select fragments.
.Pp
Usually a simple rule like:
.Bd -literal -offset indent
# reassemble incoming fragments
ipfw add reass all from any to any in
.Ed
.Pp
is all you need at the beginning of your ruleset.
.El
.Ss RULE BODY
The body of a rule contains zero or more patterns (such as
specific source and destination addresses or ports,
protocol options, incoming or outgoing interfaces, etc.)
that the packet must match in order to be recognised.
In general, the patterns are connected by (implicit)
.Cm and
operators -- i.e., all must match in order for the
rule to match.
Individual patterns can be prefixed by the
.Cm not
operator to reverse the result of the match, as in
.Pp
.Dl "ipfw add 100 allow ip from not 1.2.3.4 to any"
.Pp
Additionally, sets of alternative match patterns
.Pq Em or-blocks
can be constructed by putting the patterns in
lists enclosed between parentheses ( ) or braces { }, and
using the
.Cm or
operator as follows:
.Pp
.Dl "ipfw add 100 allow ip from { x or not y or z } to any"
.Pp
Only one level of parentheses is allowed.
Beware that most shells have special meanings for parentheses
or braces, so it is advisable to put a backslash \\ in front of them
to prevent such interpretations.
.Pp
The body of a rule must in general include a source and destination
address specifier.
The keyword
.Ar any
can be used in various places to specify that the content of
a required field is irrelevant.
.Pp
The rule body has the following format:
.Bd -ragged -offset indent
.Op Ar proto Cm from Ar src Cm to Ar dst
.Op Ar options
.Ed
.Pp
The first part (proto from src to dst) is for backward
compatibility with earlier versions of
.Fx .
In modern
.Fx
any match pattern (including MAC headers, IP protocols,
addresses and ports) can be specified in the
.Ar options
section.
.Pp
Rule fields have the following meaning:
.Bl -tag -width indent
.It Ar proto : protocol | Cm { Ar protocol Cm or ... }
.It Ar protocol : Oo Cm not Oc Ar protocol-name | protocol-number
An IP protocol specified by number or name
(for a complete list see
.Pa /etc/protocols ) ,
or one of the following keywords:
.Bl -tag -width indent
.It Cm ip4 | ipv4
Matches IPv4 packets.
.It Cm ip6 | ipv6
Matches IPv6 packets.
.It Cm ip | all
Matches any packet.
.El
.Pp
The
.Cm ipv6
in
.Cm proto
option will be treated as inner protocol.
And, the
.Cm ipv4
is not available in
.Cm proto
option.
.Pp
The
.Cm { Ar protocol Cm or ... }
format (an
.Em or-block )
is provided for convenience only but its use is deprecated.
.It Ar src No and Ar dst : Bro Cm addr | Cm { Ar addr Cm or ... } Brc Op Oo Cm not Oc Ar ports
An address (or a list, see below)
optionally followed by
.Ar ports
specifiers.
.Pp
The second format
.Em ( or-block
with multiple addresses) is provided for convenience only and
its use is discouraged.
.It Ar addr : Oo Cm not Oc Bro
.Cm any | me | me6 |
.Cm table Ns Pq Ar number Ns Op , Ns Ar value
.Ar | addr-list | addr-set
.Brc
.Bl -tag -width indent
.It Cm any
matches any IP address.
.It Cm me
matches any IP address configured on an interface in the system.
.It Cm me6
matches any IPv6 address configured on an interface in the system.
The address list is evaluated at the time the packet is
analysed.
.It Cm table Ns Pq Ar number Ns Op , Ns Ar value
Matches any IPv4 address for which an entry exists in the lookup table
.Ar number .
If an optional 32-bit unsigned
.Ar value
is also specified, an entry will match only if it has this value.
See the
.Sx LOOKUP TABLES
section below for more information on lookup tables.
.El
.It Ar addr-list : ip-addr Ns Op Ns , Ns Ar addr-list
.It Ar ip-addr :
A host or subnet address specified in one of the following ways:
.Bl -tag -width indent
.It Ar numeric-ip | hostname
Matches a single IPv4 address, specified as dotted-quad or a hostname.
Hostnames are resolved at the time the rule is added to the firewall list.
.It Ar addr Ns / Ns Ar masklen
Matches all addresses with base
.Ar addr
(specified as an IP address, a network number, or a hostname)
and mask width of
.Cm masklen
bits.
As an example, 1.2.3.4/25 or 1.2.3.0/25 will match
all IP numbers from 1.2.3.0 to 1.2.3.127 .
.It Ar addr Ns : Ns Ar mask
Matches all addresses with base
.Ar addr
(specified as an IP address, a network number, or a hostname)
and the mask of
.Ar mask ,
specified as a dotted quad.
As an example, 1.2.3.4:255.0.255.0 or 1.0.3.0:255.0.255.0 will match
1.*.3.*.
This form is advised only for non-contiguous
masks.
It is better to resort to the
.Ar addr Ns / Ns Ar masklen
format for contiguous masks, which is more compact and less
error-prone.
.El
.It Ar addr-set : addr Ns Oo Ns / Ns Ar masklen Oc Ns Cm { Ns Ar list Ns Cm }
.It Ar list : Bro Ar num | num-num Brc Ns Op Ns , Ns Ar list
Matches all addresses with base address
.Ar addr
(specified as an IP address, a network number, or a hostname)
and whose last byte is in the list between braces { } .
Note that there must be no spaces between braces and
numbers (spaces after commas are allowed).
Elements of the list can be specified as single entries
or ranges.
The
.Ar masklen
field is used to limit the size of the set of addresses,
and can have any value between 24 and 32.
If not specified,
it will be assumed as 24.
.br
This format is particularly useful to handle sparse address sets
within a single rule.
Because the matching occurs using a
bitmask, it takes constant time and dramatically reduces
the complexity of rulesets.
.br
As an example, an address specified as 1.2.3.4/24{128,35-55,89}
or 1.2.3.0/24{128,35-55,89}
will match the following IP addresses:
.br
1.2.3.128, 1.2.3.35 to 1.2.3.55, 1.2.3.89 .
.It Ar addr6-list : ip6-addr Ns Op Ns , Ns Ar addr6-list
.It Ar ip6-addr :
A host or subnet specified one of the following ways:
.Bl -tag -width indent
.It Ar numeric-ip | hostname
Matches a single IPv6 address as allowed by
.Xr inet_pton 3
or a hostname.
Hostnames are resolved at the time the rule is added to the firewall
list.
.It Ar addr Ns / Ns Ar masklen
Matches all IPv6 addresses with base
.Ar addr
(specified as allowed by
.Xr inet_pton
or a hostname)
and mask width of
.Cm masklen
bits.
.El
.Pp
No support for sets of IPv6 addresses is provided because IPv6 addresses
are typically random past the initial prefix.
.It Ar ports : Bro Ar port | port Ns \&- Ns Ar port Ns Brc Ns Op , Ns Ar ports
For protocols which support port numbers (such as TCP and UDP), optional
.Cm ports
may be specified as one or more ports or port ranges, separated
by commas but no spaces, and an optional
.Cm not
operator.
The
.Ql \&-
notation specifies a range of ports (including boundaries).
.Pp
Service names (from
.Pa /etc/services )
may be used instead of numeric port values.
The length of the port list is limited to 30 ports or ranges,
though one can specify larger ranges by using an
.Em or-block
in the
.Cm options
section of the rule.
.Pp
A backslash
.Pq Ql \e
can be used to escape the dash
.Pq Ql -
character in a service name (from a shell, the backslash must be
typed twice to avoid the shell itself interpreting it as an escape
character).
.Pp
.Dl "ipfw add count tcp from any ftp\e\e-data-ftp to any"
.Pp
Fragmented packets which have a non-zero offset (i.e., not the first
fragment) will never match a rule which has one or more port
specifications.
See the
.Cm frag
option for details on matching fragmented packets.
.El
.Ss RULE OPTIONS (MATCH PATTERNS)
Additional match patterns can be used within
rules.
Zero or more of these so-called
.Em options
can be present in a rule, optionally prefixed by the
.Cm not
operand, and possibly grouped into
.Em or-blocks .
.Pp
The following match patterns can be used (listed in alphabetical order):
.Bl -tag -width indent
.It Cm // this is a comment.
Inserts the specified text as a comment in the rule.
Everything following // is considered as a comment and stored in the rule.
You can have comment-only rules, which are listed as having a
.Cm count
action followed by the comment.
.It Cm bridged
Alias for
.Cm layer2 .
.It Cm diverted
Matches only packets generated by a divert socket.
.It Cm diverted-loopback
Matches only packets coming from a divert socket back into the IP stack
input for delivery.
.It Cm diverted-output
Matches only packets going from a divert socket back outward to the IP
stack output for delivery.
.It Cm dst-ip Ar ip-address
Matches IPv4 packets whose destination IP is one of the address(es)
specified as argument.
.It Bro Cm dst-ip6 | dst-ipv6 Brc Ar ip6-address
Matches IPv6 packets whose destination IP is one of the address(es)
specified as argument.
.It Cm dst-port Ar ports
Matches IP packets whose destination port is one of the port(s)
specified as argument.
.It Cm established
Matches TCP packets that have the RST or ACK bits set.
.It Cm ext6hdr Ar header
Matches IPv6 packets containing the extended header given by
.Ar header .
Supported headers are:
.Pp
Fragment,
.Pq Cm frag ,
Hop-to-hop options
.Pq Cm hopopt ,
any type of Routing Header
.Pq Cm route ,
Source routing Routing Header Type 0
.Pq Cm rthdr0 ,
Mobile IPv6 Routing Header Type 2
.Pq Cm rthdr2 ,
Destination options
.Pq Cm dstopt ,
IPSec authentication headers
.Pq Cm ah ,
and IPsec encapsulated security payload headers
.Pq Cm esp .
.It Cm fib Ar fibnum
Matches a packet that has been tagged to use
the given FIB (routing table) number.
.It Cm flow-id Ar labels
Matches IPv6 packets containing any of the flow labels given in
.Ar labels .
.Ar labels
is a comma separated list of numeric flow labels.
.It Cm frag
Matches packets that are fragments and not the first
fragment of an IP datagram.
Note that these packets will not have
the next protocol header (e.g.\& TCP, UDP) so options that look into
these headers cannot match.
.It Cm gid Ar group
Matches all TCP or UDP packets sent by or received for a
.Ar group .
A
.Ar group
may be specified by name or number.
.It Cm jail Ar prisonID
Matches all TCP or UDP packets sent by or received for the
jail whos prison ID is
.Ar prisonID .
.It Cm icmptypes Ar types
Matches ICMP packets whose ICMP type is in the list
.Ar types .
The list may be specified as any combination of
individual types (numeric) separated by commas.
.Em Ranges are not allowed .
The supported ICMP types are:
.Pp
echo reply
.Pq Cm 0 ,
destination unreachable
.Pq Cm 3 ,
source quench
.Pq Cm 4 ,
redirect
.Pq Cm 5 ,
echo request
.Pq Cm 8 ,
router advertisement
.Pq Cm 9 ,
router solicitation
.Pq Cm 10 ,
time-to-live exceeded
.Pq Cm 11 ,
IP header bad
.Pq Cm 12 ,
timestamp request
.Pq Cm 13 ,
timestamp reply
.Pq Cm 14 ,
information request
.Pq Cm 15 ,
information reply
.Pq Cm 16 ,
address mask request
.Pq Cm 17
and address mask reply
.Pq Cm 18 .
.It Cm icmp6types Ar types
Matches ICMP6 packets whose ICMP6 type is in the list of
.Ar types .
The list may be specified as any combination of
individual types (numeric) separated by commas.
.Em Ranges are not allowed .
.It Cm in | out
Matches incoming or outgoing packets, respectively.
.Cm in
and
.Cm out
are mutually exclusive (in fact,
.Cm out
is implemented as
.Cm not in Ns No ).
.It Cm ipid Ar id-list
Matches IPv4 packets whose
.Cm ip_id
field has value included in
.Ar id-list ,
which is either a single value or a list of values or ranges
specified in the same way as
.Ar ports .
.It Cm iplen Ar len-list
Matches IP packets whose total length, including header and data, is
in the set
.Ar len-list ,
which is either a single value or a list of values or ranges
specified in the same way as
.Ar ports .
.It Cm ipoptions Ar spec
Matches packets whose IPv4 header contains the comma separated list of
options specified in
.Ar spec .
The supported IP options are:
.Pp
.Cm ssrr
(strict source route),
.Cm lsrr
(loose source route),
.Cm rr
(record packet route) and
.Cm ts
(timestamp).
The absence of a particular option may be denoted
with a
.Ql \&! .
.It Cm ipprecedence Ar precedence
Matches IPv4 packets whose precedence field is equal to
.Ar precedence .
.It Cm ipsec
Matches packets that have IPSEC history associated with them
(i.e., the packet comes encapsulated in IPSEC, the kernel
has IPSEC support and IPSEC_FILTERTUNNEL option, and can correctly
decapsulate it).
.Pp
Note that specifying
.Cm ipsec
is different from specifying
.Cm proto Ar ipsec
as the latter will only look at the specific IP protocol field,
irrespective of IPSEC kernel support and the validity of the IPSEC data.
.Pp
Further note that this flag is silently ignored in kernels without
IPSEC support.
It does not affect rule processing when given and the
rules are handled as if with no
.Cm ipsec
flag.
.It Cm iptos Ar spec
Matches IPv4 packets whose
.Cm tos
field contains the comma separated list of
service types specified in
.Ar spec .
The supported IP types of service are:
.Pp
.Cm lowdelay
.Pq Dv IPTOS_LOWDELAY ,
.Cm throughput
.Pq Dv IPTOS_THROUGHPUT ,
.Cm reliability
.Pq Dv IPTOS_RELIABILITY ,
.Cm mincost
.Pq Dv IPTOS_MINCOST ,
.Cm congestion
.Pq Dv IPTOS_ECN_CE .
The absence of a particular type may be denoted
with a
.Ql \&! .
.It Cm dscp spec Ns Op , Ns Ar spec
Matches IPv4/IPv6 packets whose
.Cm DS
field value is contained in
.Ar spec
mask.
Multiple values can be specified via
the comma separated list.
Value can be one of keywords used in
.Cm setdscp
action or exact number.
.It Cm ipttl Ar ttl-list
Matches IPv4 packets whose time to live is included in
.Ar ttl-list ,
which is either a single value or a list of values or ranges
specified in the same way as
.Ar ports .
.It Cm ipversion Ar ver
Matches IP packets whose IP version field is
.Ar ver .
.It Cm keep-state
Upon a match, the firewall will create a dynamic rule, whose
default behaviour is to match bidirectional traffic between
source and destination IP/port using the same protocol.
The rule has a limited lifetime (controlled by a set of
.Xr sysctl 8
variables), and the lifetime is refreshed every time a matching
packet is found.
.It Cm layer2
Matches only layer2 packets, i.e., those passed to
.Nm
from ether_demux() and ether_output_frame().
.It Cm limit Bro Cm src-addr | src-port | dst-addr | dst-port Brc Ar N
The firewall will only allow
.Ar N
connections with the same
set of parameters as specified in the rule.
One or more
of source and destination addresses and ports can be
specified.
Currently,
only IPv4 flows are supported.
.It Cm lookup Bro Cm dst-ip | dst-port | src-ip | src-port | uid | jail Brc Ar N
Search an entry in lookup table
.Ar N
that matches the field specified as argument.
If not found, the match fails.
Otherwise, the match succeeds and
.Cm tablearg
is set to the value extracted from the table.
.Pp
This option can be useful to quickly dispatch traffic based on
certain packet fields.
See the
.Sx LOOKUP TABLES
section below for more information on lookup tables.
.It Cm { MAC | mac } Ar dst-mac src-mac
Match packets with a given
.Ar dst-mac
and
.Ar src-mac
addresses, specified as the
.Cm any
keyword (matching any MAC address), or six groups of hex digits
separated by colons,
and optionally followed by a mask indicating the significant bits.
The mask may be specified using either of the following methods:
.Bl -enum -width indent
.It
A slash
.Pq /
followed by the number of significant bits.
For example, an address with 33 significant bits could be specified as:
.Pp
.Dl "MAC 10
Download .txt
gitextract_r3ojrber/

├── 020-mips-hz1000.patch
├── Makefile
├── Makefile.inc
├── Makefile.openwrt
├── NOTES
├── README
├── binary/
│   ├── README.txt
│   ├── ipfw.sys
│   ├── netipfw.inf
│   ├── netipfw_m.inf
│   └── testme.bat
├── binary64/
│   └── ipfw.sys
├── configuration/
│   ├── README
│   ├── change_rules.sh
│   ├── change_rules_linux.sh
│   ├── ipfw.conf
│   ├── ipfw.rules
│   └── rc.firewall
├── glue.h
├── ipfw/
│   ├── Makefile
│   ├── add_rules
│   ├── dummynet.c
│   ├── expand_number.c
│   ├── glue.c
│   ├── humanize_number.c
│   ├── include/
│   │   ├── alias.h
│   │   ├── net/
│   │   │   ├── if_dl.h
│   │   │   └── pfvar.h
│   │   └── timeconv.h
│   ├── ipfw.8
│   ├── ipfw2.c
│   ├── ipfw2.h
│   ├── ipv6.c
│   ├── main.c
│   ├── qsort.c
│   ├── qsort_r.c
│   ├── rule_test.sh
│   └── ws2_32.def
├── kipfw/
│   ├── Makefile
│   ├── bsd_compat.c
│   ├── debug.c
│   ├── ipfw2_mod.c
│   ├── md_win.c
│   ├── missing.h
│   ├── mysetenv.sh
│   ├── netipfw.inf
│   ├── netipfw_m.inf
│   ├── sources
│   ├── win-passthru.diff
│   └── winmissing.h
├── kmod-ipfw3_2.4.35.4-brcm-2.4-1_mipsel.ipk
├── planetlab/
│   ├── Makefile.planetlab
│   ├── check_planetlab_sync
│   ├── ipfw
│   ├── ipfw.cron
│   ├── ipfwroot.spec
│   ├── ipfwslice.spec
│   ├── netconfig
│   ├── planetlab-tags.mk
│   ├── planetlab.mk
│   └── sample_hook
├── sys/
│   ├── net/
│   │   ├── if.h
│   │   ├── pfil.h
│   │   ├── radix.c
│   │   └── radix.h
│   ├── netgraph/
│   │   └── ng_ipfw.h
│   ├── netinet/
│   │   ├── in_cksum.c
│   │   ├── ip.h
│   │   ├── ip6.h
│   │   ├── ip_dummynet.h
│   │   ├── ip_fw.h
│   │   ├── ip_icmp.h
│   │   ├── ipfw/
│   │   │   ├── dn_heap.c
│   │   │   ├── dn_heap.h
│   │   │   ├── dn_sched.h
│   │   │   ├── dn_sched_fifo.c
│   │   │   ├── dn_sched_prio.c
│   │   │   ├── dn_sched_qfq.c
│   │   │   ├── dn_sched_rr.c
│   │   │   ├── dn_sched_wf2q.c
│   │   │   ├── ip_dn_glue.c
│   │   │   ├── ip_dn_io.c
│   │   │   ├── ip_dn_private.h
│   │   │   ├── ip_dummynet.c
│   │   │   ├── ip_fw2.c
│   │   │   ├── ip_fw_dynamic.c
│   │   │   ├── ip_fw_log.c
│   │   │   ├── ip_fw_lookup.c
│   │   │   ├── ip_fw_nat.c
│   │   │   ├── ip_fw_pfil.c
│   │   │   ├── ip_fw_private.h
│   │   │   ├── ip_fw_sockopt.c
│   │   │   └── ip_fw_table.c
│   │   ├── tcp.h
│   │   ├── tcp_var.h
│   │   └── udp.h
│   └── sys/
│       ├── cdefs.h
│       ├── kernel.h
│       ├── malloc.h
│       ├── mbuf.h
│       ├── module.h
│       ├── param.h
│       ├── queue.h
│       ├── syslog.h
│       ├── systm.h
│       └── taskqueue.h
├── tcc_glue.h
└── test/
    ├── Makefile
    ├── basic_ipfw.sh
    ├── dn_test.h
    ├── dynrules.sh
    ├── interpolation.c
    ├── main.c
    ├── memory_leak.sh
    ├── mylist.h
    ├── profile_bench1
    ├── profile_bench2
    ├── profile_bench3
    ├── test_dn_heap.c
    └── test_dn_sched.c
Download .txt
SYMBOL INDEX (1239 symbols across 63 files)

FILE: glue.h
  type in_addr_t (line 114) | typedef	uint32_t	in_addr_t;
  type thread (line 153) | struct thread {
  type sopt_dir (line 158) | enum sopt_dir { SOPT_GET, SOPT_SET }
  type sockopt (line 160) | struct  sockopt {
  type ipfw_msg_type (line 188) | enum ipfw_msg_type {
  type if_data (line 252) | struct if_data {
  type if_msghdr (line 262) | struct if_msghdr {
  type ifa_msghdr (line 276) | struct ifa_msghdr {
  type clockinfo (line 304) | struct clockinfo {
  type route_in6 (line 359) | struct route_in6 {
  type sk_buff (line 371) | struct sk_buff
  type dst_entry (line 371) | struct dst_entry
  type dst_entry (line 372) | struct dst_entry
  type sk_buff (line 372) | struct sk_buff
  type ptr_heap (line 390) | struct ptr_heap
  function ipv6_addr_copy (line 401) | static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_...
  type ether_addr (line 463) | struct ether_addr
  type ether_addr (line 464) | struct ether_addr
  type hostent (line 470) | struct hostent
  type sysctlhead (line 501) | struct sysctlhead {
  type sysctlentry (line 527) | struct sysctlentry {
  type sysctltable (line 533) | struct sysctltable {
  type sockopt (line 578) | struct sockopt

FILE: ipfw/dummynet.c
  type _s_x (line 42) | struct _s_x
  function oid_fill (line 85) | static void
  type dn_id (line 96) | struct dn_id
  type dn_id (line 98) | struct dn_id
  type dn_id (line 106) | struct dn_id
  type dn_id (line 108) | struct dn_id
  function sort_q (line 117) | static int
  function print_mask (line 151) | static void
  function print_header (line 173) | static void
  function list_flow (line 187) | static void
  function print_flowset_parms (line 233) | static void
  function print_extra_delay_parms (line 279) | static void
  function flush_buf (line 292) | static void
  function list_pipes (line 310) | static void
  function ipfw_delete_pipe (line 401) | int
  function is_valid_number (line 518) | static int
  function read_bandwidth (line 535) | static void
  type point (line 578) | struct point {
  function compare_points (line 583) | static int
  function interpolate_samples (line 622) | static void
  function load_extra_delays (line 667) | static void
  function ipfw_config_pipe (line 811) | void
  function dummynet_flush (line 1312) | void
  function parse_range (line 1324) | static int
  function dummynet_list (line 1378) | void

FILE: ipfw/expand_number.c
  function expand_number (line 49) | int

FILE: ipfw/glue.c
  function ipfw_show_nat (line 43) | void
  function ipfw_config_nat (line 49) | void
  function strlcpy (line 64) | size_t
  function strtonum (line 92) | long long int
  function sysctlbyname (line 150) | int
  function wnd_setsockopt (line 381) | int
  function wnd_getsockopt (line 409) | int
  function my_socket (line 439) | int
  type hostent (line 461) | struct hostent
  type ether_addr (line 466) | struct ether_addr
  function getopt (line 488) | int
  function verrx (line 565) | void
  function errx (line 575) | void
  function warnx (line 584) | void
  function tolower (line 620) | static unsigned char
  function isdigit (line 626) | static int isdigit(unsigned char c)
  function isxdigit (line 631) | static int isxdigit(unsigned char c)
  function isspace (line 636) | static int isspace(unsigned char c)
  function isascii (line 641) | static int isascii(unsigned char c)
  function islower (line 646) | static int islower(unsigned char c)
  function strcasecmp (line 651) | int
  function intmax_t (line 664) | intmax_t
  function setservent (line 670) | void
  function inet_pton (line 677) | int
  function inet_aton (line 750) | int

FILE: ipfw/humanize_number.c
  function humanize_number (line 52) | int

FILE: ipfw/include/net/if_dl.h
  type sockaddr_dl (line 57) | struct sockaddr_dl {
  type sockaddr_dl (line 76) | struct sockaddr_dl
  type sockaddr_dl (line 77) | struct sockaddr_dl

FILE: ipfw/include/net/pfvar.h
  type pf_altq (line 12) | struct pf_altq {
  type pfioc_altq (line 22) | struct pfioc_altq {

FILE: ipfw/include/timeconv.h
  function time_t (line 6) | static __inline time_t

FILE: ipfw/ipfw2.c
  type cmdline_opts (line 57) | struct cmdline_opts
  function PRINT_UINT_ARG (line 96) | static void
  type _s_x (line 107) | struct _s_x
  type _s_x (line 118) | struct _s_x
  type _s_x (line 134) | struct _s_x
  type _s_x (line 143) | struct _s_x
  type _s_x (line 154) | struct _s_x
  type _s_x (line 168) | struct _s_x
  type _s_x (line 197) | struct _s_x
  type _s_x (line 229) | struct _s_x
  type _s_x (line 246) | struct _s_x
  function pr_u64 (line 334) | int
  function do_cmd (line 377) | int
  function do_setcmd3 (line 417) | static int
  function match_token (line 446) | int
  type _s_x (line 463) | struct _s_x
  function _substrcmp (line 480) | int
  function _substrcmp2 (line 508) | int
  function print_port (line 524) | static void
  type _s_x (line 549) | struct _s_x
  function print_newports (line 566) | static void
  function strtoport (line 600) | static int
  function fill_newports (line 658) | static int
  type _s_x (line 702) | struct _s_x
  function fill_reject_code (line 722) | static void
  function print_reject_code (line 737) | static void
  function contigmask (line 759) | int
  function print_flags (line 777) | static void
  function print_ip (line 808) | static void
  function print_mac (line 902) | static void
  function fill_icmptypes (line 921) | static void
  function print_icmptypes (line 945) | static void
  function show_prerequisites (line 981) | static void
  function show_ipfw (line 1007) | static void
  function show_dyn_ipfw (line 1652) | static void
  function ipfw_sets_handler (line 1713) | void
  function ipfw_sysctl_handler (line 1821) | void
  function ipfw_list (line 1854) | void
  function lookup_host (line 2046) | static int
  function fill_ip (line 2070) | static void
  function n2mask (line 2258) | void
  function fill_flags (line 2280) | static void
  function ipfw_delete (line 2311) | void
  function fill_iface (line 2368) | static void
  function get_mac_addr_mask (line 2384) | static void
  function ipfw_insn (line 2437) | static ipfw_insn *
  function fill_comment (line 2448) | static void
  function fill_cmd (line 2479) | static void
  function ipfw_insn (line 2491) | static ipfw_insn *
  function ipfw_insn (line 2509) | static ipfw_insn *
  function ipfw_insn (line 2522) | static ipfw_insn *
  function ipfw_insn (line 2541) | static ipfw_insn *
  function ipfw_insn (line 2562) | static ipfw_insn *
  function ipfw_insn (line 2583) | static ipfw_insn *
  function ipfw_insn (line 2600) | static ipfw_insn *
  function ipfw_insn (line 2617) | static ipfw_insn *
  function ipfw_insn (line 2631) | static ipfw_insn *
  function ipfw_insn (line 2657) | static ipfw_insn *
  function ipfw_add (line 2695) | void
  function ipfw_zero (line 3750) | void
  function ipfw_flush (line 3801) | void
  function ipfw_table_handler (line 3847) | void
  function table_list (line 3953) | static void

FILE: ipfw/ipfw2.h
  type cmdline_opts (line 32) | struct cmdline_opts {
  type cmdline_opts (line 59) | struct cmdline_opts
  type _s_x (line 69) | struct _s_x {
  type tokens (line 74) | enum tokens {
  type _s_x (line 225) | struct _s_x
  type _s_x (line 226) | struct _s_x
  type in6_addr (line 230) | struct in6_addr
  type in6_addr (line 231) | struct in6_addr
  type _ipfw_insn (line 242) | struct _ipfw_insn
  type _ipfw_insn_altq (line 243) | struct _ipfw_insn_altq
  type _ipfw_insn_u32 (line 244) | struct _ipfw_insn_u32
  type _ipfw_insn_ip6 (line 245) | struct _ipfw_insn_ip6
  type _ipfw_insn_icmp6 (line 246) | struct _ipfw_insn_icmp6
  type _ipfw_insn_altq (line 272) | struct _ipfw_insn_altq
  type _ipfw_insn_ip6 (line 281) | struct _ipfw_insn_ip6
  type _ipfw_insn_u32 (line 282) | struct _ipfw_insn_u32
  type _ipfw_insn_u32 (line 283) | struct _ipfw_insn_u32
  type _ipfw_insn (line 284) | struct _ipfw_insn
  type _ipfw_insn (line 286) | struct _ipfw_insn
  type _ipfw_insn (line 286) | struct _ipfw_insn
  type _ipfw_insn (line 287) | struct _ipfw_insn
  type _ipfw_insn (line 287) | struct _ipfw_insn
  type _ipfw_insn_u32 (line 289) | struct _ipfw_insn_u32
  type _ipfw_insn_icmp6 (line 291) | struct _ipfw_insn_icmp6
  type _ipfw_insn (line 292) | struct _ipfw_insn

FILE: ipfw/ipv6.c
  type _s_x (line 45) | struct _s_x
  function fill_unreach6_code (line 53) | void
  function print_unreach6_code (line 68) | void
  function print_ip6 (line 82) | void
  function fill_icmp6types (line 133) | void
  function print_icmp6types (line 160) | void
  function print_flow6id (line 176) | void
  type _s_x (line 191) | struct _s_x
  function fill_ext6hdr (line 204) | int
  function print_ext6hdr (line 260) | void
  function lookup_host6 (line 300) | static int
  function fill_ip6 (line 329) | static int
  function fill_flow6 (line 439) | void
  function ipfw_insn (line 467) | ipfw_insn *
  function ipfw_insn (line 485) | ipfw_insn *

FILE: ipfw/main.c
  function help (line 36) | static void
  function ipfw_main (line 94) | static int
  function ipfw_readfile (line 449) | static void
  function main (line 589) | int

FILE: ipfw/qsort.c
  function swapfunc (line 65) | static inline void
  function qsort (line 109) | void

FILE: kipfw/bsd_compat.c
  type timeval (line 43) | struct timeval
  type timezone (line 43) | struct timezone
  type timeval (line 49) | struct timeval
  type in_ifaddrhashhead (line 55) | struct  in_ifaddrhashhead
  type pfil_head (line 64) | struct pfil_head
  type mbuf (line 66) | struct mbuf
  type ifnet (line 66) | struct ifnet
  type inpcb (line 66) | struct inpcb
  type pfil_head (line 68) | struct pfil_head
  type pfil_head (line 72) | struct pfil_head
  function pfil_add_hook (line 75) | int
  function pfil_remove_hook (line 81) | int
  function priv_check (line 88) | int
  function securelevel_ge (line 94) | int
  function sysctl_handle_int (line 100) | int
  function sysctl_handle_long (line 106) | int
  function ether_demux (line 112) | void
  function ether_output_frame (line 118) | int
  function in_rtalloc_ign (line 124) | void
  function icmp_error (line 130) | void
  function u_short (line 136) | u_short
  function u_short (line 142) | u_short
  type mbuf (line 151) | struct mbuf
  type mbuf (line 152) | struct mbuf
  function cred_check (line 164) | int
  function jailed (line 195) | int
  function in_localaddr (line 207) | int
  function sooptcopyout (line 213) | int
  function sooptcopyin (line 228) | int
  function getmicrouptime (line 242) | void
  type in_addr (line 252) | struct in_addr
  type in_addr (line 268) | struct in_addr
  function random (line 274) | int
  function div64 (line 298) | int64_t
  function strlcpy (line 316) | size_t
  function fnmatch (line 346) | int
  function skb_dst_set (line 377) | inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
  type dst_entry (line 382) | struct dst_entry
  type sk_buff (line 382) | struct sk_buff
  type dst_entry (line 384) | struct dst_entry
  type sysctltable (line 394) | struct sysctltable
  function kesysctl_emu_get (line 396) | int
  function kesysctl_emu_set (line 432) | int
  function underscoretopoint (line 471) | static void
  function formatnames (line 479) | static int
  function dumpGST (line 501) | static void
  function keinit_GST (line 524) | void
  function keexit_GST (line 541) | void
  function sysctl_pushback (line 549) | void

FILE: kipfw/debug.c
  function hexdump (line 51) | void hexdump(unsigned char* addr, int len, const char *msg)

FILE: kipfw/ipfw2_mod.c
  function inet_iif (line 94) | static inline int inet_iif(const struct sk_buff *skb)
  type sockopt (line 110) | struct sockopt
  type mbuf (line 114) | struct mbuf
  type ip_fw_args (line 114) | struct ip_fw_args
  type mbuf (line 117) | struct mbuf
  type ifnet (line 117) | struct ifnet
  type mbuf (line 120) | struct mbuf
  type mod_args (line 135) | struct mod_args {
  type mod_args (line 143) | struct mod_args
  type moduledata (line 147) | struct moduledata
  function my_mod_register (line 153) | int
  function init_children (line 171) | static void
  function fini_children (line 190) | static void
  function ipfw_ctl_h (line 215) | static int
  function dst_output (line 251) | int dst_output(struct skbuff *s)
  type sk_buff (line 256) | struct sk_buff
  type mbuf (line 257) | struct mbuf
  type sk_buff (line 262) | struct sk_buff
  type mbuf (line 263) | struct mbuf
  type sk_buff (line 265) | struct sk_buff
  type rtable (line 269) | struct rtable
  type flowi (line 270) | struct flowi
  type ip (line 273) | struct ip
  type ethhdr (line 305) | struct ethhdr
  type ethhdr (line 321) | struct ethhdr
  function ip_output (line 348) | int
  function do_ipfw_set_ctl (line 374) | int
  function do_ipfw_get_ctl (line 385) | int
  type nf_sockopt_ops (line 401) | struct nf_sockopt_ops
  type nf_hook_ops (line 473) | struct nf_hook_ops
  type sk_buff (line 477) | struct sk_buff
  type sk_buff (line 479) | struct sk_buff
  type net_device (line 481) | struct net_device
  type sk_buff (line 482) | struct sk_buff
  function reinject_drop (line 522) | void
  function ipfw2_queue_handler (line 535) | static int
  type route (line 588) | struct route
  type ip_moptions (line 589) | struct ip_moptions
  type inpcb (line 590) | struct inpcb
  function netisr_dispatch (line 598) | void
  type inet_hashinfo (line 655) | struct inet_hashinfo
  function linux_lookup (line 656) | int
  type nf_queue_handler (line 771) | struct nf_queue_handler
  function nf_register_hooks (line 785) | static int
  function nf_unregister_hooks (line 797) | static void
  type nf_hook_ops (line 825) | struct nf_hook_ops
  function ipfw_module_init (line 861) | int __init
  function ipfw_module_exit (line 930) | void __exit

FILE: kipfw/md_win.c
  function cred_check (line 38) | int
  function panic (line 60) | void
  function ffs (line 69) | int ffs(int bits)
  function do_gettimeofday (line 81) | void
  function time_uptime_w32 (line 119) | int time_uptime_w32()
  function ipfw2_qhandler_w32 (line 147) | int
  function netisr_dispatch (line 303) | void
  function win_freem (line 392) | void
  function strlcpy (line 403) | size_t
  function CleanupReinjected (line 429) | void CleanupReinjected(PNDIS_PACKET Packet, struct mbuf* m, PADAPT pAdapt)
  function ipfw2_qhandler_w32_oldstyle (line 441) | int
  type sock (line 523) | struct sock
  type sock (line 525) | struct sock
  function NTSTATUS (line 528) | NTSTATUS
  function VOID (line 618) | VOID dummynet_dpc(
  function VOID (line 628) | VOID ipfw_dpc(

FILE: kipfw/missing.h
  type inpcb (line 68) | struct inpcb
  type ipfw_rule_ref (line 115) | struct ipfw_rule_ref {
  type ether_header (line 144) | struct ether_header {
  type moduledata (line 183) | struct moduledata
  type moduledata (line 185) | struct moduledata
  type malloc_type (line 189) | struct malloc_type {
  type timeval (line 207) | struct timeval
  type timezone (line 207) | struct timezone
  type timeval (line 216) | struct timeval
  type in_ifaddrhashhead (line 232) | struct in_ifaddrhashhead
  type mbuf (line 240) | struct mbuf
  type mbuf (line 243) | struct mbuf
  type sctphdr (line 268) | struct sctphdr {
  type carp_header (line 303) | struct carp_header {
  type pim (line 314) | struct pim {
  type route (line 319) | struct route {
  type ifaltq (line 325) | struct ifaltq {
  type ifnet (line 349) | struct ifnet {
  type net_device (line 354) | struct net_device {
  type mbuf (line 360) | struct mbuf
  type pf_mtag (line 373) | struct pf_mtag {
  type radix_node (line 381) | struct radix_node {
  type in_addr (line 388) | struct in_addr
  type in_addr (line 402) | struct in_addr
  type timeval (line 430) | struct timeval
  type ip_moptions (line 433) | struct ip_moptions
  type route (line 434) | struct route
  type ip (line 435) | struct ip
  type mbuf (line 437) | struct mbuf
  type mbuf (line 437) | struct mbuf
  type ip (line 438) | struct ip
  type mbuf (line 439) | struct mbuf
  type mbuf (line 439) | struct mbuf
  type route (line 439) | struct route
  type ip_moptions (line 440) | struct ip_moptions
  type inpcb (line 440) | struct inpcb
  type mbuf (line 443) | struct mbuf
  type sockopt (line 446) | struct sockopt
  type sockopt (line 448) | struct sockopt
  type thread (line 451) | struct thread
  type bsd_ucred (line 457) | struct bsd_ucred {
  type ifnet (line 465) | struct ifnet
  type in_addr (line 466) | struct in_addr
  type in_addr (line 466) | struct in_addr
  type bsd_ucred (line 467) | struct bsd_ucred
  type sk_buff (line 468) | struct sk_buff
  type ucred (line 470) | struct ucred
  type sysctl_oid (line 472) | struct sysctl_oid
  type sysctl_req (line 473) | struct sysctl_req
  type __be32 (line 482) | typedef uint32_t __be32;
  type __be16 (line 483) | typedef uint16_t __be16;
  type sock (line 484) | struct sock
  type net (line 485) | struct net
  type inet_hashinfo (line 486) | struct inet_hashinfo
  type sock (line 487) | struct sock
  type inet_hashinfo (line 488) | struct inet_hashinfo
  type sock (line 492) | struct sock
  function __fls (line 505) | static inline unsigned long __fls(unsigned long word)
  type ifnet (line 553) | struct ifnet
  type mbuf (line 553) | struct mbuf
  type ifnet (line 555) | struct ifnet
  type mbuf (line 555) | struct mbuf
  type route (line 557) | struct route
  type mbuf (line 559) | struct mbuf
  type rtentry (line 561) | struct rtentry
  type mbuf (line 563) | struct mbuf
  type ucred (line 570) | struct ucred
  type in_addr (line 578) | struct in_addr
  type sk_buff (line 588) | struct sk_buff
  type bsd_ucred (line 588) | struct bsd_ucred
  type ip_fw_args (line 597) | struct ip_fw_args
  type mbuf (line 598) | struct mbuf
  type ip_fw_args (line 598) | struct ip_fw_args
  type mbuf (line 621) | struct mbuf
  type ifnet (line 621) | struct ifnet
  type inpcb (line 622) | struct inpcb
  type mbuf (line 625) | struct mbuf
  type sockopt (line 627) | struct sockopt
  type sockopt (line 628) | struct sockopt
  type mbuf (line 632) | struct mbuf
  type ip_fw_args (line 632) | struct ip_fw_args
  type ip_fw_args (line 636) | struct ip_fw_args
  type ip_fw_args (line 637) | struct ip_fw_args

FILE: kipfw/winmissing.h
  type UCHAR (line 42) | typedef UCHAR	u_char;
  type UCHAR (line 43) | typedef UCHAR	u_int8_t;
  type UCHAR (line 44) | typedef UCHAR	uint8_t;
  type USHORT (line 45) | typedef USHORT	u_short;
  type USHORT (line 46) | typedef USHORT	u_int16_t;
  type USHORT (line 47) | typedef USHORT	uint16_t;
  type USHORT (line 48) | typedef USHORT	n_short;
  type UINT (line 49) | typedef UINT	u_int;
  type INT32 (line 50) | typedef INT32	int32_t;
  type UINT32 (line 51) | typedef UINT32	u_int32_t;
  type UINT32 (line 52) | typedef UINT32	uint32_t;
  type ULONG (line 53) | typedef ULONG	u_long;
  type ULONG (line 54) | typedef ULONG	n_long;
  type UINT64 (line 55) | typedef UINT64	uint64_t;
  type UINT64 (line 56) | typedef UINT64	u_int64_t;
  type INT64 (line 57) | typedef INT64	int64_t;
  type UINT32 (line 59) | typedef UINT32	in_addr_t;
  type UCHAR (line 60) | typedef UCHAR	sa_family_t;
  type USHORT (line 61) | typedef	USHORT	in_port_t;
  type UINT32 (line 62) | typedef UINT32	__gid_t;
  type UINT32 (line 63) | typedef UINT32	gid_t;
  type UINT32 (line 64) | typedef UINT32	__uid_t;
  type UINT32 (line 65) | typedef UINT32	uid_t;
  type ULONG (line 66) | typedef ULONG	n_time;
  type __be32 (line 70) | typedef uint32_t __be32;
  type __be16 (line 71) | typedef uint16_t __be16;
  type timeval (line 86) | struct timeval {
  type in_addr (line 91) | struct in_addr {
  type sockaddr_in (line 95) | struct sockaddr_in {
  type in6_addr (line 112) | struct in6_addr {
  type sockaddr_in6 (line 147) | struct sockaddr_in6 {
  type icmphdr (line 174) | struct icmphdr {
  type timeval (line 224) | struct timeval

FILE: sys/net/pfil.h
  type mbuf (line 42) | struct mbuf
  type ifnet (line 43) | struct ifnet
  type inpcb (line 44) | struct inpcb
  type packet_filter_hook (line 50) | struct packet_filter_hook {
  type pfil_list_t (line 62) | typedef	TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t;
  type pfil_head (line 67) | struct pfil_head {
  type mbuf (line 86) | struct mbuf
  type ifnet (line 86) | struct ifnet
  type inpcb (line 87) | struct inpcb
  type pfil_head (line 87) | struct pfil_head
  type mbuf (line 88) | struct mbuf
  type ifnet (line 88) | struct ifnet
  type inpcb (line 89) | struct inpcb
  type pfil_head (line 89) | struct pfil_head
  type pfil_head (line 90) | struct pfil_head
  type mbuf (line 90) | struct mbuf
  type ifnet (line 90) | struct ifnet
  type inpcb (line 91) | struct inpcb
  type pfil_head (line 93) | struct pfil_head
  type pfil_head (line 94) | struct pfil_head
  type pfil_head (line 96) | struct pfil_head
  type packet_filter_hook (line 109) | struct packet_filter_hook
  type pfil_head (line 110) | struct pfil_head

FILE: sys/net/radix.c
  type radix_node_head (line 59) | struct radix_node_head
  type radix_node_head (line 61) | struct radix_node_head
  type radix_node (line 62) | struct radix_node
  type radix_node_head (line 63) | struct radix_node_head
  type radix_node (line 64) | struct radix_node
  type radix_node (line 65) | struct radix_node
  type radix_node (line 66) | struct radix_node
  type radix_node (line 67) | struct radix_node
  type radix_mask (line 70) | struct radix_mask
  type radix_node_head (line 71) | struct radix_node_head
  type radix_mask (line 92) | struct radix_mask
  type radix_node (line 93) | struct radix_node
  type radix_mask (line 94) | struct radix_mask
  type radix_node (line 95) | struct radix_node
  type radix_node (line 158) | struct radix_node
  type radix_node (line 161) | struct radix_node
  type radix_node (line 163) | struct radix_node
  type radix_node (line 179) | struct radix_node
  type radix_node (line 184) | struct radix_node
  function rn_refines (line 197) | int
  type radix_node (line 224) | struct radix_node
  type radix_node_head (line 227) | struct radix_node_head
  type radix_node (line 229) | struct radix_node
  function rn_satisfies_leaf (line 246) | static int
  type radix_node (line 267) | struct radix_node
  type radix_node_head (line 270) | struct radix_node_head
  type radix_node (line 273) | struct radix_node
  type radix_node (line 276) | struct radix_node
  type radix_mask (line 343) | struct radix_mask
  type radix_node (line 372) | struct	radix_node
  type radix_node (line 388) | struct radix_node
  type radix_node (line 392) | struct radix_node
  type radix_node (line 394) | struct radix_node
  type radix_node (line 421) | struct radix_node
  type radix_node_head (line 424) | struct radix_node_head
  type radix_node (line 426) | struct radix_node
  type radix_node (line 429) | struct radix_node
  type radix_node (line 431) | struct radix_node
  type radix_node (line 434) | struct radix_node
  type radix_node (line 455) | struct radix_node
  type radix_node (line 491) | struct radix_node
  type radix_node (line 497) | struct radix_node
  type radix_node (line 501) | struct radix_node
  function rn_lexobetter (line 571) | static int	/* XXX: arbitrary ordering for non-contiguous masks */
  type radix_mask (line 586) | struct radix_mask
  type radix_mask (line 589) | struct radix_mask
  type radix_mask (line 591) | struct radix_mask
  type radix_node (line 610) | struct radix_node
  type radix_node_head (line 613) | struct radix_node_head
  type radix_node (line 614) | struct radix_node
  type radix_node (line 617) | struct radix_node
  type radix_node (line 618) | struct radix_node
  type radix_mask (line 622) | struct radix_mask
  type radix_node (line 682) | struct	radix_node
  type radix_node (line 785) | struct radix_node
  type radix_node_head (line 788) | struct radix_node_head
  type radix_node (line 790) | struct radix_node
  type radix_mask (line 791) | struct radix_mask
  type radix_node (line 792) | struct radix_node
  type radix_mask (line 932) | struct radix_mask
  function rn_walktree_from (line 974) | static int
  function rn_walktree (line 1081) | static int
  function rn_inithead (line 1131) | int
  function rn_detachhead (line 1166) | int
  function rn_init (line 1182) | void

FILE: sys/net/radix.h
  type radix_node (line 50) | struct radix_node {
  type radix_mask (line 89) | struct radix_mask {
  type radix_node (line 104) | struct radix_node
  type radix_node_head (line 106) | struct radix_node_head {
  type radix_node (line 172) | struct radix_node
  type radix_node_head (line 174) | struct radix_node_head
  type radix_node (line 175) | struct radix_node
  type radix_node_head (line 176) | struct radix_node_head
  type radix_node_head (line 178) | struct radix_node_head
  type radix_node_head (line 179) | struct radix_node_head

FILE: sys/netinet/in_cksum.c
  function in_cksum (line 48) | int

FILE: sys/netinet/ip.h
  type ip (line 24) | struct ip {

FILE: sys/netinet/ip6.h
  type ip6_hdr (line 6) | struct ip6_hdr {
  type icmp6_hdr (line 23) | struct icmp6_hdr {
  type ip6_hbh (line 34) | struct ip6_hbh {
  type ip6_rthdr (line 39) | struct ip6_rthdr {
  type ip6_frag (line 46) | struct ip6_frag {
  type ip6_ext (line 54) | struct  ip6_ext {

FILE: sys/netinet/ip_dummynet.h
  type dn_id (line 52) | struct dn_id {
  type dn_link (line 113) | struct dn_link {
  type dn_fs (line 133) | struct dn_fs {
  type dn_flow (line 169) | struct dn_flow {
  type dn_sch (line 184) | struct dn_sch {
  type dn_profile (line 200) | struct dn_profile {

FILE: sys/netinet/ip_fw.h
  type ip_fw3_opheader (line 66) | typedef struct _ip_fw3_opheader {
  type ipfw_opcodes (line 100) | enum ipfw_opcodes {		/* arguments (4 byte each)	*/
  type ipfw_insn (line 265) | typedef struct	_ipfw_insn {	/* template for instructions */
  type ipfw_insn_u16 (line 285) | typedef struct	_ipfw_insn_u16 {
  type ipfw_insn_u32 (line 294) | typedef struct	_ipfw_insn_u32 {
  type ipfw_insn_ip (line 302) | typedef struct	_ipfw_insn_ip {
  type ipfw_insn_sa (line 311) | typedef struct  _ipfw_insn_sa {
  type ipfw_insn_sa6 (line 319) | typedef struct _ipfw_insn_sa6 {
  type ipfw_insn_mac (line 327) | typedef struct	_ipfw_insn_mac {
  type ipfw_insn_if (line 336) | typedef struct	_ipfw_insn_if {
  type ipfw_insn_altq (line 348) | typedef struct _ipfw_insn_altq {
  type ipfw_insn_limit (line 356) | typedef struct	_ipfw_insn_limit {
  type ipfw_insn_log (line 371) | typedef struct  _ipfw_insn_log {
  type cfg_spool (line 383) | struct cfg_spool {
  type cfg_redir (line 397) | struct cfg_redir {
  type cfg_nat (line 421) | struct cfg_nat {
  type ipfw_insn_nat (line 441) | typedef struct	_ipfw_insn_nat {
  type ipfw_insn_ip6 (line 454) | typedef struct _ipfw_insn_ip6 {
  type ipfw_insn_icmp6 (line 461) | typedef struct _ipfw_insn_icmp6 {
  type ip_fw (line 497) | struct ip_fw {
  type ipfw_flow_id (line 538) | struct ipfw_flow_id {
  type ipfw_dyn_rule (line 559) | typedef struct _ipfw_dyn_rule ipfw_dyn_rule;
  type _ipfw_dyn_rule (line 561) | struct _ipfw_dyn_rule {
  type ipfw_table_entry (line 610) | typedef struct	_ipfw_table_entry {
  type ipfw_table_xentry (line 617) | typedef struct _ipfw_table_xentry {
  type ipfw_table (line 630) | typedef struct	_ipfw_table {
  type ipfw_xtable (line 637) | typedef struct _ipfw_xtable {

FILE: sys/netinet/ipfw/dn_heap.c
  function my_free (line 57) | static void my_free(void *p) {	free(p); }
  function heap_resize (line 79) | static int
  function heap_init (line 109) | int
  function heap_insert (line 142) | int
  function heap_extract (line 179) | void
  function heap_move (line 231) | static void
  function heapify (line 274) | static void
  function heap_scan (line 283) | int
  function heap_free (line 308) | void
  type dn_ht (line 320) | struct dn_ht {
  type dn_ht (line 335) | struct dn_ht
  type dn_ht (line 336) | struct dn_ht
  function do_del (line 419) | static int
  function dn_ht_free (line 425) | void
  function dn_ht_entries (line 439) | int
  function dn_ht_scan_body (line 457) | static int
  type dn_ht (line 498) | struct dn_ht
  function dn_ht_scan (line 549) | int
  function dn_ht_scan_bucket (line 575) | int

FILE: sys/netinet/ipfw/dn_heap.h
  type dn_heap_entry (line 56) | struct dn_heap_entry {
  type dn_heap (line 61) | struct dn_heap {
  type dn_heap (line 101) | struct dn_heap
  type dn_heap (line 102) | struct dn_heap
  type dn_heap (line 103) | struct dn_heap
  type dn_heap (line 104) | struct dn_heap
  type dn_heap (line 105) | struct dn_heap
  type dn_ht (line 165) | struct dn_ht
  type dn_ht (line 167) | struct dn_ht
  type dn_ht (line 167) | struct dn_ht
  type dn_ht (line 171) | struct dn_ht
  type dn_ht (line 173) | struct dn_ht
  type dn_ht (line 174) | struct dn_ht
  type dn_ht (line 175) | struct dn_ht
  type dn_ht (line 176) | struct dn_ht

FILE: sys/netinet/ipfw/dn_sched.h
  type dn_alg (line 43) | struct dn_alg {
  type mbuf (line 157) | struct mbuf
  type dn_queue (line 158) | struct dn_queue
  type mbuf (line 158) | struct mbuf
  type mbuf (line 166) | struct mbuf
  type dn_queue (line 167) | struct dn_queue
  type mbuf (line 169) | struct mbuf
  type dn_flow (line 185) | struct dn_flow

FILE: sys/netinet/ipfw/dn_sched_fifo.c
  function fifo_enqueue (line 57) | static int
  type mbuf (line 67) | struct mbuf
  type dn_sch_inst (line 68) | struct dn_sch_inst
  type dn_queue (line 70) | struct dn_queue
  function fifo_new_sched (line 73) | static int
  function fifo_free_sched (line 85) | static int
  type dn_alg (line 99) | struct dn_alg
  type dn_queue (line 105) | struct dn_queue

FILE: sys/netinet/ipfw/dn_sched_prio.c
  type prio_si (line 69) | struct prio_si {
  function prio_enqueue (line 78) | static int
  type mbuf (line 107) | struct mbuf
  type dn_sch_inst (line 108) | struct dn_sch_inst
  type prio_si (line 110) | struct prio_si
  type prio_si (line 110) | struct prio_si
  type mbuf (line 111) | struct mbuf
  type dn_queue (line 112) | struct dn_queue
  function prio_new_sched (line 135) | static int
  function prio_new_fsk (line 146) | static int
  function prio_new_queue (line 154) | static int
  function prio_free_queue (line 189) | static int
  type dn_alg (line 203) | struct dn_alg
  type prio_si (line 210) | struct prio_si

FILE: sys/netinet/ipfw/dn_sched_qfq.c
  type qfq_sched (line 51) | struct qfq_sched
  type qfq_sched (line 52) | struct qfq_sched
  type bitmap (line 58) | typedef	unsigned long	bitmap;
  function fls (line 65) | int fls(unsigned int n)
  function __fls (line 75) | static inline unsigned long __fls(unsigned long word)
  function test_bit (line 83) | int test_bit(int ix, bitmap *p)
  function __set_bit (line 89) | void __set_bit(int ix, bitmap *p)
  function __clear_bit (line 95) | void __clear_bit(int ix, bitmap *p)
  type qfq_state (line 188) | enum qfq_state { ER, IR, EB, IB, QFQ_MAX_STATE }
  type qfq_group (line 190) | struct qfq_group
  type qfq_class (line 196) | struct qfq_class {
  type qfq_group (line 215) | struct qfq_group {
  type qfq_sched (line 227) | struct qfq_sched {
  function qfq_gt (line 240) | static inline int qfq_gt(uint64_t a, uint64_t b)
  function qfq_round_down (line 246) | static inline uint64_t qfq_round_down(uint64_t ts, unsigned int shift)
  type qfq_group (line 252) | struct qfq_group
  type qfq_sched (line 252) | struct qfq_sched
  function qfq_calc_index (line 264) | static int qfq_calc_index(uint32_t inv_w, unsigned int maxlen)
  function qfq_new_queue (line 290) | static int
  function qfq_free_queue (line 321) | static int
  function mask_from (line 334) | static inline unsigned long
  function qfq_calc_state (line 345) | static inline unsigned int
  function qfq_move_groups (line 368) | static inline void
  function qfq_unblock_groups (line 375) | static inline void
  function qfq_make_eligible (line 402) | static inline void
  function qfq_slot_insert (line 422) | static inline void
  function qfq_front_slot_remove (line 436) | static inline void
  type qfq_class (line 451) | struct qfq_class
  type qfq_group (line 452) | struct qfq_group
  function qfq_slot_rotate (line 478) | static inline void
  function qfq_update_eligible (line 488) | static inline void
  function qfq_update_class (line 508) | static inline int
  type mbuf (line 532) | struct mbuf
  type dn_sch_inst (line 533) | struct dn_sch_inst
  type qfq_sched (line 535) | struct qfq_sched
  type qfq_sched (line 535) | struct qfq_sched
  type qfq_group (line 536) | struct qfq_group
  type qfq_class (line 537) | struct qfq_class
  type mbuf (line 538) | struct mbuf
  function qfq_update_start (line 607) | static inline void
  function qfq_enqueue (line 633) | static int
  function qfq_slot_remove (line 694) | static inline void
  function qfq_deactivate_class (line 726) | static void
  function qfq_new_fsk (line 776) | static int
  function qfq_new_sched (line 788) | static int
  type dn_alg (line 807) | struct dn_alg
  type qfq_sched (line 813) | struct qfq_sched
  type qfq_class (line 814) | struct qfq_class
  type dn_queue (line 814) | struct dn_queue
  function dump_groups (line 832) | static void
  function dump_sched (line 853) | static void

FILE: sys/netinet/ipfw/dn_sched_rr.c
  type rr_queue (line 52) | struct rr_queue {
  type rr_schk (line 63) | struct rr_schk {
  type rr_si (line 70) | struct rr_si {
  function rr_append (line 75) | static inline void
  function rr_remove_head (line 91) | static inline void
  function remove_queue_q (line 110) | static inline void
  function next_pointer (line 134) | static inline void
  function rr_enqueue (line 144) | static int
  type mbuf (line 170) | struct mbuf
  type dn_sch_inst (line 171) | struct dn_sch_inst
  type rr_si (line 174) | struct rr_si
  type rr_si (line 174) | struct rr_si
  type rr_queue (line 175) | struct rr_queue
  type mbuf (line 179) | struct mbuf
  function rr_config (line 202) | static int
  function rr_new_sched (line 216) | static int
  function rr_free_sched (line 227) | static int
  function rr_new_fsk (line 235) | static int
  function rr_new_queue (line 247) | static int
  function rr_free_queue (line 266) | static int
  type dn_alg (line 287) | struct dn_alg
  type rr_si (line 293) | struct rr_si
  type rr_queue (line 294) | struct rr_queue
  type dn_queue (line 294) | struct dn_queue

FILE: sys/netinet/ipfw/dn_sched_wf2q.c
  type wf2qp_si (line 81) | struct wf2qp_si {
  type wf2qp_queue (line 90) | struct wf2qp_queue {
  function idle_check (line 108) | static void
  function wf2qp_enqueue (line 128) | static int
  type mbuf (line 184) | struct mbuf
  type dn_sch_inst (line 185) | struct dn_sch_inst
  type wf2qp_si (line 188) | struct wf2qp_si
  type wf2qp_si (line 188) | struct wf2qp_si
  type mbuf (line 189) | struct mbuf
  type dn_queue (line 190) | struct dn_queue
  type dn_heap (line 191) | struct dn_heap
  type dn_heap (line 192) | struct dn_heap
  type wf2qp_queue (line 193) | struct wf2qp_queue
  type wf2qp_queue (line 228) | struct wf2qp_queue
  type wf2qp_queue (line 236) | struct wf2qp_queue
  function wf2qp_new_sched (line 257) | static int
  function wf2qp_free_sched (line 275) | static int
  function wf2qp_new_fsk (line 287) | static int
  function wf2qp_new_queue (line 295) | static int
  function wf2qp_free_queue (line 316) | static int
  type dn_alg (line 351) | struct dn_alg
  type wf2qp_si (line 358) | struct wf2qp_si
  type wf2qp_queue (line 359) | struct wf2qp_queue
  type dn_queue (line 360) | struct dn_queue

FILE: sys/netinet/ipfw/ip_dn_glue.c
  type dn_heap_entry7 (line 62) | struct dn_heap_entry7 {
  type dn_heap7 (line 67) | struct dn_heap7 {
  type dn_flow_set (line 75) | struct dn_flow_set {
  type dn_flow_queue7 (line 130) | struct dn_flow_queue7 {
  type dn_pipe7 (line 160) | struct dn_pipe7 {        /* a pipe */
  type dn_flow_queue8 (line 195) | struct dn_flow_queue8 {
  type dn_pipe8 (line 226) | struct dn_pipe8 {        /* a pipe */
  type dn_pipe_max8 (line 265) | struct dn_pipe_max8 {
  function oid_fill (line 292) | static void
  type dn_id (line 302) | struct dn_id
  type dn_id (line 304) | struct dn_id
  type dn_pipe7 (line 311) | struct dn_pipe7
  type dn_pipe8 (line 312) | struct dn_pipe8
  type dn_pipe_max8 (line 313) | struct dn_pipe_max8
  function convertflags2new (line 326) | static int
  function convertflags2old (line 347) | static int
  function dn_compat_del (line 368) | static int
  function dn_compat_config_queue (line 404) | static int
  function dn_compat_config_pipe (line 434) | static int
  function dn_compat_config_profile (line 474) | static int
  function dn_compat_configure (line 496) | static int
  function dn_compat_calc_size (line 556) | int
  function dn_c_copy_q (line 575) | int
  function dn_c_copy_pipe (line 606) | int
  function dn_compat_copy_pipe (line 660) | int
  function dn_c_copy_fs (line 692) | int
  function dn_compat_copy_queue (line 716) | int
  function copy_data_helper_compat (line 748) | int
  function ip_dummynet_compat (line 774) | int

FILE: sys/netinet/ipfw/ip_dn_io.c
  type dn_parms (line 74) | struct dn_parms
  type mbuf (line 97) | struct mbuf
  type ifnet (line 97) | struct ifnet
  type mbuf (line 181) | struct mbuf
  type dn_pkt_tag (line 189) | struct dn_pkt_tag {
  type dn_pkt_tag (line 204) | struct dn_pkt_tag
  type mbuf (line 205) | struct mbuf
  type m_tag (line 207) | struct m_tag
  type dn_pkt_tag (line 212) | struct dn_pkt_tag
  function mq_append (line 215) | static inline void
  function dn_free_pkts (line 230) | void dn_free_pkts(struct mbuf *mnext)
  function red_drops (line 240) | static int
  function dn_enqueue (line 348) | int
  function transmit_event (line 406) | static void
  function extra_bits (line 431) | static uint64_t
  type mbuf (line 454) | struct mbuf
  type mq (line 455) | struct mq
  type dn_sch_inst (line 455) | struct dn_sch_inst
  type mq (line 457) | struct mq
  type dn_schk (line 458) | struct dn_schk
  type mbuf (line 459) | struct mbuf
  function readTSC (line 542) | uint64_t
  function do_update_cycle (line 575) | static void
  function do_drain (line 607) | static void
  function dummynet_task (line 655) | void
  function dummynet_send (line 732) | static void
  function tag_mbuf (line 821) | static inline int
  function dummynet_io (line 854) | int

FILE: sys/netinet/ipfw/ip_dn_private.h
  type mq (line 84) | struct mq {	/* a basic queue of packets*/
  function set_oid (line 88) | static inline void
  type dn_parms (line 113) | struct dn_parms {
  type delay_line (line 223) | struct delay_line {
  type dn_fsk (line 240) | struct dn_fsk { /* kernel side of a flowset */
  type dn_queue (line 284) | struct dn_queue {
  type dn_schk (line 307) | struct dn_schk {
  type dn_sch_inst (line 336) | struct dn_sch_inst {
  type dn_parms (line 372) | struct dn_parms
  type mbuf (line 376) | struct mbuf
  type ip_fw_args (line 376) | struct ip_fw_args
  type dn_queue (line 380) | struct dn_queue
  type dn_fsk (line 380) | struct dn_fsk
  type ipfw_flow_id (line 380) | struct ipfw_flow_id
  type dn_sch_inst (line 381) | struct dn_sch_inst
  type dn_schk (line 381) | struct dn_schk
  type ipfw_flow_id (line 381) | struct ipfw_flow_id
  type copy_range (line 390) | struct copy_range {
  type copy_args (line 395) | struct copy_args {
  type sockopt (line 403) | struct sockopt
  type sockopt (line 404) | struct sockopt
  type sockopt (line 405) | struct sockopt
  type dn_schk (line 407) | struct dn_schk
  type copy_args (line 407) | struct copy_args
  type dn_fsk (line 408) | struct dn_fsk
  type copy_args (line 408) | struct copy_args
  type copy_args (line 409) | struct copy_args
  type copy_args (line 410) | struct copy_args

FILE: sys/netinet/ipfw/ip_dummynet.c
  type schk_new_arg (line 70) | struct schk_new_arg {
  type callout (line 76) | struct callout
  type task (line 77) | struct task
  type taskqueue (line 78) | struct taskqueue
  function dummynet (line 81) | void
  function dn_reschedule (line 89) | void
  type dn_alg (line 97) | struct dn_alg
  type dn_alg (line 100) | struct dn_alg
  function ipdn_bound_var (line 109) | int
  type ipfw_flow_id (line 138) | struct ipfw_flow_id
  type ipfw_flow_id (line 139) | struct ipfw_flow_id
  type ipfw_flow_id (line 139) | struct ipfw_flow_id
  type ipfw_flow_id (line 159) | struct ipfw_flow_id
  type ipfw_flow_id (line 160) | struct ipfw_flow_id
  type ipfw_flow_id (line 160) | struct ipfw_flow_id
  function nonzero_mask (line 185) | static int
  function flow_id_hash (line 207) | static uint32_t
  function flow_id_cmp (line 236) | static int
  function q_hash (line 267) | static uint32_t
  function q_match (line 278) | static int
  type dn_queue (line 299) | struct dn_queue
  type dn_fsk (line 300) | struct dn_fsk
  type ipfw_flow_id (line 311) | struct ipfw_flow_id
  function dn_delete_queue (line 339) | static int
  function q_delete_cb (line 363) | static int
  function qht_delete (line 376) | static void
  type dn_queue (line 400) | struct dn_queue
  type dn_fsk (line 401) | struct dn_fsk
  type ipfw_flow_id (line 401) | struct ipfw_flow_id
  type dn_queue (line 403) | struct dn_queue
  type ipfw_flow_id (line 408) | struct ipfw_flow_id
  type dn_queue (line 411) | struct dn_queue
  type dn_queue (line 423) | struct dn_queue
  function si_hash (line 432) | static uint32_t
  function si_match (line 443) | static int
  type dn_schk (line 464) | struct dn_schk
  type dn_sch_inst (line 465) | struct dn_sch_inst
  type dn_flow (line 473) | struct dn_flow
  type delay_line (line 475) | struct delay_line
  type ipfw_flow_id (line 487) | struct ipfw_flow_id
  function si_destroy (line 508) | static int
  type dn_sch_inst (line 535) | struct dn_sch_inst
  type dn_schk (line 536) | struct dn_schk
  type ipfw_flow_id (line 536) | struct ipfw_flow_id
  type ipfw_flow_id (line 540) | struct ipfw_flow_id
  type dn_sch_inst (line 547) | struct dn_sch_inst
  function si_reset_credit (line 551) | static int
  function schk_reset_credit (line 562) | static void
  function fsk_hash (line 577) | static uint32_t
  function fsk_match (line 586) | static int
  type dn_fsk (line 599) | struct dn_fsk
  function fsk_detach (line 617) | static void
  function fsk_detach_list (line 658) | static void
  function delete_fs (line 677) | static int
  function schk_hash (line 709) | static uint32_t
  function schk_match (line 717) | static int
  type schk_new_arg (line 734) | struct schk_new_arg
  type dn_schk (line 735) | struct dn_schk
  type dn_sch_inst (line 750) | struct dn_sch_inst
  function schk_delete_cb (line 770) | static int
  function delete_schk (line 807) | static int
  function copy_obj (line 827) | static int
  function copy_obj_q (line 859) | static int
  function copy_q_cb (line 878) | static int
  function copy_q (line 891) | static int
  function copy_profile (line 909) | static int
  function copy_flowset (line 928) | static int
  function copy_si_cb (line 945) | static int
  function copy_si (line 959) | static int
  function copy_fsk_list (line 972) | static int
  function copy_data_helper (line 999) | static int
  type dn_schk (line 1065) | struct dn_schk
  function config_red (line 1074) | static int
  function update_red (line 1151) | static void
  function fsk_attach (line 1162) | static void
  function update_fs (line 1201) | static void
  function config_link (line 1242) | static int
  type dn_fsk (line 1299) | struct dn_fsk
  type dn_fs (line 1300) | struct dn_fs
  type dn_id (line 1300) | struct dn_id
  type dn_fsk (line 1303) | struct dn_fsk
  type dn_fsk (line 1332) | struct dn_fsk
  type dn_schk (line 1335) | struct dn_schk
  function config_sched (line 1387) | static int
  function config_profile (line 1586) | static int
  function dummynet_flush (line 1646) | static void
  function do_config (line 1671) | int
  function compute_space (line 1774) | static int
  function dummynet_get (line 1857) | int
  function drain_scheduler_cb (line 2008) | static int
  function drain_scheduler_sch_cb (line 2042) | static int
  function dn_drain_scheduler (line 2061) | void
  function drain_queue_cb (line 2071) | static int
  function drain_queue_fs_cb (line 2092) | static int
  function dn_drain_queue (line 2115) | void
  function ip_dn_ctl (line 2128) | static int
  function ip_dn_init (line 2184) | static void
  function ip_dn_destroy (line 2255) | static void
  function dummynet_modevent (line 2280) | static int
  function load_dn_sched (line 2306) | static int
  function unload_dn_sched (line 2336) | static int
  function dn_sched_modevent (line 2359) | int

FILE: sys/netinet/ipfw/ip_fw2.c
  type ip_fw_chain (line 133) | struct ip_fw_chain
  type cfg_nat (line 136) | struct cfg_nat
  type nat_list (line 136) | struct nat_list
  function icmptype_match (line 200) | static __inline int
  function is_icmp_query (line 211) | static int
  function flags_match (line 232) | static int
  function ipopts_match (line 246) | static int
  function tcpopts_match (line 290) | static int
  function iface_match (line 336) | static int
  function verify_path (line 392) | static int
  function icmp6type_match (line 447) | static __inline int
  function flow6id_match (line 453) | static int
  function search_ip6_addr_net (line 464) | static int
  function verify_path6 (line 491) | static int
  function is_icmp6_query (line 540) | static int
  function send_reject6 (line 554) | static void
  function send_reject (line 600) | static void
  function check_uidgid (line 645) | static int
  function set_match (line 730) | static inline void
  function ipfw_chk (line 776) | int
  function ipfw_init (line 2230) | static int
  function ipfw_destroy (line 2286) | static void
  function vnet_ipfw_init (line 2299) | static int
  function vnet_ipfw_uninit (line 2378) | static int
  function ipfw_modevent (line 2430) | static int

FILE: sys/netinet/ipfw/ip_fw_dynamic.c
  type callout (line 124) | struct callout
  type mtx (line 134) | struct mtx
  function ipfw_dyn_unlock (line 144) | void
  function hash_packet6 (line 233) | static __inline int
  function hash_packet (line 250) | static __inline int
  function unlink_dyn_rule_print (line 265) | static __inline void
  function remove_dyn_rule (line 325) | static void
  function ipfw_remove_dyn_children (line 390) | void
  function ipfw_dyn_rule (line 401) | static ipfw_dyn_rule *
  function ipfw_dyn_rule (line 544) | ipfw_dyn_rule *
  function realloc_dynamic_table (line 558) | static void
  function ipfw_dyn_rule (line 597) | static ipfw_dyn_rule *
  function ipfw_dyn_rule (line 673) | static ipfw_dyn_rule *
  function ipfw_install_state (line 715) | int
  type mbuf (line 893) | struct mbuf
  type mbuf (line 894) | struct mbuf
  type ipfw_flow_id (line 894) | struct ipfw_flow_id
  type mbuf (line 897) | struct mbuf
  type ip (line 899) | struct ip
  type ip6_hdr (line 901) | struct ip6_hdr
  type tcphdr (line 903) | struct tcphdr
  type ip (line 921) | struct ip
  type tcphdr (line 921) | struct tcphdr
  type ip6_hdr (line 925) | struct ip6_hdr
  type tcphdr (line 925) | struct tcphdr
  type tcphdr (line 947) | struct tcphdr
  type tcphdr (line 956) | struct tcphdr
  type tcphdr (line 964) | struct tcphdr
  type tcphdr (line 973) | struct tcphdr
  type tcphdr (line 985) | struct tcphdr
  type tcphdr (line 1023) | struct tcphdr
  function ipfw_tick (line 1040) | void
  function ipfw_dyn_attach (line 1136) | void
  function ipfw_dyn_detach (line 1146) | void
  function ipfw_dyn_init (line 1153) | void
  function ipfw_dyn_uninit (line 1176) | void
  function ipfw_dyn_len (line 1187) | int
  function ipfw_get_dynamic (line 1194) | void

FILE: sys/netinet/ipfw/ip_fw_log.c
  function ipfw_log_bpf (line 92) | void
  type ifnet (line 97) | struct ifnet
  function log_dummy (line 100) | static int
  function ipfw_log_output (line 106) | static int
  function ipfw_log_start (line 115) | static void
  function ipfw_log_bpf (line 124) | void
  function ipfw_log (line 163) | void

FILE: sys/netinet/ipfw/ip_fw_lookup.c
  type entry (line 93) | struct entry {
  type lookup_table (line 98) | struct lookup_table {
  function empty (line 106) | static __inline int empty(struct lookup_table *head, const void *p)
  type lookup_table (line 116) | struct lookup_table
  type lookup_table (line 117) | struct lookup_table
  type entry (line 120) | struct entry
  type entry (line 121) | struct entry
  function ipfw_lut_insert (line 183) | int
  type lookup_table (line 199) | struct lookup_table
  type entry (line 203) | struct entry
  type lookup_table (line 225) | struct lookup_table
  type entry (line 228) | struct entry
  function ipfw_lut_dump (line 236) | void
  function dump_p (line 254) | void dump_p(struct lookup_table *p, int *map)
  function main (line 262) | int main(int argc, char *argv[])

FILE: sys/netinet/ipfw/ip_fw_nat.c
  function ifaddr_change (line 58) | static void
  function flush_nat_ptrs (line 91) | static void
  function del_redir_spool_cfg (line 107) | static void
  function add_redir_spool_cfg (line 142) | static int
  function ipfw_nat (line 206) | static int
  type cfg_nat (line 333) | struct cfg_nat
  type nat_list (line 334) | struct nat_list
  type cfg_nat (line 336) | struct cfg_nat
  function ipfw_nat_cfg (line 345) | static int
  function ipfw_nat_del (line 416) | static int
  function ipfw_nat_get_cfg (line 440) | static int
  function ipfw_nat_get_log (line 491) | static int
  function ipfw_nat_init (line 530) | static void
  function ipfw_nat_destroy (line 548) | static void
  function ipfw_nat_modevent (line 574) | static int

FILE: sys/netinet/ipfw/ip_fw_pfil.c
  type mbuf (line 77) | struct mbuf
  type ipfw_rule_ref (line 77) | struct ipfw_rule_ref
  function ipfw_check_hook (line 103) | int
  function ipfw_divert (line 257) | static int
  function ipfw_hook (line 333) | static int
  function ipfw_attach_hooks (line 348) | int
  function ipfw_chg_hook (line 370) | int

FILE: sys/netinet/ipfw/ip_fw_private.h
  type _ip6dn_args (line 67) | struct _ip6dn_args {
  type ip_fw_args (line 85) | struct ip_fw_args {
  type ip (line 153) | struct ip
  type ip_fw (line 155) | struct ip_fw
  type ip_fw_args (line 155) | struct ip_fw_args
  type mbuf (line 156) | struct mbuf
  type ifnet (line 156) | struct ifnet
  type ip (line 157) | struct ip
  type tcphdr (line 179) | struct tcphdr
  type mbuf (line 180) | struct mbuf
  type mbuf (line 180) | struct mbuf
  type ipfw_flow_id (line 180) | struct ipfw_flow_id
  type ip_fw (line 182) | struct ip_fw
  type ip_fw_args (line 183) | struct ip_fw_args
  type ipfw_flow_id (line 184) | struct ipfw_flow_id
  type tcphdr (line 185) | struct tcphdr
  type ip_fw (line 186) | struct ip_fw
  type ip_fw_chain (line 202) | struct ip_fw_chain
  type ip_fw_chain (line 211) | struct ip_fw_chain {
  type sockopt (line 230) | struct sockopt
  type ip_fw_chain (line 260) | struct ip_fw_chain
  type ip_fw_chain (line 261) | struct ip_fw_chain
  type ip_fw (line 261) | struct ip_fw
  type sockopt (line 262) | struct sockopt
  type ip_fw_args (line 263) | struct ip_fw_args
  type ip_fw (line 264) | struct ip_fw
  type mbuf (line 267) | struct mbuf
  type ifnet (line 267) | struct ifnet
  type inpcb (line 268) | struct inpcb
  type radix_node (line 271) | struct radix_node
  type ip_fw_chain (line 272) | struct ip_fw_chain
  type ip_fw_chain (line 274) | struct ip_fw_chain
  type ip_fw_chain (line 275) | struct ip_fw_chain
  type ip_fw_chain (line 276) | struct ip_fw_chain
  type ip_fw_chain (line 277) | struct ip_fw_chain
  type radix_node (line 279) | struct radix_node
  type ip_fw_chain (line 280) | struct ip_fw_chain
  type ip_fw_chain (line 282) | struct ip_fw_chain
  type ip_fw_chain (line 283) | struct ip_fw_chain
  type cfg_nat (line 287) | struct cfg_nat
  type nat_list (line 287) | struct nat_list
  type ip_fw_args (line 289) | struct ip_fw_args
  type cfg_nat (line 289) | struct cfg_nat
  type mbuf (line 289) | struct mbuf
  type sockopt (line 290) | struct sockopt

FILE: sys/netinet/ipfw/ip_fw_sockopt.c
  function ipfw_find_rule (line 84) | int
  type ip_fw (line 109) | struct ip_fw
  type ip_fw_chain (line 110) | struct ip_fw_chain
  type ip_fw (line 114) | struct ip_fw
  type ip_fw (line 118) | struct ip_fw
  type ip_fw (line 138) | struct ip_fw
  type ip_fw_chain (line 139) | struct ip_fw_chain
  type ip_fw (line 139) | struct ip_fw
  type ip_fw (line 141) | struct ip_fw
  function ipfw_add_rule (line 159) | int
  function ipfw_reap_rules (line 224) | void
  function keep_rule (line 262) | static int
  function del_entry (line 286) | static int
  function clear_counters (line 442) | static void
  function zero_entry (line 464) | static int
  function check_ipfw_struct (line 527) | static int
  type ip_fw7 (line 840) | struct ip_fw7 {
  type ip_fw (line 860) | struct ip_fw
  type ip_fw (line 861) | struct ip_fw
  function ipfw_getrules (line 874) | static size_t
  function ipfw_ctl (line 937) | int
  function convert_rule_to_7 (line 1234) | int
  function convert_rule_to_8 (line 1289) | int

FILE: sys/netinet/ipfw/ip_fw_table.c
  type table_entry (line 78) | struct table_entry {
  function ipfw_add_table_entry (line 96) | int
  function ipfw_del_table_entry (line 125) | int
  function flush_table_entry (line 150) | static int
  function ipfw_flush_table (line 163) | int
  function ipfw_destroy_tables (line 178) | void
  function ipfw_init_tables (line 193) | int
  function ipfw_lookup_table (line 210) | int
  function count_table_entry (line 231) | static int
  function ipfw_count_table (line 240) | int
  function dump_table_entry (line 253) | static int
  function ipfw_dump_table (line 274) | int

FILE: sys/netinet/tcp.h
  type u_int32_t (line 42) | typedef	u_int32_t tcp_seq;
  type tcphdr (line 51) | struct tcphdr {
  type tcp_info (line 176) | struct tcp_info {

FILE: sys/netinet/udp.h
  type udphdr (line 41) | struct udphdr {

FILE: sys/sys/kernel.h
  type sysinit_elem_order (line 19) | enum sysinit_elem_order {

FILE: sys/sys/mbuf.h
  type uma_zone_t (line 24) | typedef int uma_zone_t;
  type m_tag (line 44) | struct m_tag {
  type mbuf (line 61) | struct mbuf {
  type mbuf (line 101) | struct mbuf
  type mbuf (line 101) | struct mbuf
  type m_tag (line 108) | struct m_tag
  type mbuf (line 109) | struct mbuf
  type m_tag (line 109) | struct m_tag
  function m_tag_prepend (line 116) | static __inline void
  type m_tag (line 125) | struct m_tag
  type mbuf (line 126) | struct mbuf
  type m_tag (line 126) | struct m_tag
  type m_tag (line 135) | struct m_tag
  type m_tag (line 138) | struct m_tag
  type m_tag (line 139) | struct m_tag
  type m_tag (line 149) | struct m_tag
  type m_tag (line 155) | struct m_tag
  type mbuf (line 156) | struct mbuf
  function m_tag_delete (line 161) | static __inline void
  type m_tag (line 166) | struct m_tag
  type mbuf (line 167) | struct mbuf
  type m_tag (line 167) | struct m_tag
  type m_tag (line 169) | struct m_tag
  function m_freem (line 183) | static __inline void
  type mbuf (line 208) | struct mbuf
  type mbuf (line 211) | struct mbuf

FILE: sys/sys/module.h
  type module (line 6) | struct module
  type modeventtype_t (line 9) | typedef enum modeventtype {
  type moduledata_t (line 16) | typedef struct moduledata {

FILE: sys/sys/queue.h
  type qm_trace (line 105) | struct qm_trace {
  type type (line 217) | struct type
  type type (line 321) | struct type
  type type (line 416) | struct type
  type type (line 426) | struct type
  type quehead (line 585) | struct quehead {
  function insque (line 592) | static __inline void
  function remque (line 604) | static __inline void

FILE: sys/sys/systm.h
  function callout_reset_on (line 17) | static __inline int
  type callout (line 40) | struct callout {
  function callout_reset_on (line 78) | static __inline int
  function callout_init (line 99) | static __inline void
  function callout_drain (line 106) | static __inline int
  function callout_stop (line 118) | static __inline int

FILE: sys/sys/taskqueue.h
  type task (line 9) | struct task {
  type task (line 16) | struct task {

FILE: tcc_glue.h
  type u_char (line 35) | typedef unsigned char	u_char;
  type u_int8_t (line 37) | typedef unsigned char	u_int8_t;
  type u_short (line 38) | typedef unsigned short	u_short;
  type u_int16_t (line 40) | typedef unsigned short	u_int16_t;
  type __int32_t (line 41) | typedef int		__int32_t;
  type socklen_t (line 43) | typedef int		socklen_t;
  type pid_t (line 44) | typedef int		pid_t;
  type time_t (line 45) | typedef unsigned int	time_t;
  type uint (line 46) | typedef unsigned int	uint;
  type u_int (line 47) | typedef unsigned int	u_int;
  type u_int32_t (line 49) | typedef unsigned int	u_int32_t;
  type gid_t (line 50) | typedef unsigned int	gid_t;
  type uid_t (line 51) | typedef unsigned int	uid_t;
  type u_long (line 52) | typedef unsigned long	u_long;
  type u_int64_t (line 56) | typedef unsigned long long	int u_int64_t;
  type in_addr_t (line 58) | typedef uint32_t	in_addr_t;
  type in_addr (line 59) | struct in_addr {
  type sockaddr_in (line 62) | struct sockaddr_in {
  type in6_addr (line 72) | struct in6_addr {
  type in_addr (line 129) | struct in_addr
  type in_addr (line 130) | struct in_addr
  type group (line 135) | struct group {
  type passwd (line 139) | struct passwd {
  type protoent (line 158) | struct  protoent {
  type servent (line 164) | struct  servent {
  type hostent (line 171) | struct  hostent {
  type hostent (line 180) | struct hostent
  type hostent (line 181) | struct hostent
  type protoent (line 183) | struct protoent
  type protoent (line 184) | struct protoent
  type servent (line 186) | struct servent
  type servent (line 187) | struct servent
  type WSADATA (line 197) | typedef struct WSAData {

FILE: test/dn_test.h
  type dn_id (line 45) | struct dn_id {
  type dn_fs (line 48) | struct dn_fs {
  type dn_sch (line 68) | struct dn_sch {
  type dn_flow (line 70) | struct dn_flow {
  type dn_link (line 79) | struct dn_link {
  type ip_fw_args (line 82) | struct ip_fw_args {
  type mbuf (line 85) | struct mbuf {
  type ipfw_flow_id (line 97) | struct ipfw_flow_id {
  type _md_t (line 101) | struct _md_t {
  type moduledata_t (line 106) | typedef struct _md_t moduledata_t;
  type dn_queue (line 116) | struct dn_queue {
  type dn_schk (line 120) | struct dn_schk {
  type dn_fsk (line 122) | struct dn_fsk {
  type dn_sch_inst (line 126) | struct dn_sch_inst {
  type dn_alg (line 129) | struct dn_alg {
  function mq_append (line 146) | static inline void

FILE: test/interpolation.c
  function err (line 7) | void
  function errx (line 11) | void
  type point (line 27) | struct point {
  type profile (line 32) | struct profile {
  function is_valid_number (line 41) | static int
  function compare_points (line 55) | static int
  function interpolate_samples (line 83) | static void
  function interpolate_samples_old (line 117) | static void
  function load_profile (line 202) | static void
  function main (line 315) | int main(int argc, char **argv)

FILE: test/main.c
  type q_list (line 14) | struct q_list {
  type cfg_s (line 18) | struct cfg_s {
  type dn_parms (line 88) | struct dn_parms
  type cfg_s (line 90) | struct cfg_s
  function drop (line 95) | int
  function enqueue (line 119) | static int
  type cfg_s (line 135) | struct cfg_s
  type mbuf (line 137) | struct mbuf
  function mainloop (line 148) | static int
  function dump (line 182) | int
  function getnum (line 197) | static long
  function parse_flowsets (line 251) | static void
  function init (line 347) | static int
  function main (line 496) | int
  function controller (line 539) | static void

FILE: test/mylist.h
  type list_head (line 9) | struct list_head {
  function __list_add (line 15) | static inline void
  function list_add_tail (line 25) | static inline void
  function __list_del (line 34) | static inline void
  function list_del (line 41) | static inline void

FILE: test/test_dn_heap.c
  type x (line 46) | struct x {
  function hf (line 51) | uint32_t hf(uintptr_t key, int flags, void *arg)
  function matchf (line 57) | int matchf(void *obj, uintptr_t key, int flags, void *arg)
  type x (line 67) | struct x
  function doprint (line 80) | int doprint(void *_x, void *arg)
  function test_hash (line 87) | static void
  function main (line 126) | int

FILE: test/test_dn_sched.c
  function m_freem (line 9) | void
  function dn_sched_modevent (line 15) | int
  function dn_free_pkts (line 21) | void
  function dn_delete_queue (line 31) | int
  function dn_enqueue (line 49) | int
  function ipdn_bound_var (line 66) | int
  function fls (line 78) | int
Condensed preview — 120 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,217K chars).
[
  {
    "path": "020-mips-hz1000.patch",
    "chars": 421,
    "preview": "--- include/asm-mips/param_orig.h\t2010-02-23 12:45:58.000000000 +0100\n+++ include/asm-mips/param.h\t2010-02-23 12:00:31.0"
  },
  {
    "path": "Makefile",
    "chars": 4433,
    "preview": "# $Id: Makefile 11689 2012-08-12 21:07:34Z luigi $\n#\n# Top level makefile for building ipfw/dummynet (kernel and userspa"
  },
  {
    "path": "Makefile.inc",
    "chars": 408,
    "preview": "# $Id$\n# GNU makefile header for ipfw/kipfw building\nBSD_HEAD ?= ~/FreeBSD/head\nOSARCH := $(shell uname)\nOSARCH := $(fin"
  },
  {
    "path": "Makefile.openwrt",
    "chars": 3354,
    "preview": "# Makefile to build the package in openwrt.\n# goes into package/network/utils/ipfw3/Makefile\n#\n# Edit IPFW_DIR to point "
  },
  {
    "path": "NOTES",
    "chars": 7559,
    "preview": "#\n# $Id: NOTES 6552 2010-06-15 11:24:59Z svn_panicucci $\n#\n\n------------------------------------------------------------"
  },
  {
    "path": "README",
    "chars": 10401,
    "preview": "#\n# $Id: README 11691 2012-08-12 21:32:37Z luigi $\n#\n\nThis directory contains a port of ipfw and dummynet to Linux and W"
  },
  {
    "path": "binary/README.txt",
    "chars": 1047,
    "preview": "This directory contains the binaries to install and use IPFW and\r\nDUMMYNET on a Windows Machine. The kernel part is an N"
  },
  {
    "path": "binary/netipfw.inf",
    "chars": 2268,
    "preview": "; version section\r\n[Version]\r\nSignature  = \"$Windows NT$\"\r\nClass      = NetService\r\nClassGUID  = {4D36E974-E325-11CE-BFC"
  },
  {
    "path": "binary/netipfw_m.inf",
    "chars": 1341,
    "preview": "; version section\r\n[Version]\r\nSignature  = \"$Windows NT$\"\r\nClass      = Net\r\nClassGUID  = {4D36E972-E325-11CE-BFC1-08002"
  },
  {
    "path": "binary/testme.bat",
    "chars": 2717,
    "preview": "@echo on\r\n@set CYGWIN=nodosfilewarning\r\n\r\n@ipfw -q flush\r\n@ipfw -q pipe flush\r\n@echo ###################################"
  },
  {
    "path": "configuration/README",
    "chars": 564,
    "preview": "This directorty contains some ipfw configurations and a scripts \nto safely change the firewall rules.\n\nThe firewall conf"
  },
  {
    "path": "configuration/change_rules.sh",
    "chars": 4919,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2000 Alexandre Peixoto\n# All rights reserved.\n#\n# Redistribution and use in source and binar"
  },
  {
    "path": "configuration/change_rules_linux.sh",
    "chars": 228,
    "preview": "#!/bin/sh\n#\n# marta\n# linux wrapper for the FreeBSD change rules program\n# This file load the linux configuration and ca"
  },
  {
    "path": "configuration/ipfw.conf",
    "chars": 1351,
    "preview": "# ipfw and dummynet configuration file for linux\n# XXX TO BE TESTED ON LINUX\n\n# The firewall_type variable is used to co"
  },
  {
    "path": "configuration/ipfw.rules",
    "chars": 238,
    "preview": "# This is a simple configuration file\n# add dummynet pipes and a firewall section\n\n# flush all rules ...\n# flush\n\n# dumm"
  },
  {
    "path": "configuration/rc.firewall",
    "chars": 13343,
    "preview": "#!/bin/sh -\n# Copyright (c) 1996  Poul-Henning Kamp\n# All rights reserved.\n#\n# Redistribution and use in source and bina"
  },
  {
    "path": "glue.h",
    "chars": 17983,
    "preview": "/*\n * Copyright (c) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa\n *\n * Redistribution and use in source and bina"
  },
  {
    "path": "ipfw/Makefile",
    "chars": 3304,
    "preview": "#\n# $Id: Makefile 11688 2012-08-12 20:58:26Z luigi $\n#\n# GNUMakefile to build the userland part of ipfw on Linux and Win"
  },
  {
    "path": "ipfw/add_rules",
    "chars": 558,
    "preview": "#!/bin/bash\n#\n# A test script to add rules\n\nPRG=./ipfw\n\nmyfun() {\n\t$PRG add 10 count icmp from any to 131.114.9.128\n\t$PR"
  },
  {
    "path": "ipfw/dummynet.c",
    "chars": 37746,
    "preview": "/*\n * Copyright (c) 2002-2003,2010 Luigi Rizzo\n *\n * Redistribution and use in source forms, with and without modificati"
  },
  {
    "path": "ipfw/expand_number.c",
    "chars": 3106,
    "preview": "/*-\n * Copyright (c) 2007 Eric Anderson <anderson@FreeBSD.org>\n * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.or"
  },
  {
    "path": "ipfw/glue.c",
    "chars": 23832,
    "preview": "/*\n * Copyright (C) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa\n *\n * Redistribution and use in source and bina"
  },
  {
    "path": "ipfw/humanize_number.c",
    "chars": 4714,
    "preview": "/*\t$NetBSD: humanize_number.c,v 1.13 2007/12/14 17:26:19 christos Exp $\t*/\n\n/*\n * Copyright (c) 1997, 1998, 1999, 2002 T"
  },
  {
    "path": "ipfw/include/alias.h",
    "chars": 2389,
    "preview": "#ifndef _ALIAS_H_\n#define\t_ALIAS_H_\n\n#define LIBALIAS_BUF_SIZE 128\n\n/*\n * If PKT_ALIAS_LOG is set, a message will be pri"
  },
  {
    "path": "ipfw/include/net/if_dl.h",
    "chars": 3378,
    "preview": "/*-\n * Copyright (c) 1990, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistributi"
  },
  {
    "path": "ipfw/include/net/pfvar.h",
    "chars": 723,
    "preview": "#ifndef _PF_VAR_H_\n#define _PF_VAR_H_\n\n/*\n * replacement for FreeBSD's pfqueue.h\n */\n#include <sys/queue.h>\n\n#define DIO"
  },
  {
    "path": "ipfw/include/timeconv.h",
    "chars": 282,
    "preview": "/*\n * simple override for _long_to_time()\n */\n#ifndef _TIMECONV_H_\n#define _TIMECONV_H_\nstatic __inline time_t\n_long_to_"
  },
  {
    "path": "ipfw/ipfw.8",
    "chars": 103409,
    "preview": ".\\\"\n.\\\" $FreeBSD$\n.\\\"\n.Dd October 25, 2012\n.Dt IPFW 8\n.Os\n.Sh NAME\n.Nm ipfw\n.Nd User interface for firewall, traffic sha"
  },
  {
    "path": "ipfw/ipfw2.c",
    "chars": 94081,
    "preview": "/*\n * Copyright (c) 2002-2003 Luigi Rizzo\n * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp\n * Copyright ("
  },
  {
    "path": "ipfw/ipfw2.h",
    "chars": 7010,
    "preview": "/*\n * Copyright (c) 2002-2003 Luigi Rizzo\n * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp\n * Copyright ("
  },
  {
    "path": "ipfw/ipv6.c",
    "chars": 13005,
    "preview": "/*\n * Copyright (c) 2002-2003 Luigi Rizzo\n * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp\n * Copyright ("
  },
  {
    "path": "ipfw/main.c",
    "chars": 15942,
    "preview": "/*\n * Copyright (c) 2002-2003,2010 Luigi Rizzo\n * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp\n * Copyri"
  },
  {
    "path": "ipfw/qsort.c",
    "chars": 5478,
    "preview": "/*-\n * Copyright (c) 1992, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistributi"
  },
  {
    "path": "ipfw/qsort_r.c",
    "chars": 217,
    "preview": "/*\n * This file is in the public domain.  Originally written by Garrett\n * A. Wollman.\n *\n * $FreeBSD: src/lib/libc/stdl"
  },
  {
    "path": "ipfw/rule_test.sh",
    "chars": 1989,
    "preview": "#/bin/bash\n\nCOMMAND=ipfw\n\n\necho .########## Set $COMMAND mode .##########\n$COMMAND add allow ip from any to any\n$COMMAND"
  },
  {
    "path": "ipfw/ws2_32.def",
    "chars": 1984,
    "preview": "LIBRARY ws2_32.dll\r\n\r\nEXPORTS\r\nFreeAddrInfoW\r\nGetAddrInfoW\r\nGetNameInfoW\r\nWEP\r\nWPUCompleteOverlappedRequest\r\nWSAAccept\r\n"
  },
  {
    "path": "kipfw/Makefile",
    "chars": 13775,
    "preview": "# $Id: Makefile 12257 2013-04-26 21:13:24Z luigi $\n# gnu Makefile to build linux/Windows module for ipfw+dummynet.\n#\n# T"
  },
  {
    "path": "kipfw/bsd_compat.c",
    "chars": 13379,
    "preview": "/*\n * Copyright (C) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa\n *\n * Redistribution and use in source and bina"
  },
  {
    "path": "kipfw/debug.c",
    "chars": 1289,
    "preview": "#include <ntddk.h>\n\nconst char* texify_cmd(int i)\n{\n\tif (i==110)\n\t\treturn(\"IP_FW_ADD\");\n\tif (i==111)\n\t\treturn(\"IP_FW_DEL"
  },
  {
    "path": "kipfw/ipfw2_mod.c",
    "chars": 27336,
    "preview": "/*\n * Copyright (C) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa\n *\n * Redistribution and use in source and bina"
  },
  {
    "path": "kipfw/md_win.c",
    "chars": 20335,
    "preview": "/*\n * Copyright (C) 2010 Luigi Rizzo, Francesco Magno, Universita` di Pisa\n *\n * Redistribution and use in source and bi"
  },
  {
    "path": "kipfw/missing.h",
    "chars": 19177,
    "preview": "/*\n * Copyright (C) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa\n *\n * Redistribution and use in source and bina"
  },
  {
    "path": "kipfw/mysetenv.sh",
    "chars": 4135,
    "preview": "#!/bin/bash\n\n# bash script to set a suitable environment to call MSVC's build\n# to build a 64-bit version of the kernel."
  },
  {
    "path": "kipfw/netipfw.inf",
    "chars": 2268,
    "preview": "; version section\r\n[Version]\r\nSignature  = \"$Windows NT$\"\r\nClass      = NetService\r\nClassGUID  = {4D36E974-E325-11CE-BFC"
  },
  {
    "path": "kipfw/netipfw_m.inf",
    "chars": 1342,
    "preview": "; version section\r\n[Version]\r\nSignature  = \"$Windows NT$\"\r\nClass      = Net\r\nClassGUID  = {4D36E972-E325-11CE-BFC1-08002"
  },
  {
    "path": "kipfw/sources",
    "chars": 990,
    "preview": "TARGETNAME=ipfw\r\nTARGETTYPE=DRIVER\r\n\r\nC_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER -DNDIS_WDM=1\r\n\r\nMSC_WARNING_LEVEL=/W"
  },
  {
    "path": "kipfw/win-passthru.diff",
    "chars": 9638,
    "preview": "diff -ubwrp original_passthru/miniport.c kipfw/miniport.c\n--- original_passthru/miniport.c\t2012-08-01 14:34:15.096679600"
  },
  {
    "path": "kipfw/winmissing.h",
    "chars": 7199,
    "preview": "/*\n * Copyright (c) 2010 Francesco Magno, Universita` di Pisa\n *\n * Redistribution and use in source and binary forms, w"
  },
  {
    "path": "planetlab/Makefile.planetlab",
    "chars": 5552,
    "preview": "# $Id: Makefile 11687 2012-08-12 20:51:25Z luigi $\n#\n# Top level makefile for building ipfw/dummynet (kernel and userspa"
  },
  {
    "path": "planetlab/check_planetlab_sync",
    "chars": 507,
    "preview": "#!/bin/sh\n\n#\n# This script is used to check the sync of the local repo\n# with the remote planetlab repository\n\ntmpfile=/"
  },
  {
    "path": "planetlab/ipfw",
    "chars": 1459,
    "preview": "#!/bin/sh\n#\n# ipfw\tinit the emulation service\n#\n# chkconfig: 2345 09 91\n# description: ipfw init and shutdown\n#\n\n# Sourc"
  },
  {
    "path": "planetlab/ipfw.cron",
    "chars": 187,
    "preview": "# Runs every 5 minutes and clean ipfw expired rules\n# $Id: ipfw.cron 6069 2010-04-15 09:35:33Z marta $\n*/5 * * * * root "
  },
  {
    "path": "planetlab/ipfwroot.spec",
    "chars": 7939,
    "preview": "#\n# Marta Carbone <marta.carbone@iet.unipi.it>\n# 2009 - Universita` di Pisa\n# License is BSD.\n\n# kernel_release, kernel_"
  },
  {
    "path": "planetlab/ipfwslice.spec",
    "chars": 4544,
    "preview": "#\n# TODO:\n# restart crond\n# modprobe ipfw_mod.ko (depmod ?)\n#\n\n# Marta Carbone <marta.carbone@iet.unipi.it>\n# 2009 - Uni"
  },
  {
    "path": "planetlab/netconfig",
    "chars": 386,
    "preview": "#!/bin/sh\n#\n# Marta Carbone, Luigi Rizzo\n# Copyright (C) 2009 Universita` di Pisa\n# $Id: netconfig 4533 2009-12-16 14:39"
  },
  {
    "path": "planetlab/planetlab-tags.mk",
    "chars": 402,
    "preview": "# $Id: planetlab-tags.mk 7450 2010-10-18 11:17:43Z marta $\n# These are good to build the ipfw modules from svn on kernel"
  },
  {
    "path": "planetlab/planetlab.mk",
    "chars": 806,
    "preview": "# $Id: planetlab.mk 4533 2009-12-16 14:39:23Z luigi $\n# .mk file to build a module\nkernel-MODULES := linux-2.6\nkernel-SP"
  },
  {
    "path": "planetlab/sample_hook",
    "chars": 1038,
    "preview": "#!/bin/sh\n\n#\n# Marta Carbone <marta.carbone@iet.unipi.it>\n# 2009 - Universita` di Pisa\n#\n# This is a sample hook file in"
  },
  {
    "path": "sys/net/if.h",
    "chars": 22,
    "preview": "#include <linux/if.h>\n"
  },
  {
    "path": "sys/net/pfil.h",
    "chars": 4064,
    "preview": "/*\t$FreeBSD: src/sys/net/pfil.h,v 1.16 2007/06/08 12:43:25 gallatin Exp $ */\n/*\t$NetBSD: pfil.h,v 1.22 2003/06/23 12:57:"
  },
  {
    "path": "sys/net/radix.c",
    "chars": 32029,
    "preview": "/*-\n * Copyright (c) 1988, 1989, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redist"
  },
  {
    "path": "sys/net/radix.h",
    "chars": 7009,
    "preview": "/*-\n * Copyright (c) 1988, 1989, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redist"
  },
  {
    "path": "sys/netgraph/ng_ipfw.h",
    "chars": 1596,
    "preview": "/*-\n * Copyright 2005, Gleb Smirnoff <glebius@FreeBSD.org>\n * All rights reserved.\n *\n * Redistribution and use in sourc"
  },
  {
    "path": "sys/netinet/in_cksum.c",
    "chars": 4234,
    "preview": "/*-\n * Copyright (c) 1988, 1992, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redist"
  },
  {
    "path": "sys/netinet/ip.h",
    "chars": 1700,
    "preview": "#ifndef _NETINET_IP_H_\n#define _NETINET_IP_H_\n\n#define LITTLE_ENDIAN   1234\n#define BIG_ENDIAN      4321\n#if defined(__B"
  },
  {
    "path": "sys/netinet/ip6.h",
    "chars": 2348,
    "preview": "#ifndef _NETINET_IP6_H_\n#define _NETINET_IP6_H_\n#define IN6_ARE_ADDR_EQUAL(a, b)                        \\\n(memcmp(&(a)->"
  },
  {
    "path": "sys/netinet/ip_dummynet.h",
    "chars": 8515,
    "preview": "/*-\n * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa\n * Portions Copyright (c) 2000 Akamba Corp.\n * All right"
  },
  {
    "path": "sys/netinet/ip_fw.h",
    "chars": 19944,
    "preview": "/*-\n * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa\n *\n * Redistribution and use in source and binary forms,"
  },
  {
    "path": "sys/netinet/ip_icmp.h",
    "chars": 681,
    "preview": "/*\n * additional define not present in linux\n * should go in glue.h\n */\n#ifndef _NETINET_IP_ICMP_H_\n#define _NETINET_IP_"
  },
  {
    "path": "sys/netinet/ipfw/dn_heap.c",
    "chars": 15843,
    "preview": "/*-\n * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa\n * All rights reserved\n *\n * Redistribution and use"
  },
  {
    "path": "sys/netinet/ipfw/dn_heap.h",
    "chars": 7681,
    "preview": "/*-\n * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa\n * All rights reserved\n *\n * Redistribution and use in s"
  },
  {
    "path": "sys/netinet/ipfw/dn_sched.h",
    "chars": 7466,
    "preview": "/*\n * Copyright (c) 2010 Riccardo Panicucci, Luigi Rizzo, Universita` di Pisa\n * All rights reserved\n *\n * Redistributio"
  },
  {
    "path": "sys/netinet/ipfw/dn_sched_fifo.c",
    "chars": 3738,
    "preview": "/*\n * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa\n * All rights reserved\n *\n * Redistribution and use in "
  },
  {
    "path": "sys/netinet/ipfw/dn_sched_prio.c",
    "chars": 6349,
    "preview": "/*\n * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa\n * All rights reserved\n *\n * Redistribution and use in "
  },
  {
    "path": "sys/netinet/ipfw/dn_sched_qfq.c",
    "chars": 23376,
    "preview": "/*\n * Copyright (c) 2010 Fabio Checconi, Luigi Rizzo, Paolo Valente\n * All rights reserved\n *\n * Redistribution and use "
  },
  {
    "path": "sys/netinet/ipfw/dn_sched_rr.c",
    "chars": 7342,
    "preview": "/*\n * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa\n * All rights reserved\n *\n * Redistribution and use in "
  },
  {
    "path": "sys/netinet/ipfw/dn_sched_wf2q.c",
    "chars": 12146,
    "preview": "/*\n * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa\n * Copyright (c) 2000-2002 Luigi Rizzo, Universita` di "
  },
  {
    "path": "sys/netinet/ipfw/ip_dn_glue.c",
    "chars": 22773,
    "preview": "/*-\n * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa\n * All rights reserved\n *\n * Redistribution and use in"
  },
  {
    "path": "sys/netinet/ipfw/ip_dn_io.c",
    "chars": 27892,
    "preview": "/*-\n * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa\n * All rights reserved\n *\n * Redistributi"
  },
  {
    "path": "sys/netinet/ipfw/ip_dn_private.h",
    "chars": 13971,
    "preview": "/*-\n * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa\n * All rights reserved\n *\n * Redistributi"
  },
  {
    "path": "sys/netinet/ipfw/ip_dummynet.c",
    "chars": 62986,
    "preview": "/*-\n * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa\n * Portions Copyright (c) 2000 Akamba Corp.\n * All "
  },
  {
    "path": "sys/netinet/ipfw/ip_fw2.c",
    "chars": 66377,
    "preview": "/*-\n * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa\n *\n * Redistribution and use in source and binary forms,"
  },
  {
    "path": "sys/netinet/ipfw/ip_fw_dynamic.c",
    "chars": 33085,
    "preview": "/*-\n * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa\n *\n * Redistribution and use in source and binary forms, with"
  },
  {
    "path": "sys/netinet/ipfw/ip_fw_log.c",
    "chars": 11486,
    "preview": "/*-\n * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa\n *\n * Redistribution and use in source and binary forms,"
  },
  {
    "path": "sys/netinet/ipfw/ip_fw_lookup.c",
    "chars": 8283,
    "preview": "/*-\n * Copyright (c) 2009 Luigi Rizzo Universita` di Pisa\n *\n * Redistribution and use in source and binary forms, with "
  },
  {
    "path": "sys/netinet/ipfw/ip_fw_nat.c",
    "chars": 15719,
    "preview": "/*-\n * Copyright (c) 2008 Paolo Pisati\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, "
  },
  {
    "path": "sys/netinet/ipfw/ip_fw_pfil.c",
    "chars": 10436,
    "preview": "/*-\n * Copyright (c) 2004 Andre Oppermann, Internet Business Solutions AG\n * All rights reserved.\n *\n * Redistribution a"
  },
  {
    "path": "sys/netinet/ipfw/ip_fw_private.h",
    "chars": 9624,
    "preview": "/*-\n * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa\n *\n * Redistribution and use in source and binary forms,"
  },
  {
    "path": "sys/netinet/ipfw/ip_fw_sockopt.c",
    "chars": 33437,
    "preview": "/*-\n * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa\n *\n * Supported by: Valeria Paoli\n *\n * Redistribution a"
  },
  {
    "path": "sys/netinet/ipfw/ip_fw_table.c",
    "chars": 7455,
    "preview": "/*-\n * Copyright (c) 2004 Ruslan Ermilov and Vsevolod Lobko.\n *\n * Redistribution and use in source and binary forms, wi"
  },
  {
    "path": "sys/netinet/tcp.h",
    "chars": 7988,
    "preview": "/*-\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redist"
  },
  {
    "path": "sys/netinet/tcp_var.h",
    "chars": 115,
    "preview": "#ifndef _NETINET_TCP_VAR_H_\n#define _NETINET_TCP_VAR_H_\n#include <netinet/tcp.h>\n#endif /* !_NETINET_TCP_VAR_H_ */\n"
  },
  {
    "path": "sys/netinet/udp.h",
    "chars": 2501,
    "preview": "/*-\n * Copyright (c) 1982, 1986, 1993\n *\tThe Regents of the University of California.\n * All rights reserved.\n *\n * Redi"
  },
  {
    "path": "sys/sys/cdefs.h",
    "chars": 696,
    "preview": "#ifndef _CDEFS_H_\n#define _CDEFS_H_\n\n/*\n * various compiler macros and common functions\n */\n\n#ifndef __packed\n#define __"
  },
  {
    "path": "sys/sys/kernel.h",
    "chars": 766,
    "preview": "/*\n * from freebsd's kernel.h\n */\n#ifndef _SYS_KERNEL_H_\n#define _SYS_KERNEL_H_\n\n#define SYSINIT(a, b, c, d, e)  \\\n     "
  },
  {
    "path": "sys/sys/malloc.h",
    "chars": 2014,
    "preview": "#ifndef _SYS_MALLOC_H_\n#define _SYS_MALLOC_H_\n\n/*\n * No matter what, try to get clear memory and be non-blocking.\n * XXX"
  },
  {
    "path": "sys/sys/mbuf.h",
    "chars": 7256,
    "preview": "/*\n * Copyright (C) 2009 Luigi Rizzo, Universita` di Pisa\n *\n * BSD copyright.\n *\n * A simple compatibility interface to"
  },
  {
    "path": "sys/sys/module.h",
    "chars": 1000,
    "preview": "/*\n * trivial module support\n */\n#ifndef _SYS_MODULE_H_\n#define _SYS_MODULE_H_\ntypedef struct module *module_t;\ntypedef "
  },
  {
    "path": "sys/sys/param.h",
    "chars": 155,
    "preview": "#ifndef _SYS_PARAM_H_\n#define _SYS_PARAM_H_\n\n/*\n * number of additional groups\n */\n#ifndef LINUX_24\n#define NGROUPS\t\t16\n"
  },
  {
    "path": "sys/sys/queue.h",
    "chars": 20209,
    "preview": "/*-\n * Copyright (c) 1991, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistributi"
  },
  {
    "path": "sys/sys/syslog.h",
    "chars": 170,
    "preview": "#ifndef _SYS_SYSLOG_H_\n#define _SYS_SYSLOG_H_\n/* XXX find linux equivalent */\n#define LOG_SECURITY 0\n#define LOG_NOTICE "
  },
  {
    "path": "sys/sys/systm.h",
    "chars": 3589,
    "preview": "#ifndef _SYS_SYSTM_H_\n#define _SYS_SYSTM_H_\n\n#define CALLOUT_ACTIVE          0x0002 /* callout is currently active */\n#d"
  },
  {
    "path": "sys/sys/taskqueue.h",
    "chars": 867,
    "preview": "#ifndef _SYS_TASKQUEUE_H_\n#define _SYS_TASKQUEUE_H_\n\n/*\n * Remap taskqueue to direct calls\n */\n\n#ifdef _WIN32\nstruct tas"
  },
  {
    "path": "tcc_glue.h",
    "chars": 7141,
    "preview": "/*\n * Copyright (c) 2010 Luigi Rizzo, Universita` di Pisa\n *\n * Redistribution and use in source and binary forms, with "
  },
  {
    "path": "test/Makefile",
    "chars": 1185,
    "preview": "#\n# $Id: Makefile 5626 2010-03-04 21:55:22Z luigi $\n#\n# Makefile for building userland tests\n# this is written in a form"
  },
  {
    "path": "test/basic_ipfw.sh",
    "chars": 1868,
    "preview": "#!/bin/sh\n\nIPFW=./ipfw/ipfw\nPING=/bin/ping\nRH=127.0.0.1\t\t# remote host\nR=10\t\t\t# test rule number\nP=1\t\t\t# test pipe numbe"
  },
  {
    "path": "test/dn_test.h",
    "chars": 3219,
    "preview": "/*\n * $Id: dn_test.h 5626 2010-03-04 21:55:22Z luigi $\n *\n * userspace compatibility code for dummynet schedulers\n */\n\n#"
  },
  {
    "path": "test/dynrules.sh",
    "chars": 462,
    "preview": "#!/bin/sh\n#\n# 20100507 marta, quick test for dyn rules\n# ./ipfw/ipfw -d show |grep \\ 80\n\nIPFW_MOD=dummynet2/ipfw_mod.ko\n"
  },
  {
    "path": "test/interpolation.c",
    "chars": 8389,
    "preview": "#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n\n/* gcc interpolation.c -o interpolation */\n\nvoid    \nerr(int"
  },
  {
    "path": "test/main.c",
    "chars": 15761,
    "preview": "/*\n * $Id: main.c 5626 2010-03-04 21:55:22Z luigi $\n *\n * Testing program for schedulers\n *\n * The framework include a s"
  },
  {
    "path": "test/memory_leak.sh",
    "chars": 574,
    "preview": "#!/bin/sh\n# this script execute N times the command CMD\n# collecting the memory usage on a file.\n# The value of the Dirt"
  },
  {
    "path": "test/mylist.h",
    "chars": 1088,
    "preview": "/*\n * $Id: mylist.h 5626 2010-03-04 21:55:22Z luigi $\n *\n * linux-like bidirectional lists\n */\n\n#ifndef _MYLIST_H\n#defin"
  },
  {
    "path": "test/profile_bench1",
    "chars": 334,
    "preview": "profile_no 100\ndelay prob\n207 0.000264\n255 0.034117\n270 0.072280\n279 0.106749\n288 0.148604\n298 0.184304\n302 0.202194\n353"
  },
  {
    "path": "test/profile_bench2",
    "chars": 54,
    "preview": "samples 10\ndelay prob\n0 0\n250 0\n250 0.5\n500 0.5\n500 1\n"
  },
  {
    "path": "test/profile_bench3",
    "chars": 43,
    "preview": "profile_no 100\ndelay prob\n0 0\n50 0.5\n100 1\n"
  },
  {
    "path": "test/test_dn_heap.c",
    "chars": 4408,
    "preview": "/*-\n * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa\n * All rights reserved\n *\n * Redistribution and use"
  },
  {
    "path": "test/test_dn_sched.c",
    "chars": 1693,
    "preview": "/*\n * $Id: test_dn_sched.c 5626 2010-03-04 21:55:22Z luigi $\n *\n * library functions for userland testing of dummynet sc"
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the luigirizzo/dummynet GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 120 files (1.1 MB), approximately 346.6k tokens, and a symbol index with 1239 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!