root/net/ax25/ax25_in.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ax25_rx_fragment
  2. ax25_rx_iframe
  3. ax25_state1_machine
  4. ax25_state2_machine
  5. ax25_state3_machine
  6. ax25_state4_machine
  7. ax25_process_rx_frame

   1 /*
   2  *      AX.25 release 031
   3  *
   4  *      This is ALPHA test software. This code may break your machine, randomly fail to work with new 
   5  *      releases, misbehave and/or generally screw up. It might even work. 
   6  *
   7  *      This code REQUIRES 1.2.1 or higher/ NET3.029
   8  *
   9  *      This module:
  10  *              This module is free software; you can redistribute it and/or
  11  *              modify it under the terms of the GNU General Public License
  12  *              as published by the Free Software Foundation; either version
  13  *              2 of the License, or (at your option) any later version.
  14  *
  15  *      Most of this code is based on the SDL diagrams published in the 7th
  16  *      ARRL Computer Networking Conference papers. The diagrams have mistakes
  17  *      in them, but are mostly correct. Before you modify the code could you
  18  *      read the SDL diagrams as the code is not obvious and probably very
  19  *      easy to break;
  20  *
  21  *      History
  22  *      AX.25 028a      Jonathan(G4KLX) New state machine based on SDL diagrams.
  23  *      AX.25 028b      Jonathan(G4KLX) Extracted AX25 control block from
  24  *                                      the sock structure.
  25  *      AX.25 029       Alan(GW4PTS)    Switched to KA9Q constant names.
  26  *                      Jonathan(G4KLX) Added IP mode registration.
  27  *      AX.25 030       Jonathan(G4KLX) Added AX.25 fragment reception.
  28  *                                      Upgraded state machine for SABME.
  29  *                                      Added arbitrary protocol id support.
  30  *      AX.25 031       Joerg(DL1BKE)   Added DAMA support
  31  *                      HaJo(DD8NE)     Added Idle Disc Timer T5
  32  *                      Joerg(DL1BKE)   renamed it to "IDLE" with a slightly
  33  *                                      different behaviour. Fixed defrag
  34  *                                      routine (I hope)
  35  */
  36 
  37 #include <linux/config.h>
  38 #ifdef CONFIG_AX25
  39 #include <linux/errno.h>
  40 #include <linux/types.h>
  41 #include <linux/socket.h>
  42 #include <linux/in.h>
  43 #include <linux/kernel.h>
  44 #include <linux/sched.h>
  45 #include <linux/timer.h>
  46 #include <linux/string.h>
  47 #include <linux/sockios.h>
  48 #include <linux/net.h>
  49 #include <net/ax25.h>
  50 #include <linux/inet.h>
  51 #include <linux/netdevice.h>
  52 #include <linux/skbuff.h>
  53 #include <net/sock.h>
  54 #include <net/ip.h>                     /* For ip_rcv */
  55 #include <asm/segment.h>
  56 #include <asm/system.h>
  57 #include <linux/fcntl.h>
  58 #include <linux/mm.h>
  59 #include <linux/interrupt.h>
  60 #ifdef CONFIG_NETROM
  61 #include <net/netrom.h>
  62 #endif
  63 
  64 static int ax25_rx_iframe(ax25_cb *, struct sk_buff *);
  65 
  66 /*
  67  *      Given a fragment, queue it on the fragment queue and if the fragment
  68  *      is complete, send it back to ax25_rx_iframe.
  69  */
  70 static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72         struct sk_buff *skbn, *skbo;
  73         int hdrlen;
  74         
  75         if (ax25->fragno != 0) {
  76                 if (!(*skb->data & SEG_FIRST)) {
  77                         if ((ax25->fragno - 1) == (*skb->data & SEG_REM)) {
  78                         
  79                                 /* enqueue fragment */
  80                                 
  81                                 ax25->fragno = *skb->data & SEG_REM;
  82                                 skb_pull(skb, 1);       /* skip fragno */
  83                                 ax25->fraglen += skb->len;
  84                                 skb_queue_tail(&ax25->frag_queue, skb);
  85                                 
  86                                 /* last fragment received? */
  87 
  88                                 if (ax25->fragno == 0) {
  89                                         if ((skbn = alloc_skb(AX25_MAX_HEADER_LEN + ax25->fraglen, GFP_ATOMIC)) == NULL)
  90                                                 return 0;
  91 
  92                                         skbn->free = 1;
  93                                         skbn->arp  = 1;
  94                                         skbn->dev  = skb->dev;
  95 
  96                                         if (ax25->sk != NULL) {
  97                                                 skbn->sk = ax25->sk;
  98                                                 ax25->sk->rmem_alloc += skbn->truesize;
  99                                         }
 100 
 101                                         /* get first fragment from queue */
 102                                         
 103                                         skbo = skb_dequeue(&ax25->frag_queue);
 104                                         hdrlen = skbo->data - skbo->h.raw - 2;  /* skip PID & fragno */
 105                                         
 106                                         skb_push(skbo, hdrlen + 2);             /* start of address field */
 107                                         skbn->data = skb_put(skbn, hdrlen);     /* get space for info */
 108                                         memcpy(skbn->data, skbo->data, hdrlen); /* copy address field */
 109                                         skb_pull(skbo, hdrlen + 2);             /* start of data */
 110                                         skb_pull(skbn, hdrlen + 1);             /* dito */
 111 
 112                                         /* copy data from first fragment */
 113 
 114                                         memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
 115                                         kfree_skb(skbo, FREE_READ);
 116                                         
 117                                         /* add other fragment's data */
 118 
 119                                         while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) {
 120                                                 memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
 121                                                 kfree_skb(skbo, FREE_READ);
 122                                         }
 123 
 124                                         ax25->fraglen = 0;              /* reset counter */
 125                                         
 126                                         /* 
 127                                          * mysteriously we need to re-adjust skb->data.
 128                                          * Anyway, it seems to work. Do we have the address fields
 129                                          * encoded TWICE in one sk_buff?
 130                                          */
 131                                         
 132                                         skb_pull(skbn, hdrlen);
 133 
 134                                         if (ax25_rx_iframe(ax25, skbn) == 0)
 135                                                 kfree_skb(skbn, FREE_READ);
 136                                 }
 137                                 
 138                                 return 1;
 139                         }
 140                 }
 141         } else {
 142                 /* first fragment received? */
 143 
 144                 if (*skb->data & SEG_FIRST) {
 145                         ax25->fragno = *skb->data & SEG_REM;
 146                         skb_pull(skb, 1);               /* skip fragno */
 147                         ax25->fraglen = skb->len;
 148                         skb_queue_tail(&ax25->frag_queue, skb);
 149                         return 1;
 150                 }
 151         }
 152 
 153         return 0;
 154 }
 155 
 156 /*
 157  *      This is where all valid I frames are sent to, to be dispatched to
 158  *      whichever protocol requires them.
 159  */
 160 static int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162         volatile int queued = 0;
 163         unsigned char pid;
 164         
 165         if (skb == NULL) return 0;
 166         
 167         pid = *skb->data;
 168 
 169         switch (pid) {
 170 #ifdef CONFIG_NETROM
 171                 case AX25_P_NETROM:
 172                         ax25->idletimer = ax25->idle = ax25_dev_get_value(ax25->device, AX25_VALUES_IDLE);
 173                         if (ax25_dev_get_value(ax25->device, AX25_VALUES_NETROM)) {
 174                                 skb_pull(skb, 1);       /* Remove PID */
 175                                 queued = nr_route_frame(skb, ax25);
 176                         }
 177                         break;
 178 #endif
 179 #ifdef CONFIG_INET
 180                 case AX25_P_IP:
 181                         ax25->idletimer = ax25->idle = ax25_dev_get_value(ax25->device, AX25_VALUES_IDLE);
 182                         skb_pull(skb, 1);       /* Remove PID */
 183                         skb->h.raw = skb->data;
 184                         ax25_ip_mode_set(&ax25->dest_addr, ax25->device, 'V');
 185                         ip_rcv(skb, ax25->device, NULL);        /* Wrong ptype */
 186                         queued = 1;
 187                         
 188                         break;
 189 #endif
 190                 case AX25_P_SEGMENT:
 191                         ax25->idletimer = ax25->idle = ax25_dev_get_value(ax25->device, AX25_VALUES_IDLE);
 192                         skb_pull(skb, 1);       /* Remove PID */
 193                         queued = ax25_rx_fragment(ax25, skb);
 194                         break;
 195 
 196                 default:
 197                         ax25->idletimer = ax25->idle = 0;
 198                         if (ax25->sk != NULL && ax25_dev_get_value(ax25->device, AX25_VALUES_TEXT) && ax25->sk->protocol == pid) {
 199                                 if (sock_queue_rcv_skb(ax25->sk, skb) == 0) {
 200                                         queued = 1;
 201                                 } else {
 202                                         ax25->condition |= OWN_RX_BUSY_CONDITION;
 203                                 }
 204                         }
 205                         break;
 206         }
 207 
 208         return queued;
 209 }
 210 
 211 /*
 212  *      State machine for state 1, Awaiting Connection State.
 213  *      The handling of the timer(s) is in file ax25_timer.c.
 214  *      Handling of state 0 and connection release is in ax25.c.
 215  */
 216 static int ax25_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type, int dama)
     /* [previous][next][first][last][top][bottom][index][help] */
 217 {
 218         switch (frametype) {
 219                 case SABM:
 220                         ax25->modulus = MODULUS;
 221                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 222                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 223                         break;
 224 
 225                 case SABME:
 226                         ax25->modulus = EMODULUS;
 227                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 228                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 229                         break;
 230 
 231                 case DISC:
 232                         ax25_send_control(ax25, DM, pf, C_RESPONSE);
 233                         break;
 234 
 235                 case UA:
 236                         if (pf || dama) {
 237                                 if (dama) ax25_dama_on(ax25); /* bke */
 238                                         
 239                                 ax25_calculate_rtt(ax25);
 240                                 ax25->t1timer = 0;
 241                                 ax25->t3timer = ax25->t3;
 242                                 ax25->idletimer = ax25->idle;
 243                                 ax25->vs      = 0;
 244                                 ax25->va      = 0;
 245                                 ax25->vr      = 0;
 246                                 ax25->state   = AX25_STATE_3;
 247                                 ax25->n2count = 0;
 248                                 ax25->dama_slave = dama;        /* bke */
 249                                         
 250                                 if (ax25->sk != NULL) {
 251                                         ax25->sk->state = TCP_ESTABLISHED;
 252                                         /* For WAIT_SABM connections we will produce an accept ready socket here */
 253                                         if (!ax25->sk->dead)
 254                                                 ax25->sk->state_change(ax25->sk);
 255                                 }
 256                         }
 257                         break;
 258 
 259                 case DM:
 260                         if (pf) {
 261                                 if (ax25->modulus == MODULUS) {
 262                                         ax25_clear_queues(ax25);
 263                                         ax25->state = AX25_STATE_0;
 264                                         if (ax25->sk != NULL) {
 265                                                 ax25->sk->state = TCP_CLOSE;
 266                                                 ax25->sk->err   = ECONNREFUSED;
 267                                                 if (!ax25->sk->dead)
 268                                                         ax25->sk->state_change(ax25->sk);
 269                                                 ax25->sk->dead  = 1;
 270                                         }
 271                                 } else {
 272                                         ax25->modulus = MODULUS;
 273                                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 274                                 }
 275                         }
 276                         break;
 277 
 278                 default:
 279                         if (dama && pf) /* dl1bke 960116 */
 280                                 ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
 281                         break;
 282         }
 283 
 284         return 0;
 285 }
 286 
 287 /*
 288  *      State machine for state 2, Awaiting Release State.
 289  *      The handling of the timer(s) is in file ax25_timer.c
 290  *      Handling of state 0 and connection release is in ax25.c.
 291  */
 292 static int ax25_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
     /* [previous][next][first][last][top][bottom][index][help] */
 293 {
 294         switch (frametype) {
 295                 case SABM:
 296                 case SABME:
 297                         ax25_send_control(ax25, DM, pf, C_RESPONSE);
 298                         if (ax25->dama_slave)
 299                                 ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 300                         break;
 301 
 302                 case DISC:
 303                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 304                         if (ax25->dama_slave) {
 305                                 ax25->state = AX25_STATE_0;
 306                                 ax25->dama_slave = 0;
 307                                 ax25_dama_off(ax25);
 308 
 309                                 if (ax25->sk != NULL) {
 310                                         ax25->sk->state = TCP_CLOSE;
 311                                         ax25->sk->err   = 0;
 312                                         if (!ax25->sk->dead)
 313                                                 ax25->sk->state_change(ax25->sk);
 314                                         ax25->sk->dead  = 1;
 315                                 }
 316                         }
 317                         break;
 318 
 319                 case UA:
 320                         if (pf) {
 321                                 ax25->state = AX25_STATE_0;
 322                                 ax25->dama_slave = 0;
 323                                 ax25_dama_off(ax25);
 324 
 325                                 if (ax25->sk != NULL) {
 326                                         ax25->sk->state = TCP_CLOSE;
 327                                         ax25->sk->err   = 0;
 328                                         if (!ax25->sk->dead)
 329                                                 ax25->sk->state_change(ax25->sk);
 330                                         ax25->sk->dead  = 1;
 331                                 }
 332                         }
 333                         break;
 334 
 335                 case DM:
 336                         if (pf) {
 337                                 ax25->state = AX25_STATE_0;
 338                                 ax25->dama_slave = 0;
 339                                 ax25_dama_off(ax25);
 340                                         
 341                                 if (ax25->sk != NULL) {
 342                                         ax25->sk->state = TCP_CLOSE;
 343                                         ax25->sk->err   = 0;
 344                                         if (!ax25->sk->dead)
 345                                                 ax25->sk->state_change(ax25->sk);
 346                                         ax25->sk->dead  = 1;
 347                                 }
 348                         }
 349                         break;
 350 
 351                 case I:
 352                 case REJ:
 353                 case RNR:
 354                 case RR:
 355                         if (pf) {
 356                                 if (ax25->dama_slave)
 357                                         ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 358                                 else
 359                                         ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
 360                         }
 361                         break;
 362                                 
 363                 default:
 364                         break;
 365         }
 366 
 367         return 0;
 368 }
 369 
 370 /*
 371  *      State machine for state 3, Connected State.
 372  *      The handling of the timer(s) is in file ax25_timer.c
 373  *      Handling of state 0 and connection release is in ax25.c.
 374  */
 375 static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type, int dama)
     /* [previous][next][first][last][top][bottom][index][help] */
 376 {
 377         int queued = 0;
 378 
 379         switch (frametype) {
 380                 case SABM:
 381                         if (dama) ax25_dama_on(ax25);
 382                                 
 383                         ax25->modulus   = MODULUS;
 384                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 385                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 386                         ax25->condition = 0x00;
 387                         ax25->t1timer   = 0;
 388                         ax25->t3timer   = ax25->t3;
 389                         ax25->idletimer = ax25->idle;
 390                         ax25->vs        = 0;
 391                         ax25->va        = 0;
 392                         ax25->vr        = 0;
 393                         ax25->dama_slave = dama;
 394                         break;
 395 
 396                 case SABME:
 397                         if (dama) ax25_dama_on(ax25);
 398                                 
 399                         ax25->modulus   = EMODULUS;
 400                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 401                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 402                         ax25->condition = 0x00;
 403                         ax25->t1timer   = 0;
 404                         ax25->t3timer   = ax25->t3;
 405                         ax25->idletimer = ax25->idle;
 406                         ax25->vs        = 0;
 407                         ax25->va        = 0;
 408                         ax25->vr        = 0;
 409                         ax25->dama_slave = dama;
 410                         break;
 411 
 412                 case DISC:
 413                         ax25_clear_queues(ax25);
 414                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 415                         ax25->t3timer = 0;
 416                         ax25->state   = AX25_STATE_0;
 417                         ax25->dama_slave = 0;
 418                         ax25_dama_off(ax25);
 419                         
 420                         if (ax25->sk != NULL) {
 421                                 ax25->sk->state = TCP_CLOSE;
 422                                 ax25->sk->err   = 0;
 423                                 if (!ax25->sk->dead)
 424                                         ax25->sk->state_change(ax25->sk);
 425                                 ax25->sk->dead  = 1;
 426                         }
 427                         break;
 428 
 429                 case DM:
 430                         ax25_clear_queues(ax25);
 431                         ax25->t3timer = 0;
 432                         ax25->state   = AX25_STATE_0;
 433                         ax25->dama_slave = 0;
 434                         ax25_dama_off(ax25);
 435                         if (ax25->sk) {
 436                                 ax25->sk->state = TCP_CLOSE;
 437                                 ax25->sk->err   = ECONNRESET;
 438                                 if (!ax25->sk->dead)
 439                                         ax25->sk->state_change(ax25->sk);
 440                                 ax25->sk->dead         = 1;
 441                         }
 442                         break;
 443 
 444                 case RNR:
 445                         ax25->condition |= PEER_RX_BUSY_CONDITION;
 446                         ax25_check_need_response(ax25, type, pf);
 447                         if (ax25_validate_nr(ax25, nr)) {
 448                                 ax25_check_iframes_acked(ax25, nr);
 449                                 dama_check_need_response(ax25, type, pf);
 450                         } else {
 451                                 ax25_nr_error_recovery(ax25);
 452                                 ax25->state = AX25_STATE_1;
 453                         }
 454                         break;
 455                         
 456                 case RR:
 457                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 458                         ax25_check_need_response(ax25, type, pf);
 459                         if (ax25_validate_nr(ax25, nr)) {
 460                                 ax25_check_iframes_acked(ax25, nr);
 461                                 dama_check_need_response(ax25, type, pf);
 462                         } else {
 463                                 ax25_nr_error_recovery(ax25);
 464                                 ax25->state = AX25_STATE_1;
 465                         }
 466                         break;
 467                                 
 468                 case REJ:
 469                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 470                         ax25_check_need_response(ax25, type, pf);
 471                         if (ax25_validate_nr(ax25, nr)) {
 472                                 ax25_frames_acked(ax25, nr);
 473                                 ax25_calculate_rtt(ax25);
 474                                 ax25->t1timer = 0;
 475                                 ax25->t3timer = ax25->t3;
 476                                 ax25_requeue_frames(ax25);
 477                                 dama_check_need_response(ax25, type, pf);
 478                         } else {
 479                                 ax25_nr_error_recovery(ax25);
 480                                 ax25->state = AX25_STATE_1;
 481                         }
 482                         break;
 483                         
 484                 case I:
 485 #ifndef AX25_BROKEN_NETMAC
 486                         if (type != C_COMMAND)
 487                                 break;
 488 #endif
 489                         if (!ax25_validate_nr(ax25, nr)) {
 490                                 ax25_nr_error_recovery(ax25);
 491                                 ax25->state = AX25_STATE_1;
 492                                 break;
 493                         }
 494                         if (ax25->condition & PEER_RX_BUSY_CONDITION) {
 495                                 ax25_frames_acked(ax25, nr);
 496                         } else {
 497                                 ax25_check_iframes_acked(ax25, nr);
 498                         }
 499                         if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 500                                 if (pf) {
 501                                         if (ax25->dama_slave)   /* dl1bke 960114 */
 502                                                 dama_enquiry_response(ax25);
 503                                         else
 504                                                 ax25_enquiry_response(ax25);
 505                                 }
 506                                 break;
 507                         }
 508                         if (ns == ax25->vr) {
 509                                 queued = ax25_rx_iframe(ax25, skb);
 510                                 if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 511                                         if (pf) {
 512                                                 if (ax25->dama_slave)   /* dl1bke 960114 */
 513                                                         dama_enquiry_response(ax25);
 514                                                 else
 515                                                         ax25_enquiry_response(ax25);
 516                                         }
 517                                         break;
 518                                 }
 519                                 ax25->vr = (ax25->vr + 1) % ax25->modulus;
 520                                 ax25->condition &= ~REJECT_CONDITION;
 521                                 if (pf) {
 522                                         if (ax25->dama_slave)   /* dl1bke 960114 */
 523                                                 dama_enquiry_response(ax25);
 524                                         else
 525                                                 ax25_enquiry_response(ax25);
 526                                 } else {
 527                                         if (!(ax25->condition & ACK_PENDING_CONDITION)) {
 528                                                 ax25->t2timer = ax25->t2;
 529                                                 ax25->condition |= ACK_PENDING_CONDITION;
 530                                         }
 531                                 }
 532                         } else {
 533                                 if (ax25->condition & REJECT_CONDITION) {
 534                                         if (pf) {
 535                                                 if (ax25->dama_slave)   /* dl1bke 960114 */
 536                                                         dama_enquiry_response(ax25);
 537                                                 else
 538                                                         ax25_enquiry_response(ax25);
 539                                         }
 540                                 } else {
 541                                         ax25->condition |= REJECT_CONDITION;
 542                                         if (ax25->dama_slave)           /* dl1bke 960114 */
 543                                                 dama_enquiry_response(ax25);
 544                                         else
 545                                                 ax25_send_control(ax25, REJ, pf, C_RESPONSE);
 546                                         ax25->condition &= ~ACK_PENDING_CONDITION;
 547                                 }
 548                         }
 549                         break;
 550 
 551                 case FRMR:
 552                 case ILLEGAL:
 553                         ax25_establish_data_link(ax25);
 554                         ax25->state = AX25_STATE_1;
 555                         break;
 556 
 557                 default:
 558                         break;
 559         }
 560 
 561         return queued;
 562 }
 563 
 564 /*
 565  *      State machine for state 4, Timer Recovery State.
 566  *      The handling of the timer(s) is in file ax25_timer.c
 567  *      Handling of state 0 and connection release is in ax25.c.
 568  */
 569 static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type, int dama)
     /* [previous][next][first][last][top][bottom][index][help] */
 570 {
 571         int queued = 0;
 572 
 573         switch (frametype) {
 574                 case SABM:
 575                         if (dama) ax25_dama_on(ax25);
 576                                 
 577                         ax25->dama_slave = dama;
 578                         ax25->modulus   = MODULUS;
 579                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 580                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 581                         ax25->condition = 0x00;
 582                         ax25->t1timer   = 0;
 583                         ax25->t3timer   = ax25->t3;
 584                         ax25->idletimer = ax25->idle;
 585                         ax25->vs        = 0;
 586                         ax25->va        = 0;
 587                         ax25->vr        = 0;
 588                         ax25->state     = AX25_STATE_3;
 589                         ax25->n2count   = 0;
 590                         break;
 591 
 592                 case SABME:
 593                         if (dama) ax25_dama_on(ax25);
 594                                 
 595                         ax25->dama_slave = dama;
 596                         ax25->modulus   = EMODULUS;
 597                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 598                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 599                         ax25->condition = 0x00;
 600                         ax25->t1timer   = 0;
 601                         ax25->t3timer   = ax25->t3;
 602                         ax25->idletimer = ax25->idle;
 603                         ax25->vs        = 0;
 604                         ax25->va        = 0;
 605                         ax25->vr        = 0;
 606                         ax25->state     = AX25_STATE_3;
 607                         ax25->n2count   = 0;
 608                         break;
 609 
 610                 case DISC:
 611                         ax25_clear_queues(ax25);
 612                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 613                         ax25->t3timer = 0;
 614                         ax25->state   = AX25_STATE_0;
 615                         ax25->dama_slave = 0;
 616                         ax25_dama_off(ax25);
 617                         
 618                         if (ax25->sk != NULL) {
 619                                 ax25->sk->state = TCP_CLOSE;
 620                                 ax25->sk->err   = 0;
 621                                 if (!ax25->sk->dead)
 622                                         ax25->sk->state_change(ax25->sk);
 623                                 ax25->sk->dead  = 1;
 624                         }
 625                         break;
 626 
 627                 case DM:
 628                         ax25_clear_queues(ax25);
 629                         ax25->t3timer = 0;
 630                         ax25->state   = AX25_STATE_0;
 631                         ax25->dama_slave = 0;
 632                         ax25_dama_off(ax25);
 633                         
 634                         if (ax25->sk != NULL) {
 635                                 ax25->sk->state = TCP_CLOSE;
 636                                 ax25->sk->err   = ECONNRESET;
 637                                 if (!ax25->sk->dead)
 638                                         ax25->sk->state_change(ax25->sk);
 639                                 ax25->sk->dead  = 1;
 640                         }
 641                         break;
 642 
 643                 case RNR:
 644                         ax25->condition |= PEER_RX_BUSY_CONDITION;
 645                         if (type == C_RESPONSE && pf) {
 646                                 ax25->t1timer = 0;
 647                                 if (ax25_validate_nr(ax25, nr)) {
 648                                         ax25_frames_acked(ax25, nr);
 649                                         if (ax25->vs == ax25->va) {
 650                                                 ax25->t3timer = ax25->t3;
 651                                                 ax25->n2count = 0;
 652                                                 ax25->state   = AX25_STATE_3;
 653                                         }
 654                                 } else {
 655                                         ax25_nr_error_recovery(ax25);
 656                                         ax25->state = AX25_STATE_1;
 657                                 }
 658                                 break;
 659                         }
 660                          
 661                         ax25_check_need_response(ax25, type, pf);
 662                         if (ax25_validate_nr(ax25, nr)) {
 663                                 ax25_frames_acked(ax25, nr);
 664                                 dama_check_need_response(ax25, type, pf);
 665                         } else {
 666                                 ax25_nr_error_recovery(ax25);
 667                                 ax25->state = AX25_STATE_1;
 668                         }
 669                         break;
 670                         
 671                 case RR:
 672                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 673                         if ( pf && (type == C_RESPONSE || (ax25->dama_slave && type == C_COMMAND)) ) {
 674                                 ax25->t1timer = 0;
 675                                 if (ax25_validate_nr(ax25, nr)) {
 676                                         ax25_frames_acked(ax25, nr);
 677                                         if (ax25->vs == ax25->va) {
 678                                                 ax25->t3timer = ax25->t3;
 679                                                 ax25->n2count = 0;
 680                                                 ax25->state   = AX25_STATE_3;
 681                                         } else {
 682                                                 ax25_requeue_frames(ax25);
 683                                         }
 684                                         dama_check_need_response(ax25, type, pf);
 685                                 } else {
 686                                         ax25_nr_error_recovery(ax25);
 687                                         ax25->state = AX25_STATE_1;
 688                                 }
 689                                 break;
 690                         }
 691 
 692                         ax25_check_need_response(ax25, type, pf);
 693                         if (ax25_validate_nr(ax25, nr)) {
 694                                 ax25_frames_acked(ax25, nr);
 695                                 dama_check_need_response(ax25, type, pf);
 696                         } else {
 697                                 ax25_nr_error_recovery(ax25);
 698                                 ax25->state = AX25_STATE_1;
 699                         }
 700                         break;
 701 
 702                 case REJ:
 703                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 704                         if ( pf && (type == C_RESPONSE || (ax25->dama_slave && type == C_COMMAND)) ) {
 705                                 ax25->t1timer = 0;
 706                                 if (ax25_validate_nr(ax25, nr)) {
 707                                         ax25_frames_acked(ax25, nr);
 708                                         if (ax25->vs == ax25->va) {
 709                                                 ax25->t3timer = ax25->t3;
 710                                                 ax25->n2count = 0;
 711                                                 ax25->state   = AX25_STATE_3;
 712                                         } else {
 713                                                 ax25_requeue_frames(ax25);
 714                                         }
 715                                         dama_check_need_response(ax25, type, pf);
 716                                 } else {
 717                                         ax25_nr_error_recovery(ax25);
 718                                         ax25->state = AX25_STATE_1;
 719                                 }
 720                                 break;
 721                         }
 722                         
 723                         ax25_check_need_response(ax25, type, pf);       
 724                         if (ax25_validate_nr(ax25, nr)) {
 725                                 ax25_frames_acked(ax25, nr);
 726                                 if(ax25->vs != ax25->va) {
 727                                         ax25_requeue_frames(ax25);
 728                                 }
 729                                 dama_check_need_response(ax25, type, pf);
 730                         } else {
 731                                 ax25_nr_error_recovery(ax25);
 732                                 ax25->state = AX25_STATE_1;
 733                         }
 734                         break;
 735 
 736                 case I:
 737 #ifndef AX25_BROKEN_NETMAC
 738                         if (type != C_COMMAND)
 739                                 break;
 740 #endif
 741                         if (!ax25_validate_nr(ax25, nr)) {
 742                                 ax25_nr_error_recovery(ax25);
 743                                 ax25->state = AX25_STATE_1;
 744                                 break;
 745                         }
 746                         ax25_frames_acked(ax25, nr);
 747                         if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 748                                 if (pf) {       /* dl1bke 960114 */
 749                                         if (ax25->dama_slave)
 750                                                 ax25_enquiry_response(ax25);
 751                                         else
 752                                                 dama_enquiry_response(ax25);
 753                                 }
 754                                 break;
 755                         }
 756                         if (ns == ax25->vr) {
 757                                 queued = ax25_rx_iframe(ax25, skb);
 758                                 if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 759                                         if (pf) {       /* dl1bke 960114 */
 760                                                 if (ax25->dama_slave)
 761                                                         dama_enquiry_response(ax25);
 762                                                 else
 763                                                         ax25_enquiry_response(ax25);
 764                                         }
 765                                         break;
 766                                 }
 767                                 ax25->vr = (ax25->vr + 1) % ax25->modulus;
 768                                 ax25->condition &= ~REJECT_CONDITION;
 769                                 if (pf) {
 770                                         if (ax25->dama_slave)   /* dl1bke 960114 */
 771                                                 dama_enquiry_response(ax25);
 772                                         else
 773                                                 ax25_enquiry_response(ax25);
 774                                 } else {
 775                                         if (!(ax25->condition & ACK_PENDING_CONDITION)) {
 776                                                 ax25->t2timer = ax25->t2;
 777                                                 ax25->condition |= ACK_PENDING_CONDITION;
 778                                         }
 779                                 }
 780                         } else {
 781                                 if (ax25->condition & REJECT_CONDITION) {
 782                                         if (pf) {       /* dl1bke 960114 */
 783                                                 if (ax25->dama_slave)
 784                                                         dama_enquiry_response(ax25);
 785                                                 else
 786                                                         ax25_enquiry_response(ax25);
 787                                         }
 788                                 } else {
 789                                         ax25->condition |= REJECT_CONDITION;
 790                                         if (ax25->dama_slave)           /* dl1bke 960114 */
 791                                                 dama_enquiry_response(ax25);
 792                                         else
 793                                                 ax25_send_control(ax25, REJ, pf, C_RESPONSE);
 794                                         ax25->condition &= ~ACK_PENDING_CONDITION;
 795                                 }
 796                         }
 797                         break;
 798                 
 799                 case FRMR:
 800                 case ILLEGAL:
 801                         ax25_establish_data_link(ax25);
 802                         ax25->state = AX25_STATE_1;
 803                         break;
 804 
 805                 default:
 806                         break;
 807         }
 808 
 809         return queued;
 810 }
 811 
 812 /*
 813  *      Higher level upcall for a LAPB frame
 814  */
 815 int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, int dama)
     /* [previous][next][first][last][top][bottom][index][help] */
 816 {
 817         int queued = 0, frametype, ns, nr, pf;
 818         
 819         if (ax25->sk != NULL && ax25->state == AX25_STATE_0 && ax25->sk->dead)
 820                 return queued;
 821 
 822         if (ax25->state != AX25_STATE_1 && ax25->state != AX25_STATE_2 &&
 823             ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4) {
 824                 printk("ax25_process_rx_frame: frame received - state = %d\n", ax25->state);
 825                 return queued;
 826         }
 827 
 828         del_timer(&ax25->timer);
 829 
 830         frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
 831 
 832         switch (ax25->state) {
 833                 case AX25_STATE_1:
 834                         queued = ax25_state1_machine(ax25, skb, frametype, pf, type, dama);
 835                         break;
 836                 case AX25_STATE_2:
 837                         queued = ax25_state2_machine(ax25, skb, frametype, pf, type);
 838                         break;
 839                 case AX25_STATE_3:
 840                         queued = ax25_state3_machine(ax25, skb, frametype, ns, nr, pf, type, dama);
 841                         break;
 842                 case AX25_STATE_4:
 843                         queued = ax25_state4_machine(ax25, skb, frametype, ns, nr, pf, type, dama);
 844                         break;
 845         }
 846 
 847         ax25_set_timer(ax25);
 848 
 849         return queued;
 850 }
 851 
 852 #endif

/* [previous][next][first][last][top][bottom][index][help] */