Udit Gupta
Udit Gupta

Reputation: 3272

need an awk/sed/cut alternative for an simple looking issue on tcpdump output

This is my input file to the problem, it contains different type of n/w packets along with header information.

This is a sample file consisting of only two packets ...

18:10:17.528660 IP6 2001::100 > 2001::200: ESP(spi=0x00005fb4,seq=0x23),
length 168
    0x0000:  6000 0000 00A8 3220 2001 0000 0000 0000   ................
    0x0010:  0000 0000 0000 0100 2001 0000 0000 0000   ................
    0x0020:  0000 0000 0000 0200 0000 5FB4 0000 0023   ................
    0x0030:  0000 0000 0000 0000 0000 0000 0000 0000   ................
    0x0040:  0000 0000 0000 0000 0000 0000 0000 0000   ................
    0x0050:  0000 0000 0000 0000 0000 0000 0000 0000   ................
    0x0060:  5361 6C74 6564 5F5F 1267 6EE1 8FFD A625   ................
    0x0070:  6DAB 0F22 B006 0809 505F CD62 4C4F FCC2   ................
    0x0080:  0966 DD9A E1E8 F582 EF63 C8BF 5F08 3D46   ................
    0x0090:  3033 3361 3666 6131 3430 3036 6163 3931   ................
    0x00a0:  3365 6137 3936 3866 6133 6334 6434 3837   ................
    0x00b0:  3037 6531 6534 3761 0A00 0000 0000 0000   ................
    0x00c0:  0000 0000 0000 0000 0000 0000 0000 0000   ................
18:10:17.528660 IP6 2001::100 > 2001::200: ESP(spi=0x00005fb4,seq=0x23), 
length 168
    0x0000:  6000 0000 0070 3220 0000 0000 0000 0000   ................
    0x0040:  0000 0000 0000 0001 0000 0000 0000 0000   ................
    0x0050:  0000 0000 0000 0002 0000 0270 0000 000D   ................
    0x0060:  5361 6C74 6564 5F5F 682A CB8F 97D9 10A2   ................
    0x0070:  1D12 88CB EE21 9F00 42AF AFA4 C919 B1E6   ................
    0x0080:  045A B5DF 93BE FA50 3231 3164 3939 6534   ................
    0x0090:  3332 6563 3634 3737 6133 6265 3231 6161   ................
    0x00a0:  3730 3866 6331 3636 3363 3933 6232 3264   ................
    0x00b0:  0A00 0000 0000 0000 0000 0000 0000 0000   ................
    0x00c0:  0000 0000 0000 0000                       ........

these ... could be anything they are respective ascii charaters corresponding to the specified hex characters. I need to extract the middle hex portion only of each packet.

I need output in the following format.

6000 0000 00A8 3220 2001 0000 0000 0000
0000 0000 0000 0100 2001 0000 0000 0000
0000 0000 0000 0200 0000 5FB4 0000 0023
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
5361 6C74 6564 5F5F 1267 6EE1 8FFD A625
6DAB 0F22 B006 0809 505F CD62 4C4F FCC2
0966 DD9A E1E8 F582 EF63 C8BF 5F08 3D46
3033 3361 3666 6131 3430 3036 6163 3931
3365 6137 3936 3866 6133 6334 6434 3837
3037 6531 6534 3761 0A00 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000

For example,here two files should generate namely ipsec_packet1.txt and ipsec_packet2.txt and each should consist of middle hex portion specified in above format only.

Here is my script ..

 cat received_ipsec.txt | tr '[a-z]' '[A-Z]' > tmp_tcpdump.txt

 count=`grep -w -c 0X0000 tmp_tcpdump.txt`

 grep -w -n 0X0000 tmp_tcpdump.txt > tmp_samp.txt

 i=1

 cut -d ":" -f$i tmp_samp.txt | tr '\n' ' ' > tmp_try.txt

 while [ $i -le $count ]

 do

    k=`expr $i + 1 `

    prev_j=`cut -d " " -f$i tmp_try.txt`
    next_j=`cut -d " " -f$k tmp_try.txt`

