All of lore.kernel.org
 help / color / mirror / Atom feed
* Unable to receive UI frames with DGRAM socket
@ 2021-09-21 18:56 thomas
  2021-09-22 15:36 ` David Ranch
       [not found] ` <e235ee10-5774-f690-0c5e-5dc575482936@trinnet.net>
  0 siblings, 2 replies; 6+ messages in thread
From: thomas @ 2021-09-21 18:56 UTC (permalink / raw)
  To: linux-hams

Hi.

I'm trying to send and receive UI frames with a DGRAM socket, but am
not having any success. I've resorted to using bpftrace to find where
the frames are dropped and the code looks very strange to me.

After bind() to an address, netstat -nap shows:

Active AX.25 sockets
Dest       Source     Device  State        Vr/Vs    Send-Q  Recv-Q
*          M6VMB-1    ax0     LISTENING    000/000  0       0

That seems fine, but note the unspecified destination. That's on
purpose, since I want to listen to any and all UI frames going to
M6VMB-1.

But it looks like UI frames will only work when both source and
destination are an exact match.

ax25_get_socket() checks both[1], and it's called from ax25_rcv[2].

And that's where the packet is dropped. With my bpftrace[3] I see this
(annotated. function name means kprobe, tilde-version means kretprobe):

Attaching 11 probes...
ax25_kiss_rcv()        # Packet received
ax25cmp                # Is it our port address?
~ax25cmp 0             # ... yes it is
ax25_send_to_raw(,0xffff9d2078d37e00, f0)
    Type (3 for UI): 3     # UI packet
    Proto: f0              # AX25_P_TEXT
ax25cmp                    # is this socket listening for this?
~ax25cmp 0                 # ... yes, but it's not a raw socket,
                           #     so never mind.
~ax25_send_to_raw
ax25_get_socket(l@,d`g,type=2)   # ok, time to find the right socket
ax25cmp              # does this dst address match local?
~ax25cmp 0           # .. yes it does!
ax25cmp              # does the src match... "*" from netstat?
~ax25cmp 1           # ... of course it doesn't, but why should it?
~ax25_get_socket = (nil)    # found no socket listening :-(
kfree_skb                   # throw packet on the floor
~ax25_kiss_rcv              # give up


Is this a bug? Is it even possible to receive UI frames without a raw
socket?

As a workaround, is it possible to set the destination address for
bind()ing? That'd make it point-to-point UI, so still not great.

By the way, I also found it odd that socket addresses are compared
before socket type. Surely it must be slightly more efficient to check
socket type (SOCK_RAW or DGRAM) first, and only do the address
comparisons after?

The packet looks fine on the receive side in axlisten:

radio6: fm 2E0VMB-3 to M6VMB-1 ctl UI^ pid=F0(Text) len 5 19:43:32.787076
0000  hello

[1] https://elixir.bootlin.com/linux/latest/source/net/ax25/af_ax25.c#L179
[2] https://elixir.bootlin.com/linux/latest/source/net/ax25/ax25_in.c#L260
[3] #!/bin/bpftrace

#include <linux/skbuff.h>
#include <uapi/linux/ax25.h>

kprobe:ax25_kiss_rcv {@t[tid]=1; printf("ax25_kiss_rcv()\n");}
kretprobe:ax25_kiss_rcv {delete(@t[tid]); printf("~ax25_kiss_rcv\n");}


kprobe:ax25_send_to_raw /@t[tid]==1/ {
  $skb = (struct sk_buff*)arg1;
  printf("ax25_send_to_raw(,%p, %x)\n", $skb, arg2);
  printf("    Type (3 for UI): %x\n", *$skb->data);
  printf("    Proto: %x\n", arg2);
}
kretprobe:ax25_send_to_raw /@t[tid]==1/ {
  printf("~ax25_send_to_raw\n");
}

kprobe:netif_rx /@t[tid]==1/ {  printf("netif_rx\n");}

kprobe:ax25cmp /@t[tid]==1/ {  printf("ax25cmp\n");}
kretprobe:ax25cmp /@t[tid]==1/ {
  printf("~ax25cmp %d\n", retval);
}


kprobe:ax25_get_socket /@t[tid]==1/ {
  $a = (ax25_address*)arg0;
  $b = (ax25_address*)arg1;
  printf("ax25_get_socket(%s,%s,type=%x)\n",
        $a->ax25_call,
        $b->ax25_call,
        arg2);
  @oride[tid] = 1;
}
kretprobe:ax25_get_socket /@t[tid]==1/ {
  printf("~ax25_get_socket = %p\n", retval);
  delete(@oride[tid]);
}

kretprobe:ax25_listen_mine /@t[tid]==1/ {  printf("~ax25_listen_mine
%d\n", retval);}

kprobe:kfree_skb /@t[tid]==1/ {  printf("kfree_skb\n");}


--
typedef struct me_s {
  char name[]      = { "Thomas Habets" };
  char email[]     = { "thomas@habets.se" };
  char kernel[]    = { "Linux" };
  char *pgpKey[]   = { "http://www.habets.pp.se/pubkey.txt" };
  char pgp[] = { "9907 8698 8A24 F52F 1C2E  87F6 39A4 9EEA 460A 0169" };
  char coolcmd[]   = { "echo '. ./_&. ./_'>_;. ./_" };
} me_t;

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-09-25 11:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-21 18:56 Unable to receive UI frames with DGRAM socket thomas
2021-09-22 15:36 ` David Ranch
     [not found] ` <e235ee10-5774-f690-0c5e-5dc575482936@trinnet.net>
2021-09-22 21:11   ` thomas
2021-09-24 17:29     ` thomas
2021-09-24 18:18       ` David Ranch
2021-09-25 11:27         ` thomas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.