# Please read and meditate on netgraph(4), ipacctctl(8) and ngctl(8).

# Enable ng_ipacct (i.e. enable run startup script "ng_ipacct.sh")
#ng_ipacct_enable="YES"

# Enable kernel modules loading.
# On "ng_ipacct.sh start" all kernel modules specified
# in ${ng_ipacct_modules_list} will be loaded.
# Note: on "ng_ipacct.sh stop" only "ng_ipacct" will be unloaded.
ng_ipacct_modules_load="YES"

# Netgraph can load required ng_* modules automatically on the hook creation
# - except for "ng_ether". Generally, modules preloading is recommended.
# Do not add to this list modules which are statically compiled into kernel.
#ng_ipacct_modules_list="netgraph ng_ether ng_cisco ng_socket ng_tee ng_ipacct"
ng_ipacct_modules_list="netgraph ng_ether ng_ipacct"

# List of monitored interfaces. For each interface additional vars must be
# specified in corresponding variables 'ng_ipacct_IFACE_*'.
# See examples below.
#ng_ipacct_interfaces="xl0 cx0 vpn0"

# Default start/stop scripts.
#
# Single quotes are required to preserve newlines.
# '%%iface%%' will be automatically expanded with a relevant interface.
# This feature should be applied to use indentical rules
# for similar interfaces.
ng_ipacct_default_ether_start='
	mkpeer %%iface%%: tee lower right
	name %%iface%%:lower %%iface%%_tee
	connect %%iface%%: lower upper left

	mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
	name %%iface%%_tee:right2left %%iface%%_ip_acct
	connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
'

ng_ipacct_default_ether_stop='
	shutdown %%iface%%_ip_acct:
	shutdown %%iface%%_tee:
	shutdown %%iface%%:
'

ng_ipacct_bpf_ether_start='
	mkpeer %%iface%%: tee lower right
	name %%iface%%:lower %%iface%%_tee
	connect %%iface%%: lower upper left

	mkpeer %%iface%%_tee: bpf right2left %%iface%%_in
	name %%iface%%_tee:right2left %%iface%%_bpf
	connect %%iface%%_tee: right2left left2right %%iface%%_out
	
	mkpeer %%iface%%_bpf: ipacct %%iface%%_match_in %%iface%%_in
	name %%iface%%_bpf:%%iface%%_match_in %%iface%%_ip_acct
	connect %%iface%%_bpf: %%iface%%_ip_acct: %%iface%%_match_out %%iface%%_out
'

ng_ipacct_bpf_ether_stop='
	shutdown %%iface%%_ip_acct:
	shutdown %%iface%%_bpf:
	shutdown %%iface%%_tee:
	shutdown %%iface%%:
'

# EXAMPLE 1. Ethernet interface

#        +-------------------------------+
#        |                               |
#      (upper)              (left2right)-----------(xl0_in)
#        |                      |        |             |
#       xl0         +--(left)-xl0_tee-(right)     xl0_ip_acct
#        |          |           |                      |
#      (lower)      |       (right2left)-----------(xl0_out)
#        |          |
#        +----------+
#
# xl0           - ng_ether
# xl0_tee       - ng_tee
# xl0_ip_acct   - ng_ipacct

# Configuration for 'xl0_ip_acct' node:

ng_ipacct_xl0_dlt="EN10MB"	# required line; see ipacctctl(8)
ng_ipacct_xl0_threshold="15000"	# '5000' by default
ng_ipacct_xl0_verbose="yes"	# 'yes' by default
ng_ipacct_xl0_saveuid="yes"	# 'no' by default
ng_ipacct_xl0_savetime="no"	# 'no' by default
ng_ipacct_xl0_start=${ng_ipacct_default_ether_start}
ng_ipacct_xl0_stop=${ng_ipacct_default_ether_stop}
ng_ipacct_xl0_checkpoint_script="path/to/your/script --checkpoint-and-save xl0"
			# this script is called on "stop" (to save accumulated 
			# data) or via "rc.d/ng_ipacct.sh checkpoint"

