Re: [Wireshark-dev] Sub_dissectors assertion failed
On Mon, May 24, 2010 at 3:54 PM, Guy Harris g...@alum.mit.edu wrote: OK, so that's a little more complicated. There are (at least) three ways of handling that: 1) dissect the IP rider and the custom protocol as separate protocols, and use the standard mechanisms for handing off from the IP rider dissector to the custom protocol dissector; 2) dissect the IP rider and the custom protocol as separate protocols, and use a specialized mechanism for handing off from the IP rider dissector to the custom protocol dissector; 3) dissect them as a single protocol. For 1), you would have to pass the IP protocol number from the IP rider protocol to the custom protocol. What you would do there is: In the IP rider dissector: in its register-handoff routine, register it in the ip.proto dissector table with its IP protocol number, and fetch a handle for the custom protocol dissector with find_dissector(), using the name the custom dissector uses to register itself; in its dissection routine, fetch the IP protocol number field's value into a local variable, and, when you want to call the custom protocol's dissector, set pinfo-private_data to point to the local variable and call the custom protocol dissector, using its handle, with call_dissector(). In the custom protocol dissector: in its register routine, register the dissector handle with register_dissector(), using the same name that the IP rider dissector uses to find it; in its register-handoff routine, fetch the ip.proto dissector table with find_dissector_table(); in its dissection routine, when it is to call the dissector for its payload, use dissector_try_port(), using the IP protocol number pointed to by pinfo-private_data. 2) could be done similar to 1), except that you could just directly call the custom protocol dissector and have it take an additional argument, the IP protocol number, as an argument, or you could just dissect both protocol layers in the same routine. That would, however, mean that some of the work done for you by call_dissector(), such as saving and restoring some state (which might not matter if your dissector doesn't change it), setting the current protocol name that shows up in some messages, and updating the list-of-protocols field, won't be done. I wouldn't recommend doing it that way. How 3) would be done should be obvious, but there might be reasons not to do that. Ok. I did a mixture of 1 and 2. Otherwise, here comes another question. I solved the problem exhibited in: http://img80.imageshack.us/img80/5582/malformed.gif You mean the problem that Wireshark thinks that 0x1bc4 is not equal to 0x1bc4? :-) Yep :D by hardcoding a value into the reported_length parameter of tvb_new_subset() instead of using -1. This is obviously not a long term solution, so what I need to get at is the IP header's value for Total Length (ip.len). That's odd - the reported_length value for the tvbuff handed to the IPR dissector should be the total length value from the IP header unless this is an IP fragment, so changing the value of the length shouldn't matter. Is the packet in question the first fragment of an IP datagram? Nope. The problem had to do with the code in packet-ip.c between lines 2375 and 2394. If I left it as -1 it equated to 65,535 and the next dissector in line didn't like that I suppose. Something with what ip_checksum returned triggered it. Well, I've got it working right now. I may need more help later with preferences. There's one more bug hanging around I just saw and I'll work on that tomorrow. Thanks a ton Guy. -Scott ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Sub_dissectors assertion failed
On May 24, 2010, at 9:40 AM, Scott wrote: Hi Guy! I hope your weekend was enjoyable. Thanks! I hope yours was enjoyable, too. On Sat, May 22, 2010 at 2:39 PM, Guy Harris g...@alum.mit.edu wrote: So presumably the IP protocol rider protocol has fields of its own. Does the IP protocol rider have an IP protocol number assigned to it, so that you have: link-layer protocol IP, with the IP protocol number having the value for the IP protocol rider protocol IP protocol rider protocol custom protocol some protocol that normally runs directly atop IP or is this a non-standard encapsulation where you have: link-layer protocol IP, with the IP protocol number having the value for the protocol that's above the custom protocol IP protocol rider protocol custom protocol some protocol that normally runs directly atop IP The former. So that means that either the IP protocol rider protocol, or the custom protocol, needs to have a field giving the protocol number of the protocol that runs top the custom protocol. Which of of them has that field? I overcame the problem of the protocols not matching by seeing that the protocol number copied over from IP to my IP rider and *supposedly* stored in hf_[IPR protocol] field was incorrect. It was 65,000 something when printf'd. What does hf_register_info do with that variable (hf_[IPR protocol])? What do you mean by hf_[IPR protocol]? A protocol *does* have a gint value that corresponds to it, but it's not put into the hf_register_info array for that protocol; it's separately returned by the call to proto_register_protocol(). That value is used in the protocol dissector's proto_tree_add_item() or proto_tree_add_protocol_format() call that adds the top-level item in the protocol tree for that protocol's data. In the array of hf_register_info values are structures that have information about various fields in packets for that protocol; that includes pointers to hf_ variables for those fields. Those hf_ variables are set by the proto_register_field_array() call. Both the proto_ values returned by proto_register_protocol(), and the hf_ values set by proto_register_field_array(), are used as indices into a big table of structures giving information about protocols and fields. Those indices are passed to various routines that add items to protocol trees, as well as some other routines. I suppose telling it that it is an FT_UINT8 tells it how to read it from the tvbuff_t. The type field of an hf_register_info structure indicates, for octal and hex values, how many digits to display. proto_tree_add_item() will fetch the value from the tvbuff, but the call it uses depends on the length field, not the type of the field - there are, I think, some dissectors where a field of a given FT_UINTn or FT_INTn type doesn't always have the same length in the packet. ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Sub_dissectors assertion failed
Hi, On Mon, May 24, 2010 at 01:18:00PM -0600, Scott wrote: I need to get at is the IP header's value for Total Length (ip.len). Is there a function for that? packet_info-iplen ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Sub_dissectors assertion failed
On May 24, 2010, at 12:18 PM, Scott wrote: On Mon, May 24, 2010 at 11:57 AM, Guy Harris g...@alum.mit.edu wrote: So that means that either the IP protocol rider protocol, or the custom protocol, needs to have a field giving the protocol number of the protocol that runs top the custom protocol. Which of of them has that field? The IP Rider contains that field. OK, so that's a little more complicated. There are (at least) three ways of handling that: 1) dissect the IP rider and the custom protocol as separate protocols, and use the standard mechanisms for handing off from the IP rider dissector to the custom protocol dissector; 2) dissect the IP rider and the custom protocol as separate protocols, and use a specialized mechanism for handing off from the IP rider dissector to the custom protocol dissector; 3) dissect them as a single protocol. For 1), you would have to pass the IP protocol number from the IP rider protocol to the custom protocol. What you would do there is: In the IP rider dissector: in its register-handoff routine, register it in the ip.proto dissector table with its IP protocol number, and fetch a handle for the custom protocol dissector with find_dissector(), using the name the custom dissector uses to register itself; in its dissection routine, fetch the IP protocol number field's value into a local variable, and, when you want to call the custom protocol's dissector, set pinfo-private_data to point to the local variable and call the custom protocol dissector, using its handle, with call_dissector(). In the custom protocol dissector: in its register routine, register the dissector handle with register_dissector(), using the same name that the IP rider dissector uses to find it; in its register-handoff routine, fetch the ip.proto dissector table with find_dissector_table(); in its dissection routine, when it is to call the dissector for its payload, use dissector_try_port(), using the IP protocol number pointed to by pinfo-private_data. 2) could be done similar to 1), except that you could just directly call the custom protocol dissector and have it take an additional argument, the IP protocol number, as an argument, or you could just dissect both protocol layers in the same routine. That would, however, mean that some of the work done for you by call_dissector(), such as saving and restoring some state (which might not matter if your dissector doesn't change it), setting the current protocol name that shows up in some messages, and updating the list-of-protocols field, won't be done. I wouldn't recommend doing it that way. How 3) would be done should be obvious, but there might be reasons not to do that. I overcame the problem of the protocols not matching by seeing that the protocol number copied over from IP to my IP rider and *supposedly* stored in hf_[IPR protocol] field was incorrect. It was 65,000 something when printf'd. What does hf_register_info do with that variable (hf_[IPR protocol])? What do you mean by hf_[IPR protocol]? Sorry, I wasn't especially clear. I meant one of the variables declared as: static int hf_IPR_protocol = -1; that is used in the hf_register_info struct. I didn't know what those were for (I thought they stored the actual value extracted from the packet), but you answered my question with: the hf_ values set by proto_register_field_array(), are used as indices into a big table of structures giving information about protocols and fields. Those indices are passed to various routines that add items to protocol trees, as well as some other routines. Yes - not all fields *have* integral values, so the hf_ variable couldn't be used for that purpose. If this is still the wrong format (calling dissector_try_port twice or otherwise), please let me know! Yes, it is - see above for the right way to handle those two protocols. Otherwise, here comes another question. I solved the problem exhibited in: http://img80.imageshack.us/img80/5582/malformed.gif You mean the problem that Wireshark thinks that 0x1bc4 is not equal to 0x1bc4? :-) by hardcoding a value into the reported_length parameter of tvb_new_subset() instead of using -1. This is obviously not a long term solution, so what I need to get at is the IP header's value for Total Length (ip.len). That's odd - the reported_length value for the tvbuff handed to the IPR dissector should be the total length value from the IP header unless this is an IP fragment, so changing the value of the length shouldn't matter. Is the packet in question the first fragment of an IP datagram? ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev
Re: [Wireshark-dev] Sub_dissectors assertion failed
On May 21, 2010, at 6:42 PM, Scott wrote: On Fri, May 21, 2010 at 3:18 PM, Guy Harris g...@alum.mit.edu wrote: So what protocols does your custom protocol run on top of? For now the custom protocol is a dummy protocol that only contains a 32-bit int and rides on top of the IP protocol rider (*it*). So presumably the IP protocol rider protocol has fields of its own. Does the IP protocol rider have an IP protocol number assigned to it, so that you have: link-layer protocol IP, with the IP protocol number having the value for the IP protocol rider protocol IP protocol rider protocol custom protocol some protocol that normally runs directly atop IP or is this a non-standard encapsulation where you have: link-layer protocol IP, with the IP protocol number having the value for the protocol that's above the custom protocol IP protocol rider protocol custom protocol some protocol that normally runs directly atop IP The former can be done without modifying Wireshark, but not the way you're doing it. The latter *CANNOT* be done without Wireshark's IP dissector to directly call the dissector for the IP protocol rider protocol. ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Sub_dissectors assertion failed
-Original Message- From: wireshark-dev-boun...@wireshark.org [mailto:wireshark-dev-boun...@wireshark.org] On Behalf Of Scott Sent: Friday, May 21, 2010 1:50 PM To: Developer support list for Wireshark Subject: Re: [Wireshark-dev] Sub_dissectors assertion failed Thanks for the reply Guy! I have some followup questions. [ snippy-snip] Quite a number of questions? Yes. I feel like README.developer is good but it doesn't explain all. Guidance from you and any other developers is much appreciated. -Scott I could not agree more. A few diagrams in the developer guide would be worth thousands of words. Just when I think I know what I am doing I realise that, indeed, I don't... ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Sub_dissectors assertion failed
Thanks for the reply Guy! I have some followup questions. I killed the original error of ERROR:packet.c:709:dissector_add: assertion failed: (sub_dissectors) by calling register_dissector_table() in proto_register_..(). Apparently I didn't know I needed to do that, but it makes sense. To answer a question you posed me: If I am writing a dissector for a protocol that rides on top of IP but then allows any protocol to follow it, Do you truly mean any protocol, so that, for example, you could follow it with X.25 or HTTP or Ethernet, or do you mean, for example, any protocol *that runs atop IP* can follow it? I mean *any protocol that runs atop IP* can follow it. I am going to work on all protocols registered with IP to follow it as soon as I get *another* custom dissector/protocol that I am working on, which can follow it, to work. Let's call the custom protocol *custom* and the IP rider *it* to simplify things. I have the custom protocol doing dissector_add([field switch on *it*], [macro expansion that matches a field value], *custom*_handle) in its handoff routine. However, for some reason it is apparently not being called upon to dissect because it is not showing up as a header in the packet window. I am unsure of why similar code for *it* - IP doesn't work for *custom* - *it*. I've tooled around with tvb_new_subset() and even tried calling dissector_next (a routine mentioned in README.developer but that doesn't actually exist) to no avail yet. I've tried call_dissector(), but that's probably not what I want. As a by the way, you mentioned in your reply: If you mean, for example, any protocol that runs atop IP, then you should grab hold of the ip.proto dissector table: dissector_table_t ip_proto_dissector_table; ... ip_proto_dissector_table = find_dissector_table(ip.proto); and then use that to hand off the payload to the next dissector with that dissector table, the protocol number, and dissector_try_port(). How do I hand off the payload to the next dissector with that dissector table, the protocol number, and dissector_try_port()? Is that through a function call? And what does dissector_try_port() do? All I could tell is that it returns a gboolean. More questions I haven't been able to find answers to: *The proto_handoff_..(void) routine's main job is to register the dissector with other dissectors so it gets called at the right moment, correct? *What is the difference between create_dissector_handle() and new_create_dissector_handle()? Quite a number of questions? Yes. I feel like README.developer is good but it doesn't explain all. Guidance from you and any other developers is much appreciated. -Scott ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Sub_dissectors assertion failed
On May 21, 2010, at 12:49 PM, Scott wrote: I killed the original error of ERROR:packet.c:709:dissector_add: assertion failed: (sub_dissectors) by calling register_dissector_table() in proto_register_..(). Apparently I didn't know I needed to do that, but it makes sense. Yes. As indicated: 1) you can't register in a dissector table until the dissector table is registered; 2) the *only* ordering guarantee we offer is that all register routines are run before any register-handoff routines are run; so, to make sure that all the dissector tables are registered before any registrations are attempted in dissector tables, you must register dissector tables in your register routine and register dissectors *in* dissector tables in the register-handoff routines (dissector tables are used by dissectors to hand off the remaining packet data to the next protocol, hence the handoff in register-handoff). I mean *any protocol that runs atop IP* can follow it. Then you want to do what I suggested to find the right dissector for the following protocol - just get the ip.proto dissector table and use that. I am going to work on all protocols registered with IP to follow it as soon as I get *another* custom dissector/protocol that I am working on, which can follow it, to work. Let's call the custom protocol *custom* and the IP rider *it* to simplify things. I have the custom protocol doing dissector_add([field switch on *it*], [macro expansion that matches a field value], *custom*_handle) in its handoff routine. However, for some reason it is apparently not being called upon to dissect because it is not showing up as a header in the packet window. So what protocols does your custom protocol run on top of? It needs to register with the appropriate dissector table or tables for those protocols, using the appropriate value (Ethernet type, IP protocol type, etc.). As a by the way, you mentioned in your reply: If you mean, for example, any protocol that runs atop IP, then you should grab hold of the ip.proto dissector table: dissector_table_t ip_proto_dissector_table; ... ip_proto_dissector_table = find_dissector_table(ip.proto); and then use that to hand off the payload to the next dissector with that dissector table, the protocol number, and dissector_try_port(). How do I hand off the payload to the next dissector with that dissector table, the protocol number, and dissector_try_port()? Is that through a function call? Yes. The name of the function you call is dissector_try_port. And what does dissector_try_port() do? All I could tell is that it returns a gboolean. It takes, as arguments: 1) a handle for a dissector table that uses integral values as keys (it should really be dissector_try_uint(); the port is historical); 2) an integral value to use to select a dissector from that dissector table; 3) a tvbuff_t * that refers to a tvbuff with the data to be dissected by the selected dissector; 4) a packet_info *, which should be the one the dissector calling dissector_try_port() was handed; 5) a proto_tree *, which should be the one the dissector calling dissector_try_port() was handed. If it finds a dissector in the dissector table that was registered with the integral value in question, it calls it, handing it the tvbuff_t *, the packet_info *, and the proto_tree *, and returns TRUE. If not, it returns FALSE; you then need to decide how to dissect the data (for example, just show it as raw data). For example, the Ethernet dissector calls dissector_try_port(), handing it the Ethernet-type dissector table, and the Ethernet type value from the packet. More questions I haven't been able to find answers to: *The proto_handoff_..(void) routine's main job is to register the dissector with other dissectors so it gets called at the right moment, correct? Yes. *What is the difference between create_dissector_handle() and new_create_dissector_handle()? There are two types of dissectors: 1) dissectors for protocol fields such as Ethernet types where the value used when you select a dissector (integral value for dissector_try_port()) is uniquely assigned to a protocol, so that you can pretty much guarantee that the selected dissector is the right one; 2) dissectors for protocol fields such as UDP or TCP ports where the value is assigned to the protocol but could be used by other protocols, so you *can't* guarantee that the selected dissector is the right one. In addition, in some cases the calling dissector needs to know how much data from the tvbuff was considered part of the data for the called dissector's protocol, i.e. where it doesn't always get the rest of the packet. New-style dissectors are for case 2) and for the other case mentioned. For case 2), they do some heuristic checks to see if the packet looks appropriate
Re: [Wireshark-dev] Sub_dissectors assertion failed
On Fri, May 21, 2010 at 3:18 PM, Guy Harris g...@alum.mit.edu wrote: So what protocols does your custom protocol run on top of? For now the custom protocol is a dummy protocol that only contains a 32-bit int and rides on top of the IP protocol rider (*it*). I got the custom protocol to show up in the packet detail window ok, although not how I expected.. And what does dissector_try_port() do? All I could tell is that it returns a gboolean. It takes, as arguments: 1) a handle for a dissector table that uses integral values as keys (it should really be dissector_try_uint(); the port is historical); 2) an integral value to use to select a dissector from that dissector table; 3) a tvbuff_t * that refers to a tvbuff with the data to be dissected by the selected dissector; 4) a packet_info *, which should be the one the dissector calling dissector_try_port() was handed; 5) a proto_tree *, which should be the one the dissector calling dissector_try_port() was handed. When I called dissector_try_port() from the *it* IP rider protocol like this: dissector_try_port(subdissector_table, hf_[type switch], next_tvb, pinfo, tree) the dummy protocol didn't match correctly. However, when I called it like this: dissector_try_port(subdissector_table, pinfo-destport, next_tvb, pinfo, tree) it matched fine. This doesn't make a lot of sense to me (is it REALLY matching on the port?) because the dummy custom protocol does: dissector_add([*it*].[type], [macro], test_handle), which doesn't seem to have anything to do with the port. I mean *any protocol that runs atop IP* can follow it. Then you want to do what I suggested to find the right dissector for the following protocol - just get the ip.proto dissector table and use that. Because the dummy protocol doesn't have a subdissectors table, the original IP rider protocol needs to call dissector_try_port() again to grab the dissectors for any protocols that may follow the dummy protocol (TCP, ICMP, etc.). Here's the code I have: /* dissector_try_port() call for the dummy protocol */ ip_dissector_table = find_dissector_table(ip.proto); next_tvb = tvb_new_subset(next_tvb, [macro for dummy proto length], -1, -1); dissector_try_port(ip_dissector_table, hf_[*it* field that is a copy of ip.proto's], next_tvb, pinfo, tree); But I assume nothing is matching because no protocols show up after the dummy protocol in the packet details window. -Scott ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
[Wireshark-dev] Sub_dissectors assertion failed
Devs, This post pertains to two (probably) interrelated things. If I am writing a dissector for a protocol that rides on top of IP but then allows any protocol to follow it, how do I register them all correctly with my dissector? I see that IP does this by enumerating protocol numbers in ipproto.h and then having dissectors call: dissector_add(ip.proto, IP_PROTO_.., .._handle); but think it would be overkill to do exactly the same thing in my case. --- Also, besides all the pre-defined protocols I also tried registering a custom dissector with it and got this: ERROR:packet.c:709:dissector_add: assertion failed: (sub_dissectors) Help will be appreciated. -Scott ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe
Re: [Wireshark-dev] Sub_dissectors assertion failed
On May 20, 2010, at 5:58 PM, Scott wrote: If I am writing a dissector for a protocol that rides on top of IP but then allows any protocol to follow it, Do you truly mean any protocol, so that, for example, you could follow it with X.25 or HTTP or Ethernet, or do you mean, for example, any protocol *that runs atop IP* can follow it? how do I register them all correctly with my dissector? I see that IP does this by enumerating protocol numbers in ipproto.h and then having dissectors call: dissector_add(ip.proto, IP_PROTO_.., .._handle); but think it would be overkill to do exactly the same thing in my case. If you mean, for example, any protocol that runs atop IP, then you should grab hold of the ip.proto dissector table: dissector_table_t ip_proto_dissector_table; ... ip_proto_dissector_table = find_dissector_table(ip.proto); and then use that to hand off the payload to the next dissector with that dissector table, the protocol number, and dissector_try_port(). That way, any dissector that has registered itself for a protocol that can run atop IP will also be called by your dissector when appropriate. Also, besides all the pre-defined protocols I also tried registering a custom dissector with it and got this: ERROR:packet.c:709:dissector_add: assertion failed: (sub_dissectors) You passed to dissector_add() a first argument that did not correspond to a dissector table that existed at that time. This means that either 1) you did this in your register routine rather than your register-handoff routine or 2) you passed the name of a dissector table that never gets created. The register routine is not supposed to register a dissector in *any* dissector tables, it's supposed to register protocol fields and register the dissector tables themselves, it's the register-handoff routine that should register dissectors in dissector tables. This is because there is no guarantee that register routines will be executed in any particular order, so there's no guarantee that a dissector table will be created before a dissector tries to register in it. The only guarantee we make is that *all* register routines will be run before *any* register-handoff routine is run, so if all dissector tables are created in register routines, and all registration of dissectors in dissector tables is done in register-handoff routines, the only way a registration of a dissector in a dissector table will fail would be if dissector_add() etc. were passed the name of a dissector table that doesn't exist. ___ Sent via:Wireshark-dev mailing list wireshark-dev@wireshark.org Archives:http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:wireshark-dev-requ...@wireshark.org?subject=unsubscribe