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 
 134         switch (*skb->data) {
 135 #ifdef CONFIG_NETROM
 136                 case AX25_P_NETROM:
 137                         if (ax25_dev_get_value(ax25->device, AX25_VALUES_NETROM)) {
 138                                 skb_pull(skb, 1);       /* Remove PID */
 139                                 queued = nr_route_frame(skb, ax25);
 140                         }
 141                         break;
 142 #endif
 143 #ifdef CONFIG_INET
 144                 case AX25_P_IP:
 145                         skb_pull(skb, 1);       /* Remove PID */
 146                         skb->h.raw = skb->data;
 147                         ax25_ip_mode_set(&ax25->dest_addr, ax25->device, 'V');
 148                         ip_rcv(skb, skb->dev, NULL);    /* Wrong ptype */
 149                         queued = 1;
 150                         break;
 151 #endif
 152                 case AX25_P_TEXT:
 153                         if (ax25->sk != NULL && ax25_dev_get_value(ax25->device, AX25_VALUES_TEXT)) {
 154                                 if (sock_queue_rcv_skb(ax25->sk, skb) == 0) {
 155                                         queued = 1;
 156                                 } else {
 157                                         ax25->condition |= OWN_RX_BUSY_CONDITION;
 158                                 }
 159                         }
 160                         break;
 161                         
 162                 case AX25_P_SEGMENT:
 163                         skb_pull(skb, 1);       /* Remove PID */
 164                         queued = ax25_rx_fragment(ax25, skb);
 165                         break;
 166 
 167                 default:
 168                         break;
 169         }
 170 
 171         return queued;
 172 }
 173 
 174 /*
 175  *      State machine for state 1, Awaiting Connection State.
 176  *      The handling of the timer(s) is in file ax25_timer.c.
 177  *      Handling of state 0 and connection release is in ax25.c.
 178  */
 179 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] */
 180 {
 181         switch (frametype) {
 182                 case SABM:
 183                         ax25->modulus = MODULUS;
 184                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 185                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 186                         break;
 187 
 188                 case SABME:
 189                         ax25->modulus = EMODULUS;
 190                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 191                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 192                         break;
 193 
 194                 case DISC:
 195                         ax25_send_control(ax25, DM, pf, C_RESPONSE);
 196                         break;
 197 
 198                 case UA:
 199                         if (pf) {
 200                                 ax25_calculate_rtt(ax25);
 201                                 ax25->t1timer = 0;
 202                                 ax25->t3timer = ax25->t3;
 203                                 ax25->vs      = 0;
 204                                 ax25->va      = 0;
 205                                 ax25->vr      = 0;
 206                                 ax25->state   = AX25_STATE_3;
 207                                 ax25->n2count = 0;
 208                                 if (ax25->sk != NULL) {
 209                                         ax25->sk->state = TCP_ESTABLISHED;
 210                                         /* For WAIT_SABM connections we will produce an accept ready socket here */
 211                                         if (!ax25->sk->dead)
 212                                                 ax25->sk->state_change(ax25->sk);
 213                                 }
 214                         }
 215                         break;
 216 
 217                 case DM:
 218                         if (pf) {
 219                                 if (ax25->modulus == MODULUS) {
 220                                         ax25_clear_queues(ax25);
 221                                         ax25->state = AX25_STATE_0;
 222                                         if (ax25->sk != NULL) {
 223                                                 ax25->sk->state = TCP_CLOSE;
 224                                                 ax25->sk->err   = ECONNREFUSED;
 225                                                 if (!ax25->sk->dead)
 226                                                         ax25->sk->state_change(ax25->sk);
 227                                                 ax25->sk->dead  = 1;
 228                                         }
 229                                 } else {
 230                                         ax25->modulus = MODULUS;
 231                                         ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 232                                 }
 233                         }
 234                         break;
 235 
 236                 default:
 237                         break;
 238         }
 239 
 240         return 0;
 241 }
 242 
 243 /*
 244  *      State machine for state 2, Awaiting Release State.
 245  *      The handling of the timer(s) is in file ax25_timer.c
 246  *      Handling of state 0 and connection release is in ax25.c.
 247  */
 248 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] */
 249 {
 250         switch (frametype) {
 251                 case SABM:
 252                 case SABME:
 253                         ax25_send_control(ax25, DM, pf, C_RESPONSE);
 254                         break;
 255 
 256                 case DISC:
 257                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 258                         break;
 259 
 260                 case UA:
 261                         if (pf) {
 262                                 ax25->state = AX25_STATE_0;
 263                                 if (ax25->sk != NULL) {
 264                                         ax25->sk->state = TCP_CLOSE;
 265                                         ax25->sk->err   = 0;
 266                                         if (!ax25->sk->dead)
 267                                                 ax25->sk->state_change(ax25->sk);
 268                                         ax25->sk->dead  = 1;
 269                                 }
 270                         }
 271                         break;
 272 
 273                 case DM:
 274                         if (pf) {
 275                                 ax25->state = AX25_STATE_0;
 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 I:
 287                 case REJ:
 288                 case RNR:
 289                 case RR:
 290                         if (pf)
 291                                 ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
 292                         break;
 293                                 
 294                 default:
 295                         break;
 296         }
 297 
 298         return 0;
 299 }
 300 
 301 /*
 302  *      State machine for state 3, Connected State.
 303  *      The handling of the timer(s) is in file ax25_timer.c
 304  *      Handling of state 0 and connection release is in ax25.c.
 305  */
 306 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] */
 307 {
 308         int queued = 0;
 309 
 310         switch (frametype) {
 311                 case SABM:
 312                         ax25->modulus   = MODULUS;
 313                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 314                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 315                         ax25->condition = 0x00;
 316                         ax25->t1timer   = 0;
 317                         ax25->t3timer   = ax25->t3;
 318                         ax25->vs        = 0;
 319                         ax25->va        = 0;
 320                         ax25->vr        = 0;
 321                         break;
 322 
 323                 case SABME:
 324                         ax25->modulus   = EMODULUS;
 325                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 326                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 327                         ax25->condition = 0x00;
 328                         ax25->t1timer   = 0;
 329                         ax25->t3timer   = ax25->t3;
 330                         ax25->vs        = 0;
 331                         ax25->va        = 0;
 332                         ax25->vr        = 0;
 333                         break;
 334 
 335                 case DISC:
 336                         ax25_clear_queues(ax25);
 337                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 338                         ax25->t3timer = 0;
 339                         ax25->state   = AX25_STATE_0;
 340                         if (ax25->sk != NULL) {
 341                                 ax25->sk->state = TCP_CLOSE;
 342                                 ax25->sk->err   = 0;
 343                                 if (!ax25->sk->dead)
 344                                         ax25->sk->state_change(ax25->sk);
 345                                 ax25->sk->dead  = 1;
 346                         }
 347                         break;
 348 
 349                 case UA:
 350                         ax25_establish_data_link(ax25);
 351                         ax25->state = AX25_STATE_1;
 352                         break;
 353 
 354                 case DM:
 355                         ax25_clear_queues(ax25);
 356                         ax25->t3timer = 0;
 357                         ax25->state   = AX25_STATE_0;
 358                         if (ax25->sk) {
 359                                 ax25->sk->state = TCP_CLOSE;
 360                                 ax25->sk->err   = ECONNRESET;
 361                                 if (!ax25->sk->dead)
 362                                         ax25->sk->state_change(ax25->sk);
 363                                 ax25->sk->dead         = 1;
 364                         }
 365                         break;
 366 
 367                 case RNR:
 368                         ax25->condition |= PEER_RX_BUSY_CONDITION;
 369                         ax25_check_need_response(ax25, type, pf);
 370                         if (ax25_validate_nr(ax25, nr)) {
 371                                 ax25_check_iframes_acked(ax25, nr);
 372                         } else {
 373                                 ax25_nr_error_recovery(ax25);
 374                                 ax25->state = AX25_STATE_1;
 375                         }
 376                         break;
 377                         
 378                 case RR:
 379                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 380                         ax25_check_need_response(ax25, type, pf);
 381                         if (ax25_validate_nr(ax25, nr)) {
 382                                 ax25_check_iframes_acked(ax25, nr);
 383                         } else {
 384                                 ax25_nr_error_recovery(ax25);
 385                                 ax25->state = AX25_STATE_1;
 386                         }
 387                         break;
 388                                 
 389                 case REJ:
 390                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 391                         ax25_check_need_response(ax25, type, pf);
 392                         if (ax25_validate_nr(ax25, nr)) {
 393                                 ax25_frames_acked(ax25, nr);
 394                                 ax25_calculate_rtt(ax25);
 395                                 ax25->t1timer = 0;
 396                                 ax25->t3timer = ax25->t3;
 397                         } else {
 398                                 ax25_nr_error_recovery(ax25);
 399                                 ax25->state = AX25_STATE_1;
 400                         }
 401                         break;
 402                         
 403                 case I:
 404                         if (type != C_COMMAND)
 405                                 break;
 406                         if (!ax25_validate_nr(ax25, nr)) {
 407                                 ax25_nr_error_recovery(ax25);
 408                                 ax25->state = AX25_STATE_1;
 409                                 break;
 410                         }
 411                         if (ax25->condition & PEER_RX_BUSY_CONDITION) {
 412                                 ax25_frames_acked(ax25, nr);
 413                         } else {
 414                                 ax25_check_iframes_acked(ax25, nr);
 415                         }
 416                         if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 417                                 if (pf) ax25_enquiry_response(ax25);
 418                                 break;
 419                         }
 420                         if (ns == ax25->vr) {
 421                                 queued = ax25_rx_iframe(ax25, skb);
 422                                 if (ax25->condition & OWN_RX_BUSY_CONDITION) {
 423                                         if (pf) ax25_enquiry_response(ax25);
 424                                         break;
 425                                 }
 426                                 ax25->vr = (ax25->vr + 1) % ax25->modulus;
 427                                 ax25->condition &= ~REJECT_CONDITION;
 428                                 if (pf) {
 429                                         ax25_enquiry_response(ax25);
 430                                 } else {
 431                                         if (!(ax25->condition & ACK_PENDING_CONDITION)) {
 432                                                 ax25->t2timer = ax25->t2;
 433                                                 ax25->condition |= ACK_PENDING_CONDITION;
 434                                         }
 435                                 }
 436                         } else {
 437                                 if (ax25->condition & REJECT_CONDITION) {
 438                                         if (pf) ax25_enquiry_response(ax25);
 439                                 } else {
 440                                         ax25->condition |= REJECT_CONDITION;
 441                                         ax25_send_control(ax25, REJ, pf, C_RESPONSE);
 442                                         ax25->condition &= ~ACK_PENDING_CONDITION;
 443                                 }
 444                         }
 445                         break;
 446 
 447                 case FRMR:
 448                 case ILLEGAL:
 449                         ax25_establish_data_link(ax25);
 450                         ax25->state = AX25_STATE_1;
 451                         break;
 452 
 453                 default:
 454                         break;
 455         }
 456 
 457         return queued;
 458 }
 459 
 460 /*
 461  *      State machine for state 4, Timer Recovery State.
 462  *      The handling of the timer(s) is in file ax25_timer.c
 463  *      Handling of state 0 and connection release is in ax25.c.
 464  */
 465 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] */
 466 {
 467         int queued = 0;
 468 
 469         switch (frametype) {
 470                 case SABM:
 471                         ax25->modulus   = MODULUS;
 472                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
 473                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 474                         ax25->condition = 0x00;
 475                         ax25->t1timer   = 0;
 476                         ax25->t3timer   = ax25->t3;
 477                         ax25->vs        = 0;
 478                         ax25->va        = 0;
 479                         ax25->vr        = 0;
 480                         ax25->state     = AX25_STATE_3;
 481                         ax25->n2count   = 0;
 482                         break;
 483 
 484                 case SABME:
 485                         ax25->modulus   = EMODULUS;
 486                         ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
 487                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 488                         ax25->condition = 0x00;
 489                         ax25->t1timer   = 0;
 490                         ax25->t3timer   = ax25->t3;
 491                         ax25->vs        = 0;
 492                         ax25->va        = 0;
 493                         ax25->vr        = 0;
 494                         ax25->state     = AX25_STATE_3;
 495                         ax25->n2count   = 0;
 496                         break;
 497 
 498                 case DISC:
 499                         ax25_clear_queues(ax25);
 500                         ax25_send_control(ax25, UA, pf, C_RESPONSE);
 501                         ax25->t3timer = 0;
 502                         ax25->state   = AX25_STATE_0;
 503                         if (ax25->sk != NULL) {
 504                                 ax25->sk->state = TCP_CLOSE;
 505                                 ax25->sk->err   = 0;
 506                                 if (!ax25->sk->dead)
 507                                         ax25->sk->state_change(ax25->sk);
 508                                 ax25->sk->dead  = 1;
 509                         }
 510                         break;
 511 
 512                 case UA:
 513                         ax25_establish_data_link(ax25);
 514                         ax25->state = AX25_STATE_1;
 515                         break;
 516 
 517                 case DM:
 518                         ax25_clear_queues(ax25);
 519                         ax25->t3timer = 0;
 520                         ax25->state   = AX25_STATE_0;
 521                         if (ax25->sk != NULL) {
 522                                 ax25->sk->state = TCP_CLOSE;
 523                                 ax25->sk->err   = ECONNRESET;
 524                                 if (!ax25->sk->dead)
 525                                         ax25->sk->state_change(ax25->sk);
 526                                 ax25->sk->dead  = 1;
 527                         }
 528                         break;
 529 
 530                 case RNR:
 531                         ax25->condition |= PEER_RX_BUSY_CONDITION;
 532                         if (type == C_RESPONSE && pf) {
 533                                 ax25->t1timer = 0;
 534                                 if (ax25_validate_nr(ax25, nr)) {
 535                                         ax25_frames_acked(ax25, nr);
 536                                         if (ax25->vs == ax25->va) {
 537                                                 ax25->t3timer = ax25->t3;
 538                                                 ax25->n2count = 0;
 539                                                 ax25->state   = AX25_STATE_3;
 540                                         }
 541                                 } else {
 542                                         ax25_nr_error_recovery(ax25);
 543                                         ax25->state = AX25_STATE_1;
 544                                 }
 545                                 break;
 546                         }
 547                         if (type == C_COMMAND && pf)
 548                                 ax25_enquiry_response(ax25);
 549                         if (ax25_validate_nr(ax25, nr)) {
 550                                 ax25_frames_acked(ax25, nr);
 551                         } else {
 552                                 ax25_nr_error_recovery(ax25);
 553                                 ax25->state = AX25_STATE_1;
 554                         }
 555                         break;
 556                         
 557                 case RR:
 558                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 559                         if (type == C_RESPONSE && pf) {
 560                                 ax25->t1timer = 0;
 561                                 if (ax25_validate_nr(ax25, nr)) {
 562                                         ax25_frames_acked(ax25, nr);
 563                                         if (ax25->vs == ax25->va) {
 564                                                 ax25->t3timer = ax25->t3;
 565                                                 ax25->n2count = 0;
 566                                                 ax25->state   = AX25_STATE_3;
 567                                         }
 568                                 } else {
 569                                         ax25_nr_error_recovery(ax25);
 570                                         ax25->state = AX25_STATE_1;
 571                                 }
 572                                 break;
 573                         }
 574                         if (type == C_COMMAND && pf)
 575                                 ax25_enquiry_response(ax25);
 576                         if (ax25_validate_nr(ax25, nr)) {
 577                                 ax25_frames_acked(ax25, nr);
 578                         } else {
 579                                 ax25_nr_error_recovery(ax25);
 580                                 ax25->state = AX25_STATE_1;
 581                         }
 582                         break;
 583 
 584                 case REJ:
 585                         ax25->condition &= ~PEER_RX_BUSY_CONDITION;
 586                         if (type == C_RESPONSE && pf) {
 587                                 ax25->t1timer = 0;
 588                                 if (ax25_validate_nr(ax25, nr)) {
 589                                         ax25_frames_acked(ax25, nr);
 590                                         if (ax25->vs == ax25->va) {
 591                                                 ax25->t3timer = ax25->t3;
 592                                                 ax25->n2count = 0;
 593                                                 ax25->state   = AX25_STATE_3;
 594                                         }
 595                                 } else {
 596                                         ax25_nr_error_recovery(ax25);
 597                                         ax25->state = AX25_STATE_1;
 598                                 }
 599                                 break;
 600                         }
 601                         if (type == C_COMMAND && pf)
 602                                 ax25_enquiry_response(ax25);
 603                         if (ax25_validate_nr(ax25, nr)) {
 604                                 ax25_frames_acked(ax25, nr);
 605                         } else {
 606                                 ax25_nr_error_recovery(ax25);
 607                                 ax25->state = AX25_STATE_1;
 608                         }
 609                         break;
 610 
 611                 case I:
 612                         if (type != C_COMMAND)
 613                                 break;
 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->state != AX25_STATE_1 && ax25->state != AX25_STATE_2 &&
 672             ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4) {
 673                 printk("ax25_process_rx_frame: frame received - state = %d\n", ax25->state);
 674                 return queued;
 675         }
 676 
 677         del_timer(&ax25->timer);
 678 
 679         frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
 680 
 681         switch (ax25->state) {
 682                 case AX25_STATE_1:
 683                         queued = ax25_state1_machine(ax25, skb, frametype, pf, type);
 684                         break;
 685                 case AX25_STATE_2:
 686                         queued = ax25_state2_machine(ax25, skb, frametype, pf, type);
 687                         break;
 688                 case AX25_STATE_3:
 689                         queued = ax25_state3_machine(ax25, skb, frametype, ns, nr, pf, type);
 690                         break;
 691                 case AX25_STATE_4:
 692                         queued = ax25_state4_machine(ax25, skb, frametype, ns, nr, pf, type);
 693                         break;
 694         }
 695 
 696         ax25_set_timer(ax25);
 697 
 698         return queued;
 699 }
 700 
 701 #endif

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