# netgraph experimentation



## schmurfy (May 17, 2010)

Hi,
after some time I think I now have a way to solve my problem (http://forums.freebsd.org/showthread.php?t=13837) so I dived in everything i could find related to netgraph and the ng_bpf node type and I have to say netgraph is really an awesome piece of software 

To tried to apply my recent knowledge to a real case and so set up a bpf filter dropping all icmp packets coming from the outside on one of the interfaces of my freebsd box but it seems there is still something I miss or do not understand as it does not work at all  (I know there are other and simpler way to do that that is not the point here)

Here my current state ($IF is my interface, I have ng_ether, ng_socket and ng_bpf modules loaded):


```
$ ngctl
+ mkpeer $IF: bpf lower input
+ name $IF:lower bpf0
+ connect bpf0: $IF: nomatch upper
```

I used a bash script from the ng_bpf manpage (source at the bottom of this post) to create this line and feed the bpf node following:


```
+ msg bpf0: setprogram { thisHook="input" ifMatch="match" ifNotMatch="nomatch" bpf_prog_len=6 bpf_prog=[ { code=40 jt=0 jf=0 k=12 } { 
code=21 jt=0 jf=3 k=2048 } { code=48 jt=0 jf=0 k=23 } { code=21 jt=0 jf=1 k=1 } { code=6 jt=0 jf=0 k=8192 } { code=6 jt=0 jf=0 k=0 } ] }
```

Now if my understanding of all this is correct I should have every packet entering my box via the $IF interface flow through the $IF:lower hook to the bpf node and then depending on whether it matched the filter or not exit this node on match or nomatch hooks (I tried to connect each to the upper hooks of $IF with no visible change) and then if the packet does no match the bpf filter it should exits through the nomatch hooks connected to the upper hooks of $IF and then be handled by the system as if nothing happened.

Am I misunderstanding something here ? From everything I read I am sure I am not far for making this works but it does not :\

The bash script to create the bpf program:

```
PATTERN="icmp"
NODEPATH="bpf0:"
INHOOK="input"
MATCHHOOK="match"
NOTMATCHHOOK="nomatch"

BPFPROG=$( tcpdump -s 8192 -ddd ${PATTERN} | \
           ( read len ; \
             echo -n "bpf_prog_len=$len" ; \
             echo -n "bpf_prog=[" ; \
             while read code jt jf k ; do \
                 echo -n " { code=$code jt=$jt jf=$jf k=$k }" ; \
             done ; \
             echo " ]" ) )


echo ngctl msg ${NODEPATH} setprogram { thisHook=\"${INHOOK}\" \
  ifMatch=\"${MATCHHOOK}\" \
  ifNotMatch=\"${NOTMATCHHOOK}\" \
  ${BPFPROG} }
```

Thanks for any help, I am sure awesome things could done by the pf/netgraph combination and I have some I really wish to try


----------



## schmurfy (May 20, 2010)

nobody uses netgraph ?


----------



## schmurfy (Jun 5, 2010)

I found the answer, here it is for the records (this example will block any icmp packet coming from the outside and let everything from the inside go out):


```
ngctl
+ mkpeer lan: npf lower input
+ name lan:lower bpf0
+ connect bpf0: lan: nomatch upper
+ msg bpf0: setprogram { thisHook="input" ifMatch="match" ifNotMatch="nomatch" \
 bpf_prog_len=6 bpf_prog=[ { code=40 jt=0 jf=0 k=12 } { code=21 jt=0 jf=3 k=2048 } \
  { code=48 jt=0 jf=0 k=23 } { code=21 jt=0 jf=1 k=1 } { code=6 jt=0 jf=0 k=8192 } \
  { code=6 jt=0 jf=0 k=0 } ] }
+ msg bpf0: setprogram { thisHook="nomatch" ifMatch="out" ifNotMatch="input" \
 bpf_prog_len=1 bpf_prog=[ { code=6 jt=0 jf=0 k=8192 } ] }
```

I simply did not took in account that you have to set 2 bpf filters, one for each traffic direction (inside => outside and outside => inside).


----------

