| Summary: | mistake in ng_bpf(4) manpage | ||
|---|---|---|---|
| Product: | Documentation | Reporter: | Eugenio Maffione <eugenio.maffione> |
| Component: | Books & Articles | Assignee: | Giorgos Keramidas <keramida> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Latest | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->freebsd-doc reclassify. On Wed, 30 Apr 2008 11:41:57 GMT, Eugenio Maffione <eugenio.maffione@telecomitalia.it> wrote: > I'm writing to you because I think to have found a little mistake in > the ng_bpf man page. > > Actually the mistake is in the script proposed in the manpage. Good catch :) > I notice that in some cases the statement > printf " { code=%d jt=%d jf=%d k=%d }", \$1, \$2, \$3, \$4; > causes an incorrect programming of the bpf filter. > > This happens when the "k" value exceed the MAX_INTEGER value as when, > for example, the tcpdump expression refers a network where the the > first octect is greater than 128. > > In that case the awk generates a negative value for "k" and the bpf > matches always (I don't understand why, but it happens). ACK. I can reproduce this here. > This happens when the "k" value exceed the MAX_INTEGER value as when, > for example, the tcpdump expression refers a network where the the > first octect is greater than 128. (e.g . PATTERN="udp and dst net > 255.255.0.0/16") We don't really need awk for that. A simple shell script will also do: : $ sudo tcpdump -s 8192 -ddd "udp and dst net 255.255.0.0/16" | \ : ( read len ; \ : echo "bpf_prog_len=$len" ; \ : echo "bpf_prog=[" ; \ : while read code jt jf k ; do \ : echo "{ code=$code jt=$jt jf=$jf k=$k }" ; \ : done ; \ : echo "]" ) This yields: : bpf_prog_len=10 : bpf_prog=[ : { code=40 jt=0 jf=0 k=12 } : { code=21 jt=7 jf=0 k=34525 } : { code=21 jt=0 jf=6 k=2048 } : { code=48 jt=0 jf=0 k=23 } : { code=21 jt=0 jf=4 k=17 } : { code=32 jt=0 jf=0 k=30 } : { code=84 jt=0 jf=0 k=4294901760 } : { code=21 jt=0 jf=1 k=4294901760 } : { code=6 jt=0 jf=0 k=8192 } : { code=6 jt=0 jf=0 k=0 } : ] I'll replace the awk version with the shell code, if there are no objections in the next few days. Thank you for reporting what you noticed, and the for excellent analysis of why it happens :-) State Changed From-To: open->analyzed I'll handle this. Responsible Changed From-To: freebsd-doc->keramida State Changed From-To: analyzed->patched Fixed in head. I will merge the new example to the stable/6 and stable/7 branches in a few days. Author: keramida (doc committer) Date: Fri Jan 30 19:33:04 2009 New Revision: 187935 URL: http://svn.freebsd.org/changeset/base/187935 Log: Sometimes, depending on the bpf filter rules used in $PATTERN, the example script of the manpage feeds awk(1) with values larger than UINT32_MAX. Then awk prints a negative value, and this messes up $BPFPROG. Trying to load the resulting bpf byte codes with ngctl then fails. For example, the output for PATTERN="udp and dst net 255.255.0.0/16" should be (all in one line): bpf_prog_len=10 bpf_prog=[ { code=40 jt=0 jf=0 k=12 } { code=21 jt=7 jf=0 k=34525 } { code=21 jt=0 jf=6 k=2048 } { code=48 jt=0 jf=0 k=23 } { code=21 jt=0 jf=4 k=17 } { code=32 jt=0 jf=0 k=30 } { code=84 jt=0 jf=0 k=4294901760 } { code=21 jt=0 jf=1 k=4294901760 } { code=6 jt=0 jf=0 k=8192 } { code=6 jt=0 jf=0 k=0 } ] The two k=4294901760 values are displayed as k=-2147483648 by awk. Replace the awk script of the manpage example with a slower but safer version, that doesn't really attempt to convert the byte code printed by tcpdump from string to number and back. PR: docs/123255 Submitted by: Eugenio Maffione, eugenio.maffione at telecomitalia.it MFC after: 3 days Modified: head/share/man/man4/ng_bpf.4 Modified: head/share/man/man4/ng_bpf.4 ============================================================================== --- head/share/man/man4/ng_bpf.4 Fri Jan 30 18:34:54 2009 (r187934) +++ head/share/man/man4/ng_bpf.4 Fri Jan 30 19:33:04 2009 (r187935) @@ -156,21 +156,14 @@ INHOOK="hook1" MATCHHOOK="hook2" NOTMATCHHOOK="hook3" -cat > /tmp/bpf.awk << xxENDxx -{ - if (!init) { - printf "bpf_prog_len=%d bpf_prog=[", \\$1; - init=1; - } else { - printf " { code=%d jt=%d jf=%d k=%d }", \\$1, \\$2, \\$3, \\$4; - } -} -END { - print " ]" -} -xxENDxx - -BPFPROG=`tcpdump -s 8192 -ddd ${PATTERN} | awk -f /tmp/bpf.awk` +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 " ]" ) ) ngctl msg ${NODEPATH} setprogram { thisHook=\\"${INHOOK}\\" \\ ifMatch=\\"${MATCHHOOK}\\" \\ _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" Author: keramida (doc committer) Date: Mon Feb 2 04:57:36 2009 New Revision: 187999 URL: http://svn.freebsd.org/changeset/base/187999 Log: MFC 187935 from /head Sometimes, depending on the bpf filter rules used in $PATTERN, the example script of the manpage feeds awk(1) with values larger than UINT32_MAX. Then awk prints a negative value, and this messes up $BPFPROG. Trying to load the resulting bpf byte codes with ngctl then fails. For example, the output for PATTERN="udp and dst net 255.255.0.0/16" should be (all in one line): bpf_prog_len=10 bpf_prog=[ { code=40 jt=0 jf=0 k=12 } { code=21 jt=7 jf=0 k=34525 } { code=21 jt=0 jf=6 k=2048 } { code=48 jt=0 jf=0 k=23 } { code=21 jt=0 jf=4 k=17 } { code=32 jt=0 jf=0 k=30 } { code=84 jt=0 jf=0 k=4294901760 } { code=21 jt=0 jf=1 k=4294901760 } { code=6 jt=0 jf=0 k=8192 } { code=6 jt=0 jf=0 k=0 } ] The two k=4294901760 values are displayed as k=-2147483648 by awk. Replace the awk script of the manpage example with a slower but safer version, that doesn't really attempt to convert the byte code printed by tcpdump from string to number and back. PR: docs/123255 Submitted by: Eugenio Maffione, eugenio.maffione at telecomitalia.it Modified: stable/7/share/man/man4/ (props changed) stable/7/share/man/man4/igb.4 (props changed) stable/7/share/man/man4/ng_bpf.4 Modified: stable/7/share/man/man4/ng_bpf.4 ============================================================================== --- stable/7/share/man/man4/ng_bpf.4 Mon Feb 2 04:53:39 2009 (r187998) +++ stable/7/share/man/man4/ng_bpf.4 Mon Feb 2 04:57:36 2009 (r187999) @@ -156,21 +156,14 @@ INHOOK="hook1" MATCHHOOK="hook2" NOTMATCHHOOK="hook3" -cat > /tmp/bpf.awk << xxENDxx -{ - if (!init) { - printf "bpf_prog_len=%d bpf_prog=[", \\$1; - init=1; - } else { - printf " { code=%d jt=%d jf=%d k=%d }", \\$1, \\$2, \\$3, \\$4; - } -} -END { - print " ]" -} -xxENDxx - -BPFPROG=`tcpdump -s 8192 -ddd ${PATTERN} | awk -f /tmp/bpf.awk` +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 " ]" ) ) ngctl msg ${NODEPATH} setprogram { thisHook=\\"${INHOOK}\\" \\ ifMatch=\\"${MATCHHOOK}\\" \\ _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" Author: keramida (doc committer) Date: Mon Feb 2 04:59:00 2009 New Revision: 188000 URL: http://svn.freebsd.org/changeset/base/188000 Log: MFC 187935 from /head Sometimes, depending on the bpf filter rules used in $PATTERN, the example script of the manpage feeds awk(1) with values larger than UINT32_MAX. Then awk prints a negative value, and this messes up $BPFPROG. Trying to load the resulting bpf byte codes with ngctl then fails. For example, the output for PATTERN="udp and dst net 255.255.0.0/16" should be (all in one line): bpf_prog_len=10 bpf_prog=[ { code=40 jt=0 jf=0 k=12 } { code=21 jt=7 jf=0 k=34525 } { code=21 jt=0 jf=6 k=2048 } { code=48 jt=0 jf=0 k=23 } { code=21 jt=0 jf=4 k=17 } { code=32 jt=0 jf=0 k=30 } { code=84 jt=0 jf=0 k=4294901760 } { code=21 jt=0 jf=1 k=4294901760 } { code=6 jt=0 jf=0 k=8192 } { code=6 jt=0 jf=0 k=0 } ] The two k=4294901760 values are displayed as k=-2147483648 by awk. Replace the awk script of the manpage example with a slower but safer version, that doesn't really attempt to convert the byte code printed by tcpdump from string to number and back. PR: docs/123255 Submitted by: Eugenio Maffione, eugenio.maffione at telecomitalia.it Modified: stable/6/share/man/man4/ (props changed) stable/6/share/man/man4/ng_bpf.4 stable/6/share/man/man4/xl.4 (props changed) Modified: stable/6/share/man/man4/ng_bpf.4 ============================================================================== --- stable/6/share/man/man4/ng_bpf.4 Mon Feb 2 04:57:36 2009 (r187999) +++ stable/6/share/man/man4/ng_bpf.4 Mon Feb 2 04:59:00 2009 (r188000) @@ -156,21 +156,14 @@ INHOOK="hook1" MATCHHOOK="hook2" NOTMATCHHOOK="hook3" -cat > /tmp/bpf.awk << xxENDxx -{ - if (!init) { - printf "bpf_prog_len=%d bpf_prog=[", \\$1; - init=1; - } else { - printf " { code=%d jt=%d jf=%d k=%d }", \\$1, \\$2, \\$3, \\$4; - } -} -END { - print " ]" -} -xxENDxx - -BPFPROG=`tcpdump -s 8192 -ddd ${PATTERN} | awk -f /tmp/bpf.awk` +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 " ]" ) ) ngctl msg ${NODEPATH} setprogram { thisHook=\\"${INHOOK}\\" \\ ifMatch=\\"${MATCHHOOK}\\" \\ _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" State Changed From-To: patched->closed Thanks for submitting the original problem to Gnats, and for being patient while I pondered about a good way to solve this. I have merged the fix to the stable/6 [r188000] and the stable/7 [r187999] branches now. |
I'm writing to you because I think to have found a little mistake in the ng_bpf man page. Actually the mistake is in the script proposed in the manpage. I notice that in some cases the statement printf " { code=%d jt=%d jf=%d k=%d }", \$1, \$2, \$3, \$4; causes an incorrect programming of the bpf filter. This happens when the "k" value exceed the MAX_INTEGER value as when, for example, the tcpdump expression refers a network where the the first octect is greater than 128. In that case the awk generates a negative value for "k" and the bpf matches always (I don't understand why, but it happens). Fix: I tried to change the printf statement changing the format for using a conversion to unsigned (%u) but the poor result is to have the absolute value of "k" (so just deleting the minus) [this probably is a problem in awk]. Finallly, I've found that the working one format for the printg in the manpage is " { code=%d jt=%d jf=%d k=%s }" that preserves the right unsigned integer values. Hopefully this help some other novice... How-To-Repeat: This happens when the "k" value exceed the MAX_INTEGER value as when, for example, the tcpdump expression refers a network where the the first octect is greater than 128. (e.g . PATTERN="udp and dst net 255.255.0.0/16")