1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) 8 */ 9 #include <linux/errno.h> 10 #include <linux/types.h> 11 #include <linux/socket.h> 12 #include <linux/in.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/spinlock.h> 16 #include <linux/timer.h> 17 #include <linux/string.h> 18 #include <linux/sockios.h> 19 #include <linux/net.h> 20 #include <net/ax25.h> 21 #include <linux/inet.h> 22 #include <linux/netdevice.h> 23 #include <linux/skbuff.h> 24 #include <net/sock.h> 25 #include <asm/uaccess.h> 26 #include <asm/system.h> 27 #include <linux/fcntl.h> 28 #include <linux/mm.h> 29 #include <linux/interrupt.h> 30 31 static struct ax25_protocol *protocol_list; 32 static DEFINE_RWLOCK(protocol_list_lock); 33 34 static HLIST_HEAD(ax25_linkfail_list); 35 static DEFINE_SPINLOCK(linkfail_lock); 36 37 static struct listen_struct { 38 struct listen_struct *next; 39 ax25_address callsign; 40 struct net_device *dev; 41 } *listen_list = NULL; 42 static DEFINE_SPINLOCK(listen_lock); 43 44 /* 45 * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT, 46 * AX25_P_IP or AX25_P_ARP ... 47 */ 48 void ax25_register_pid(struct ax25_protocol *ap) 49 { 50 write_lock_bh(&protocol_list_lock); 51 ap->next = protocol_list; 52 protocol_list = ap; 53 write_unlock_bh(&protocol_list_lock); 54 } 55 56 EXPORT_SYMBOL_GPL(ax25_register_pid); 57 58 void ax25_protocol_release(unsigned int pid) 59 { 60 struct ax25_protocol *s, *protocol; 61 62 write_lock_bh(&protocol_list_lock); 63 protocol = protocol_list; 64 if (protocol == NULL) { 65 write_unlock_bh(&protocol_list_lock); 66 return; 67 } 68 69 if (protocol->pid == pid) { 70 protocol_list = protocol->next; 71 write_unlock_bh(&protocol_list_lock); 72 kfree(protocol); 73 return; 74 } 75 76 while (protocol != NULL && protocol->next != NULL) { 77 if (protocol->next->pid == pid) { 78 s = protocol->next; 79 protocol->next = protocol->next->next; 80 write_unlock_bh(&protocol_list_lock); 81 kfree(s); 82 return; 83 } 84 85 protocol = protocol->next; 86 } 87 write_unlock_bh(&protocol_list_lock); 88 } 89 90 EXPORT_SYMBOL(ax25_protocol_release); 91 92 void ax25_linkfail_register(struct ax25_linkfail *lf) 93 { 94 spin_lock_bh(&linkfail_lock); 95 hlist_add_head(&lf->lf_node, &ax25_linkfail_list); 96 spin_unlock_bh(&linkfail_lock); 97 } 98 99 EXPORT_SYMBOL(ax25_linkfail_register); 100 101 void ax25_linkfail_release(struct ax25_linkfail *lf) 102 { 103 spin_lock_bh(&linkfail_lock); 104 hlist_del_init(&lf->lf_node); 105 spin_unlock_bh(&linkfail_lock); 106 } 107 108 EXPORT_SYMBOL(ax25_linkfail_release); 109 110 int ax25_listen_register(ax25_address *callsign, struct net_device *dev) 111 { 112 struct listen_struct *listen; 113 114 if (ax25_listen_mine(callsign, dev)) 115 return 0; 116 117 if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL) 118 return -ENOMEM; 119 120 listen->callsign = *callsign; 121 listen->dev = dev; 122 123 spin_lock_bh(&listen_lock); 124 listen->next = listen_list; 125 listen_list = listen; 126 spin_unlock_bh(&listen_lock); 127 128 return 0; 129 } 130 131 EXPORT_SYMBOL(ax25_listen_register); 132 133 void ax25_listen_release(ax25_address *callsign, struct net_device *dev) 134 { 135 struct listen_struct *s, *listen; 136 137 spin_lock_bh(&listen_lock); 138 listen = listen_list; 139 if (listen == NULL) { 140 spin_unlock_bh(&listen_lock); 141 return; 142 } 143 144 if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) { 145 listen_list = listen->next; 146 spin_unlock_bh(&listen_lock); 147 kfree(listen); 148 return; 149 } 150 151 while (listen != NULL && listen->next != NULL) { 152 if (ax25cmp(&listen->next->callsign, callsign) == 0 && listen->next->dev == dev) { 153 s = listen->next; 154 listen->next = listen->next->next; 155 spin_unlock_bh(&listen_lock); 156 kfree(s); 157 return; 158 } 159 160 listen = listen->next; 161 } 162 spin_unlock_bh(&listen_lock); 163 } 164 165 EXPORT_SYMBOL(ax25_listen_release); 166 167 int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) 168 { 169 int (*res)(struct sk_buff *, ax25_cb *) = NULL; 170 struct ax25_protocol *protocol; 171 172 read_lock(&protocol_list_lock); 173 for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) 174 if (protocol->pid == pid) { 175 res = protocol->func; 176 break; 177 } 178 read_unlock(&protocol_list_lock); 179 180 return res; 181 } 182 183 int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) 184 { 185 struct listen_struct *listen; 186 187 spin_lock_bh(&listen_lock); 188 for (listen = listen_list; listen != NULL; listen = listen->next) 189 if (ax25cmp(&listen->callsign, callsign) == 0 && 190 (listen->dev == dev || listen->dev == NULL)) { 191 spin_unlock_bh(&listen_lock); 192 return 1; 193 } 194 spin_unlock_bh(&listen_lock); 195 196 return 0; 197 } 198 199 void ax25_link_failed(ax25_cb *ax25, int reason) 200 { 201 struct ax25_linkfail *lf; 202 struct hlist_node *node; 203 204 spin_lock_bh(&linkfail_lock); 205 hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node) 206 lf->func(ax25, reason); 207 spin_unlock_bh(&linkfail_lock); 208 } 209 210 int ax25_protocol_is_registered(unsigned int pid) 211 { 212 struct ax25_protocol *protocol; 213 int res = 0; 214 215 read_lock_bh(&protocol_list_lock); 216 for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) 217 if (protocol->pid == pid) { 218 res = 1; 219 break; 220 } 221 read_unlock_bh(&protocol_list_lock); 222 223 return res; 224 } 225