root/net/ax25/ax25_in.c

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

DEFINITIONS

This source file includes following definitions.
  1. ax25_rx_fragment
  2. ax25_rx_iframe
  3. ax25_state1_machine
  4. ax25_state2_machine
  5. ax25_state3_machine
  6. ax25_state4_machine
  7. ax25_process_rx_frame

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

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