^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) Darryl Miles G7LED (dlm@g7led.demon.co.uk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) Steven Whitehouse GW7RRM (stevew@acm.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) Hans Alblas PE1AYX (hans@esrac.ele.tue.nl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/sockios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <net/ax25.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/termios.h> /* For TIOCINQ/OUTQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/sysctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <net/tcp_states.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <net/arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) HLIST_HEAD(ax25_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) DEFINE_SPINLOCK(ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static const struct proto_ops ax25_proto_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static void ax25_free_sock(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ax25_cb_put(sk_to_ax25(sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Socket removal during an interrupt is now safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static void ax25_cb_del(ax25_cb *ax25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (!hlist_unhashed(&ax25->ax25_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) spin_lock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) hlist_del_init(&ax25->ax25_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) spin_unlock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ax25_cb_put(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Kill all bound sockets on a dropped device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static void ax25_kill_by_device(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ax25_dev *ax25_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ax25_cb *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) spin_lock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ax25_for_each(s, &ax25_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (s->ax25_dev == ax25_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) sk = s->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (!sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) spin_unlock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) s->ax25_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ax25_disconnect(s, ENETUNREACH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) spin_lock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) spin_unlock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) s->ax25_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ax25_disconnect(s, ENETUNREACH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) spin_lock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* The entry could have been deleted from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * list meanwhile and thus the next pointer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * no longer valid. Play it safe and restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * the scan. Forward progress is ensured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * because we set s->ax25_dev to NULL and we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * are never passed a NULL 'dev' argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) spin_unlock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Handle device status changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int ax25_device_event(struct notifier_block *this, unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct net_device *dev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (!net_eq(dev_net(dev), &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Reject non AX.25 devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (dev->type != ARPHRD_AX25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) case NETDEV_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ax25_dev_device_up(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case NETDEV_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ax25_kill_by_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ax25_rt_device_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ax25_dev_device_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * Add a socket to the bound sockets list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) void ax25_cb_add(ax25_cb *ax25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) spin_lock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ax25_cb_hold(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) hlist_add_head(&ax25->ax25_node, &ax25_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) spin_unlock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Find a socket that wants to accept the SABM we have just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct sock *ax25_find_listener(ax25_address *addr, int digi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct net_device *dev, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ax25_cb *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) spin_lock(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ax25_for_each(s, &ax25_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if ((s->iamdigi && !digi) || (!s->iamdigi && digi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (s->sk && !ax25cmp(&s->source_addr, addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) s->sk->sk_type == type && s->sk->sk_state == TCP_LISTEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* If device is null we match any device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (s->ax25_dev == NULL || s->ax25_dev->dev == dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) sock_hold(s->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) spin_unlock(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return s->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) spin_unlock(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * Find an AX.25 socket given both ends.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct sock *ax25_get_socket(ax25_address *my_addr, ax25_address *dest_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct sock *sk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ax25_cb *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) spin_lock(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ax25_for_each(s, &ax25_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (s->sk && !ax25cmp(&s->source_addr, my_addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) !ax25cmp(&s->dest_addr, dest_addr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) s->sk->sk_type == type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) sk = s->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) spin_unlock(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Find an AX.25 control block given both ends. It will only pick up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * floating AX.25 control blocks or non Raw socket bound control blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ax25_cb *ax25_find_cb(ax25_address *src_addr, ax25_address *dest_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ax25_digi *digi, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ax25_cb *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) spin_lock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ax25_for_each(s, &ax25_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (s->sk && s->sk->sk_type != SOCK_SEQPACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (s->ax25_dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (ax25cmp(&s->source_addr, src_addr) == 0 && ax25cmp(&s->dest_addr, dest_addr) == 0 && s->ax25_dev->dev == dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (digi != NULL && digi->ndigi != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (s->digipeat == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (ax25digicmp(s->digipeat, digi) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (s->digipeat != NULL && s->digipeat->ndigi != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ax25_cb_hold(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) spin_unlock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) spin_unlock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) EXPORT_SYMBOL(ax25_find_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) void ax25_send_to_raw(ax25_address *addr, struct sk_buff *skb, int proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ax25_cb *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct sk_buff *copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) spin_lock(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ax25_for_each(s, &ax25_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (s->sk != NULL && ax25cmp(&s->source_addr, addr) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) s->sk->sk_type == SOCK_RAW &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) s->sk->sk_protocol == proto &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) s->ax25_dev->dev == skb->dev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) atomic_read(&s->sk->sk_rmem_alloc) <= s->sk->sk_rcvbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if ((copy = skb_clone(skb, GFP_ATOMIC)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (sock_queue_rcv_skb(s->sk, copy) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) kfree_skb(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) spin_unlock(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * Deferred destroy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) void ax25_destroy_socket(ax25_cb *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * Handler for deferred kills.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void ax25_destroy_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ax25_cb *ax25 = from_timer(ax25, t, dtimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) sk=ax25->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) bh_lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ax25_destroy_socket(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) bh_unlock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * This is called from user mode and the timers. Thus it protects itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * against interrupt users but doesn't worry about being called during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * work. Once it is removed from the queue no interrupt or bottom half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * will touch it and we are (fairly 8-) ) safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) void ax25_destroy_socket(ax25_cb *ax25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ax25_cb_del(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ax25_stop_heartbeat(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ax25_stop_t1timer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ax25_stop_t2timer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ax25_stop_t3timer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ax25_stop_idletimer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ax25_clear_queues(ax25); /* Flush the queues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (ax25->sk != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) while ((skb = skb_dequeue(&ax25->sk->sk_receive_queue)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (skb->sk != ax25->sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* A pending connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ax25_cb *sax25 = sk_to_ax25(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Queue the unaccepted socket for death */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) sock_orphan(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* 9A4GL: hack to release unaccepted sockets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) skb->sk->sk_state = TCP_LISTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ax25_start_heartbeat(sax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sax25->state = AX25_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) skb_queue_purge(&ax25->sk->sk_write_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (ax25->sk != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (sk_has_allocations(ax25->sk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* Defer: outstanding buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) timer_setup(&ax25->dtimer, ax25_destroy_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ax25->dtimer.expires = jiffies + 2 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) add_timer(&ax25->dtimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct sock *sk=ax25->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ax25->sk=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ax25_cb_put(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * dl1bke 960311: set parameters for existing AX.25 connections,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * includes a KILL command to abort any connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * VERY useful for debugging ;-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct ax25_ctl_struct ax25_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ax25_digi digi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ax25_dev *ax25_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) unsigned int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (copy_from_user(&ax25_ctl, arg, sizeof(ax25_ctl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if ((ax25_dev = ax25_addr_ax25dev(&ax25_ctl.port_addr)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (ax25_ctl.digi_count > AX25_MAX_DIGIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (ax25_ctl.arg > ULONG_MAX / HZ && ax25_ctl.cmd != AX25_KILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) digi.ndigi = ax25_ctl.digi_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) for (k = 0; k < digi.ndigi; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) digi.calls[k] = ax25_ctl.digi_addr[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if ((ax25 = ax25_find_cb(&ax25_ctl.source_addr, &ax25_ctl.dest_addr, &digi, ax25_dev->dev)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) switch (ax25_ctl.cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case AX25_KILL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) #ifdef CONFIG_AX25_DAMA_SLAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (ax25_dev->dama.slave && ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_DAMA_SLAVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ax25_dama_off(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ax25_disconnect(ax25, ENETRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case AX25_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (ax25->modulus == AX25_MODULUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (ax25_ctl.arg < 1 || ax25_ctl.arg > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (ax25_ctl.arg < 1 || ax25_ctl.arg > 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ax25->window = ax25_ctl.arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) case AX25_T1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ax25->rtt = (ax25_ctl.arg * HZ) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ax25->t1 = ax25_ctl.arg * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case AX25_T2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ax25->t2 = ax25_ctl.arg * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case AX25_N2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ax25_ctl.arg < 1 || ax25_ctl.arg > 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ax25->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ax25->n2 = ax25_ctl.arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case AX25_T3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (ax25_ctl.arg > ULONG_MAX / HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ax25->t3 = ax25_ctl.arg * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) case AX25_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (ax25_ctl.arg > ULONG_MAX / (60 * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ax25->idle = ax25_ctl.arg * 60 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) case AX25_PACLEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (ax25_ctl.arg < 16 || ax25_ctl.arg > 65535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ax25->paclen = ax25_ctl.arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) goto einval_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ax25_cb_put(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) einval_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static void ax25_fillin_cb_from_dev(ax25_cb *ax25, ax25_dev *ax25_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ax25->rtt = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ax25->t1 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ax25->t2 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ax25->t3 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ax25->n2 = ax25_dev->values[AX25_VALUES_N2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ax25->paclen = ax25_dev->values[AX25_VALUES_PACLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ax25->idle = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_IDLE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ax25->backoff = ax25_dev->values[AX25_VALUES_BACKOFF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (ax25_dev->values[AX25_VALUES_AXDEFMODE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ax25->modulus = AX25_EMODULUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ax25->window = ax25_dev->values[AX25_VALUES_EWINDOW];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ax25->modulus = AX25_MODULUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ax25->window = ax25_dev->values[AX25_VALUES_WINDOW];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * Fill in a created AX.25 created control block with the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * values for a particular device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) void ax25_fillin_cb(ax25_cb *ax25, ax25_dev *ax25_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ax25->ax25_dev = ax25_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (ax25->ax25_dev != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ax25_fillin_cb_from_dev(ax25, ax25_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * No device, use kernel / AX.25 spec default values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ax25->rtt = msecs_to_jiffies(AX25_DEF_T1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ax25->t1 = msecs_to_jiffies(AX25_DEF_T1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ax25->t2 = msecs_to_jiffies(AX25_DEF_T2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ax25->t3 = msecs_to_jiffies(AX25_DEF_T3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ax25->n2 = AX25_DEF_N2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ax25->paclen = AX25_DEF_PACLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ax25->idle = msecs_to_jiffies(AX25_DEF_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ax25->backoff = AX25_DEF_BACKOFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (AX25_DEF_AXDEFMODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ax25->modulus = AX25_EMODULUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ax25->window = AX25_DEF_EWINDOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ax25->modulus = AX25_MODULUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ax25->window = AX25_DEF_WINDOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * Create an empty AX.25 control block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ax25_cb *ax25_create_cb(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if ((ax25 = kzalloc(sizeof(*ax25), GFP_ATOMIC)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) refcount_set(&ax25->refcount, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) skb_queue_head_init(&ax25->write_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) skb_queue_head_init(&ax25->frag_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) skb_queue_head_init(&ax25->ack_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) skb_queue_head_init(&ax25->reseq_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ax25_setup_timers(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ax25_fillin_cb(ax25, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ax25->state = AX25_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * Handling for system calls applied via the various interfaces to an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * AX25 socket object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int ax25_setsockopt(struct socket *sock, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) sockptr_t optval, unsigned int optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) char devname[IFNAMSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) unsigned int opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (level != SOL_AX25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (optlen < sizeof(unsigned int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (copy_from_sockptr(&opt, optval, sizeof(unsigned int)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ax25 = sk_to_ax25(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) switch (optname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) case AX25_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (ax25->modulus == AX25_MODULUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (opt < 1 || opt > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (opt < 1 || opt > 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) ax25->window = opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) case AX25_T1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (opt < 1 || opt > UINT_MAX / HZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ax25->rtt = (opt * HZ) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ax25->t1 = opt * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) case AX25_T2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (opt < 1 || opt > UINT_MAX / HZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ax25->t2 = opt * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) case AX25_N2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (opt < 1 || opt > 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ax25->n2 = opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case AX25_T3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (opt < 1 || opt > UINT_MAX / HZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ax25->t3 = opt * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) case AX25_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (opt > UINT_MAX / (60 * HZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ax25->idle = opt * 60 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) case AX25_BACKOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (opt > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ax25->backoff = opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) case AX25_EXTSEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ax25->modulus = opt ? AX25_EMODULUS : AX25_MODULUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) case AX25_PIDINCL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ax25->pidincl = opt ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) case AX25_IAMDIGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ax25->iamdigi = opt ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) case AX25_PACLEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (opt < 16 || opt > 65535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ax25->paclen = opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) case SO_BINDTODEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (optlen > IFNAMSIZ - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) optlen = IFNAMSIZ - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) memset(devname, 0, sizeof(devname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (copy_from_sockptr(devname, optval, optlen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) res = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (sk->sk_type == SOCK_SEQPACKET &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) (sock->state != SS_UNCONNECTED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) sk->sk_state == TCP_LISTEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) res = -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dev = __dev_get_by_name(&init_net, devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) res = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ax25->ax25_dev = ax25_dev_ax25dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (!ax25->ax25_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) res = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ax25_fillin_cb(ax25, ax25->ax25_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) res = -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int ax25_getsockopt(struct socket *sock, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) char __user *optval, int __user *optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct ax25_dev *ax25_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) char devname[IFNAMSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) void *valptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) int maxlen, length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (level != SOL_AX25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (get_user(maxlen, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (maxlen < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) valptr = (void *) &val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) length = min_t(unsigned int, maxlen, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ax25 = sk_to_ax25(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) switch (optname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case AX25_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) val = ax25->window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case AX25_T1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) val = ax25->t1 / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case AX25_T2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) val = ax25->t2 / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) case AX25_N2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) val = ax25->n2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) case AX25_T3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) val = ax25->t3 / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) case AX25_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) val = ax25->idle / (60 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) case AX25_BACKOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) val = ax25->backoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case AX25_EXTSEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) val = (ax25->modulus == AX25_EMODULUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case AX25_PIDINCL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) val = ax25->pidincl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case AX25_IAMDIGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) val = ax25->iamdigi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) case AX25_PACLEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) val = ax25->paclen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case SO_BINDTODEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ax25_dev = ax25->ax25_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (ax25_dev != NULL && ax25_dev->dev != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) strlcpy(devname, ax25_dev->dev->name, sizeof(devname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) length = strlen(devname) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) *devname = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) valptr = (void *) devname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (put_user(length, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return copy_to_user(optval, valptr, length) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static int ax25_listen(struct socket *sock, int backlog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (sk->sk_type == SOCK_SEQPACKET && sk->sk_state != TCP_LISTEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) sk->sk_max_ack_backlog = backlog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) sk->sk_state = TCP_LISTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) res = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * XXX: when creating ax25_sock we should update the .obj_size setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static struct proto ax25_proto = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .name = "AX25",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .obj_size = sizeof(struct ax25_sock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static int ax25_create(struct net *net, struct socket *sock, int protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) int kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (protocol < 0 || protocol > U8_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (!net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return -EAFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) switch (sock->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) case SOCK_DGRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (protocol == 0 || protocol == PF_AX25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) protocol = AX25_P_TEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case SOCK_SEQPACKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) switch (protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) case PF_AX25: /* For CLX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) protocol = AX25_P_TEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case AX25_P_SEGMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) #ifdef CONFIG_INET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) case AX25_P_ARP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case AX25_P_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) #ifdef CONFIG_NETROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) case AX25_P_NETROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) #ifdef CONFIG_ROSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) case AX25_P_ROSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) #ifdef CONFIG_NETROM_MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) case AX25_P_NETROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (ax25_protocol_is_registered(AX25_P_NETROM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) #ifdef CONFIG_ROSE_MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) case AX25_P_ROSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (ax25_protocol_is_registered(AX25_P_ROSE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) case SOCK_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (!capable(CAP_NET_RAW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, kern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (sk == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) ax25 = ax25_sk(sk)->cb = ax25_create_cb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!ax25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) sk_free(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) sock_init_data(sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) sk->sk_destruct = ax25_free_sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) sock->ops = &ax25_proto_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) sk->sk_protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) ax25->sk = sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) ax25_cb *ax25, *oax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) sk = sk_alloc(sock_net(osk), PF_AX25, GFP_ATOMIC, osk->sk_prot, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (sk == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if ((ax25 = ax25_create_cb()) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) sk_free(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) switch (osk->sk_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case SOCK_DGRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) case SOCK_SEQPACKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) sk_free(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) ax25_cb_put(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) sock_init_data(NULL, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) sk->sk_type = osk->sk_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) sk->sk_priority = osk->sk_priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) sk->sk_protocol = osk->sk_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) sk->sk_rcvbuf = osk->sk_rcvbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) sk->sk_sndbuf = osk->sk_sndbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) sk->sk_state = TCP_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) sock_copy_flags(sk, osk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) oax25 = sk_to_ax25(osk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ax25->modulus = oax25->modulus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) ax25->backoff = oax25->backoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ax25->pidincl = oax25->pidincl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ax25->iamdigi = oax25->iamdigi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) ax25->rtt = oax25->rtt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ax25->t1 = oax25->t1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ax25->t2 = oax25->t2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ax25->t3 = oax25->t3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) ax25->n2 = oax25->n2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ax25->idle = oax25->idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ax25->paclen = oax25->paclen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) ax25->window = oax25->window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ax25->ax25_dev = ax25_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ax25->source_addr = oax25->source_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (oax25->digipeat != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ax25->digipeat = kmemdup(oax25->digipeat, sizeof(ax25_digi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (ax25->digipeat == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) sk_free(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ax25_cb_put(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ax25_sk(sk)->cb = ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) sk->sk_destruct = ax25_free_sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ax25->sk = sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static int ax25_release(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (sk == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) sock_orphan(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ax25 = sk_to_ax25(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (sk->sk_type == SOCK_SEQPACKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) switch (ax25->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) case AX25_STATE_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) ax25_disconnect(ax25, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ax25_destroy_socket(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) case AX25_STATE_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) case AX25_STATE_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ax25_disconnect(ax25, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (!sock_flag(ax25->sk, SOCK_DESTROY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) ax25_destroy_socket(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) case AX25_STATE_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) case AX25_STATE_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ax25_clear_queues(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) ax25->n2count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) case AX25_PROTO_STD_SIMPLEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case AX25_PROTO_STD_DUPLEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ax25_send_control(ax25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) AX25_DISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) AX25_POLLON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) AX25_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) ax25_stop_t2timer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) ax25_stop_t3timer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ax25_stop_idletimer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) #ifdef CONFIG_AX25_DAMA_SLAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) case AX25_PROTO_DAMA_SLAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) ax25_stop_t3timer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ax25_stop_idletimer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) ax25_calculate_t1(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) ax25_start_t1timer(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) ax25->state = AX25_STATE_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) sk->sk_state = TCP_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) sk->sk_shutdown |= SEND_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) sk->sk_state_change(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) sock_set_flag(sk, SOCK_DESTROY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) sk->sk_state = TCP_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) sk->sk_shutdown |= SEND_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) sk->sk_state_change(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) ax25_destroy_socket(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) sock->sk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * We support a funny extension here so you can (as root) give any callsign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * digipeated via a local address as source. This hack is obsolete now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * that we've implemented support for SO_BINDTODEVICE. It is however small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * and trivially backward compatible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) ax25_dev *ax25_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) ax25_uid_assoc *user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ax25_address call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (addr_len != sizeof(struct sockaddr_ax25) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) addr_len != sizeof(struct full_sockaddr_ax25))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /* support for old structure may go away some time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * ax25_bind(): uses old (6 digipeater) socket structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) (addr_len > sizeof(struct full_sockaddr_ax25)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (addr->fsa_ax25.sax25_family != AF_AX25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) user = ax25_findbyuid(current_euid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (user) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) call = user->call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) ax25_uid_put(user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (ax25_uid_policy && !capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) call = addr->fsa_ax25.sax25_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ax25 = sk_to_ax25(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (!sock_flag(sk, SOCK_ZAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) ax25->source_addr = call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * User already set interface with SO_BINDTODEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (ax25->ax25_dev != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (addr_len > sizeof(struct sockaddr_ax25) && addr->fsa_ax25.sax25_ndigis == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (ax25cmp(&addr->fsa_digipeater[0], &null_ax25_address) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) (ax25_dev = ax25_addr_ax25dev(&addr->fsa_digipeater[0])) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) err = -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if ((ax25_dev = ax25_addr_ax25dev(&addr->fsa_ax25.sax25_call)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) err = -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (ax25_dev != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) ax25_fillin_cb(ax25, ax25_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ax25_cb_add(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) sock_reset_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * FIXME: nonblock behaviour looks like it may have a bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static int __must_check ax25_connect(struct socket *sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct sockaddr *uaddr, int addr_len, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) ax25_cb *ax25 = sk_to_ax25(sk), *ax25t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) ax25_digi *digi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) int ct = 0, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * some sanity checks. code further down depends on this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (addr_len == sizeof(struct sockaddr_ax25))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /* support for this will go away in early 2.5.x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) * ax25_connect(): uses obsolete socket structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) else if (addr_len != sizeof(struct full_sockaddr_ax25))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* support for old structure may go away some time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * ax25_connect(): uses old (6 digipeater) socket structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) (addr_len > sizeof(struct full_sockaddr_ax25)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (fsa->fsa_ax25.sax25_family != AF_AX25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) /* deal with restarts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (sock->state == SS_CONNECTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) switch (sk->sk_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) case TCP_SYN_SENT: /* still trying */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) err = -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) case TCP_ESTABLISHED: /* connection established */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) sock->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) case TCP_CLOSE: /* connection refused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) sock->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) err = -ECONNREFUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (sk->sk_state == TCP_ESTABLISHED && sk->sk_type == SOCK_SEQPACKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) err = -EISCONN; /* No reconnect on a seqpacket socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) sk->sk_state = TCP_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) sock->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) kfree(ax25->digipeat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) ax25->digipeat = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * Handle digi-peaters to be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (addr_len > sizeof(struct sockaddr_ax25) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) fsa->fsa_ax25.sax25_ndigis != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /* Valid number of digipeaters ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (fsa->fsa_ax25.sax25_ndigis < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) addr_len < sizeof(struct sockaddr_ax25) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) sizeof(ax25_address) * fsa->fsa_ax25.sax25_ndigis) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if ((digi = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) digi->ndigi = fsa->fsa_ax25.sax25_ndigis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) digi->lastrepeat = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) while (ct < fsa->fsa_ax25.sax25_ndigis) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if ((fsa->fsa_digipeater[ct].ax25_call[6] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) AX25_HBIT) && ax25->iamdigi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) digi->repeated[ct] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) digi->lastrepeat = ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) digi->repeated[ct] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) digi->calls[ct] = fsa->fsa_digipeater[ct];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) ct++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * Must bind first - autobinding in this may or may not work. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * the socket is already bound, check to see if the device has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * been filled in, error if it hasn't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (sock_flag(sk, SOCK_ZAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /* check if we can remove this feature. It is broken. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@yaina.de\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) kfree(digi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) ax25_fillin_cb(ax25, ax25->ax25_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) ax25_cb_add(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (ax25->ax25_dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) kfree(digi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) err = -EHOSTUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (sk->sk_type == SOCK_SEQPACKET &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) (ax25t=ax25_find_cb(&ax25->source_addr, &fsa->fsa_ax25.sax25_call, digi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) ax25->ax25_dev->dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) kfree(digi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) err = -EADDRINUSE; /* Already such a connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) ax25_cb_put(ax25t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) ax25->dest_addr = fsa->fsa_ax25.sax25_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) ax25->digipeat = digi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) /* First the easy one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (sk->sk_type != SOCK_SEQPACKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) sock->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) sk->sk_state = TCP_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /* Move to connecting socket, ax.25 lapb WAIT_UA.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) sock->state = SS_CONNECTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) sk->sk_state = TCP_SYN_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) case AX25_PROTO_STD_SIMPLEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) case AX25_PROTO_STD_DUPLEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) ax25_std_establish_data_link(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) #ifdef CONFIG_AX25_DAMA_SLAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) case AX25_PROTO_DAMA_SLAVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) ax25->modulus = AX25_MODULUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (ax25->ax25_dev->dama.slave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) ax25_ds_establish_data_link(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ax25_std_establish_data_link(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) ax25->state = AX25_STATE_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) ax25_start_heartbeat(ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) /* Now the loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) err = -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (sk->sk_state == TCP_SYN_SENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) prepare_to_wait(sk_sleep(sk), &wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (sk->sk_state != TCP_SYN_SENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (!signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) err = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) finish_wait(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (sk->sk_state != TCP_ESTABLISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) /* Not in ABM, not in WAIT_UA -> failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) sock->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) err = sock_error(sk); /* Always set at this point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) sock->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) static int ax25_accept(struct socket *sock, struct socket *newsock, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) bool kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) struct sock *newsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (sock->state != SS_UNCONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if ((sk = sock->sk) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (sk->sk_type != SOCK_SEQPACKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (sk->sk_state != TCP_LISTEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * The read queue this time is holding sockets ready to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * hooked into the SABM we saved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) skb = skb_dequeue(&sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (flags & O_NONBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) err = -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (!signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) err = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) finish_wait(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) newsk = skb->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) sock_graft(newsk, newsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) /* Now attach up the new socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) sk_acceptq_removed(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) newsock->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) int peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) unsigned char ndigi, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) memset(fsa, 0, sizeof(*fsa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) ax25 = sk_to_ax25(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (peer != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (sk->sk_state != TCP_ESTABLISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) fsa->fsa_ax25.sax25_family = AF_AX25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) fsa->fsa_ax25.sax25_call = ax25->dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (ax25->digipeat != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) ndigi = ax25->digipeat->ndigi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) fsa->fsa_ax25.sax25_ndigis = ndigi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) for (i = 0; i < ndigi; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) fsa->fsa_digipeater[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) ax25->digipeat->calls[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) fsa->fsa_ax25.sax25_family = AF_AX25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) fsa->fsa_ax25.sax25_call = ax25->source_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) fsa->fsa_ax25.sax25_ndigis = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (ax25->ax25_dev != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) memcpy(&fsa->fsa_digipeater[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) ax25->ax25_dev->dev->dev_addr, AX25_ADDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) fsa->fsa_digipeater[0] = null_ax25_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) err = sizeof (struct full_sockaddr_ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) DECLARE_SOCKADDR(struct sockaddr_ax25 *, usax, msg->msg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct sockaddr_ax25 sax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) ax25_digi dtmp, *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) ax25_cb *ax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) int lv, err, addr_len = msg->msg_namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) ax25 = sk_to_ax25(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (sock_flag(sk, SOCK_ZAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) err = -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (sk->sk_shutdown & SEND_SHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) send_sig(SIGPIPE, current, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) err = -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (ax25->ax25_dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) err = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) if (len > ax25->ax25_dev->dev->mtu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (usax != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (usax->sax25_family != AF_AX25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) if (addr_len == sizeof(struct sockaddr_ax25))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) /* ax25_sendmsg(): uses obsolete socket structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) else if (addr_len != sizeof(struct full_sockaddr_ax25))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) /* support for old structure may go away some time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) * ax25_sendmsg(): uses old (6 digipeater)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * socket structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) (addr_len > sizeof(struct full_sockaddr_ax25))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (addr_len > sizeof(struct sockaddr_ax25) && usax->sax25_ndigis != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) int ct = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)usax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) /* Valid number of digipeaters ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (usax->sax25_ndigis < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) usax->sax25_ndigis > AX25_MAX_DIGIS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) addr_len < sizeof(struct sockaddr_ax25) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) sizeof(ax25_address) * usax->sax25_ndigis) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) dtmp.ndigi = usax->sax25_ndigis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) while (ct < usax->sax25_ndigis) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) dtmp.repeated[ct] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) dtmp.calls[ct] = fsa->fsa_digipeater[ct];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) ct++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) dtmp.lastrepeat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) sax = *usax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if (sk->sk_type == SOCK_SEQPACKET &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) ax25cmp(&ax25->dest_addr, &sax.sax25_call)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) err = -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (usax->sax25_ndigis == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) dp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) dp = &dtmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) * FIXME: 1003.1g - if the socket is like this because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) * it has become closed (not started closed) and is VC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) * we ought to SIGPIPE, EPIPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (sk->sk_state != TCP_ESTABLISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) sax.sax25_family = AF_AX25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) sax.sax25_call = ax25->dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) dp = ax25->digipeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) /* Build a packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /* Assume the worst case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) size = len + ax25->ax25_dev->dev->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) skb = sock_alloc_send_skb(sk, size, msg->msg_flags&MSG_DONTWAIT, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) skb_reserve(skb, size - len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) /* User data follows immediately after the AX.25 data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /* Add the PID if one is not supplied by the user in the skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) if (!ax25->pidincl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) *(u8 *)skb_push(skb, 1) = sk->sk_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (sk->sk_type == SOCK_SEQPACKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) /* Connected mode sockets go via the LAPB machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (sk->sk_state != TCP_ESTABLISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /* Shove it onto the queue and kick */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) ax25_output(ax25, ax25->paclen, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) err = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) skb_push(skb, 1 + ax25_addr_size(dp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) /* Building AX.25 Header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) /* Build an AX.25 header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) lv = ax25_addr_build(skb->data, &ax25->source_addr, &sax.sax25_call,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) dp, AX25_COMMAND, AX25_MODULUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) skb_set_transport_header(skb, lv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) *skb_transport_header(skb) = AX25_UI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) /* Datagram frames go straight out of the door as UI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) ax25_queue_xmit(skb, ax25->ax25_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) err = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) int copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) * This works for seqpacket too. The receiver has ordered the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) * queue for us! We do one quick check first though
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (sk->sk_type == SOCK_SEQPACKET && sk->sk_state != TCP_ESTABLISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) /* Now we can treat all alike */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) flags & MSG_DONTWAIT, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (!sk_to_ax25(sk)->pidincl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) skb_pull(skb, 1); /* Remove PID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) copied = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (copied > size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) copied = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) msg->msg_flags |= MSG_TRUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) skb_copy_datagram_msg(skb, 0, msg, copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if (msg->msg_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) ax25_digi digi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) ax25_address src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) const unsigned char *mac = skb_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) memset(sax, 0, sizeof(struct full_sockaddr_ax25));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) &digi, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) sax->sax25_family = AF_AX25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) /* We set this correctly, even though we may not let the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) application know the digi calls further down (because it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) did NOT ask to know them). This could get political... **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) sax->sax25_ndigis = digi.ndigi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) sax->sax25_call = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (sax->sax25_ndigis != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)sax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) for (ct = 0; ct < digi.ndigi; ct++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) fsa->fsa_digipeater[ct] = digi.calls[ct];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) msg->msg_namelen = sizeof(struct full_sockaddr_ax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) skb_free_datagram(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) err = copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) static int ax25_shutdown(struct socket *sk, int how)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) /* FIXME - generate DM and RNR states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) case TIOCOUTQ: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) long amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (amount < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) amount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) res = put_user(amount, (int __user *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) case TIOCINQ: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) long amount = 0L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /* These two are safe on a single CPU system as only user tasks fiddle here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) amount = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) res = put_user(amount, (int __user *) argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) case SIOCAX25DELUID: /* Delete a uid from the uid/call map table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) case SIOCAX25GETUID: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) struct sockaddr_ax25 sax25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) if (copy_from_user(&sax25, argp, sizeof(sax25))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) res = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) res = ax25_uid_ioctl(cmd, &sax25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) case SIOCAX25NOUID: { /* Set the default policy (default/bar) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) long amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (!capable(CAP_NET_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) res = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) if (get_user(amount, (long __user *)argp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) res = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (amount < 0 || amount > AX25_NOUID_BLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) ax25_uid_policy = amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) case SIOCADDRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) case SIOCDELRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) case SIOCAX25OPTRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (!capable(CAP_NET_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) res = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) res = ax25_rt_ioctl(cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) case SIOCAX25CTLCON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) if (!capable(CAP_NET_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) res = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) res = ax25_ctl_ioctl(cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) case SIOCAX25GETINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) case SIOCAX25GETINFOOLD: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) ax25_cb *ax25 = sk_to_ax25(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) struct ax25_info_struct ax25_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) ax25_info.t1 = ax25->t1 / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) ax25_info.t2 = ax25->t2 / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) ax25_info.t3 = ax25->t3 / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) ax25_info.idle = ax25->idle / (60 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) ax25_info.n2 = ax25->n2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) ax25_info.t1timer = ax25_display_timer(&ax25->t1timer) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) ax25_info.t2timer = ax25_display_timer(&ax25->t2timer) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) ax25_info.t3timer = ax25_display_timer(&ax25->t3timer) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) ax25_info.n2count = ax25->n2count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) ax25_info.state = ax25->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) ax25_info.rcv_q = sk_rmem_alloc_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) ax25_info.snd_q = sk_wmem_alloc_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) ax25_info.vs = ax25->vs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) ax25_info.vr = ax25->vr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) ax25_info.va = ax25->va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) ax25_info.vs_max = ax25->vs; /* reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) ax25_info.paclen = ax25->paclen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) ax25_info.window = ax25->window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) /* old structure? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if (cmd == SIOCAX25GETINFOOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) static int warned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (!warned) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) printk(KERN_INFO "%s uses old SIOCAX25GETINFO\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) warned=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct_deprecated))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) res = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) case SIOCAX25ADDFWD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) case SIOCAX25DELFWD: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) struct ax25_fwd_struct ax25_fwd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (!capable(CAP_NET_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) res = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) if (copy_from_user(&ax25_fwd, argp, sizeof(ax25_fwd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) res = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) res = ax25_fwd_ioctl(cmd, &ax25_fwd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) case SIOCGIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) case SIOCSIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) case SIOCGIFDSTADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) case SIOCSIFDSTADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) case SIOCGIFBRDADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) case SIOCSIFBRDADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) case SIOCGIFNETMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) case SIOCSIFNETMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) case SIOCGIFMETRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) case SIOCSIFMETRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) res = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) static void *ax25_info_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) __acquires(ax25_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) spin_lock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return seq_hlist_start(&ax25_list, *pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) static void *ax25_info_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) return seq_hlist_next(v, &ax25_list, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) static void ax25_info_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) __releases(ax25_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) spin_unlock_bh(&ax25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) static int ax25_info_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) ax25_cb *ax25 = hlist_entry(v, struct ax25_cb, ax25_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) char buf[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) * New format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) * magic dev src_addr dest_addr,digi1,digi2,.. st vs vr va t1 t1 t2 t2 t3 t3 idle idle n2 n2 rtt window paclen Snd-Q Rcv-Q inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) seq_printf(seq, "%p %s %s%s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) ax25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) ax2asc(buf, &ax25->source_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) ax25->iamdigi? "*":"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) seq_printf(seq, "%s", ax2asc(buf, &ax25->dest_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) seq_printf(seq, ",%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) ax2asc(buf, &ax25->digipeat->calls[k]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) ax25->digipeat->repeated[k]? "*":"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) seq_printf(seq, " %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %d %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) ax25->state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) ax25->vs, ax25->vr, ax25->va,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) ax25_display_timer(&ax25->t1timer) / HZ, ax25->t1 / HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) ax25_display_timer(&ax25->t2timer) / HZ, ax25->t2 / HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) ax25_display_timer(&ax25->t3timer) / HZ, ax25->t3 / HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) ax25_display_timer(&ax25->idletimer) / (60 * HZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) ax25->idle / (60 * HZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) ax25->n2count, ax25->n2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) ax25->rtt / HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) ax25->window,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) ax25->paclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) if (ax25->sk != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) seq_printf(seq, " %d %d %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) sk_wmem_alloc_get(ax25->sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) sk_rmem_alloc_get(ax25->sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) sock_i_ino(ax25->sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) seq_puts(seq, " * * *\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) static const struct seq_operations ax25_info_seqops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) .start = ax25_info_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) .next = ax25_info_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) .stop = ax25_info_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) .show = ax25_info_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) static const struct net_proto_family ax25_family_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) .family = PF_AX25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) .create = ax25_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) static const struct proto_ops ax25_proto_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) .family = PF_AX25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) .release = ax25_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) .bind = ax25_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) .connect = ax25_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) .socketpair = sock_no_socketpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) .accept = ax25_accept,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) .getname = ax25_getname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) .poll = datagram_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) .ioctl = ax25_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) .gettstamp = sock_gettstamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) .listen = ax25_listen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) .shutdown = ax25_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) .setsockopt = ax25_setsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) .getsockopt = ax25_getsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) .sendmsg = ax25_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) .recvmsg = ax25_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) .mmap = sock_no_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) .sendpage = sock_no_sendpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) * Called by socket.c on kernel start up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) static struct packet_type ax25_packet_type __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) .type = cpu_to_be16(ETH_P_AX25),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) .func = ax25_kiss_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) static struct notifier_block ax25_dev_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) .notifier_call = ax25_device_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static int __init ax25_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) int rc = proto_register(&ax25_proto, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) sock_register(&ax25_family_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) dev_add_pack(&ax25_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) register_netdevice_notifier(&ax25_dev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) proc_create_seq("ax25_route", 0444, init_net.proc_net, &ax25_rt_seqops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) proc_create_seq("ax25", 0444, init_net.proc_net, &ax25_info_seqops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) proc_create_seq("ax25_calls", 0444, init_net.proc_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) &ax25_uid_seqops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) module_init(ax25_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) MODULE_DESCRIPTION("The amateur radio AX.25 link layer protocol");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) MODULE_ALIAS_NETPROTO(PF_AX25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) static void __exit ax25_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) remove_proc_entry("ax25_route", init_net.proc_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) remove_proc_entry("ax25", init_net.proc_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) remove_proc_entry("ax25_calls", init_net.proc_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) unregister_netdevice_notifier(&ax25_dev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) dev_remove_pack(&ax25_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) sock_unregister(PF_AX25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) proto_unregister(&ax25_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) ax25_rt_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) ax25_uid_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) ax25_dev_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) module_exit(ax25_exit);