// this part need attention ......

    if [ $i -eq $count ]
    then

            awk -v prev_j=$prev_j '{if(NR>=prev_j)print $0}' 
      tmp_tcpdump.txt > tmp_packet.txt


       // first trial failed so commented

          # cut -d ":" -f2 tmp_packet.txt | sed 's/ *//' | 
          #   cut -d " " -f1-8 > ipsec_packet$i.txt

       // secone trial failde so commented

          #  cut -d " " -f 3-10 tmp_packet.txt > ipsec_packet$i.txt

       // third one although it also not working properly but will 
          explain it below


      cut -d ":" -f2 tmp_packet.txt | awk -F " " 
      '{printf "%s %s %s %s %s %s %s %s \n",
       $1,$2,$3,$4,$5,$6,$7,$8}' >ipsec_packet$i.txt

    else
            awk -v prev_j=$prev_j -v next_j=$next_j 
       '{if(NR>=prev_j && NR<next_j-1)print $0}' tmp_tcpdump.txt
       > tmp_packet.txt

      # cut -d ":" -f2 tmp_packet.txt | sed 's/ *//' | 
      #  cut -d " " -f1-8 > ipsec_packet$i.txt

     #  cut -d " " -f 3-10 tmp_packet.txt > ipsec_packet$i.txt


       cut -d ":" -f2 tmp_packet.txt | awk -F " " 
    '{printf "%s %s %s %s %s %s %s %s \n",
     $1,$2,$3,$4,$5,$6,$7,$8}' > ipsec_packet$i.txt

    fi

    i=`expr $i + 1 `

   done 

Now what is the problem creating part is ...

   cut -d ":" -f2 tmp_packet.txt | awk -F " " 
    '{printf "%s %s %s %s %s %s %s %s \n",
     $1,$2,$3,$4,$5,$6,$7,$8}' 

if last line is something like that then no problen (as in packet 1 above)

   0000 0000 0000 0000 0000 0000 0000 0000 

but if last line is something like that then there is a problem (as in packet 2 above)

   0000 0000 0000 0000 

then it will grasp the other four fields from the dotted portion like ..

   0000 0000 0000 0000 ....

May be I do not require all this to perform my task but I am new so do not know much about this sed/awk world.

EDIT:

this is output of one of the sample of grep ...and I do not have any reason why it is in this format. That is why I have not used a simple cut by column logic

2:      0X0000:  6000 0000 00A8 3220 2001 0000 0000 0000  
16:        0X0000:       6000 0000 0070 3220 0000 0000 0000 0000
27:     0X0000:  6000 0000 0080 3220 0000 0000 0000 0000

Upvotes: 1

Views: 1989

Answers (4)

jaypal singh
jaypal singh

Reputation: 77185

Awk Solution:

awk '$1~/0x/ {$1="";$10="";print}' INPUT_FILE | awk 'NF!=8{$NF=""; print;next} {$1=$1}1'

Execution:

[jaypal:~/Temp] cat file4
18:10:17.528660 IP6 2001::100 > 2001::200: ESP(spi=0x00005fb4,seq=0x23),
length 168
    0x0000:  6000 0000 00A8 3220 2001 0000 0000 0000   ................
    0x0010:  0000 0000 0000 0100 2001 0000 0000 0000   ................
    0x0020:  0000 0000 0000 0200 0000 5FB4 0000 0023   ................
    0x0030:  0000 0000 0000 0000 0000 0000 0000 0000   ................
    0x0040:  0000 0000 0000 0000 0000 0000 0000 0000   ................
    0x0050:  0000 0000 0000 0000 0000 0000 0000 0000   ................
    0x0060:  5361 6C74 6564 5F5F 1267 6EE1 8FFD A625   ................
    0x0070:  6DAB 0F22 B006 0809 505F CD62 4C4F FCC2   ................
    0x0080:  0966 DD9A E1E8 F582 EF63 C8BF 5F08 3D46   ................
    0x0090:  3033 3361 3666 6131 3430 3036 6163 3931   ................
    0x00a0:  3365 6137 3936 3866 6133 6334 6434 3837   ................
    0x00b0:  3037 6531 6534 3761 0A00 0000 0000 0000   ................
    0x00c0:  0000 0000 0000 0000 0000 0000 0000 0000   ................
