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/config.h> 10 #include <linux/errno.h> 11 #include <linux/types.h> 12 #include <linux/socket.h> 13 #include <linux/in.h> 14 #include <linux/kernel.h> 15 #include <linux/sched.h> 16 #include <linux/spinlock.h> 17 #include <linux/timer.h> 18 #include <linux/string.h> 19 #include <linux/sockios.h> 20 #include <linux/net.h> 21 #include <net/ax25.h> 22 #include <linux/inet.h> 23 #include <linux/netdevice.h> 24 #include <linux/skbuff.h> 25 #include <net/sock.h> 26 #include <asm/uaccess.h> 27 #include <asm/system.h> 28 #include <linux/fcntl.h> 29 #include <linux/mm.h> 30 #include <linux/interrupt.h> 31 32 static struct protocol_struct { 33 struct protocol_struct *next; 34 unsigned int pid; 35 int (*func)(struct sk_buff *, ax25_cb *); 36 } *protocol_list = NULL; 37 static DEFINE_RWLOCK(protocol_list_lock); 38 39 static struct linkfail_struct { 40 struct linkfail_struct *next; 41 void (*func)(ax25_cb *, int); 42 } *linkfail_list = NULL; 43 static DEFINE_SPINLOCK(linkfail_lock); 44 45 static struct listen_struct { 46 struct listen_struct *next; 47 ax25_address callsign; 48 struct net_device *dev; 49 } *listen_list = NULL; 50 static DEFINE_SPINLOCK(listen_lock); 51 52 int ax25_protocol_register(unsigned int pid, 53 int (*func)(struct sk_buff *, ax25_cb *)) 54 { 55 struct protocol_struct *protocol; 56 57 if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT) 58 return 0; 59 #ifdef CONFIG_INET 60 if (pid == AX25_P_IP || pid == AX25_P_ARP) 61 return 0; 62 #endif 63 if ((protocol = kmalloc(sizeof(*protocol), GFP_ATOMIC)) == NULL) 64 return 0; 65 66 protocol->pid = pid; 67 protocol->func = func; 68 69 write_lock(&protocol_list_lock); 70 protocol->next = protocol_list; 71 protocol_list = protocol; 72 write_unlock(&protocol_list_lock); 73 74 return 1; 75 } 76 77 void ax25_protocol_release(unsigned int pid) 78 { 79 struct protocol_struct *s, *protocol; 80 81 write_lock(&protocol_list_lock); 82 protocol = protocol_list; 83 if (protocol == NULL) { 84 write_unlock(&protocol_list_lock); 85 return; 86 } 87 88 if (protocol->pid == pid) { 89 protocol_list = protocol->next; 90 write_unlock(&protocol_list_lock); 91 kfree(protocol); 92 return; 93 } 94 95 while (protocol != NULL && protocol->next != NULL) { 96 if (protocol->next->pid == pid) { 97 s = protocol->next; 98 protocol->next = protocol->next->next; 99 write_unlock(&protocol_list_lock); 100 kfree(s); 101 return; 102 } 103 104 protocol = protocol->next; 105 } 106 write_unlock(&protocol_list_lock); 107 } 108 109 int ax25_linkfail_register(void (*func)(ax25_cb *, int)) 110 { 111 struct linkfail_struct *linkfail; 112 113 if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL) 114 return 0; 115 116 linkfail->func = func; 117 118 spin_lock_bh(&linkfail_lock); 119 linkfail->next = linkfail_list; 120 linkfail_list = linkfail; 121 spin_unlock_bh(&linkfail_lock); 122 123 return 1; 124 } 125 126 void ax25_linkfail_release(void (*func)(ax25_cb *, int)) 127 { 128 struct linkfail_struct *s, *linkfail; 129 130 spin_lock_bh(&linkfail_lock); 131 linkfail = linkfail_list; 132 if (linkfail == NULL) { 133 spin_unlock_bh(&linkfail_lock); 134 return; 135 } 136 137 if (linkfail->func == func) { 138 linkfail_list = linkfail->next; 139 spin_unlock_bh(&linkfail_lock); 140 kfree(linkfail); 141 return; 142 } 143 144 while (linkfail != NULL && linkfail->next != NULL) { 145 if (linkfail->next->func == func) { 146 s = linkfail->next; 147 linkfail->next = linkfail->next->next; 148 spin_unlock_bh(&linkfail_lock); 149 kfree(s); 150 return; 151 } 152 153 linkfail = linkfail->next; 154 } 155 spin_unlock_bh(&linkfail_lock); 156 } 157 158 int ax25_listen_register(ax25_address *callsign, struct net_device *dev) 159 { 160 struct listen_struct *listen; 161 162 if (ax25_listen_mine(callsign, dev)) 163 return 0; 164 165 if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL) 166 return 0; 167 168 listen->callsign = *callsign; 169 listen->dev = dev; 170 171 spin_lock_bh(&listen_lock); 172 listen->next = listen_list; 173 listen_list = listen; 174 spin_unlock_bh(&listen_lock); 175 176 return 1; 177 } 178 179 void ax25_listen_release(ax25_address *callsign, struct net_device *dev) 180 { 181 struct listen_struct *s, *listen; 182 183 spin_lock_bh(&listen_lock); 184 listen = listen_list; 185 if (listen == NULL) { 186 spin_unlock_bh(&listen_lock); 187 return; 188 } 189 190 if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) { 191 listen_list = listen->next; 192 spin_unlock_bh(&listen_lock); 193 kfree(listen); 194 return; 195 } 196 197 while (listen != NULL && listen->next != NULL) { 198 if (ax25cmp(&listen->next->callsign, callsign) == 0 && listen->next->dev == dev) { 199 s = listen->next; 200 listen->next = listen->next->next; 201 spin_unlock_bh(&listen_lock); 202 kfree(s); 203 return; 204 } 205 206 listen = listen->next; 207 } 208 spin_unlock_bh(&listen_lock); 209 } 210 211 int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) 212 { 213 int (*res)(struct sk_buff *, ax25_cb *) = NULL; 214 struct protocol_struct *protocol; 215 216 read_lock(&protocol_list_lock); 217 for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) 218 if (protocol->pid == pid) { 219 res = protocol->func; 220 break; 221 } 222 read_unlock(&protocol_list_lock); 223 224 return res; 225 } 226 227 int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) 228 { 229 struct listen_struct *listen; 230 231 spin_lock_bh(&listen_lock); 232 for (listen = listen_list; listen != NULL; listen = listen->next) 233 if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL)) { 234 spin_unlock_bh(&listen_lock); 235 return 1; 236 } 237 spin_unlock_bh(&listen_lock); 238 239 return 0; 240 } 241 242 void ax25_link_failed(ax25_cb *ax25, int reason) 243 { 244 struct linkfail_struct *linkfail; 245 246 spin_lock_bh(&linkfail_lock); 247 for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) 248 (linkfail->func)(ax25, reason); 249 spin_unlock_bh(&linkfail_lock); 250 } 251 252 int ax25_protocol_is_registered(unsigned int pid) 253 { 254 struct protocol_struct *protocol; 255 int res = 0; 256 257 read_lock(&protocol_list_lock); 258 for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) 259 if (protocol->pid == pid) { 260 res = 1; 261 break; 262 } 263 read_unlock(&protocol_list_lock); 264 265 return res; 266 } 267