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/timer.h> 16 #include <linux/string.h> 17 #include <linux/sockios.h> 18 #include <linux/net.h> 19 #include <net/ax25.h> 20 #include <linux/inet.h> 21 #include <linux/netdevice.h> 22 #include <linux/skbuff.h> 23 #include <net/sock.h> 24 #include <asm/uaccess.h> 25 #include <asm/system.h> 26 #include <linux/fcntl.h> 27 #include <linux/mm.h> 28 #include <linux/interrupt.h> 29 30 /* 31 * The default broadcast address of an interface is QST-0; the default address 32 * is LINUX-1. The null address is defined as a callsign of all spaces with 33 * an SSID of zero. 34 */ 35 36 const ax25_address ax25_bcast = 37 {{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, 0 << 1}}; 38 const ax25_address ax25_defaddr = 39 {{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, 1 << 1}}; 40 const ax25_address null_ax25_address = 41 {{' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, 0 << 1}}; 42 43 EXPORT_SYMBOL_GPL(ax25_bcast); 44 EXPORT_SYMBOL_GPL(ax25_defaddr); 45 EXPORT_SYMBOL(null_ax25_address); 46 47 /* 48 * ax25 -> ascii conversion 49 */ 50 char *ax2asc(char *buf, const ax25_address *a) 51 { 52 char c, *s; 53 int n; 54 55 for (n = 0, s = buf; n < 6; n++) { 56 c = (a->ax25_call[n] >> 1) & 0x7F; 57 58 if (c != ' ') *s++ = c; 59 } 60 61 *s++ = '-'; 62 63 if ((n = ((a->ax25_call[6] >> 1) & 0x0F)) > 9) { 64 *s++ = '1'; 65 n -= 10; 66 } 67 68 *s++ = n + '0'; 69 *s++ = '\0'; 70 71 if (*buf == '\0' || *buf == '-') 72 return "*"; 73 74 return buf; 75 76 } 77 78 EXPORT_SYMBOL(ax2asc); 79 80 /* 81 * ascii -> ax25 conversion 82 */ 83 void asc2ax(ax25_address *addr, const char *callsign) 84 { 85 const char *s; 86 int n; 87 88 for (s = callsign, n = 0; n < 6; n++) { 89 if (*s != '\0' && *s != '-') 90 addr->ax25_call[n] = *s++; 91 else 92 addr->ax25_call[n] = ' '; 93 addr->ax25_call[n] <<= 1; 94 addr->ax25_call[n] &= 0xFE; 95 } 96 97 if (*s++ == '\0') { 98 addr->ax25_call[6] = 0x00; 99 return; 100 } 101 102 addr->ax25_call[6] = *s++ - '0'; 103 104 if (*s != '\0') { 105 addr->ax25_call[6] *= 10; 106 addr->ax25_call[6] += *s++ - '0'; 107 } 108 109 addr->ax25_call[6] <<= 1; 110 addr->ax25_call[6] &= 0x1E; 111 } 112 113 EXPORT_SYMBOL(asc2ax); 114 115 /* 116 * Compare two ax.25 addresses 117 */ 118 int ax25cmp(const ax25_address *a, const ax25_address *b) 119 { 120 int ct = 0; 121 122 while (ct < 6) { 123 if ((a->ax25_call[ct] & 0xFE) != (b->ax25_call[ct] & 0xFE)) /* Clean off repeater bits */ 124 return 1; 125 ct++; 126 } 127 128 if ((a->ax25_call[ct] & 0x1E) == (b->ax25_call[ct] & 0x1E)) /* SSID without control bit */ 129 return 0; 130 131 return 2; /* Partial match */ 132 } 133 134 EXPORT_SYMBOL(ax25cmp); 135 136 /* 137 * Compare two AX.25 digipeater paths. 138 */ 139 int ax25digicmp(const ax25_digi *digi1, const ax25_digi *digi2) 140 { 141 int i; 142 143 if (digi1->ndigi != digi2->ndigi) 144 return 1; 145 146 if (digi1->lastrepeat != digi2->lastrepeat) 147 return 1; 148 149 for (i = 0; i < digi1->ndigi; i++) 150 if (ax25cmp(&digi1->calls[i], &digi2->calls[i]) != 0) 151 return 1; 152 153 return 0; 154 } 155 156 /* 157 * Given an AX.25 address pull of to, from, digi list, command/response and the start of data 158 * 159 */ 160 const unsigned char *ax25_addr_parse(const unsigned char *buf, int len, 161 ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags, 162 int *dama) 163 { 164 int d = 0; 165 166 if (len < 14) return NULL; 167 168 if (flags != NULL) { 169 *flags = 0; 170 171 if (buf[6] & AX25_CBIT) 172 *flags = AX25_COMMAND; 173 if (buf[13] & AX25_CBIT) 174 *flags = AX25_RESPONSE; 175 } 176 177 if (dama != NULL) 178 *dama = ~buf[13] & AX25_DAMA_FLAG; 179 180 /* Copy to, from */ 181 if (dest != NULL) 182 memcpy(dest, buf + 0, AX25_ADDR_LEN); 183 if (src != NULL) 184 memcpy(src, buf + 7, AX25_ADDR_LEN); 185 186 buf += 2 * AX25_ADDR_LEN; 187 len -= 2 * AX25_ADDR_LEN; 188 189 digi->lastrepeat = -1; 190 digi->ndigi = 0; 191 192 while (!(buf[-1] & AX25_EBIT)) { 193 if (d >= AX25_MAX_DIGIS) return NULL; /* Max of 6 digis */ 194 if (len < 7) return NULL; /* Short packet */ 195 196 memcpy(&digi->calls[d], buf, AX25_ADDR_LEN); 197 digi->ndigi = d + 1; 198 199 if (buf[6] & AX25_HBIT) { 200 digi->repeated[d] = 1; 201 digi->lastrepeat = d; 202 } else { 203 digi->repeated[d] = 0; 204 } 205 206 buf += AX25_ADDR_LEN; 207 len -= AX25_ADDR_LEN; 208 d++; 209 } 210 211 return buf; 212 } 213 214 /* 215 * Assemble an AX.25 header from the bits 216 */ 217 int ax25_addr_build(unsigned char *buf, const ax25_address *src, 218 const ax25_address *dest, const ax25_digi *d, int flag, int modulus) 219 { 220 int len = 0; 221 int ct = 0; 222 223 memcpy(buf, dest, AX25_ADDR_LEN); 224 buf[6] &= ~(AX25_EBIT | AX25_CBIT); 225 buf[6] |= AX25_SSSID_SPARE; 226 227 if (flag == AX25_COMMAND) buf[6] |= AX25_CBIT; 228 229 buf += AX25_ADDR_LEN; 230 len += AX25_ADDR_LEN; 231 232 memcpy(buf, src, AX25_ADDR_LEN); 233 buf[6] &= ~(AX25_EBIT | AX25_CBIT); 234 buf[6] &= ~AX25_SSSID_SPARE; 235 236 if (modulus == AX25_MODULUS) 237 buf[6] |= AX25_SSSID_SPARE; 238 else 239 buf[6] |= AX25_ESSID_SPARE; 240 241 if (flag == AX25_RESPONSE) buf[6] |= AX25_CBIT; 242 243 /* 244 * Fast path the normal digiless path 245 */ 246 if (d == NULL || d->ndigi == 0) { 247 buf[6] |= AX25_EBIT; 248 return 2 * AX25_ADDR_LEN; 249 } 250 251 buf += AX25_ADDR_LEN; 252 len += AX25_ADDR_LEN; 253 254 while (ct < d->ndigi) { 255 memcpy(buf, &d->calls[ct], AX25_ADDR_LEN); 256 257 if (d->repeated[ct]) 258 buf[6] |= AX25_HBIT; 259 else 260 buf[6] &= ~AX25_HBIT; 261 262 buf[6] &= ~AX25_EBIT; 263 buf[6] |= AX25_SSSID_SPARE; 264 265 buf += AX25_ADDR_LEN; 266 len += AX25_ADDR_LEN; 267 ct++; 268 } 269 270 buf[-1] |= AX25_EBIT; 271 272 return len; 273 } 274 275 int ax25_addr_size(const ax25_digi *dp) 276 { 277 if (dp == NULL) 278 return 2 * AX25_ADDR_LEN; 279 280 return AX25_ADDR_LEN * (2 + dp->ndigi); 281 } 282 283 /* 284 * Reverse Digipeat List. May not pass both parameters as same struct 285 */ 286 void ax25_digi_invert(const ax25_digi *in, ax25_digi *out) 287 { 288 int ct; 289 290 out->ndigi = in->ndigi; 291 out->lastrepeat = in->ndigi - in->lastrepeat - 2; 292 293 /* Invert the digipeaters */ 294 for (ct = 0; ct < in->ndigi; ct++) { 295 out->calls[ct] = in->calls[in->ndigi - ct - 1]; 296 297 if (ct <= out->lastrepeat) { 298 out->calls[ct].ax25_call[6] |= AX25_HBIT; 299 out->repeated[ct] = 1; 300 } else { 301 out->calls[ct].ax25_call[6] &= ~AX25_HBIT; 302 out->repeated[ct] = 0; 303 } 304 } 305 } 306 307