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

* Re: Unable to receive UI frames with DGRAM socket
  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>
  1 sibling, 0 replies; 6+ messages in thread
From: David Ranch @ 2021-09-22 15:36 UTC (permalink / raw)
  To: thomas, linux-hams


Hello Thomas,

I recommend to look at how ax25-apps's "listen" program works to get 
some ideas.  It DOESN'T bind to the stack in the way you're proposing 
and instead uses the SOCK_PACKET approach.

--David
KI6ZHD


On 09/21/2021 11:56 AM, thomas@habets.se wrote:
> 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

* Re: Unable to receive UI frames with DGRAM socket
       [not found] ` <e235ee10-5774-f690-0c5e-5dc575482936@trinnet.net>
@ 2021-09-22 21:11   ` thomas
  2021-09-24 17:29     ` thomas
  0 siblings, 1 reply; 6+ messages in thread
From: thomas @ 2021-09-22 21:11 UTC (permalink / raw)
  To: David Ranch; +Cc: linux-hams

On Wed, 22 Sep 2021 16:32:41 +0100, David Ranch <linux-hams@trinnet.net> said:
> I recommend to look at how ax25-apps's "listen" program works to get
> some ideas.  It DOESN'T bind to the stack in the way you're proposing
> and instead uses the SOCK_PACKET approach.

Yeah, I tried to draw inspiration from others. But I'm failing to find
anything that doesn't require root.

E.g. axlisten from ax25-apps does:
  socket(AF_PACKET, SOCK_PACKET, htons(ETH_P_AX25))
axlisten -a does:
  socket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))

Both require root (or NET_ADMIN, or whatever capability).

But surely there should be a way to use SOCK_DGRAM, in any capacity at
all?
The code explicitly handles it here:
https://elixir.bootlin.com/linux/latest/source/net/ax25/ax25_in.c#L260

While working on this I've actually already been doing experiments
with SOCK_PACKET, and yes sure aside from needing root and requiring
parsing the AX.25 header myself, it does work.

But those are two major drawbacks.

--
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

* Re: Unable to receive UI frames with DGRAM socket
  2021-09-22 21:11   ` thomas
@ 2021-09-24 17:29     ` thomas
  2021-09-24 18:18       ` David Ranch
  0 siblings, 1 reply; 6+ messages in thread
From: thomas @ 2021-09-24 17:29 UTC (permalink / raw)
  To: David Ranch; +Cc: linux-hams

On Wed, 22 Sep 2021 22:11:11 +0100, thomas@habets.se said:
> But surely there should be a way to use SOCK_DGRAM, in any capacity at
> all?

I made an ugly patch that at least will make SOCK_DGRAM work.

I didn't make too much effort into perfecting it, because it's unclear
to me how SOCK_DGRAM is supposed to even work.

E.g. it seems to be possible to bind() to addresses that don't have an
axparms --assoc, but should it be?

And I'm not sure if I should change the transport header size for UI
frames without L3 information so that it's 1 for AX25_P_TEXT
frames. Seems that I should seeing as how experimentally when you send
it it's only one byte.

There's also the issue of multiple sockets listening to the same
SSID. Should that be possible? Currently the input handling code only
looks up the first `struct sock` and gives the packet there.

Summary of problems before this patch:
* AX25 SOCK_DGRAM just plain seems broken, meaning SEQPACKET and
  PACKET (effectively RAW) are the only two options for userspace.
* And PACKET, the only way to receive UI frames, requires root
* PACKET also requires parsing the header, including digipeater path,
  by the user.

Summary of problems with this patch:
* Transport header is probably set incorrectly
* Only one socket can receive the data, including broadcast data
* It's unclear what socket semantics are intended
* Unclear what socket security restrictions are intended

But it works. Aside from the problems above it does work:

recvfrom(3, "PING", 4196, 0, {sa_family=AF_AX25,
fsa_ax25={sax25_call={ax25_call="\x9a\x60\xa8\x90\x86\x40\x69"} /*
M0THC-4 */, sax25_ndigis=0}}, [72]) = 4

