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                                                 atomic_add(skbn->truesize, &ax25->sk->rmem_alloc);
  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);             /* ditto */
 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         ax25->idletimer = ax25->idle;
 168         
 169         pid = *skb->data;
 170 
 171         switch (pid) {
 172 #ifdef CONFIG_NETROM
 173                 case AX25_P_NETROM:
 174                         if (ax25_dev_get_value(ax25->device, AX25_VALUES_NETROM)) {
 175                                 skb_pull(skb, 1);       /* Remove PID */
 176                                 queued = nr_route_frame(skb, ax25);
 177                         }
 178                         break;
 179 #endif
 180 #ifdef CONFIG_INET
 181                 case AX25_P_IP:
 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                         break;
 188 #endif
 189                 case AX25_P_SEGMENT:
 190                         skb_pull(skb, 1);       /* Remove PID */
 191                         queued = ax25_rx_fragment(ax25, skb);
 192                         break;
 193 
 194                 default:
 195                         if (ax25->sk != NULL && ax25_dev_get_value(ax25->device, AX25_VALUES_TEXT) && ax25->sk->protocol == pid) {
 196                                 if (sock_queue_rcv_skb(ax25->sk, skb) == 0) {
 197                                         queued = 1;
 198                                 } else {
 199                                         ax25->condition |= OWN_RX_BUSY_CONDITION;
 200                                 }
 201                         }
 202                         break;
 203         }
 204 
 205         return queued;
 206 }
 207 
 208 /*
 209  *      State machine for state 1, Awaiting Connection State.
 210  *      The handling of the timer(s) is in file ax25_timer.c.
 211  *      Handling of state 0 and connection release is in ax25.c.
 212  */
 213 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] */
 214 {
 215         switch (frametype) {
 216                 case SABM:
 217                         ax25->modulus = MODULUS;
 218                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 219                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 220                         break;
 221 
 222                 case SABME:
 223                         ax25->modulus = EMODULUS;
 224                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 225                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 226                         break;
 227 
 228                 case DISC:
 229                         ax25_send_control(ax25, DM, pf, C_RESPONSE);
 230                         break;
 231 
 232                 case UA:
 233                         if (pf || dama) {
 234                                 if (dama) ax25_dama_on(ax25); /* bke */
 235                                         
 236                                 ax25_calculate_rtt(ax25);
 237                                 ax25->t1timer = 0;
 238                                 ax25->t3timer = ax25->t3;
 239                                 ax25->idletimer = ax25->idle;
 240                                 ax25->vs      = 0;
 241                                 ax25->va      = 0;
 242                                 ax25->vr      = 0;
 243                                 ax25->state   = AX25_STATE_3;
 244                                 ax25->n2count = 0;
 245                                 ax25->dama_slave = dama;        /* bke */
 246                                         
 247                                 if (ax25->sk != NULL) {
 248                                         ax25->sk->state = TCP_ESTABLISHED;
 249                                         /* For WAIT_SABM connections we will produce an accept ready socket here */
 250                                         if (!ax25->sk->dead)
 251                                                 ax25->sk->state_change(ax25->sk);
 252                                 }
 253                         }
 254                         break;
 255 
 256                 case DM:
 257                         if (pf) {
 258                                 if (ax25->modulus == MODULUS) {
 259                                         ax25_clear_queues(ax25);
 260                                         ax25->state = AX25_STATE_0;
 261                                         if (ax25->sk != NULL) {
 262                                                 ax25->sk->state = TCP_CLOSE;
 263                                                 ax25->sk->err   = ECONNREFUSED;
 264                                                 if (!ax25->sk->dead)
 265                                                         ax25->sk->state_change(ax25->sk);
 266                                                 ax25->sk->dead  = 1;
 267                                         }
 268                                 } else {
 269                                         ax25->modulus = MODULUS;
 270                                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 271                                 }
 272                         }
 273                         break;
 274 
 275                 default:
 276                         if (dama && pf) /* dl1bke 960116 */
 277                                 ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
 278                         break;
 279         }
 280 
 281         return 0;
 282 }
 283 
 284 /*
 285  *      State machine for state 2, Awaiting Release State.
 286  *      The handling of the timer(s) is in file ax25_timer.c
 287  *      Handling of state 0 and connection release is in ax25.c.
 288  */
 289 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] */
 290 {
 291         switch (frametype) {
 292                 case SABM:
 293                 case SABME:
 294                         ax25_send_control(ax25, DM, pf, C_RESPONSE);
 295                         if (ax25->dama_slave)
 296                                 ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 297                         break;
 298 
 299                 case DISC:
 300                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 301                         if (ax25->dama_slave) {
 302                                 ax25->state = AX25_STATE_0;
 303                                 ax25_dama_off(ax25);
 304 
 305                                 if (ax25->sk != NULL) {
 306                                         ax25->sk->state = TCP_CLOSE;
 307                                         ax25->sk->err   = 0;
 308                                         if (!ax25->sk->dead)
 309                                                 ax25->sk->state_change(ax25->sk);
 310                                         ax25->sk->dead  = 1;
 311                                 }
 312                         }
 313                         break;
 314 
 315                 case UA:
 316                         if (pf) {
 317                                 ax25->state = AX25_STATE_0;
 318                                 ax25_dama_off(ax25);
 319 
 320                                 if (ax25->sk != NULL) {
 321                                         ax25->sk->state = TCP_CLOSE;
 322                                         ax25->sk->err   = 0;
 323                                         if (!ax25->sk->dead)
 324                                                 ax25->sk->state_change(ax25->sk);
 325                                         ax25->sk->dead  = 1;
 326                                 }
 327                         }
 328                         break;
 329 
 330                 case DM:
 331                         if (pf) {
 332                                 ax25->state = AX25_STATE_0;
 333                                 ax25_dama_off(ax25);
 334                                         
 335                                 if (ax25->sk != NULL) {
 336                                         ax25->sk->state = TCP_CLOSE;
 337                                         ax25->sk->err   = 0;
 338                                         if (!ax25->sk->dead)
 339                                                 ax25->sk->state_change(ax25->sk);
 340                                         ax25->sk->dead  = 1;
 341                                 }
 342                         }
 343                         break;
 344 
 345                 case I:
 346                 case REJ:
 347                 case RNR:
 348                 case RR:
 349                         if (pf) {
 350                                 if (ax25->dama_slave)
 351                                         ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
 352                                 else
 353                                         ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
 354                         }
 355                         break;
 356                                 
 357                 default:
 358                         break;
 359         }
 360 
 361         return 0;
 362 }
 363 
 364 /*
 365  *      State machine for state 3, Connected State.
 366  *      The handling of the timer(s) is in file ax25_timer.c
 367  *      Handling of state 0 and connection release is in ax25.c.
 368  */
 369 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] */
 370 {
 371         int queued = 0;
 372 
 373         switch (frametype) {
 374                 case SABM:
 375                         if (dama) ax25_dama_on(ax25);
 376                                 
 377                         ax25->modulus   = MODULUS;
 378                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 379                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 380                         ax25->condition = 0x00;
 381                         ax25->t1timer   = 0;
 382                         ax25->t3timer   = ax25->t3;
 383                         ax25->idletimer = ax25->idle;
 384                         ax25->vs        = 0;
 385                         ax25->va        = 0;
 386                         ax25->vr        = 0;
 387                         ax25->dama_slave = dama;
 388                         break;
 389 
 390                 case SABME:
 391                         if (dama) ax25_dama_on(ax25);
 392                                 
 393                         ax25->modulus   = EMODULUS;
 394                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 395                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 396                         ax25->condition = 0x00;
 397                         ax25->t1timer   = 0;
 398                         ax25->t3timer   = ax25->t3;
 399                         ax25->idletimer = ax25->idle;
 400                         ax25->vs        = 0;
 401                         ax25->va        = 0;
 402                         ax25->vr        = 0;
 403                         ax25->dama_slave = dama;
 404                         break;
 405 
 406                 case DISC:
 407                         ax25_clear_queues(ax25);
 408                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 409                         ax25->t3timer = 0;
 410                         ax25->state   = AX25_STATE_0;
 411                         ax25_dama_off(ax25);
 412                         
 413                         if (ax25->sk != NULL) {
 414                                 ax25->sk->state = TCP_CLOSE;
 415                                 ax25->sk->err   = 0;
 416                                 if (!ax25->sk->dead)
 417                                         ax25->sk->state_change(ax25->sk);
 418                                 ax25->sk->dead  = 1;
 419                         }
 420                         break;
 421 
 422                 case DM:
 423                         ax25_clear_queues(ax25);
 424                         ax25->t3timer = 0;
 425                         ax25->state   = AX25_STATE_0;
 426                         ax25_dama_off(ax25);
 427                         if (ax25->sk) {
 428                                 ax25->sk->state = TCP_CLOSE;
 429                                 ax25->sk->err   = ECONNRESET;
 430                                 if (!ax25->sk->dead)
 431                                         ax25->sk->state_change(ax25->sk);
 432                                 ax25->sk->dead         = 1;
 433                         }
 434                         break;
 435 
 436                 case RNR:
 437                         ax25->condition |= PEER_RX_BUSY_CONDITION;
 438                         ax25_check_need_response(ax25, type, pf);
 439                         if (ax25_validate_nr(ax25, nr)) {
 440                                 ax25_check_iframes_acked(ax25, nr);
 441                                 dama_check_need_response(ax25, type, pf);
 442                         } else {
 443                                 ax25_nr_error_recovery(ax25);
 444                                 ax25->state = AX25_STATE_1;
 445                         }
 446                         break;
 447                         
 448                 case RR:
 449                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 450                         ax25_check_need_response(ax25, type, pf);
 451                         if (ax25_validate_nr(ax25, nr)) {
 452                                 ax25_check_iframes_acked(ax25, nr);
 453                                 dama_check_need_response(ax25, type, pf);
 454                         } else {
 455                                 ax25_nr_error_recovery(ax25);
 456                                 ax25->state = AX25_STATE_1;
 457                         }
 458                         break;
 459                                 
 460                 case REJ:
 461                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 462                         ax25_check_need_response(ax25, type, pf);
 463                         if (ax25_validate_nr(ax25, nr)) {
 464                                 ax25_frames_acked(ax25, nr);
 465                                 ax25_calculate_rtt(ax25);
 466                                 ax25->t1timer = 0;
 467                                 ax25->t3timer = ax25->t3;
 468                                 ax25_requeue_frames(ax25);
 469                                 dama_check_need_response(ax25, type, pf);
 470                         } else {
 471                                 ax25_nr_error_recovery(ax25);
 472                                 ax25->state = AX25_STATE_1;
 473                         }
 474                         break;
 475                         
 476                 case I:
 477 #ifndef AX25_BROKEN_NETMAC
 478                         if (type != C_COMMAND)
 479                                 break;
 480 #endif
 481                         if (!ax25_validate_nr(ax25, nr)) {
 482                                 ax25_nr_error_recovery(ax25);
 483                                 ax25->state = AX25_STATE_1;
 484                                 break;
 485                         }
 486                         if (ax25->condition & PEER_RX_BUSY_CONDITION) {
 487                                 ax25_frames_acked(ax25, nr);
 488                         } else {
 489                                 ax25_check_iframes_acked(ax25, nr);
 490                         }
 491                         if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 492                                 if (pf) {
 493                                         if (ax25->dama_slave)   /* dl1bke 960114 */
 494                                                 dama_enquiry_response(ax25);
 495                                         else
 496                                                 ax25_enquiry_response(ax25);
 497                                 }
 498                                 break;
 499                         }
 500                         if (ns == ax25->vr) {
 501                                 queued = ax25_rx_iframe(ax25, skb);
 502                                 if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 503                                         if (pf) {
 504                                                 if (ax25->dama_slave)   /* dl1bke 960114 */
 505                                                         dama_enquiry_response(ax25);
 506                                                 else
 507                                                         ax25_enquiry_response(ax25);
 508                                         }
 509                                         break;
 510                                 }
 511                                 ax25->vr = (ax25->vr + 1) % ax25->modulus;
 512                                 ax25->condition &= ~REJECT_CONDITION;
 513                                 if (pf) {
 514                                         if (ax25->dama_slave)   /* dl1bke 960114 */
 515                                                 dama_enquiry_response(ax25);
 516                                         else
 517                                                 ax25_enquiry_response(ax25);
 518                                 } else {
 519                                         if (!(ax25->condition & ACK_PENDING_CONDITION)) {
 520                                                 ax25->t2timer = ax25->t2;
 521                                                 ax25->condition |= ACK_PENDING_CONDITION;
 522                                         }
 523                                 }
 524                         } else {
 525                                 if (ax25->condition & REJECT_CONDITION) {
 526                                         if (pf) {
 527                                                 if (ax25->dama_slave)   /* dl1bke 960114 */
 528                                                         dama_enquiry_response(ax25);
 529                                                 else
 530                                                         ax25_enquiry_response(ax25);
 531                                         }
 532                                 } else {
 533                                         ax25->condition |= REJECT_CONDITION;
 534                                         if (ax25->dama_slave)           /* dl1bke 960114 */
 535                                                 dama_enquiry_response(ax25);
 536                                         else
 537                                                 ax25_send_control(ax25, REJ, pf, C_RESPONSE);
 538                                         ax25->condition &= ~ACK_PENDING_CONDITION;
 539                                 }
 540                         }
 541                         break;
 542 
 543                 case FRMR:
 544                 case ILLEGAL:
 545                         ax25_establish_data_link(ax25);
 546                         ax25->state = AX25_STATE_1;
 547                         break;
 548 
 549                 default:
 550                         break;
 551         }
 552 
 553         return queued;
 554 }
 555 
 556 /*
 557  *      State machine for state 4, Timer Recovery State.
 558  *      The handling of the timer(s) is in file ax25_timer.c
 559  *      Handling of state 0 and connection release is in ax25.c.
 560  */
 561 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] */
 562 {
 563         int queued = 0;
 564 
 565         switch (frametype) {
 566                 case SABM:
 567                         if (dama) ax25_dama_on(ax25);
 568                                 
 569                         ax25->dama_slave = dama;
 570                         ax25->modulus   = MODULUS;
 571                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 572                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 573                         ax25->condition = 0x00;
 574                         ax25->t1timer   = 0;
 575                         ax25->t3timer   = ax25->t3;
 576                         ax25->idletimer = ax25->idle;
 577                         ax25->vs        = 0;
 578                         ax25->va        = 0;
 579                         ax25->vr        = 0;
 580                         ax25->state     = AX25_STATE_3;
 581                         ax25->n2count   = 0;
 582                         break;
 583 
 584                 case SABME:
 585                         if (dama) ax25_dama_on(ax25);
 586                                 
 587                         ax25->dama_slave = dama;
 588                         ax25->modulus   = EMODULUS;
 589                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 590                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 591                         ax25->condition = 0x00;
 592                         ax25->t1timer   = 0;
 593                         ax25->t3timer   = ax25->t3;
 594                         ax25->idletimer = ax25->idle;
 595                         ax25->vs        = 0;
 596                         ax25->va        = 0;
 597                         ax25->vr        = 0;
 598                         ax25->state     = AX25_STATE_3;
 599                         ax25->n2count   = 0;
 600                         break;
 601 
 602                 case DISC:
 603                         ax25_clear_queues(ax25);
 604                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 605                         ax25->t3timer = 0;
 606                         ax25->state   = AX25_STATE_0;
 607                         ax25_dama_off(ax25);
 608                         
 609                         if (ax25->sk != NULL) {
 610                                 ax25->sk->state = TCP_CLOSE;
 611                                 ax25->sk->err   = 0;
 612                                 if (!ax25->sk->dead)
 613                                         ax25->sk->state_change(ax25->sk);
 614                                 ax25->sk->dead  = 1;
 615                         }
 616                         break;
 617 
 618                 case DM:
 619                         ax25_clear_queues(ax25);
 620                         ax25->t3timer = 0;
 621                         ax25->state   = AX25_STATE_0;
 622                         ax25_dama_off(ax25);
 623                         
 624                         if (ax25->sk != NULL) {
 625                                 ax25->sk->state = TCP_CLOSE;
 626                                 ax25->sk->err   = ECONNRESET;
 627                                 if (!ax25->sk->dead)
 628                                         ax25->sk->state_change(ax25->sk);
 629                                 ax25->sk->dead  = 1;
 630                         }
 631                         break;
 632 
 633                 case RNR:
 634                         ax25->condition |= PEER_RX_BUSY_CONDITION;
 635                         if (type == C_RESPONSE && pf) {
 636                                 ax25->t1timer = 0;
 637                                 if (ax25_validate_nr(ax25, nr)) {
 638                                         ax25_frames_acked(ax25, nr);
 639                                         if (ax25->vs == ax25->va) {
 640                                                 ax25->t3timer = ax25->t3;
 641                                                 ax25->n2count = 0;
 642                                                 ax25->state   = AX25_STATE_3;
 643                                         }
 644                                 } else {
 645                                         ax25_nr_error_recovery(ax25);
 646                                         ax25->state = AX25_STATE_1;
 647                                 }
 648                                 break;
 649                         }
 650                          
 651                         ax25_check_need_response(ax25, type, pf);
 652                         if (ax25_validate_nr(ax25, nr)) {
 653                                 ax25_frames_acked(ax25, nr);
 654                                 dama_check_need_response(ax25, type, pf);
 655                         } else {
 656                                 ax25_nr_error_recovery(ax25);
 657                                 ax25->state = AX25_STATE_1;
 658                         }
 659                         break;
 660                         
 661                 case RR:
 662                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 663                         if ( pf && (type == C_RESPONSE || (ax25->dama_slave && type == C_COMMAND)) ) {
 664                                 ax25->t1timer = 0;
 665                                 if (ax25_validate_nr(ax25, nr)) {
 666                                         ax25_frames_acked(ax25, nr);
 667                                         if (ax25->vs == ax25->va) {
 668                                                 ax25->t3timer = ax25->t3;
 669                                                 ax25->n2count = 0;
 670                                                 ax25->state   = AX25_STATE_3;
 671                                         } else {
 672                                                 ax25_requeue_frames(ax25);
 673                                         }
 674                                         dama_check_need_response(ax25, type, pf);
 675                                 } else {
 676                                         ax25_nr_error_recovery(ax25);
 677                                         ax25->state = AX25_STATE_1;
 678                                 }
 679                                 break;
 680                         }
 681 
 682                         ax25_check_need_response(ax25, type, pf);
 683                         if (ax25_validate_nr(ax25, nr)) {
 684                                 ax25_frames_acked(ax25, nr);
 685                                 dama_check_need_response(ax25, type, pf);
 686                         } else {
 687                                 ax25_nr_error_recovery(ax25);
 688                                 ax25->state = AX25_STATE_1;
 689                         }
 690                         break;
 691 
 692                 case REJ:
 693                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 694                         if ( pf && (type == C_RESPONSE || (ax25->dama_slave && type == C_COMMAND)) ) {
 695                                 ax25->t1timer = 0;
 696                                 if (ax25_validate_nr(ax25, nr)) {
 697                                         ax25_frames_acked(ax25, nr);
 698                                         if (ax25->vs == ax25->va) {
 699                                                 ax25->t3timer = ax25->t3;
 700                                                 ax25->n2count = 0;
 701                                                 ax25->state   = AX25_STATE_3;
 702                                         } else {
 703                                                 ax25_requeue_frames(ax25);
 704                                         }
 705                                         dama_check_need_response(ax25, type, pf);
 706                                 } else {
 707                                         ax25_nr_error_recovery(ax25);
 708                                         ax25->state = AX25_STATE_1;
 709                                 }
 710                                 break;
 711                         }
 712                         
 713                         ax25_check_need_response(ax25, type, pf);       
 714                         if (ax25_validate_nr(ax25, nr)) {
 715                                 ax25_frames_acked(ax25, nr);
 716                                 if(ax25->vs != ax25->va) {
 717                                         ax25_requeue_frames(ax25);
 718                                 }
 719                                 dama_check_need_response(ax25, type, pf);
 720                         } else {
 721                                 ax25_nr_error_recovery(ax25);
 722                                 ax25->state = AX25_STATE_1;
 723                         }
 724                         break;
 725 
 726                 case I:
 727 #ifndef AX25_BROKEN_NETMAC
 728                         if (type != C_COMMAND)
 729                                 break;
 730 #endif
 731                         if (!ax25_validate_nr(ax25, nr)) {
 732                                 ax25_nr_error_recovery(ax25);
 733                                 ax25->state = AX25_STATE_1;
 734                                 break;
 735                         }
 736                         ax25_frames_acked(ax25, nr);
 737                         if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 738                                 if (pf) {       /* dl1bke 960114 */
 739                                         if (ax25->dama_slave)
 740                                                 ax25_enquiry_response(ax25);
 741                                         else
 742                                                 dama_enquiry_response(ax25);
 743                                 }
 744                                 break;
 745                         }
 746                         if (ns == ax25->vr) {
 747                                 queued = ax25_rx_iframe(ax25, skb);
 748                                 if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 749                                         if (pf) {       /* dl1bke 960114 */
 750                                                 if (ax25->dama_slave)
 751                                                         dama_enquiry_response(ax25);
 752                                                 else
 753                                                         ax25_enquiry_response(ax25);
 754                                         }
 755                                         break;
 756                                 }
 757                                 ax25->vr = (ax25->vr + 1) % ax25->modulus;
 758                                 ax25->condition &= ~REJECT_CONDITION;
 759                                 if (pf) {
 760                                         if (ax25->dama_slave)   /* dl1bke 960114 */
 761                                                 dama_enquiry_response(ax25);
 762                                         else
 763                                                 ax25_enquiry_response(ax25);
 764                                 } else {
 765                                         if (!(ax25->condition & ACK_PENDING_CONDITION)) {
 766                                                 ax25->t2timer = ax25->t2;
 767                                                 ax25->condition |= ACK_PENDING_CONDITION;
 768                                         }
 769                                 }
 770                         } else {
 771                                 if (ax25->condition & REJECT_CONDITION) {
 772                                         if (pf) {       /* dl1bke 960114 */
 773                                                 if (ax25->dama_slave)
 774                                                         dama_enquiry_response(ax25);
 775                                                 else
 776                                                         ax25_enquiry_response(ax25);
 777                                         }
 778                                 } else {
 779                                         ax25->condition |= REJECT_CONDITION;
 780                                         if (ax25->dama_slave)           /* dl1bke 960114 */
 781                                                 dama_enquiry_response(ax25);
 782                                         else
 783                                                 ax25_send_control(ax25, REJ, pf, C_RESPONSE);
 784                                         ax25->condition &= ~ACK_PENDING_CONDITION;
 785                                 }
 786                         }
 787                         break;
 788                 
 789                 case FRMR:
 790                 case ILLEGAL:
 791                         ax25_establish_data_link(ax25);
 792                         ax25->state = AX25_STATE_1;
 793                         break;
 794 
 795                 default:
 796                         break;
 797         }
 798 
 799         return queued;
 800 }
 801 
 802 /*
 803  *      Higher level upcall for a LAPB frame
 804  */
 805 int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, int dama)
     /* [previous][next][first][last][top][bottom][index][help] */
 806 {
 807         int queued = 0, frametype, ns, nr, pf;
 808         
 809         if (ax25->sk != NULL && ax25->state == AX25_STATE_0 && ax25->sk->dead)
 810                 return queued;
 811 
 812         if (ax25->state != AX25_STATE_1 && ax25->state != AX25_STATE_2 &&
 813             ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4) {
 814                 printk("ax25_process_rx_frame: frame received - state = %d\n", ax25->state);
 815                 return queued;
 816         }
 817 
 818         del_timer(&ax25->timer);
 819 
 820         frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
 821 
 822         switch (ax25->state) {
 823                 case AX25_STATE_1:
 824                         queued = ax25_state1_machine(ax25, skb, frametype, pf, type, dama);
 825                         break;
 826                 case AX25_STATE_2:
 827                         queued = ax25_state2_machine(ax25, skb, frametype, pf, type);
 828                         break;
 829                 case AX25_STATE_3:
 830                         queued = ax25_state3_machine(ax25, skb, frametype, ns, nr, pf, type, dama);
 831                         break;
 832                 case AX25_STATE_4:
 833                         queued = ax25_state4_machine(ax25, skb, frametype, ns, nr, pf, type, dama);
 834                         break;
 835         }
 836 
 837         ax25_set_timer(ax25);
 838 
 839         return queued;
 840 }
 841 
 842 #endif

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