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

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