Author: wmb Date: 2009-09-25 03:46:29 +0200 (Fri, 25 Sep 2009) New Revision: 1379
Added: ofw/inet/capture.fth Modified: ofw/inet/ethernet.fth ofw/inet/loadpkg.fth Log: Added "capture" feature for Ethernet packet logging in pcap format, viewable by tcpdump and wireshark. Thanks to Luke Gorrie.
Added: ofw/inet/capture.fth =================================================================== --- ofw/inet/capture.fth (rev 0) +++ ofw/inet/capture.fth 2009-09-25 01:46:29 UTC (rev 1379) @@ -0,0 +1,105 @@ +\ See license at end of file +purpose: Capture ethernet packets into PCAP-format trace files +\ PCAP is the file format used by tcpdump and wireshark etc. +\ Spec: http://wiki.wireshark.org/Development/LibpcapFileFormat + +\ NOTE: This program does not economise on calls to fputs. should it? + +headerless + +0 value capture-file +d# 64 value capture-length +0 value #captured + +\ Write n-byte integers in host byte order. there's probably a simpler way.. +variable buffer +: write32 ( u -- ) buffer ! buffer 4 capture-file fputs ; +: write16 ( u -- ) buffer w! buffer 2 capture-file fputs ; + +: snaplen ( len -- snaplen ) capture-length min ; +: write-seconds ( ms -- ) d# 1000 / write32 ; +: write-microseconds ( ms -- ) d# 1000 mod d# 1000 * write32 ; +: write-timestamp ( -- ) get-msecs dup write-seconds write-microseconds ; + +: write-packet ( adr len -- ) + write-timestamp ( adr len ) + dup snaplen write32 ( adr len ) + dup write32 ( adr len ) + snaplen capture-file fputs ( ) +; + +: capture-packet ( adr len -- adr len ) + 2dup write-packet ( adr len ) + #captured 1+ to #captured ( adr len ) +; + +: install-hooks ( -- ) + ['] capture-packet to send-ethernet-packet-hook + ['] capture-packet to receive-ethernet-packet-hook +; + +: uninstall-hooks ( -- ) + ['] noop to send-ethernet-packet-hook + ['] noop to receive-ethernet-packet-hook +; + +headers + +: stop-capture ( -- ) + capture-file close-file + 0 to capture-file + uninstall-hooks +; + +: start-capture ( fileid -- ) + to capture-file + 0 to #captured + h# a1b2c3d4 write32 \ magic (host byte order) + 2 write16 \ major version + 4 write16 \ minor version + 0 write32 \ gmt offset - ignore + 0 write32 \ timestamp accuracy - ignore + capture-length write32 \ per-packet capture length + 1 write32 \ data link type (1 = ethernet) + install-hooks +; + +also forth definitions +: capture ( "file" -- ) + safe-parse-word r/w create-file abort" couldn't create capture file" + start-capture +; + +: .capture ( -- ) + capture-file if + ." Capture enabled: " #captured . ." packet(s) captured." cr + else + ." Capture not enabled" + then +; +previous definitions + +\ LICENSE_BEGIN +\ Copyright (c) 2009 Luke Gorrie +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END +
Modified: ofw/inet/ethernet.fth =================================================================== --- ofw/inet/ethernet.fth 2009-09-25 01:44:24 UTC (rev 1378) +++ ofw/inet/ethernet.fth 2009-09-25 01:46:29 UTC (rev 1379) @@ -10,6 +10,9 @@ 0 instance value (link-mtu) \ max packet size 0 instance value packet-buffer
+defer send-ethernet-packet-hook ' noop is send-ethernet-packet-hook +defer receive-ethernet-packet-hook ' noop is receive-ethernet-packet-hook + \ Determine the Ethernet address for his-ip-addr instance defer resolve-en-addr ( 'dest-adr type -- 'en-adr type ) \ will be set later @@ -115,6 +118,8 @@ pause packet-buffer link-mtu " read" $call-parent ( type length|-error ) dup 0> if ( type length ) + packet-buffer swap ( type packet length ) + receive-ethernet-packet-hook nip ( type length ) select-ethernet-header ( type length ) over en-type xw@ = if ( type length ) nip /ether-header payload false exit ( adr len false ) @@ -146,7 +151,9 @@ en-type xw! ( data-len ) my-en-addr en-source-addr copy-en-addr ( data-len )
- the-struct swap /ether-header + tuck " write" $call-parent ( len actual ) + the-struct swap /ether-header + ( data-adr data-len ) + send-ethernet-packet-hook ( data-adr data-len ) + tuck " write" $call-parent ( len actual ) <> if ." Network transmit error" cr then ;
Modified: ofw/inet/loadpkg.fth =================================================================== --- ofw/inet/loadpkg.fth 2009-09-25 01:44:24 UTC (rev 1378) +++ ofw/inet/loadpkg.fth 2009-09-25 01:46:29 UTC (rev 1379) @@ -16,3 +16,4 @@ fload ${BP}/ofw/inet/attr-ip.fth \ Save IP info in /chosen fload ${BP}/ofw/inet/encdec.fth \ Packet encoding/decoding primitives fload ${BP}/ofw/inet/dns.fth \ Domain name resolver (RFC1034/5) +fload ${BP}/ofw/inet/capture.fth \ Packet capture to PCAP files
openfirmware@openfirmware.info