18:10:17.528660 IP6 2001::100 > 2001::200: ESP(spi=0x00005fb4,seq=0x23), 
length 168
    0x0000:  6000 0000 0070 3220 0000 0000 0000 0000   ................
    0x0040:  0000 0000 0000 0001 0000 0000 0000 0000   ................
    0x0050:  0000 0000 0000 0002 0000 0270 0000 000D   ................
    0x0060:  5361 6C74 6564 5F5F 682A CB8F 97D9 10A2   ................
    0x0070:  1D12 88CB EE21 9F00 42AF AFA4 C919 B1E6   ................
    0x0080:  045A B5DF 93BE FA50 3231 3164 3939 6534   ................
    0x0090:  3332 6563 3634 3737 6133 6265 3231 6161   ................
    0x00a0:  3730 3866 6331 3636 3363 3933 6232 3264   ................
    0x00b0:  0A00 0000 0000 0000 0000 0000 0000 0000   ................
    0x00c0:  0000 0000 0000 0000                       ........

[jaypal:~/Temp] awk '$1~/0x/ {$1="";$10="";print}' INPUT_FILE | awk 'NF!=8{$NF=""; print;next} {$1=$1}1'
6000 0000 00A8 3220 2001 0000 0000 0000
0000 0000 0000 0100 2001 0000 0000 0000
0000 0000 0000 0200 0000 5FB4 0000 0023
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
5361 6C74 6564 5F5F 1267 6EE1 8FFD A625
6DAB 0F22 B006 0809 505F CD62 4C4F FCC2
0966 DD9A E1E8 F582 EF63 C8BF 5F08 3D46
3033 3361 3666 6131 3430 3036 6163 3931
3365 6137 3936 3866 6133 6334 6434 3837
3037 6531 6534 3761 0A00 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
6000 0000 0070 3220 0000 0000 0000 0000
0000 0000 0000 0001 0000 0000 0000 0000
0000 0000 0000 0002 0000 0270 0000 000D
5361 6C74 6564 5F5F 682A CB8F 97D9 10A2
1D12 88CB EE21 9F00 42AF AFA4 C919 B1E6
045A B5DF 93BE FA50 3231 3164 3939 6534
3332 6563 3634 3737 6133 6265 3231 6161
3730 3866 6331 3636 3363 3933 6232 3264
0A00 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 

OR

You can even use this - cut -d " " -f 6-13 INPUT_FILE | sed -e '/^$\|^[A-Z]/d' -e 's/^ //g'

Upvotes: 0

Zsolt Botykai
Zsolt Botykai

Reputation: 51693

With (g)awk:

awk '/^ *0x....:/ {print substr($0,14,39)}' INPUTFILE

HTH

Upvotes: 0

Kent
Kent

Reputation: 195249

based on your example, you simply need a short awk oneliner: note that there are two space in -F

 awk -F'  ' '{print $4}' yourFile

to get the parts you need.

a test on your example: (t is the file)

kent$  awk -F'  ' '{print $4}' t


6000 0000 00A8 3220 2001 0000 0000 0000
0000 0000 0000 0100 2001 0000 0000 0000
0000 0000 0000 0200 0000 5FB4 0000 0023
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
5361 6C74 6564 5F5F 1267 6EE1 8FFD A625
6DAB 0F22 B006 0809 505F CD62 4C4F FCC2
0966 DD9A E1E8 F582 EF63 C8BF 5F08 3D46
3033 3361 3666 6131 3430 3036 6163 3931
3365 6137 3936 3866 6133 6334 6434 3837
3037 6531 6534 3761 0A00 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000


6000 0000 0070 3220 0000 0000 0000 0000
0000 0000 0000 0001 0000 0000 0000 0000
0000 0000 0000 0002 0000 0270 0000 000D
5361 6C74 6564 5F5F 682A CB8F 97D9 10A2
1D12 88CB EE21 9F00 42AF AFA4 C919 B1E6
045A B5DF 93BE FA50 3231 3164 3939 6534
3332 6563 3634 3737 6133 6265 3231 6161
3730 3866 6331 3636 3363 3933 6232 3264
0A00 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000

Upvotes: 0

user1046334
user1046334

Reputation:

After you grep only the relevant line, just do

cut -d: -f2- | cut -c3-42

There can be off-by-one errors, but those you can fix by trial and error. Alternatively, you can do it by just one lone cut -c... but you need to count more characters.

Upvotes: 2

Related Questions