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

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