This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

wireshark mate sip 2nd or 3rd pdu filter

0

I have a wireshark capture that contains a lot of sip subscribe and notify. I am using mate to do the filtering. Each gop will contain normally 4 PDUS (Subscribe-200OK, Notify-200OK). I can filter the first and last pdu of all Gops, but I would like to filter only the 2nd or 3rd pdu of all gops. Does anyone have an idea on how I can achieve this. Is it a filter that I don't know about or some more work in the mate script?. Here is the mate script.

Transform start_stop_cond {
Match (method="SUBSCRIBE") (msg_type=start);
Match (resp_code,req_method="NOTIFY") (msg_type=stop);
};

Pdu sip_pdu Proto sip Transport ip {

Extract user From sip.from.user; Extract user From sip.to.user; Extract user From sip.ppi.user; Extract callid From sip.Call-ID; Extract method From sip.Method; Extract cseq From sip.CSeq.seq; Extract resp_code From sip.Status-Code; Extract req_method From sip.CSeq.method; Transform start_stop_cond; };

Gop sip_gop On sip_pdu Match (callid) {

Start(msg_type=start); Stop(msg_type=stop); };

Done;

Thanks so much in advance.

asked 21 Apr ‘16, 11:37

Carlos%20Lopez's gravatar image

Carlos Lopez
6225
accept rate: 0%

edited 21 Apr ‘16, 13:56

I don’t know any way to filter/refer to a PDU of a particular position within a GoP. Is your example just an example or you are really interested in the 200 to the SUBSCRIBE and/or the first and mandatory NOTIFY, or you’ve used that message exchange just as an example?

(21 Apr ‘16, 16:00) sindy

Hi Sindy. In this case I just want to check if the Notify is seen before the 200OK for Subscribe. Any idea how to filter this?. for the whole capture? I imagined that by printing the 2nd pdu for all gops I might see the issue I am looking for. Thanks.

(22 Apr ‘16, 12:40) Carlos Lopez


One Answer:

1

Okay, so we've moved from a generic requirement, which was almost impossible to fulfil, to a specific one. Much easier, I tell ya :-)

My suggestion here is to forge a dedicated GoP AVP using a Transform in the GoP. The principle relies on the fact that the Transform is invoked each time when the GoP's AVPL is modified due to assignment of a new PDU to the GoP, and that the Match clauses within a Transform are only executed until the first success.

So you'd use a "flag" AVP which would be added to the GoP's AVPL when either the 200(SUBSCRIBE) or the NOTIFY arrive while this flag AVP hasn't been created yet, and the value of this AVP would be either "200" or "NOTIFY" depending on which message has caused it to be added to the GoP's AVPL.

There is another important thing, a Transform used in a GoP works with the AVPL of the GoP, not with the AVPLs of the newly arrived PDUs. So we have to add a single unique AVP per each PDU to the GoP's AVPL so that the GoP's Transform would do what we want. This effectively means that we need to forge a single AVP distinguishing the 200 response to SUBSCRIBE from the 200 response to NOTIFY at PDU level, and Extra it into the GoP.

So the complete code would be something like:

Transform start_stop_cond {
  Match (method="SUBSCRIBE") (msg_type=start);
  Match (resp_code,req_method="NOTIFY") (msg_type=stop);
};

Transform xtract_rsp { Match (resp_code, req_method="SUBSCRIBE") Insert (resp_to="SUBSCRIBE"); Match (resp_code, req_method="NOTIFY") Insert (resp_to="NOTIFY"); };

Pdu sip_pdu Proto sip Transport ip { Extract user From sip.from.user; Extract user From sip.to.user; Extract user From sip.ppi.user; Extract callid From sip.Call-ID; Extract method From sip.Method; Extract cseq From sip.CSeq.seq; Extract resp_code From sip.Status-Code; Extract req_method From sip.CSeq.method; Transform start_stop_cond, xtract_rsp; };

