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

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