root/net/ax25/ax25_in.c

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

DEFINITIONS

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

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

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