1. 环境版本
类别 | 版本 | 链接 |
---|---|---|
libpcap | 1.7.4 | https://github.com/the-tcpdump-group/libpcap/releases/tag/libpcap-1.7.4 |
tcpdump | 4.5.1 | https://github.com/the-tcpdump-group/tcpdump/releases/tag/tcpdump-4.5.1 |
目标内核 | 4.9.84 | / |
编译系统 | Ubuntu 20.04.06 Linux 5.15.0 | / |
tcpdump 依赖于 libpcap,先根据以上链接下载 libpcap 和 tcpdump
2. 交叉编译
2.1 设置交叉编译环境变量
export PATH=/opt/linaro-14.04/gcc-linaro-arm-linux-gnueabihf-4.8/bin:$PATH
export CC=arm-linux-gnueabihf-gcc
需要根据自己交叉编译工具链的路径和交叉编译 gcc 文件名进行替换
2.2 交叉编译 libpcap
交叉编译不能确定目标内核版本,需要手工指定嵌入式系统的内核版本,通过 ac_cv_linux_vers 进行指定
tar -zxvf libpcap-libpcap-1.7.4.tar.gz
cd libpcap-libpcap-1.7.4
ac_cv_linux_vers=4.9.84 ./configure --host=arm-linux --with-pcap=linux
make
sudo make install
执行 ac_cv_linux_vers=4.9.84 ./configure --host=arm-linux --with-pcap=linux 命令后需要输出如下内容才表明配置成功:
configure: creating ./config.status
config.status: creating Makefile
config.status: creating pcap-filter.manmisc
config.status: creating pcap-linktype.manmisc
config.status: creating pcap-tstamp.manmisc
config.status: creating pcap-savefile.manfile
config.status: creating pcap.3pcap
config.status: creating pcap_compile.3pcap
config.status: creating pcap_datalink.3pcap
config.status: creating pcap_dump_open.3pcap
config.status: creating pcap_get_tstamp_precision.3pcap
config.status: creating pcap_list_datalinks.3pcap
config.status: creating pcap_list_tstamp_types.3pcap
config.status: creating pcap_open_dead.3pcap
config.status: creating pcap_open_offline.3pcap
config.status: creating pcap_set_tstamp_precision.3pcap
config.status: creating pcap_set_tstamp_type.3pcap
config.status: creating config.h
config.status: executing default-1 commands
执行 make 之后需要输入如下内容才表明编译成功:
arm-linux-gnueabihf-gcc -fpic -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -g -O2 -c bpf_filter.c
if grep GIT ./VERSION >/dev/null; then \
read ver <./VERSION; \
echo $ver | tr -d '\012'; \
date +_%Y_%m_%d; \
else \
cat ./VERSION; \
fi | sed -e 's/.*/char pcap_version[] = "&";/' > version.c
arm-linux-gnueabihf-gcc -fpic -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -g -O2 -c version.c
arm-linux-gnueabihf-ar rc libpcap.a pcap-linux.o pcap-usb-linux.o pcap-can-linux.o pcap-netfilter-linux.o fad-getad.o pcap.o inet.o gencode.o optimize.o nametoaddr.o etherent.o savefile.o sf-pcap.o sf-pcap-ng.o pcap-common.o bpf_image.o bpf_dump.o scanner.o grammar.o bpf_filter.o version.o
arm-linux-gnueabihf-ranlib libpcap.a
VER=`cat ./VERSION`; \
MAJOR_VER=`sed 's/\([0-9][0-9]*\)\..*/\1/' ./VERSION`; \
arm-linux-gnueabihf-gcc -shared -Wl,-soname,libpcap.so.$MAJOR_VER \
-o libpcap.so.$VER pcap-linux.o pcap-usb-linux.o pcap-can-linux.o pcap-netfilter-linux.o fad-getad.o pcap.o inet.o gencode.o optimize.o nametoaddr.o etherent.o savefile.o sf-pcap.o sf-pcap-ng.o pcap-common.o bpf_image.o bpf_dump.o scanner.o grammar.o bpf_filter.o version.o
./config.status --file=pcap-config.tmp:./pcap-config.in
config.status: creating pcap-config.tmp
mv pcap-config.tmp pcap-config
chmod a+x pcap-config
如果执行 sudo make install 报错如下:
VER=`cat ./VERSION`; \
MAJOR_VER=`sed 's/\([0-9][0-9]*\)\..*/\1/' ./VERSION`; \
arm-linux-gnueabihf-gcc -shared -Wl,-soname,libpcap.so.$MAJOR_VER \
-o libpcap.so.$VER pcap-linux.o pcap-usb-linux.o pcap-can-linux.o pcap-netfilter-linux.o fad-getad.o pcap.o inet.o gencode.o optimize.o nametoaddr.o etherent.o savefile.o sf-pcap.o sf-pcap-ng.o pcap-common.o bpf_image.o bpf_dump.o scanner.o grammar.o bpf_filter.o version.o
/bin/sh: 3: arm-linux-gnueabihf-gcc: not found
make: *** [Makefile:372: libpcap.so] Error 127
明明之前已经指定了交叉编译路径,为啥还会发现不了??此时可以在执行 make install 时指定交叉编译工具的路径:
sudo make install CC=/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc RANLIB=/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ranlib
2.2 交叉编译 tcpdump
交叉编译不能确定目标内核版本,需要手工指定嵌入式系统的内核版本,通过 ac_cv_linux_vers 进行指定
tar -zxvf tcpdump-tcpdump-4.5.1.tar.gz
cd tcpdump-tcpdump-4.5.1
ac_cv_linux_vers=4.9.84 ./configure --host=arm-linux
make
编译完成后将在本目录下生成 tcpdump 可执行文件(2.8M左右),但是这种情况下,在目标系统上运行 tcpdump 需要依赖 libpcap.so.1(libpcap.so.1.7.4)(在之前编译 libpcap 的目录下可以找到)
需要生成不依赖 libpcap 共享库的 tcpdump,需要重新执行 make,如下图所示:
make LDFLAGS="-static"
将会输出如下结果,可以忽略警告,表示编译成功:
arm-linux-gnueabihf-gcc -ffloat-store -DHAVE_CONFIG_H -I./missing -D_U_="__attribute__((unused))" -I. -I/usr/local/include -I./missing -g -O2 -static -o tcpdump addrtoname.o af.o checksum.o cpack.o gmpls.o oui.o gmt2local.o ipproto.o nlpid.o l2vpn.o machdep.o parsenfsfh.o in_cksum.o print-802_11.o print-802_15_4.o print-ap1394.o print-ah.o print-arcnet.o print-aodv.o print-arp.o print-ascii.o print-atalk.o print-atm.o print-beep.o print-bfd.o print-bgp.o print-bootp.o print-bt.o print-calm-fast.o print-carp.o print-cdp.o print-cfm.o print-chdlc.o print-cip.o print-cnfp.o print-dccp.o print-decnet.o print-domain.o print-dtp.o print-dvmrp.o print-enc.o print-egp.o print-eap.o print-eigrp.o print-esp.o print-ether.o print-fddi.o print-forces.o print-fr.o print-geonet.o print-gre.o print-hsrp.o print-icmp.o print-igmp.o print-igrp.o print-ip.o print-ipcomp.o print-ipfc.o print-ipnet.o print-ipx.o print-isoclns.o print-juniper.o print-krb.o print-l2tp.o print-lane.o print-ldp.o print-lldp.o print-llc.o print-lmp.o print-lspping.o print-lwapp.o print-lwres.o print-mobile.o print-mpcp.o print-mpls.o print-mptcp.o print-msdp.o print-msnlb.o print-nflog.o print-nfs.o print-ntp.o print-null.o print-olsr.o print-openflow.o print-openflow-1.0.o print-ospf.o print-pgm.o print-pim.o print-ppi.o print-ppp.o print-pppoe.o print-pptp.o print-radius.o print-raw.o print-rip.o print-rpki-rtr.o print-rrcp.o print-rsvp.o print-rx.o print-sctp.o print-sflow.o print-sip.o print-sl.o print-sll.o print-slow.o print-snmp.o print-stp.o print-sunatm.o print-sunrpc.o print-symantec.o print-syslog.o print-tcp.o print-telnet.o print-tftp.o print-timed.o print-tipc.o print-token.o print-udld.o print-udp.o print-usb.o print-vjc.o print-vqp.o print-vrrp.o print-vtp.o print-wb.o print-zephyr.o print-zeromq.o print-vxlan.o print-otv.o signature.o setsignal.o tcpdump.o util.o version.o print-smb.o smbutil.o strlcat.o strlcpy.o print-isakmp.o -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lpcap
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: tcpdump.o: in function `droproot':
/home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./tcpdump.c:566: warning: Using 'initgroups' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: /home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./tcpdump.c:544: warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: /usr/local/lib/libpcap.a(nametoaddr.o): in function `pcap_nametoaddrinfo':
/home/xingzb/work/ssd_tcpdump/libpcap-libpcap-1.7.4/./nametoaddr.c:128: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: addrtoname.o: in function `getname':
/home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./addrtoname.c:249: warning: Using 'gethostbyaddr' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: /usr/local/lib/libpcap.a(nametoaddr.o): in function `pcap_nametoaddr':
/home/xingzb/work/ssd_tcpdump/libpcap-libpcap-1.7.4/./nametoaddr.c:102: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: /usr/local/lib/libpcap.a(nametoaddr.o): in function `pcap_nametonetaddr':
/home/xingzb/work/ssd_tcpdump/libpcap-libpcap-1.7.4/./nametoaddr.c:146: warning: Using 'getnetbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: print-cnfp.o: in function `cnfp_print':
/home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./print-cnfp.c:155: warning: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: print-isakmp.o: in function `ikev1_id_print':
/home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./print-isakmp.c:925: warning: Using 'setprotoent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: /home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./print-isakmp.c:931: warning: Using 'endprotoent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: /usr/local/lib/libpcap.a(nametoaddr.o): in function `pcap_nametoproto':
/home/xingzb/work/ssd_tcpdump/libpcap-libpcap-1.7.4/./nametoaddr.c:263: warning: Using 'getprotobyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: /usr/local/lib/libpcap.a(nametoaddr.o): in function `pcap_nametoport':
/home/xingzb/work/ssd_tcpdump/libpcap-libpcap-1.7.4/./nametoaddr.c:176: warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: addrtoname.o: in function `init_servarray':
/home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./addrtoname.c:737: warning: Using 'getservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: /home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./addrtoname.c:757: warning: Using 'endservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/gcc-sigmastar-9.1.0-2020.07-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/9.1.0/../../../../arm-linux-gnueabihf/bin/ld: print-sunrpc.o: in function `progstr':
/home/xingzb/work/ssd_tcpdump/tcpdump-tcpdump-4.5.1/./print-sunrpc.c:163: warning: Using 'getrpcbynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
编译完成后将在本目录下生成不需要依赖 libpcap 共享库的 tcpdump 可执行文件(9.7M左右)
3 设备运行 tcpdump 磁盘空间不足的处理
如果目标设备的磁盘空间不足,可以尝试以下方式实时把抓取的数据通过网络传输出去。
-
使用 SSH 传输数据:
在目标设备上运行 tcpdump 并通过 SSH 将数据传输到另一台设备:
tcpdump -i eth0 -w - | ssh user@remote_host ‘cat > /path/to/save/capture.pcap’这条命令会在本地设备上捕获数据,并通过 SSH 将数据传输到远程设备上的指定路径。
-
使用 netcat (nc) 传输数据:
在远程设备上启动 netcat 监听:
nc -l -p 12345 > /path/to/save/capture.pcap在本地设备上运行 tcpdump 并通过 netcat 发送数据:
tcpdump -i eth0 -w - | nc remote_host 12345这条命令会在本地设备上捕获数据,并通过 netcat 将数据传输到远程设备上的指定端口。
-
使用 Wireshark 远程捕获:
在本地设备上运行 tcpdump 并将数据通过管道传输到 Wireshark:
tcpdump -i eth0 -w - | wireshark -k -i -这条命令会在本地设备上捕获数据,并通过管道将数据传输到 Wireshark 进行实时分析。