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 af_ax25.c. 14 */ 15 16#include <linux/errno.h> 17#include <linux/types.h> 18#include <linux/socket.h> 19#include <linux/in.h> 20#include <linux/kernel.h> 21#include <linux/sched.h> 22#include <linux/timer.h> 23#include <linux/string.h> 24#include <linux/sockios.h> 25#include <linux/net.h> 26#include <net/ax25.h> 27#include <linux/inet.h> 28#include <linux/netdevice.h> 29#include <linux/if_arp.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#include <linux/notifier.h> 38#include <linux/proc_fs.h> 39#include <linux/stat.h> 40#include <linux/netfilter.h> 41#include <linux/sysctl.h> 42#include <net/ip.h> 43#include <net/arp.h> 44 45/* 46 * Callsign/UID mapper. This is in kernel space for security on multi-amateur machines. 47 */ 48 49static ax25_uid_assoc *ax25_uid_list; 50 51int ax25_uid_policy = 0; 52 53ax25_address *ax25_findbyuid(uid_t uid) 54{ 55 ax25_uid_assoc *ax25_uid; 56 57 for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { 58 if (ax25_uid->uid == uid) 59 return &ax25_uid->call; 60 } 61 62 return NULL; 63} 64 65int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) 66{ 67 ax25_uid_assoc *s, *ax25_uid; 68 unsigned long flags; 69 70 switch (cmd) { 71 case SIOCAX25GETUID: 72 for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { 73 if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) 74 return ax25_uid->uid; 75 } 76 return -ENOENT; 77 78 case SIOCAX25ADDUID: 79 if (!capable(CAP_NET_ADMIN)) 80 return -EPERM; 81 if (ax25_findbyuid(sax->sax25_uid)) 82 return -EEXIST; 83 if (sax->sax25_uid == 0) 84 return -EINVAL; 85 if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL) 86 return -ENOMEM; 87 ax25_uid->uid = sax->sax25_uid; 88 ax25_uid->call = sax->sax25_call; 89 save_flags(flags); cli(); 90 ax25_uid->next = ax25_uid_list; 91 ax25_uid_list = ax25_uid; 92 restore_flags(flags); 93 return 0; 94 95 case SIOCAX25DELUID: 96 if (!capable(CAP_NET_ADMIN)) 97 return -EPERM; 98 for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { 99 if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) 100 break; 101 } 102 if (ax25_uid == NULL) 103 return -ENOENT; 104 save_flags(flags); cli(); 105 if ((s = ax25_uid_list) == ax25_uid) { 106 ax25_uid_list = s->next; 107 restore_flags(flags); 108 kfree(ax25_uid); 109 return 0; 110 } 111 while (s != NULL && s->next != NULL) { 112 if (s->next == ax25_uid) { 113 s->next = ax25_uid->next; 114 restore_flags(flags); 115 kfree(ax25_uid); 116 return 0; 117 } 118 s = s->next; 119 } 120 restore_flags(flags); 121 return -ENOENT; 122 123 default: 124 return -EINVAL; 125 } 126 127 return -EINVAL; /*NOTREACHED */ 128} 129 130int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length) 131{ 132 ax25_uid_assoc *pt; 133 int len = 0; 134 off_t pos = 0; 135 off_t begin = 0; 136 137 cli(); 138 139 len += sprintf(buffer, "Policy: %d\n", ax25_uid_policy); 140 141 for (pt = ax25_uid_list; pt != NULL; pt = pt->next) { 142 len += sprintf(buffer + len, "%6d %s\n", pt->uid, ax2asc(&pt->call)); 143 144 pos = begin + len; 145 146 if (pos < offset) { 147 len = 0; 148 begin = pos; 149 } 150 151 if (pos > offset + length) 152 break; 153 } 154 155 sti(); 156 157 *start = buffer + (offset - begin); 158 len -= offset - begin; 159 160 if (len > length) len = length; 161 162 return len; 163} 164 165/* 166 * Free all memory associated with UID/Callsign structures. 167 */ 168void __exit ax25_uid_free(void) 169{ 170 ax25_uid_assoc *s, *ax25_uid = ax25_uid_list; 171 172 while (ax25_uid != NULL) { 173 s = ax25_uid; 174 ax25_uid = ax25_uid->next; 175 176 kfree(s); 177 } 178} 179