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

Changing the link-layer type of input frames

0

Hi,

I am writing a dissector plugin for Wireshark, which decapsulates an Ethernet frame with an additional tag between src address and type/length field (like 802.1q). I understood about the wtap_encap dissector table. By default (as far as I know) Wireshark reads the link-layer type from the interface (which is usually 1 => Ethernet) and that's the first dissector that it uses. My target is to change the link-layer input type of wireshark to 147 (DLT_USER0) so that my dissector can be the entry point of the process of decapsulation. How can I do that ? I tried to make a crazy pipe

tcpdump -l -nvvvXXes0 | od -Ax -tx1 -v - | text2pcap -l 147 - - | wireshark -k -i -

The goal of the upper command is to capture (live) packets with tcpdump then use od to hexdump them in the appropriate format for text2pcap which then changes the link-layer type to 147 and pipes that to wireshark. The problem is that text2pcap, for some reason, merges the packets and outputs them to wireshark as 64000 byte packets.

Is there any other way of making a live wireshark capture while changing the link-layer type to 147 ?
And what's the problem of text2pcap ? Maybe I'm not using the appropriate options to tcpdump and it doesn't like the input format ...

asked 09 Jul '13, 06:50

dvlahovski's gravatar image

dvlahovski
5114
accept rate: 0%


3 Answers:

2

There are several problems with your command chain.

1.) tcpdump output to od

This is what tcpdump writes on my system, if I run it with your parameters (tcpdump -l -nvvvXXes0).

01:14:07.649043 00:0c:29:f6:9e:14 > 00:50:56:e0:14:49, ethertype IPv4 (0x0800), length 95: (tos 0x0, ttl 64, id 9872, offset 0, flags [DF], proto TCP (6), length 81)
    192.168.158.128.50199 > 1.2.3.4.443: Flags [P.], cksum 0x6667 (correct), seq 1547098647:1547098688, ack 492193187, win 64197, length 41
    0x0000:  0050 56e0 1449 000c 29f6 9e14 0800 4500  .PV..I..).....E.
    0x0010:  0051 2690 4000 4006 53e8 c0a8 9e80 5043  .Q&[email protected]@.S.....PC
    0x0020:  10c3 c417 01bb 5c36 da17 1d56 45a3 5018  ......\6...VE.P.
    0x0030:  fac5 6667 0000 1703 0100 24a0 d25c bdcb  ..fg......$..\..
    0x0040:  9f8e 7ffd 2892 68a8 9fee d381 8d85 ee0e  ....(.h.........
    0x0050:  2f42 8e1a 4942 d8c7 e65b 07f0 0be2 e9    /B..IB...[.....

Converting that output with od to hex and then piping it to text2pcap does not work, as you will pipe the hex representation of the ASCII output of tcpdump to text2pcap. This will give totally random results.

2.) Output of tcpdump

The output of tcpdump is (unfortunately) not in a format that text2pcap understands (see man page of text2pcap)

Text2pcap understands a hexdump of the form generated by od -Ax -tx1 -v. In other words, each byte is individually displayed and surrounded with a space. Each line begins with an offset describing the position in the file. The offset is a hex number (can also be octal or decimal - see -o), of more than two hex digits. Here is a sample dump that text2pcap can recognize:

Output of tcpdump:

01:14:07.649043 00:0c:29:f6:9e:14 > 00:50:56:e0:14:49, ethertype IPv4 (0x0800), length 95: (tos 0x0, ttl 64, id 9872, offset 0, flags [DF], proto TCP (6), length 81)
    192.168.158.128.50199 > 1.2.3.4.443: Flags [P.], cksum 0x6667 (correct), seq 1547098647:1547098688, ack 492193187, win 64197, length 41
    0x0000:  0050 56e0 1449 000c 29f6 9e14 0800 4500  .PV..I..).....E.
    0x0010:  0051 2690 4000 4006 53e8 c0a8 9e80 5043  .Q&[email protected]@.S.....PC

This is what text2pcap needs:

01:14:07.649043
0000  00 50 56 e0 14 49 00 0c 29 f6 9e 14 08 00 45 00
0010  00 51 26 90 40 00 40 06 53 e8 c0 a8 9e 80 50 43

So, you need to reformat the tcpdump output. Here is a small perl script that will reformat the text.

#!/usr/bin/perl

$| = 1;

my $regexp_time = '(\d\d:\d\d:\d\d.\d+ )'; my $regexp_hex = '(0x\d+:\s+)([0-9a-f ]+)+ ';

while (<STDIN>) {

my $input = $_;

if ($input =~ /^$regexp_time/) { print "$1\n"; }

if ($input =~ /$regexp_hex/) { my $counter = $1; my $line = $2;

  $line =~ s/ //g;
  $counter =~ s/(0x|:)//g;

  print $counter . join(&#39; &#39;, ( $line =~ m/../g )) . &quot;\n&quot;;

} }

Then run your command like this:

tcpdump -l -nvvvXXes0 | perl convert.pl | text2pcap -l 147 - - | wireshark -k -i -

Please report back, if it works. I was not able to test it yet.

UPDATE:

Basically it (the script) works, but without a dissector for the link-layer type 147, the data makes no sense to wireshark.

Regards
Kurt

answered 10 Jul ‘13, 03:13

Kurt%20Knochner's gravatar image

Kurt Knochner ♦
24.8k1039237
accept rate: 15%

edited 11 Jul ‘13, 01:02

Hi,
Thank you very much for the help !
The script really perfectly does the job. But for the first N packets. I mean that, when I run the command chain, the first time, I got 17 proper packets (with total length of ~2100 bytes) and then it started to print only 16 byte packets. After that, I ran it a second time and then got 64 proper packets (with total size of ~4400 bytes) and then started to output only 16 byte packets again. And it happens every time - from a given point on(undefined, I think, because the byte offset after it happens is different every time) it prints only 16 byte packets. When I changed the link-layer type to 1, to see what’s happening, I saw that it was dissecting the proper packets without a problem. The 16 byte packets ethertype was recognized, but they were (obviously) stated as malformed. Do you have any idea why does this problem occur ?

Best regards and many thanks,
D. Vlahovski

(18 Jul ‘13, 06:54) dvlahovski
1

I had the same issue with text2pcap 1.6.9 (Ubuntu). After I upgraded to 1.10.0 the problem was gone.

(19 Jul ‘13, 01:47) Kurt Knochner ♦

0

I think the problem is that your hex stream after the od command is just one continuous block of hex data, so text2pcap probably cuts it into the larges slices it can. Have you tried the -m parameter of text2pcak that limits the maximum packet size? I haven't tested if it help, but you might want to check it out. Unfortunately that will probably result in packets of the same size, and not what they originally where, so I guess it will not help that much either.

You could also try to get better results by capturing with dumpcap or tshark to get the frame delimiter right, but once again I haven't tried that myself. All in all you're trying some sort of Frankenstein capture maneuver and I'm not sure if it can work at all :-)

Maybe changing the link-layer type in the file after capture is complete may be an option?

answered 10 Jul '13, 02:05

Jasper's gravatar image

Jasper ♦♦
23.8k551284
accept rate: 18%

0

My target is to change the link-layer input type of wireshark to 147 (DLT_USER0) so that my dissector can be the entry point of the process of decapsulation. How can I do that ?

Try

editcap -T user0 -F libpcap {input file} {output file}

to read a pcap file {input file} and write out the exact same packet data to a pcap file {output file}, but with a different link-layer header type in the file header.

That might also work for pcap-ng files (if you're reading a pcap-ng file, you can leave out the -F libpcap).

answered 18 Jul '13, 12:23

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%