# EXAMPLE 2. Cronyx Sigma WAN adapter with HDLC encapsulation 

# cx0_hdlc-(downstream)----(rawdata)-cx0
#    |
# (inet)  (left2right)--------------------(cx0_in)
#    |      |                                |
# (left)-cx0_tee-(right)---(inet)-ng0     cx0_ip_acct
#           |                                |
#         (right2left)--------------------(cx0_out)
#
# cx0           - ng_cx
# cx0_hdlc      - ng_cisco
# cx0_tee       - ng_tee
# cx0_ip_acct   - ng_ipacct

# Configuration for 'cx0_ip_acct' node:

ng_ipacct_cx0_dlt="RAW"
ng_ipacct_cx0_start='
	mkpeer %%iface%%: cisco rawdata downstream
	name %%iface%%:rawdata %%iface%%_hdlc
	mkpeer %%iface%%_hdlc: tee inet left
	name %%iface%%_hdlc:inet %%iface%%_tee
	mkpeer %%iface%%_tee: iface right inet

	mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
	name %%iface%%_tee:right2left %%iface%%_ip_acct
	connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
'
ng_ipacct_cx0_stop='
	shutdown %%iface%%_ip_acct:
	shutdown %%iface%%_tee:
	shutdown %%iface%%_hdlc:
'

# EXAMPLE 3. PPTP (via mpd), divert traffic to ng_ksocket

# ipfw add tee 4001 ip from any to any via ng0 in
# ipfw add tee 4002 ip from any to any via ng0 out

#      USER-LEVEL	|	KERNEL-LEVEL
# 			|
# div4	*.4001	------>	| ----> ks_vpn0_in
#			|	    |
#			|    (inet/raw/divert)------(vpn0_in)
#			|				|
#			|			   vpn0_ip_acct
#			|				|
#			|    (inet/raw/divert)------(vpn0_out)
#			|	    |
# div4	*.4002	------>	| ----> ks_vpn0_out
#
# ks_vpn0_in	- ng_ksocket
# ks_vpn0_out	- ng_ksocket
# vpn0_ip_acct	- ng_ipacct

ng_ipacct_vpn0_dlt="RAW"
ng_ipacct_vpn0_start='
	mkpeer ipacct dummy dummy
	name .:dummy %%iface%%_ip_acct

	mkpeer %%iface%%_ip_acct: ksocket  %%iface%%_in inet/raw/divert
	name %%iface%%_ip_acct:%%iface%%_in  ks_%%iface%%_in
	msg ks_%%iface%%_in:  bind inet/0.0.0.0:4001

	mkpeer %%iface%%_ip_acct: ksocket %%iface%%_out inet/raw/divert
	name %%iface%%_ip_acct:%%iface%%_out ks_%%iface%%_out
	msg ks_%%iface%%_out: bind inet/0.0.0.0:4002

	rmhook .:dummy
'
ng_ipacct_vpn0_stop='
	shutdown %%iface%%_ip_acct:
'

# EXAMPLE 4. Ethernet interface with BPF

#   +-------------------------------+
#   |                               |
# (upper)              (left2right)-----(xl0_in) (xl0_match_in)----(xl0_in)
#   |                      |        |        |     |                    |
#  xl0         +--(left)-xl0_tee-(right)     xl0_bpf               xl0_ip_acct
#   |          |           |                 |     |                    |
# (lower)      |       (right2left)----(xl0_out) (xl0_match_out)--(xl0_out)
#   |          |
#   +----------+
#
# xl0           - ng_ether
# xl0_tee       - ng_tee
# xl0_bpf       - ng_bpf
# xl0_ip_acct   - ng_ipacct

# Configuration for 'xl0_ip_acct' node:

