Bash 또는 awk에서 16진수 덤프를 바이트 단위로 읽는 방법은 무엇입니까?

Bash 또는 awk에서 16진수 덤프를 바이트 단위로 읽는 방법은 무엇입니까?

이는 다음 명령을 사용하여 캡처한 IPv6 TCP 패킷의 16진수 출력입니다 tcpdump.

 6000 0000 0018 0620 0000 0000
 0000 0000 0000 0000 0000 0001 0000 0000
 0000 0000 0000 0000 0000 0002 *0026 0026
 0000 0001 0000 0002 {5}412 0065 0034 0000*
 6162 6364    

패킷 자체는 *위의 s 사이에 있습니다. 패킷 길이를 32비트 워드로 나타냅니다 {5}(따라서 5워드 길이 - 20바이트). 이 정보에서 tcp 헤더를 추출하려면 bash/awk 스크립트를 사용해야 하므로 스크립트는 길이 바이트를 찾고 이를 사용하여 얼마나 더 읽어야 하는지 알아야 합니다. Bash나 awk에서 어떻게 할 수 있나요?

답변1

이는 Perl이나 Python에서 하는 작업에 가깝지만 순수 bash에서도 수행할 수 있습니다. 경고: 테스트되지 않았습니다.

ipv6_packet='6000 … 6364'
ipv6_packet=${ipv6_packet,,?}               # normalize hexadecimal digits to lowercase, just in case
ipv6_packet=${ipv6_packet//[!0-9a-f]/}      # remove whitespace and everything else that isn't a hex digit
tcp_packet=${ipv6_packet:80}                # all but the first 40 bytes (IPv6 header)
((tcp_data_offset=0x${tcp_packet:24:1}*4))  # data offset (25th nybble), converted from words to bytes
tcp_header=${tcp_packet:0:$tcp_data_offset} # that's the TCP header (still in hexdump form)

또는 줄여서:

ipv6_packet=${ipv6_packet,,?}; ipv6_packet=${ipv6_packet//[!0-9a-f]/}
tcp_header=${ipv6_packet:80:$((0x${ipv6_packet:104:1}*4))}

관련 정보