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

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