This source file includes following definitions.
- ax25_clear_queues
 
- ax25_frames_acked
 
- ax25_validate_nr
 
- ax25_decode
 
- ax25_send_control
 
- ax25_return_dm
 
- ax25_calculate_t1
 
- ax25_calculate_rtt
 
- ax25_parse_addr
 
- build_ax25_addr
 
- size_ax25_addr
 
- ax25_digi_invert
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 #include <linux/config.h>
  29 #ifdef CONFIG_AX25
  30 #include <linux/errno.h>
  31 #include <linux/types.h>
  32 #include <linux/socket.h>
  33 #include <linux/in.h>
  34 #include <linux/kernel.h>
  35 #include <linux/sched.h>
  36 #include <linux/timer.h>
  37 #include <linux/string.h>
  38 #include <linux/sockios.h>
  39 #include <linux/net.h>
  40 #include <net/ax25.h>
  41 #include <linux/inet.h>
  42 #include <linux/netdevice.h>
  43 #include <linux/skbuff.h>
  44 #include <net/sock.h>
  45 #include <asm/segment.h>
  46 #include <asm/system.h>
  47 #include <linux/fcntl.h>
  48 #include <linux/mm.h>
  49 #include <linux/interrupt.h>
  50 
  51 
  52 
  53 
  54 
  55 
  56 void ax25_clear_queues(ax25_cb *ax25)
     
  57 {
  58         struct sk_buff *skb;
  59 
  60         while ((skb = skb_dequeue(&ax25->write_queue)) != NULL) {
  61                 skb->free = 1;
  62                 kfree_skb(skb, FREE_WRITE);
  63         }
  64 
  65         while ((skb = skb_dequeue(&ax25->ack_queue)) != NULL) {
  66                 skb->free = 1;
  67                 kfree_skb(skb, FREE_WRITE);
  68         }
  69 
  70         while ((skb = skb_dequeue(&ax25->reseq_queue)) != NULL) {
  71                 kfree_skb(skb, FREE_READ);
  72         }
  73 
  74         while ((skb = skb_dequeue(&ax25->frag_queue)) != NULL) {
  75                 kfree_skb(skb, FREE_READ);
  76         }
  77 }
  78 
  79 
  80 
  81 
  82 
  83 
  84 void ax25_frames_acked(ax25_cb *ax25, unsigned short nr)
     
  85 {
  86         struct sk_buff *skb, *skb_prev = NULL;
  87 
  88         
  89 
  90 
  91         if (ax25->va != nr) {
  92                 while (skb_peek(&ax25->ack_queue) != NULL && ax25->va != nr) {
  93                         skb = skb_dequeue(&ax25->ack_queue);
  94                         skb->free = 1;
  95                         kfree_skb(skb, FREE_WRITE);
  96                         ax25->va = (ax25->va + 1) % ax25->modulus;
  97                 }
  98         }
  99 
 100         
 101 
 102 
 103 
 104 
 105         while ((skb = skb_dequeue(&ax25->ack_queue)) != NULL) {
 106                 if (skb_prev == NULL)
 107                         skb_queue_head(&ax25->write_queue, skb);
 108                 else
 109                         skb_append(skb_prev, skb);
 110                 skb_prev = skb;
 111         }
 112 }
 113 
 114 
 115 
 116 
 117 
 118 int ax25_validate_nr(ax25_cb *ax25, unsigned short nr)
     
 119 {
 120         unsigned short vc = ax25->va;
 121 
 122         while (vc != ax25->vs) {
 123                 if (nr == vc) return 1;
 124                 vc = (vc + 1) % ax25->modulus;
 125         }
 126         
 127         if (nr == ax25->vs) return 1;
 128 
 129         return 0;
 130 }
 131 
 132 
 133 
 134 
 135 
 136 int ax25_decode(ax25_cb *ax25, struct sk_buff *skb, int *ns, int *nr, int *pf)
     
 137 {
 138         unsigned char *frame;
 139         int frametype = ILLEGAL;
 140 
 141         frame = skb->data;
 142         *ns = *nr = *pf = 0;
 143 
 144         if (ax25->modulus == MODULUS) {
 145                 if ((frame[0] & S) == 0) {
 146                         frametype = I;                  
 147                         *ns = (frame[0] >> 1) & 0x07;
 148                         *nr = (frame[0] >> 5) & 0x07;
 149                         *pf = frame[0] & PF;
 150                 } else if ((frame[0] & U) == 1) {       
 151                         frametype = frame[0] & 0x0F;
 152                         *nr = (frame[0] >> 5) & 0x07;
 153                         *pf = frame[0] & PF;
 154                 } else if ((frame[0] & U) == 3) {       
 155                         frametype = frame[0] & ~PF;
 156                         *pf = frame[0] & PF;
 157                 }
 158                 skb_pull(skb, 1);
 159         } else {
 160                 if ((frame[0] & S) == 0) {
 161                         frametype = I;                  
 162                         *ns = (frame[0] >> 1) & 0x7F;
 163                         *nr = (frame[1] >> 1) & 0x7F;
 164                         *pf = frame[1] & EPF;
 165                         skb_pull(skb, 2);
 166                 } else if ((frame[0] & U) == 1) {       
 167                         frametype = frame[0] & 0x0F;
 168                         *nr = (frame[1] >> 1) & 0x7F;
 169                         *pf = frame[1] & EPF;
 170                         skb_pull(skb, 2);
 171                 } else if ((frame[0] & U) == 3) {       
 172                         frametype = frame[0] & ~PF;
 173                         *pf = frame[0] & PF;
 174                         skb_pull(skb, 1);
 175                 }
 176         }
 177 
 178         return frametype;
 179 }
 180 
 181 
 182 
 183 
 184 
 185 
 186 void ax25_send_control(ax25_cb *ax25, int frametype, int poll_bit, int type)
     
 187 {
 188         struct sk_buff *skb;
 189         unsigned char  *dptr;
 190         struct device *dev;
 191         
 192         if ((dev = ax25->device) == NULL)
 193                 return; 
 194 
 195         if ((skb = alloc_skb(AX25_BPQ_HEADER_LEN + size_ax25_addr(ax25->digipeat) + 2, GFP_ATOMIC)) == NULL)
 196                 return;
 197 
 198         skb_reserve(skb, AX25_BPQ_HEADER_LEN + size_ax25_addr(ax25->digipeat));
 199 
 200         if (ax25->sk != NULL) {
 201                 skb->sk = ax25->sk;
 202                 ax25->sk->wmem_alloc += skb->truesize;
 203         }
 204 
 205         
 206         if (ax25->modulus == MODULUS) {
 207                 dptr = skb_put(skb, 1);
 208                 *dptr = frametype;
 209                 *dptr |= (poll_bit) ? PF : 0;
 210                 if ((frametype & U) == S)               
 211                         *dptr |= (ax25->vr << 5);
 212         } else {
 213                 if ((frametype & U) == U) {
 214                         dptr = skb_put(skb, 1);
 215                         *dptr = frametype;
 216                         *dptr |= (poll_bit) ? PF : 0;
 217                 } else {
 218                         dptr = skb_put(skb, 2);
 219                         dptr[0] = frametype;
 220                         dptr[1] = (ax25->vr << 1);
 221                         dptr[1] |= (poll_bit) ? EPF : 0;
 222                 }
 223         }
 224 
 225         skb->free = 1;
 226 
 227         ax25_transmit_buffer(ax25, skb, type);
 228 }
 229 
 230 
 231 
 232 
 233 
 234 
 235 void ax25_return_dm(struct device *dev, ax25_address *src, ax25_address *dest, ax25_digi *digi)
     
 236 {
 237         struct sk_buff *skb;
 238         char *dptr;
 239         ax25_digi retdigi;
 240 
 241         if (dev == NULL)
 242                 return;
 243 
 244         if ((skb = alloc_skb(AX25_BPQ_HEADER_LEN + size_ax25_addr(digi) + 1, GFP_ATOMIC)) == NULL)
 245                 return; 
 246 
 247         skb_reserve(skb, AX25_BPQ_HEADER_LEN + size_ax25_addr(digi));
 248 
 249         ax25_digi_invert(digi, &retdigi);
 250 
 251         dptr = skb_put(skb, 1);
 252         skb->sk = NULL;
 253 
 254         *dptr = DM | PF;
 255 
 256         
 257 
 258 
 259 
 260         dptr  = skb_push(skb, size_ax25_addr(digi));
 261         dptr += build_ax25_addr(dptr, dest, src, &retdigi, C_RESPONSE, MODULUS);
 262 
 263         skb->arp  = 1;
 264         skb->free = 1;
 265 
 266         ax25_queue_xmit(skb, dev, SOPRI_NORMAL);
 267 }
 268 
 269 
 270 
 271 
 272 unsigned short ax25_calculate_t1(ax25_cb *ax25)
     
 273 {
 274 #ifndef NO_BACKOFF
 275         int n, t = 2;
 276 
 277         if (ax25->backoff) {
 278                 for (n = 0; n < ax25->n2count; n++)
 279                         t *= 2;
 280 
 281                 if (t > 8) t = 8;
 282         }
 283 
 284         return t * ax25->rtt;
 285 #else
 286         return 2 * ax25->rtt;
 287 #endif
 288 }
 289 
 290 
 291 
 292 
 293 void ax25_calculate_rtt(ax25_cb *ax25)
     
 294 {
 295         if (ax25->t1timer > 0 && ax25->n2count == 0)
 296                 ax25->rtt = (9 * ax25->rtt + ax25->t1 - ax25->t1timer) / 10;
 297 
 298         
 299         if (ax25->rtt < 1 * PR_SLOWHZ)
 300                 ax25->rtt = 1 * PR_SLOWHZ;
 301 }
 302 
 303 
 304 
 305 
 306  
 307 
 308 
 309 
 310 
 311 
 312 unsigned char *ax25_parse_addr(unsigned char *buf, int len, ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags)
     
 313 {
 314         int d = 0;
 315         
 316         if (len < 14) return NULL;
 317                 
 318         if (flags != NULL) {
 319                 *flags = 0;
 320         
 321                 if (buf[6] & LAPB_C) {
 322                         *flags = C_COMMAND;
 323                 }
 324                 if (buf[13] & LAPB_C) {
 325                         *flags = C_RESPONSE;
 326                 }
 327         }
 328                 
 329         
 330         if (dest != NULL) memcpy(dest, buf + 0, AX25_ADDR_LEN);
 331         if (src != NULL)  memcpy(src,  buf + 7, AX25_ADDR_LEN);
 332         buf += 2 * AX25_ADDR_LEN;
 333         len -= 2 * AX25_ADDR_LEN;
 334         digi->lastrepeat = -1;
 335         digi->ndigi      = 0;
 336         
 337         while (!(buf[-1] & LAPB_E))
 338         {
 339                 if (d >= 6)  return NULL;       
 340                 if (len < 7) return NULL;       
 341 
 342                 if (digi != NULL) {
 343                         memcpy(&digi->calls[d], buf, AX25_ADDR_LEN);
 344                         digi->ndigi = d + 1;
 345                         if (buf[6] & AX25_REPEATED) {
 346                                 digi->repeated[d] = 1;
 347                                 digi->lastrepeat  = d;
 348                         } else {
 349                                 digi->repeated[d] = 0;
 350                         }
 351                 }
 352 
 353                 buf += AX25_ADDR_LEN;
 354                 len -= AX25_ADDR_LEN;
 355                 d++;
 356         }
 357 
 358         return buf;
 359 }
 360 
 361 
 362 
 363 
 364 int build_ax25_addr(unsigned char *buf, ax25_address *src, ax25_address *dest, ax25_digi *d, int flag, int modulus)
     
 365 {
 366         int len = 0;
 367         int ct  = 0;
 368 
 369         memcpy(buf, dest, AX25_ADDR_LEN);
 370         buf[6] &= ~(LAPB_E | LAPB_C);
 371         buf[6] |= SSSID_SPARE;
 372 
 373         if (flag == C_COMMAND) buf[6] |= LAPB_C;
 374 
 375         buf += AX25_ADDR_LEN;
 376         len += AX25_ADDR_LEN;
 377 
 378         memcpy(buf, src, AX25_ADDR_LEN);
 379         buf[6] &= ~(LAPB_E | LAPB_C);
 380         buf[6] &= ~SSSID_SPARE;
 381 
 382         if (modulus == MODULUS) {
 383                 buf[6] |= SSSID_SPARE;
 384         } else {
 385                 buf[6] |= ESSID_SPARE;
 386         }
 387 
 388         if (flag == C_RESPONSE) buf[6] |= LAPB_C;
 389 
 390         
 391 
 392 
 393         if (d == NULL || d->ndigi == 0) {
 394                 buf[6] |= LAPB_E;
 395                 return 2 * AX25_ADDR_LEN;
 396         }       
 397         
 398         buf += AX25_ADDR_LEN;
 399         len += AX25_ADDR_LEN;
 400         
 401         while (ct < d->ndigi) {
 402                 memcpy(buf, &d->calls[ct], AX25_ADDR_LEN);
 403                 if (d->repeated[ct])
 404                         buf[6] |= AX25_REPEATED;
 405                 else
 406                         buf[6] &= ~AX25_REPEATED;
 407                 buf[6] &= ~LAPB_E;
 408                 buf[6] |= SSSID_SPARE;
 409 
 410                 buf += AX25_ADDR_LEN;
 411                 len += AX25_ADDR_LEN;
 412                 ct++;
 413         }
 414 
 415         buf[-1] |= LAPB_E;
 416         
 417         return len;
 418 }
 419 
 420 int size_ax25_addr(ax25_digi *dp)
     
 421 {
 422         if (dp == NULL)
 423                 return 2 * AX25_ADDR_LEN;
 424 
 425         return AX25_ADDR_LEN * (2 + dp->ndigi);
 426 }
 427         
 428 
 429 
 430      
 431 void ax25_digi_invert(ax25_digi *in, ax25_digi *out)
     
 432 {
 433         int ct = 0;
 434         
 435         
 436         
 437         while (ct < in->ndigi) {
 438                 out->calls[ct]    = in->calls[in->ndigi - ct - 1];
 439                 out->repeated[ct] = 0;
 440                 ct++;
 441         }
 442         
 443         
 444         out->ndigi = in->ndigi;
 445 
 446         
 447         out->lastrepeat = 0;
 448 }
 449 
 450 #endif