ng_ipacct_xl0_dlt="EN10MB"	# required line; see ipacctctl(8)
ng_ipacct_xl0_threshold="15000"	# '5000' by default
ng_ipacct_xl0_verbose="yes"	# 'yes' by default
ng_ipacct_xl0_saveuid="yes"	# 'no' by default
ng_ipacct_xl0_savetime="no"	# 'no' by default
ng_ipacct_xl0_start=${ng_ipacct_bpf_ether_start}
ng_ipacct_xl0_stop=${ng_ipacct_bpf_ether_stop}
ng_ipacct_xl0_checkpoint_script="path/to/your/script --checkpoint-and-save xl0"
			# this script is called on "stop" (to save accumulated 
			# data) or via "rc.d/ng_ipacct.sh checkpoint"
ng_ipacct_xl0_afterstart_script="path/to/your/script --load-bpf-filters xl0"
			# this script is called just after initialization
			# of nodes to load filters into xl0_bpf

# EXAMPLE 5. Really _divert_ traffic to ng_ksocket

# ipfw add divert 4001 ip from any to any via em0 in
# ipfw add divert 4002 ip from any to any via em0 out

#    USER-LEVEL | KERNEL-LEVEL
#               |
# div4 *.4001 ->|-> ipfw_ks_in                              in-(ipfw_echo_in)
#               |       |                                   |
#               | (inet/raw/divert)---(left)-(ipfw_tee_in)-right
#               |                                |
#               |                            left2right---(ipfw_in)
#               |			                |
#               |		                    ipfw_ip_acct
#               |			                |
#               |                            left2right---(ipfw_out)
#               |                                |
#               | (inet/raw/divert)---(left)-(ipfw_tee_out)-right
#               |       |                                    |
# div4 *.4002 ->|-> ipfw_ks_out                              out-(ipfw_echo_out)
#
# ipfw_ks_in	- ng_ksocket
# ipfw_ks_out	- ng_ksocket
# ipfw_tee_in	- ng_tee
# ipfw_tee_out	- ng_tee
# ipfw_ip_acct	- ng_ipacct
# ipfw_echo_in	- ng_echo
# ipfw_echo_out	- ng_echo

ng_ipacct_ks_start='
	mkpeer ipacct dummy dummy
	name .:dummy %%iface%%_ip_acct

	mkpeer %%iface%%_ip_acct: tee  %%iface%%_in left2right
	name   %%iface%%_ip_acct:%%iface%%_in  %%iface%%_tee_in
	mkpeer %%iface%%_ip_acct: tee  %%iface%%_out left2right
	name   %%iface%%_ip_acct:%%iface%%_out %%iface%%_tee_out

	mkpeer %%iface%%_tee_in:  echo right in
	name   %%iface%%_tee_in:right  %%iface%%_echo_in
	mkpeer %%iface%%_tee_out: echo right out
	name   %%iface%%_tee_out:right %%iface%%_echo_out
	
	mkpeer %%iface%%_tee_in: ksocket  left inet/raw/divert
	name   %%iface%%_tee_in:left  %%iface%%_ks_in
	msg    %%iface%%_ks_in:  bind inet/0.0.0.0:4001

	mkpeer %%iface%%_tee_out: ksocket left inet/raw/divert
	name   %%iface%%_tee_out:left %%iface%%_ks_out
	msg    %%iface%%_ks_out: bind inet/0.0.0.0:4002

	rmhook .:dummy
'
ng_ipacct_ks_stop='
	shutdown %%iface%%_ks_in:
	shutdown %%iface%%_ks_out:
	shutdown %%iface%%_tee_in:
	shutdown %%iface%%_tee_out:
'
ng_ipacct_ks_dlt="RAW"		# required line; see ipacctctl(8)
ng_ipacct_ks_threshold="15000"	# '5000' by default
ng_ipacct_ks_verbose="yes"	# 'yes' by default
ng_ipacct_ks_saveuid="yes"	# 'no' by default
ng_ipacct_ks_savetime="no"	# 'no' by default
ng_ipacct_ks_checkpoint_script="path/to/your/script --checkpoint-and-save ks"
			# this script is called on "stop" (to save accumulated 
			# data) or via "rc.d/ng_ipacct.sh checkpoint"
