roPcap
26 min
ropcap is used to analyze pcap files for udp traffic flows, prepare them for replay (optionally filtering and rewriting headers), replay them onto a network interface with drift free pacing, and extract raw udp payload streams from pcap captures it is available as of bos 9 1 143 if a message port is set via setport() , the object posts ropcapevent messages for replay lifecycle events (started, stopped, looped, underrun, dropped) only one ropcap instance may exist at a time createobject("ropcap") returns invalid if another instance is already alive if using tmp\ / you need to be mindful of how big the pcap is if its large, it won’t fit into a ram based tmp\ / and you should use local storage instead (for example, sd / ) ifpcap analyze(filename as string) as object scans all packets in filename and returns a roarray of roassociativearray , one entry per udp flow found flows are sorted by packet count in descending order returns an empty array if the file cannot be opened or contains no udp flows each entry in the returned array contains the following keys key type description src ip string source ipv4 address src port integer source udp port dst ip string destination ipv4 address dst port integer destination udp port packet count integer number of udp packets in the flow prepare(params as roassociativearray) as integer filters packets from the input pcap and writes a replay ready output pcap, optionally rewriting destination ip and udp port headers the source mac address and source ip address in every output packet are always rewritten to the values of the specified network interface if rewriteoutputdestaddress is a multicast address, the destination mac is derived using the rfc 1112 formula if it is a unicast address, the destination mac is resolved via the kernel arp cache; the destination must already be reachable (e g via a prior ping) before calling prepare() returns a pcapengineerror integer code; 0 on success see error codes /#error codes required parameters key type description inputfile string path to the source pcap file outputfile string path to write the prepared pcap (must differ from inputfile ) interface string network interface name used to resolve the source mac and ip (e g "eth0" ) optional filter parameters key type description filterinputsourceaddress string keep only packets with this ipv4 source address filterinputsourceport integer keep only udp packets from this source port (1024–65535) filterinputdestaddress string keep only packets with this ipv4 destination address filterinputdestport integer keep only udp packets to this destination port (1024–65535) autoflowselect boolean see note below optional rewrite parameters key type description rewriteoutputdestaddress string rewrite the destination ip address (unicast or multicast) rewriteoutputdestport integer rewrite the udp destination port (1024–65535) autoflowselect default behavior when no filterinput keys are supplied, autoflowselect defaults to true the flow with the highest packet count is selected automatically when any filterinput key is present, autoflowselect defaults to false if the filter criteria match more than one flow, prepare() returns pcap err ambiguous flow ( 7) instead of picking one an explicit autoflowselect key always overrides the default extractstream(params as roassociativearray) as integer concatenates the raw udp payload bytes of every matching packet in inputfile and writes them to outputfile no prior prepare() call is required this is useful for recovering the original byte stream from a udp capture — for example, extracting an mpeg ts file from a ts over udp recording the filter criteria must resolve to exactly one udp flow use autoflowselect to select the highest count flow automatically when the filter is broad returns a pcapengineerror integer code; 0 on success see error codes /#error codes may return pcap err read failed ( 8) if the input file is corrupt or truncated required parameters key type description inputfile string path to the source pcap file outputfile string path to write the extracted stream; created or truncated optional filter parameters same as prepare() filterinputsourceaddress , filterinputsourceport , filterinputdestaddress , filterinputdestport , autoflowselect (same default logic as prepare() ) start(params as roassociativearray) as boolean starts replaying the prepared pcap file on the specified network interface packets are paced at their original inter packet intervals using absolute monotonic timestamps so timing overshoot on one packet cannot accumulate into drift over subsequent packets blocks until the sender thread has started or failed to start posts a ropcapevent with type 1 (started) to the message port on success returns true on success; false if the sender thread could not be started required parameters key type description filename string path to the prepared pcap file to replay interface string network interface name to send on (e g "eth0" ) optional parameters key type description loopcount integer number of times to loop through the file; 0 (default) loops forever preloadintomemory boolean if true , loads the entire file into ram before replay begins (capped at 50% of total system ram) use this when deterministic per packet timing is required and the file fits comfortably in memory default is streaming mode, which reads from disk with a 20 mib readahead buffer and is suitable for any file size stop() as void returns true while the sender thread is executing the replay loop returns false once the loop count is exhausted, stop() is called, or a fatal error occurs after start() returned true getstats() as roassociativearray returns a snapshot of replay statistics safe to call at any time, including while replay is running key type description packets sent integer frames successfully transmitted since the last start() packets dropped integer frames dropped due to no buffer space / busy, since the last start() loops completed integer full loop passes that have finished cleanly underruns integer times the streaming readahead buffer was empty; always 0 when preloadintomemory is true elapsed ms integer wall clock milliseconds since the last start() or resetstats() call; 0 when stopped timing sample count integer number of packets contributing to the timing fields below timing mean us integer mean timing error in microseconds; positive means the packet went out late, negative means early timing min us integer minimum (most early) timing error in microseconds timing max us integer maximum (most late) timing error in microseconds timing stddev us integer sample standard deviation of timing error in microseconds timing fields are 0 until at least one packet has been sent resetstats() as void resets all replay statistics to zero safe to call while replay is running counters updated by the replay thread after the call reflect only activity since the reset ifmessageport setport(port as romessageport) posts messages of type ropcapevent to the attached message port ifuserdata setuserdata(user data as object) sets the user data that will be returned when events are raised getuserdata() as object returns the user data previously set via setuserdata() returns invalid if no data has been set ropcapevent ropcapevent is posted to the message port set on ropcap whenever a replay lifecycle event occurs ifpcapevent getint() as integer returns the event type code value name description 1 started replay thread started and is sending packets 2 stopped replay thread stopped (loop count exhausted, stop() called, or fatal error) 3 looped one full pass completed; getdata() returns the 1 indexed loop number 4 underrun streaming readahead buffer was empty; replay timing may have been affected 5 dropped a packet was dropped; getdata() returns the cumulative drop count at the time of the drop getdata() as integer returns event specific data see the table above returns 0 for events where no additional data applies error codes prepare() and extractstream() return one of the following integer codes value name description 0 pcap ok success 1 pcap err file not found inputfile does not exist or cannot be opened 2 pcap err invalid flow port a port value is outside the valid range \[1024, 65535] 3 pcap err write failed outputfile could not be written 4 pcap err invalid interface the interface name is invalid or not found on the system 5 pcap err invalid param an invalid parameter was supplied bad ip address format, inputfile and outputfile are the same path, or a unicast rewriteoutputdestaddress could not be resolved to a mac via arp 6 pcap err no matching flow the filter criteria matched no flows; supply a less restrictive filter or verify the input file contains the expected traffic 7 pcap err ambiguous flow the filter criteria matched more than one distinct flow; tighten the filter to select exactly one, or set autoflowselect true to pick the highest count flow automatically 8 pcap err read failed extractstream() only the input file is corrupt or truncated examples analyze a pcap file print all udp flows found in a capture file pcap = createobject("ropcap") flows = pcap analyze("sd /capture pcap") for each flow in flows print flow\ src ip + " " + flow\ src port tostr() + " > " + flow\ dst ip + " " + flow\ dst port tostr() + " packets=" + flow\ packet count tostr() end for prepare and replay with event handling select a flow, rewrite it to a local multicast group, and replay it three times while monitoring events pcap = createobject("ropcap") port = createobject("romessageport") pcap setport(port) ' step 1 — inspect the capture to find the flow flows = pcap analyze("sd /source pcap") if flows count() = 0 print "no udp flows found" stop end if ' step 2 — prepare filter to the largest flow, rewrite destination params = createobject("roassociativearray") params inputfile = "sd /source pcap" params outputfile = "tmp\ /prepared pcap" params interface = "eth0" ' autoflowselect defaults to true when no filterinput keys are given, ' so the highest count flow is selected automatically params rewriteoutputdestaddress = "239 1 2 3" params rewriteoutputdestport = 1234 result = pcap prepare(params) if result <> 0 print "prepare failed " + result tostr() stop end if ' step 3 — replay three times startparams = createobject("roassociativearray") startparams filename = "tmp\ /prepared pcap" startparams interface = "eth0" startparams loopcount = 3 if not pcap start(startparams) print "start failed" stop end if ' step 4 — event loop while true msg = wait(0, port) if type(msg) = "ropcapevent" select case msg getint() case 3 ' looped print "completed loop " + msg getdata() tostr() case 5 ' dropped print "drop count " + msg getdata() tostr() case 2 ' stopped print "replay finished" exit while end select end if end while stats = pcap getstats() print "sent=" + stats packets sent tostr() + " dropped=" + stats packets dropped tostr() + " underruns=" + stats underruns tostr() extract a raw stream from a pcap recover an mpeg ts file from a ts over udp capture no prepare() or network interface is needed pcap = createobject("ropcap") params = createobject("roassociativearray") params inputfile = "sd /recording pcap" params outputfile = "sd /extracted ts" ' autoflowselect defaults to true when no filterinput keys are given ' set explicit filter keys to target a specific flow in a multi flow capture params filterinputdestaddress = "239 10 20 30" params filterinputdestport = 1234 ' autoflowselect defaults to false because filterinput keys are present; ' set it explicitly to true to auto pick if the filter still matches multiple flows params autoflowselect = true result = pcap extractstream(params) if result = 0 print "stream extracted successfully" else print "extractstream failed " + result tostr() end if