Отслеживание пакета по мере его прохождения через ядро (linux)
у меня есть две машины, которые настроены на использование Ip-безопасности, а машина A (давайте назовем их A и B) имеет сокет, который привязан к определенному порту UDP на локальной машине, и он часто опрашивает его, чтобы увидеть, получено ли что-нибудь на нем.
когда я отключаю Ip-безопасность, данные между двумя машинами проходят нормально, и я отправляю и получаю пакеты нормально. Но когда Ip-безопасность включена, пакет не попадает в этот сокет на машине, отправленной машиной Б.
Я tcpdump
на обеих машинах, и я вижу, что (зашифрованный) пакет отправляется с машины B и принимается на машине A. Но после этого пакет переходит в ядро и где-то либо в расшифровке пакета, либо на какой-то другой фазе пакет отбрасывается.
Я хочу иметь возможность отслеживать пакет, когда он проходит через ядро, и видеть, где он отброшен. Есть некоторые /proc
что я могу использовать для этой цели? Другой метод я могу подумайте о том, чтобы вставить операторы отладки по всему ядру и перекомпилировать его, а затем попытаться отправить пакет снова и пройти отладку.
спасибо и извините за длинное сообщение, но это было необходимо.
2 ответов
пожалуйста, обратитесь к проекту под названием SystemTap. Он позволяет вставлять удобные скрипты, подключенные к любому коду ядра, без перекомпиляции ядра. Например:
probe function("ip_rcv").call {
printf("%d: ->ip_rcv()\n", gettimeofday_ms())
}
он будет выдавать печать ядра для каждого полученного пакета на сетевом уровне. Конечно, вам нужно будет прочитать источники, чтобы следовать оттуда глубже в сетевой стек.
SystemTap очень способен и довольно документирован о различных крючках, которые могут быть вставленный.
да, как сказал Дэн, SystemTap полезен. Но мой любимый ftrace.
Для справки:
поэтому для отслеживания сетевого трафика в целом поместите следующее в оболочку bash и запустите его как root:
mkdir /debug
mount -t debugfs nodev /debug
mount -t debugfs nodev /sys/kernel/debug
echo '*' >/debug/tracing/set_ftrace_filter
echo function_graph >/debug/tracing/current_tracer
echo 1 >/debug/tracing/tracing_on
sleep 20
echo 0 >/debug/tracing/tracing_on
cat /debug/tracing/trace > /tmp/tracing.out$$
и так далее по пути приема:
5) | tcp_recvmsg() {
5) | lock_sock_nested() {
5) 0.042 us | _cond_resched();
5) | _raw_spin_lock_bh() {
5) 0.040 us | local_bh_disable();
5) 0.414 us | }
5) 0.040 us | _raw_spin_unlock();
5) 0.040 us | local_bh_enable();
5) 1.814 us | }
5) | skb_copy_datagram_iovec() {
5) 0.042 us | _cond_resched();
5) 0.588 us | }
5) 0.042 us | tcp_rcv_space_adjust();
5) | __kfree_skb() {
5) | skb_release_all() {
5) | skb_release_head_state() {
5) 0.044 us | sock_rfree();
5) 0.670 us | }
5) | skb_release_data() {
5) | put_page() {
5) 0.049 us | put_compound_page();
5) 0.449 us | }
и так:
обработка Netlink:
6) | rtnetlink_rcv() {
6) | mutex_lock() {
6) 0.090 us | _cond_resched();
6) 1.455 us | }
6) | netlink_rcv_skb() {
6) | rtnetlink_rcv_msg() {
6) 0.150 us | mutex_unlock();
6) | __netlink_dump_start() {
6) | netlink_lookup() {
6) 0.091 us | _raw_read_lock();
6) 0.100 us | netlink_compare();
6) 1.791 us | }
6) | mutex_lock() {
6) 0.095 us | _cond_resched();
6) 0.913 us | }
6) 0.100 us | try_module_get();
6) 0.090 us | mutex_unlock();
и это попадание также:
3) | tcp_v4_rcv() {
3) | sk_filter() {
3) | security_sock_rcv_skb() {
3) 0.076 us | cap_socket_sock_rcv_skb();
3) 0.867 us | }
3) 1.630 us | }
3) 0.076 us | _raw_spin_lock();
3) 0.477 us | tcp_prequeue();
3) | tcp_v4_do_rcv() {
3) 0.088 us | tcp_md5_do_lookup();
3) 0.109 us | tcp_parse_md5sig_option();
3) 0.072 us | ipv4_dst_check();
3) | tcp_rcv_established() {
3) 0.076 us | tcp_parse_aligned_timestamp.part.34();
3) | tcp_queue_rcv() {
3) | tcp_try_coalesce.part.41() {
3) 0.835 us | skb_try_coalesce();
3) 1.722 us | }
3) 2.637 us | }
и это выход (начиная с syscall " sendmsg()"):
5) | SyS_sendmsg() {
5) | __sys_sendmsg() {
5) | sockfd_lookup_light() {
5) 0.080 us | fget_light();
5) 0.502 us | }
5) | ___sys_sendmsg() {
5) 0.117 us | copy_msghdr_from_user();
5) 0.101 us | verify_iovec();
5) | sock_sendmsg() {
5) | security_socket_sendmsg() {
5) | apparmor_socket_sendmsg() {
5) 0.092 us | aa_revalidate_sk();
5) 0.580 us | }
5) 1.044 us | }
5) | unix_stream_sendmsg() {
5) 0.113 us | wait_for_unix_gc();
5) | security_socket_getpeersec_dgram() {
5) 0.044 us | apparmor_socket_getpeersec_dgram();
5) 0.479 us | }
5) | sock_alloc_send_pskb() {
5) | __alloc_skb() {
5) | kmem_cache_alloc_node() {
5) 0.042 us | _cond_resched();
5) 0.648 us | }
5) | __kmalloc_reserve.isra.27() {
5) | __kmalloc_node_track_caller() {
5) 0.074 us | kmalloc_slab();
5) 0.040 us | _cond_resched();
5) 0.504 us | __slab_alloc();
5) 1.878 us | }
5) 2.276 us | }
5) 0.175 us | ksize();
5) 4.217 us | }
Надеюсь, вам понравится....