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