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

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