Hi,
I have an app that's similar in structure to the new nextEx() example, that basically creates a list containing information on all/each of the packets in a PCAP file. Per the nextEx() example, among the information output is the output from packet.getFrameNumber().
I have another app that, when given a frame number, is suppose to search through the original PCAP file, find the packet with a matching frame number, then dump out more detailed info on that packet.
The problem that I'm having is that when the 2nd app is run, it can't find the packet with the matching frame number. It appears that the frame numbers output from the 1st app are completely different from the frame numbers?
What does packet.getFrameNumber() actually do? Is it getting some number that is actually in the PCAP file, or is it just an incrementing number or something like that, that jNetPcap is keeping track of?
What I really need is something, some number that is constant, that I can use to reference/identify/locate a given packet within a PCAP
...
BTW, it may be that I missed it, but I've been looking through the Javadocs, and I don't see a getFrameNumber() method in PcapPacket. I just found getFrameNumber() in JPacket, but I'm not using JPacket (at least, I don't think I am).
Thanks,
Jim
Hi,
BTW, the 1st app I mentioned actually does that over several PCAP files, in a loop, i.e., it isn't reading through just a single PCAP file.
I'm wondering if maybe that may be the problem, i.e., is the number returned by getFrameNumber() cumulative over multiple PCAP files?
The first app DOES do a pcap.close() after processing each PCAP file, before processing the next PCAP file. Is there something else I need to do so that the frame number for a given packet within a given PCAP file would always be the same?
Thanks,
Jim
Frame numbers are assigned by the quick-scanner (JScanner class). They are not read from a file. Scanner assigns framenumbers sequentially as it processes each packet. There are 2 global scanners. First scanner is actually a thread-local scanner retrieved using JScanner.localScanner() used by Pcap.loop and Pcap.dispatch methods. The second is also a global scanner that is specifically assigned to processing JPacket.scan requests. The 2 scanners will assign framenumbers out of their own pool of available numbers. The frame numbers between them might overlap.
Also note that some analyzers inject packets into the input packet stream when do perform analysis. The moment they are scanned by a scanner they are assigned numbers as well.
Analysis doesn't take place automatically, unless you enable it, so packet injection won't skew those numbers.
As to how come Scanner assigned frame numbers do not match the actual packet stored in a capture file, that really depends on what that particular scanner is also doing. nextEx uses the JPacket.scan scanner type, not the thread-local JScanner. If you create any additional packets that also get scanned that will throw numbers off. The frame numbers don't reset back to 0 when you close pcap and open another pcap file. They were never intended as an index into a file, but simply sequential identifier for a packet. Wireshark does same thing since it has inject packets into the packet buffer after analysis as well.
JScanner frame numbers start at 0, so make sure your index into the file starting with a 0 as first as well. If you
jNetStream is not supported right now, but version 3.0a would be perfect for what you want to do. It 3.0a provides full indexing support for pcap files. You open a file and then you access packets like a list collection. 3.0a doesn't decode packets though. So you would have to use a combination of jnetstream to parse the file and jnetpcap to decode the packets. Easy to do though since jnetstream gives a the packet in a ByteBuffer which you could pass onto JMemoryPacket and have it scanned. When I offer support for jnetstream it will have full decoding capabilities that will be layered on top of what jnetpcap has to offer, but with a much friendlier API and file manipulation capabilities.
One thing you can do is create a new scanner for every file your process and use the custom scanner instead of the JPacket.scan method. Result is identical except frame numbers will reset back to 0:
JBuffer packet = new JBuffer(JMemory.POINTER);
PcapHeader hdr = new PcapHeader(JMemory.POINTER)
for (String file: myFiles) {
JScanner scanner = new JScanner();
Pcap pcap = ..; // Open file
while (nextEx(hdr, buf)...) {
PcapPacket packet = new PcapPacket(hdr, buf);
scanner.scan(JRegistry.mapDLTToId(pcap.datalink()), packet);
}
}
Something like that will reset the frame number.
BTW: both PcapPacket and JMemoryPacket are subclasses of JPacket class.
Mark,
I'll start taking a look at the suggestion in your last post above, but, just to be clear, I'd have to make a similar change in both the 1st app (the one that runs through all the PCAP files and creates my list) and the 2nd app (the one that extracts a single packet from a given PCAP file, using the frame number)? Is that correct.
And, if I do that, it would look like:
PCAP File 1 - 1st packet - frame number=0
- 2nd packet - frame number=1
.
.
.
PCAP File 2 - 1st packet - frame number=0
- 2nd packet - frame number=1
.
.
.
PCAP File 3 - 1st packet - frame number=0
- 2nd packet - frame number=1
.
.
.
Is that correct?
Also, with your suggestion, should I do something to destroy the JScanner after each PCAP file is processed?
Thanks,
Jim
Yes in both so that frame numbers match up.
I'll revisit the issue of frame numbers in the future to see if there is anything there that needs to be done differently.
Hi,
Sorry. I editted my post instead of adding a new msg. What would your recommendation be re. the JScanner? Should I destroy it after processing each file?
The reason for the question is that I already ran into some OutOfMemory exceptions, that I had to take of, by re-configuring my app, so I'm trying to be a bit more wary about heap usage.
Thanks,
Jim
JBuffer packet = new JBuffer(JMemory.POINTER);
PcapHeader hdr = new PcapHeader(JMemory.POINTER)
for (String file: myFiles) {
JScanner scanner = new JScanner();
Pcap pcap = ..; // Open file
while (nextEx(hdr, buf)...) {
PcapPacket packet = new PcapPacket(hdr, buf);
scanner.scan(JRegistry.mapDLTToId(pcap.datalink()), packet);
}
}
Something like that will reset the frame number.
BTW: both PcapPacket and JMemoryPacket are subclasses of JPacket class.
HAH!
I think that in your snippet above, you had the params for scanner.scan() reversed
???
Jim
Mark,
FYI, your suggestion works well!!
Jim
Glad to hear it.
You should let java GC take care of freeing the memory. Although JScanner is a heavy object, default allocates 100kb, when you release reference to it java will release that memory.
I will think about enhancing the API to let users provide their own frame counters or at minimum reset the current counter value.
Hi,
As I said, it's working now, with your suggestion, but there is something weird.
My search app dumps out the selected packet, using the pcap toString(). I noticed that the field labelled "Frame:" in the toString() output is always 1 less than what my app got from the getFrameNumber().
Do you know why the result from getFrameNumber() is "one off" from what the toString() method outputs?
In my case, it's not a problem, because I use getFrameNumber(), which apparently always returns the "one off" number, but I was just curious.
Thanks for your help,
Jim
You should let java GC take care of freeing the memory. Although JScanner is a heavy object, default allocates 100kb, when you release reference to it java will release that memory.
I will think about enhancing the API to let users provide their own frame counters or at minimum reset the current counter value.
Hi,
Thanks for the info. after posting, I realized that I'm instantiating the JScanner inside a class that gets called by my main class, which would cause the memory to be returned to the heap (i.e., the JScanner, etc. should only exist while a file is being processed). So, I think that you're correct that the GC should take care of it.
Thanks,
Jim