This is our old Q&A Site. Please post any new questions and answers at

Guys, I am trying to use TShark to capture ip packets with or and mpls packets with 2 layer label (23,25) or 1 layer label 19 at the same time with below command but failed

tshark -i eth1 -w test2.cap '(net or or (mpls and mpls 19) or (mpls 23 and mpls 25)'

it seems like only the first "mpls and mpls 19" filter will any of you guys can tell if we can capture 2 layer label (23,25) and 1 layer label 19 at the same time please?

asked 13 Dec '10, 19:08

alexzhao's gravatar image

accept rate: 0%

edited 13 Dec '10, 19:09

First of all, capture filters use BPF filters and BPF is based on a tiny state machine with a few machine instructions. You can show the code that will be used by a capture filter by using dumpcap -d or tcpdump -d.

Whenever a keyword is used in a capture filter that denotes an encapsulation (vlan, mpls, ppp, etc), the offset into the packet is increased by the size of the encapsulation header. So in your case, each mpls keyword increases the offset with 4 bytes. This results in BPF code that looks at the wrong place for your mpls labels. As can be seen in the following output (restricted to the first part of your filter):

$ tcpdump -d '(mpls and mpls 19)'
(000) ldh      [12]
(001) jeq      #0x8847          jt 2    jf 8
(002) ldb      [16]
(003) jset     #0x1             jt 8    jf 4
(004) ld       [18]
(005) and      #0xfffff000
(006) jeq      #0x13000         jt 7    jf 8
(007) ret      #65535
(008) ret      #0

The first mpls label starts at offset 14 and the second at offset 18. However, the generated code first looks at the "bottom of stack" bit of the first mpls header and then checks the actual label in the second mpls header. So using mpls keywords multiple times in a filter will not help you.

The only way to get the result you want is to manually look at the proper locations for your mpls labels. You can change your filter (only the mpls part) to:

$ tcpdump -d 'mpls and ( 
    (ether[14:4]&0xfffff100=0x13100) or 
    (ether[14:4]&0xfffff100=0x17000 and ether[18:4]&0xfffff100=0x19100) 
(000) ldh      [12]
(001) jeq      #0x8847          jt 2    jf 10
(002) ld       [14]
(003) and      #0xfffff100
(004) jeq      #0x13100         jt 9    jf 5
(005) jeq      #0x17000         jt 6    jf 10
(006) ld       [18]
(007) and      #0xfffff100
(008) jeq      #0x19100         jt 9    jf 10
(009) ret      #65535
(010) ret      #0

(I have split the command for readability, it should be on one line though)

This filter first checks for the mpls ethertype. Then it checks the first mpls header to see whether label 19 is present and that it is the last label in the stack. If not, it checks whether label 23 is present and that label 23 is not the last label. In case of the latter, it then checks the second mpls header to see whether it has label 25 and that is now is the last label in the stack.

I don't have a MPLS trace with multiple labels to experiment with, but looking at the generated BPF code, I think it should work :-)

permanent link

answered 14 Dec '10, 01:02

SYN-bit's gravatar image

SYN-bit ♦♦
accept rate: 20%

Thanks, it perfectly resolved my question and give me a new way to capture packets with T-shark filter.

(14 Dec '10, 05:32) alexzhao

I converted your answer to a comment, please have a look at :

to know why :-)

(14 Dec '10, 05:57) SYN-bit ♦♦
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here



Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text]( "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:


question asked: 13 Dec '10, 19:08

question was seen: 9,929 times

last updated: 14 Dec '10, 05:57

p​o​w​e​r​e​d by O​S​Q​A