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