Transform mark_it { Match (first_was); // only this rule, which doesn't change the GoP's AVPL, is executed if the first_was AVP already exists for the GoP's AVPL, ensuring that it is added only once Match (method="NOTIFY") Insert (first_was="NOTIFY"); Match (resp_to="SUBSCRIBE") Insert (first_was="RSP2SUBSCRIBE"); };

Gop sip_gop On sip_pdu Match (callid) { Start(msg_type=start); Stop(msg_type=stop); Extra (method,resp_to); Transform mark_it; };

Done;

EDIT: To respond the title of the question rather than the particular need, the approach actually could be generalized in terms that you could

  • organize a rudimentary PDU counter in a GoP (but the increment function needs to be implemented manually using a Transform, so the processing speed would be impacted and the number of PDUs per GoP would have to be reasonably low)

  • save information about several PDUs of interest (e.g. the 2nd and the 3rd) for use in display filter, but as the AVPs can only be assigned constant values, not values of other AVPs, and each protocol field may only be Extracted once per PDU, there is no way to e.g. store the cseq values of these messages

  • delete the information from each new PDU after it has been used to modify the GoP’s AVPL, using a “cleanup” Transform. This last step may also functionally replace the PDU’s own Transform creating the “resp_to” AVP.

So an example of the result would look like this:

Transform start_stop_cond {
Match (method="SUBSCRIBE") (msg_type=start);
Match (resp_code,req_method="NOTIFY") (msg_type=stop);
};

Pdu sip_pdu Proto sip Transport ip { Extract user From sip.from.user; Extract user From sip.to.user; Extract user From sip.ppi.user; Extract callid From sip.Call-ID; Extract method From sip.Method; Extract cseq From sip.CSeq.seq; Extract resp_code From sip.Status-Code; Extract req_method From sip.CSeq.method; Transform start_stop_cond; };

Transform pdu_counter { Match (last_pdu=9) Replace (last_pdu="max"); Match (last_pdu=8) Replace (last_pdu=9); Match (last_pdu=7) Replace (last_pdu=8); Match (last_pdu=6) Replace (last_pdu=7); Match (last_pdu=5) Replace (last_pdu=6); Match (last_pdu=4) Replace (last_pdu=5); Match (last_pdu=3) Replace (last_pdu=4); Match (last_pdu=2) Replace (last_pdu=3); Match (last_pdu=1) Replace (last_pdu=2); Match (last_pdu="max") (); Match () Insert (last_pdu=1); };

Transform record_2nd { Match (last_pdu{1|3|4|5|6|7|8|9|"max"}); //skip the rest unless we're dealing with PDU number 2 Match (method="NOTIFY") (pdu_2="NOTIFY"); Match (resp_code,req_method="SUBSCRIBE") (pdu_2="RSP2SUBSCRIBE"); Match () (pdu_2="OTHER"); };

Transform record_3rd { Match (last_pdu{1|2|4|5|6|7|8|9|"max"}); //skip the rest unless we're dealing with PDU number 3 Match (method="NOTIFY") (pdu_3="NOTIFY"); Match (resp_code,req_method="SUBSCRIBE") (pdu_3="RSP2SUBSCRIBE"); Match () (pdu_3="OTHER"); };

Transform drop_extra { Match Loose (method, resp_code,req_method) Replace (); };

Gop sip_gop On sip_pdu Match (callid) { Start(msg_type=start); Stop(msg_type=stop); Extra (method,resp_code,req_method); Transform pdu_counter,record_2nd,record_3rd,drop_extra; };

Done;

answered 22 Apr ‘16, 14:23

sindy's gravatar image

sindy
6.0k4851
accept rate: 24%

edited 23 Apr ‘16, 02:40

Hi Sindy. Thanks a lot for your help. The result on your first proposal, I thought I had a capture which contained the notify before the 200OK for subscribe, but I didn’t. then I modified the capture I have as follows: ,(exported hex capture, reversed the order in two places of the 200OK for subscribe <-> notify and imported back to wireshark), then added the first proposal in mate but it always inserted in the attribute of all the Gops the following:

first_was: RSP2SUBSCRIBE

Then I tried your 2nd proposal and I can see in the packets I reversed, the following:

pdu_3: RSP2SUBSCRIBE
pdu_2: NOTIFY

On those I didn't reverse the order I saw this:

pdu_3: NOTIFY  
pdu_2: RSP2SUBSCRIBE

Can you spot what the issue is with the first proposal?
I wonder wouldn't it be a nice feature to have the pdu order/number within the gop under the number of PDUs something like: PDU: in frame: 6 (0.000001 : 0.000001).No=2, and so on.
Thanks so much.

(23 Apr '16, 06:17) Carlos Lopez

wouldn't it be a nice feature

if you want a Wireshark feature, you can always file a bug with severity "Enhancement". But be prepared that MATE is not widely popular so enhancements to it may have a very low priority.

Can you spot what the issue is with the first proposal?

Seemingly not without the capture, as I cannot see anything wrong in my MATE code even now. So please publish your modified capture (i.e. the one containing some NOTIFY before 200(SUBSCRIBE)) somewhere like Cloudshark (a preferred option on this site), Google Drive, Dropbox, ... and put a login-free link to it here.

Nevertheless:

  • you can reach the same goal by simply removing everything related to Transform record_3rd from the second proposal and renaming pdu_2 to something you like more

  • by debugging the first proposal yourself, you'd obtain a better understanding how MATE works.

I thought I had a capture which contained the notify before the 200 OK for subscribe

I'm wondering what is the goal of the whole exercise here. Normally, the order of sending of those two messages depends on the SIP stack processing the received SUBSCRIBE, so it should be the same for all SUBSCRIBE-initiated dialogs; the order of reception of the two messages may be swapped due to the nature of the meshed packet networks (even if no packets are lost), so the issuer of the SUBSCRIBE must be prepared for such situation and shouldn't expect the two messages to come in any particular order. The sole purpose of the first NOTIFY is to inform the subscriber about the state of the subscribed object as soon as possible, not to affect the state diagram of the dialog.

(23 Apr '16, 06:46) sindy

The issue is that the application I am working on is throwing some errors and I suspect the reception of resp and req in different order was the culprit, for sure this is a bug, but I haven't been able to probe that, at least not until now, in any case I got your first proposal and remove the extra as last step and the result looks better now. Here it is. Thanks so much for your help. I am very grateful.

Transform start_stop_cond {
  Match (method="SUBSCRIBE") (msg_type=start);
  Match (resp_code,req_method="NOTIFY") (msg_type=stop);
};

Transform xtract_rsp { Match (resp_code, req_method="SUBSCRIBE") Insert (resp_to="SUBSCRIBE"); Match (resp_code, req_method="NOTIFY") Insert (resp_to="NOTIFY"); };

Pdu sip_pdu Proto sip Transport ip { Extract user From sip.from.user; Extract user From sip.to.user; Extract user From sip.ppi.user; Extract callid From sip.Call-ID; Extract method From sip.Method; Extract cseq From sip.CSeq.seq; Extract resp_code From sip.Status-Code; Extract req_method From sip.CSeq.method; Transform start_stop_cond, xtract_rsp; };

Transform mark_it { Match (first_was); // only this rule, which doesn't change the GoP's AVPL, is executed if the first_was AVP already exists for the GoP's AVPL, ensuring that it is added only once Match (method="NOTIFY") Insert (first_was="NOTIFY"); Match (resp_to="SUBSCRIBE") Insert (first_was="RSP2SUBSCRIBE"); };

Transform rem_extra { Match Loose (method, resp_to) Replace (); };

Gop sip_gop On sip_pdu Match (callid) { Start(msg_type=start); Stop(msg_type=stop); Extra (method,resp_to); Transform mark_it, rem_extra;enter code here };

Done;

(23 Apr ‘16, 07:39) Carlos Lopez

in any case I got your first proposal and remove the extra as last step and the result looks better now

That’s quite odd, as the first proposal contains another mechanism to ensure that the first_was is added only once (as that mechanism seemed to me easier to understand than the “Extra, Make use of, Remove” one, maybe I was wrong?).

Normally, the “list of PDU types already encountered in the GoP” (methods and their responses) is growing with each PDU, but the first_was AVP should be added only once, which is either when the GoP’s AVPL has been just extended with method=“NOTIFY” or when it has been just extended with resp_to=“SUBSCRIBE”. There is nothing in the code that could replace an existing first_was, so in the worst case, there should have been both first_was=“NOTIFY” and first_was=“RSP2SUBSCRIBE if NOTIFY has come first and the mechanism has failed.

I went so far as to use one of the subscribe-notify captures in my archive and arrange the four packets in question both ways (using Export Specified Packets, Time Shift, and Merge), and it worked well - if the first packet following the SUBSCRIBE is the NOTIFY, I get first_was: NOTIFY, otherwise I get first_was: RSP2SUBSCRIBE. So I keep my proposal in the Answer as it was.

(23 Apr ‘16, 08:18) sindy