(actually should the local interface SSID be added to the sax25_ndigis
here. It's not, as you can see)

diff --git a/include/net/ax25.h b/include/net/ax25.h
index 8b7eb46ad72d..acc557d53cb7 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -303,7 +303,7 @@ extern struct hlist_head ax25_list;
 extern spinlock_t ax25_list_lock;
 void ax25_cb_add(ax25_cb *);
 struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int);
-struct sock *ax25_get_socket(ax25_address *, ax25_address *, int);
+struct sock *ax25_get_socket(ax25_address *, int);
 ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *,
                      struct net_device *);
 void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 269ee89d2c2b..4c41717530b8 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -176,17 +176,15 @@ struct sock *ax25_find_listener(ax25_address
*addr, int digi,
 /*
  *     Find an AX.25 socket given both ends.
  */
-struct sock *ax25_get_socket(ax25_address *my_addr, ax25_address *dest_addr,
-       int type)
+struct sock *ax25_get_socket(ax25_address *my_addr, int type)
 {
        struct sock *sk = NULL;
        ax25_cb *s;

        spin_lock(&ax25_list_lock);
        ax25_for_each(s, &ax25_list) {
-               if (s->sk && !ax25cmp(&s->source_addr, my_addr) &&
-                   !ax25cmp(&s->dest_addr, dest_addr) &&
-                   s->sk->sk_type == type) {
+               if (s->sk && s->sk->sk_type == type &&
+                   !ax25cmp(&s->source_addr, my_addr)) {
                        sk = s->sk;
                        sock_hold(sk);
                        break;
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index cd6afe895db9..9872b92a58ca 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -231,12 +231,11 @@ static int ax25_rcv(struct sk_buff *skb, struct
net_device *dev,

                ax25_send_to_raw(&dest, skb, skb->data[1]);

-               if (!mine && ax25cmp(&dest, (ax25_address
*)dev->broadcast) != 0)
-                       goto free;
-
                /* Now we are pointing at the pid byte */
                switch (skb->data[1]) {
                case AX25_P_IP:
+                       if (!mine && ax25cmp(&dest, (ax25_address
*)dev->broadcast) != 0)
+                               goto free;
                        skb_pull(skb,2);                /* drop PID/CTRL */
                        skb_reset_transport_header(skb);
                        skb_reset_network_header(skb);
@@ -247,6 +246,8 @@ static int ax25_rcv(struct sk_buff *skb, struct
net_device *dev,
                        break;

                case AX25_P_ARP:
+                       if (!mine && ax25cmp(&dest, (ax25_address
*)dev->broadcast) != 0)
+                               goto free;
                        skb_pull(skb,2);
                        skb_reset_transport_header(skb);
                        skb_reset_network_header(skb);
@@ -257,7 +258,7 @@ static int ax25_rcv(struct sk_buff *skb, struct
net_device *dev,
                        break;
                case AX25_P_TEXT:
                        /* Now find a suitable dgram socket */
-                       sk = ax25_get_socket(&dest, &src, SOCK_DGRAM);
+                       sk = ax25_get_socket(&dest, SOCK_DGRAM);
                        if (sk != NULL) {
                                bh_lock_sock(sk);
                                if (atomic_read(&sk->sk_rmem_alloc) >=
@@ -267,7 +268,7 @@ static int ax25_rcv(struct sk_buff *skb, struct
net_device *dev,
                                        /*
                                         *      Remove the control and PID.
                                         */
-                                       skb_pull(skb, 2);
+                                       skb_pull(skb, 1);
                                        if (sock_queue_rcv_skb(sk, skb) != 0)
                                                kfree_skb(skb);
                                }

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

* Re: Unable to receive UI frames with DGRAM socket
  2021-09-24 17:29     ` thomas
@ 2021-09-24 18:18       ` David Ranch
  2021-09-25 11:27         ` thomas
  0 siblings, 1 reply; 6+ messages in thread
From: David Ranch @ 2021-09-24 18:18 UTC (permalink / raw)
  To: thomas; +Cc: linux-hams


Hello Thomas,

I'm not qualified to answer if your changes here are valid, secure, a 
good idea, etc.  I would recommend to start a discussion with the Linux 
AX.25 maintainer who would know better on a programmatic level:

    https://raw.githubusercontent.com/torvalds/linux/master/MAINTAINERS
    --
    AX.25 NETWORK LAYER
    M:	Ralf Baechle <ralf@linux-mips.org>
    L:	linux-hams@vger.kernel.org
    S:	Maintained
    W:	http://www.linux-ax25.org/
    F:	include/net/ax25.h
    F:	include/uapi/linux/ax25.h
    F:	net/ax25/
    --


Ps.  It dawned on me that there is another approach to give non-root yet 
promiscuous AX.25 listening abilities in Linux:

    ax25spyd:  https://salsa.debian.org/debian-hamradio-team/ax25spyd

I don't think it's actively maintained and I've seen some intermittent 
working / broken behavior on it but it DOES mostly work.  Something to 
consider.

--David
KI6ZHD



On 09/24/2021 10:29 AM, thomas@habets.se wrote:
> On Wed, 22 Sep 2021 22:11:11 +0100, thomas@habets.se said:
>> But surely there should be a way to use SOCK_DGRAM, in any capacity at
>> all?
>
> I made an ugly patch that at least will make SOCK_DGRAM work.
>
> I didn't make too much effort into perfecting it, because it's unclear
> to me how SOCK_DGRAM is supposed to even work.
>
> E.g. it seems to be possible to bind() to addresses that don't have an
> axparms --assoc, but should it be?
>
> And I'm not sure if I should change the transport header size for UI
> frames without L3 information so that it's 1 for AX25_P_TEXT
> frames. Seems that I should seeing as how experimentally when you send
> it it's only one byte.
>
> There's also the issue of multiple sockets listening to the same
> SSID. Should that be possible? Currently the input handling code only
> looks up the first `struct sock` and gives the packet there.
>
> Summary of problems before this patch:
> * AX25 SOCK_DGRAM just plain seems broken, meaning SEQPACKET and
>   PACKET (effectively RAW) are the only two options for userspace.
> * And PACKET, the only way to receive UI frames, requires root
> * PACKET also requires parsing the header, including digipeater path,
>   by the user.
>
> Summary of problems with this patch:
> * Transport header is probably set incorrectly
> * Only one socket can receive the data, including broadcast data
> * It's unclear what socket semantics are intended
> * Unclear what socket security restrictions are intended
>
> But it works. Aside from the problems above it does work:
>
> recvfrom(3, "PING", 4196, 0, {sa_family=AF_AX25,
> fsa_ax25={sax25_call={ax25_call="\x9a\x60\xa8\x90\x86\x40\x69"} /*
> M0THC-4 */, sax25_ndigis=0}}, [72]) = 4
>
> (actually should the local interface SSID be added to the sax25_ndigis
> here. It's not, as you can see)
>
> diff --git a/include/net/ax25.h b/include/net/ax25.h
> index 8b7eb46ad72d..acc557d53cb7 100644
> --- a/include/net/ax25.h
> +++ b/include/net/ax25.h
> @@ -303,7 +303,7 @@ extern struct hlist_head ax25_list;
>  extern spinlock_t ax25_list_lock;
>  void ax25_cb_add(ax25_cb *);
>  struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int);
> -struct sock *ax25_get_socket(ax25_address *, ax25_address *, int);
> +struct sock *ax25_get_socket(ax25_address *, int);
>  ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *,
>                       struct net_device *);
>  void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
> diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
> index 269ee89d2c2b..4c41717530b8 100644
> --- a/net/ax25/af_ax25.c
> +++ b/net/ax25/af_ax25.c
> @@ -176,17 +176,15 @@ struct sock *ax25_find_listener(ax25_address
> *addr, int digi,
>  /*
>   *     Find an AX.25 socket given both ends.
>   */
> -struct sock *ax25_get_socket(ax25_address *my_addr, ax25_address *dest_addr,
> -       int type)
> +struct sock *ax25_get_socket(ax25_address *my_addr, int type)
>  {
>         struct sock *sk = NULL;
>         ax25_cb *s;
>
>         spin_lock(&ax25_list_lock);
>         ax25_for_each(s, &ax25_list) {
> -               if (s->sk && !ax25cmp(&s->source_addr, my_addr) &&
> -                   !ax25cmp(&s->dest_addr, dest_addr) &&
> -                   s->sk->sk_type == type) {
> +               if (s->sk && s->sk->sk_type == type &&
> +                   !ax25cmp(&s->source_addr, my_addr)) {
>                         sk = s->sk;
>                         sock_hold(sk);
>                         break;
> diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
> index cd6afe895db9..9872b92a58ca 100644
> --- a/net/ax25/ax25_in.c
> +++ b/net/ax25/ax25_in.c
> @@ -231,12 +231,11 @@ static int ax25_rcv(struct sk_buff *skb, struct
> net_device *dev,
>
>                 ax25_send_to_raw(&dest, skb, skb->data[1]);
>
> -               if (!mine && ax25cmp(&dest, (ax25_address
> *)dev->broadcast) != 0)
> -                       goto free;
> -
>                 /* Now we are pointing at the pid byte */
>                 switch (skb->data[1]) {
>                 case AX25_P_IP:
> +                       if (!mine && ax25cmp(&dest, (ax25_address
> *)dev->broadcast) != 0)
> +                               goto free;
>                         skb_pull(skb,2);                /* drop PID/CTRL */
>                         skb_reset_transport_header(skb);
>                         skb_reset_network_header(skb);
> @@ -247,6 +246,8 @@ static int ax25_rcv(struct sk_buff *skb, struct
> net_device *dev,
>                         break;
>
>                 case AX25_P_ARP:
> +                       if (!mine && ax25cmp(&dest, (ax25_address
> *)dev->broadcast) != 0)
> +                               goto free;
>                         skb_pull(skb,2);
>                         skb_reset_transport_header(skb);
>                         skb_reset_network_header(skb);
> @@ -257,7 +258,7 @@ static int ax25_rcv(struct sk_buff *skb, struct
> net_device *dev,
>                         break;
>                 case AX25_P_TEXT:
>                         /* Now find a suitable dgram socket */
> -                       sk = ax25_get_socket(&dest, &src, SOCK_DGRAM);
> +                       sk = ax25_get_socket(&dest, SOCK_DGRAM);
>                         if (sk != NULL) {
>                                 bh_lock_sock(sk);
>                                 if (atomic_read(&sk->sk_rmem_alloc) >=
> @@ -267,7 +268,7 @@ static int ax25_rcv(struct sk_buff *skb, struct
> net_device *dev,
>                                         /*
>                                          *      Remove the control and PID.
>                                          */
> -                                       skb_pull(skb, 2);
> +                                       skb_pull(skb, 1);
>                                         if (sock_queue_rcv_skb(sk, skb) != 0)
>                                                 kfree_skb(skb);
>                                 }
>

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

* Re: Unable to receive UI frames with DGRAM socket
  2021-09-24 18:18       ` David Ranch
@ 2021-09-25 11:27         ` thomas
  0 siblings, 0 replies; 6+ messages in thread
From: thomas @ 2021-09-25 11:27 UTC (permalink / raw)
  To: David Ranch; +Cc: linux-hams

On Fri, 24 Sep 2021 19:18:25 +0100, David Ranch <linux-hams@trinnet.net> said:
> I would recommend to start a discussion with the Linux
> AX.25 maintainer who would know better on a programmatic level:

Thanks, I'll do that.

> Ps.  It dawned on me that there is another approach to give non-root yet
> promiscuous AX.25 listening abilities in Linux:
>
>     ax25spyd:  https://salsa.debian.org/debian-hamradio-team/ax25spyd

Thanks. I had a look, and it seems that this is essentially a root
daemon that multiplexes AX.25 access through an API.

Note that I don't actually want promiscuous AX.25 listening. I just
want to bind() and then receive UI frames destined for that
address. Just like UDP.

If I understand that correctly then really the applications no longer
use AX.25 sockets, and I start wondering if it's even worth having
support for them in the kernel, as opposed to just having a KISS
multiplexer daemon plus a library.

I tried out ax25spyd and as expected I got:

socket(AF_INET, SOCK_PACKET, 0x300 /* IPPROTO_??? */) = -1 EPERM
(Operation not permitted)

--
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.