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