home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / network / src_1218.zip / LAPB.C < prev    next >
C/C++ Source or Header  |  1991-01-27  |  17KB  |  676 lines

  1. /* Link Access Procedures Balanced (LAPB), the upper sublayer of
  2.  * AX.25 Level 2.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "timer.h"
  9. #include "ax25.h"
  10. #include "lapb.h"
  11. #include "ip.h"
  12. #include "netrom.h"
  13.  
  14. static void handleit __ARGS((struct ax25_cb *axp,int pid,struct mbuf *bp));
  15. static void procdata __ARGS((struct ax25_cb *axp,struct mbuf *bp));
  16. static int ackours __ARGS((struct ax25_cb *axp,int16 n));
  17. static void clr_ex __ARGS((struct ax25_cb *axp));
  18. static void enq_resp __ARGS((struct ax25_cb *axp));
  19. static void inv_rex __ARGS((struct ax25_cb *axp));
  20.  
  21. /* Process incoming frames */
  22. int
  23. lapb_input(axp,cmdrsp,bp)
  24. struct ax25_cb *axp;        /* Link control structure */
  25. int cmdrsp;            /* Command/response flag */
  26. struct mbuf *bp;        /* Rest of frame, starting with ctl */
  27. {
  28.     int control;
  29.     int class;        /* General class (I/S/U) of frame */
  30.     int16 type;        /* Specific type (I/RR/RNR/etc) of frame */
  31.     char pf;        /* extracted poll/final bit */
  32.     char poll = 0;
  33.     char final = 0;
  34.     int16 nr;        /* ACK number of incoming frame */
  35.     int16 ns;        /* Seq number of incoming frame */
  36.     int16 tmp;
  37.  
  38.     if(bp == NULLBUF || axp == NULLAX25){
  39.         free_p(bp);
  40.         return -1;
  41.     }
  42.  
  43.     /* Extract the various parts of the control field for easy use */
  44.     if((control = PULLCHAR(&bp)) == -1){
  45.         free_p(bp);    /* Probably not necessary */
  46.         return -1;
  47.     }
  48.     type = ftype(control);
  49.     class = type & 0x3;
  50.     pf = control & PF;
  51.     /* Check for polls and finals */
  52.     if(pf){
  53.         switch(cmdrsp){
  54.         case LAPB_COMMAND:
  55.             poll = YES;
  56.             break;
  57.         case LAPB_RESPONSE:
  58.             final = YES;
  59.             break;
  60.         }
  61.     }
  62.     /* Extract sequence numbers, if present */
  63.     switch(class){
  64.     case I:
  65.     case I+2:
  66.         ns = (control >> 1) & MMASK;
  67.     case S:    /* Note fall-thru */
  68.         nr = (control >> 5) & MMASK;
  69.         break;
  70.     }
  71.     /* This section follows the SDL diagrams by K3NA fairly closely */
  72.     switch(axp->state){
  73.     case LAPB_DISCONNECTED:
  74.         switch(type){
  75.         case SABM:    /* Initialize or reset link */
  76.             sendctl(axp,LAPB_RESPONSE,UA|pf);    /* Always accept */
  77.             clr_ex(axp);
  78.             axp->unack = axp->vr = axp->vs = 0;
  79.             lapbstate(axp,LAPB_CONNECTED);/* Resets state counters */
  80.             axp->srt = Axirtt;
  81.             axp->mdev = 0;
  82.             set_timer(&axp->t1,2*axp->srt);
  83.             start_timer(&axp->t3);
  84.             break;
  85.         case DM:    /* Ignore to avoid infinite loops */
  86.             break;
  87.         default:    /* All others get DM */
  88.             if(poll)
  89.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  90.             break;
  91.         }
  92.         break;
  93.     case LAPB_SETUP:
  94.         switch(type){
  95.         case SABM:    /* Simultaneous open */
  96.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  97.             break;
  98.         case DISC:
  99.             sendctl(axp,LAPB_RESPONSE,DM|pf);
  100.             break;
  101.         case UA:    /* Connection accepted */
  102.             /* Note: xmit queue not cleared */
  103.             stop_timer(&axp->t1);
  104.             start_timer(&axp->t3);
  105.             axp->unack = axp->vr = axp->vs = 0;
  106.             lapbstate(axp,LAPB_CONNECTED);
  107.             break;            
  108.         case DM:    /* Connection refused */
  109.             free_q(&axp->txq);
  110.             stop_timer(&axp->t1);
  111.             axp->reason = LB_DM;
  112.             lapbstate(axp,LAPB_DISCONNECTED);
  113.             break;
  114.         default:    /* All other frames ignored */
  115.             break;
  116.         }
  117.         break;
  118.     case LAPB_DISCPENDING:
  119.         switch(type){
  120.         case SABM:
  121.             sendctl(axp,LAPB_RESPONSE,DM|pf);
  122.             break;
  123.         case DISC:
  124.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  125.             break;
  126.         case UA:
  127.         case DM:
  128.             stop_timer(&axp->t1);
  129.             lapbstate(axp,LAPB_DISCONNECTED);
  130.             break;
  131.         default:    /* Respond with DM only to command polls */
  132.             if(poll)
  133.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  134.             break;
  135.         }
  136.         break;
  137.     case LAPB_CONNECTED:
  138.         switch(type){
  139.         case SABM:
  140.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  141.             clr_ex(axp);
  142.             free_q(&axp->txq);
  143.             stop_timer(&axp->t1);
  144.             start_timer(&axp->t3);
  145.             axp->unack = axp->vr = axp->vs = 0;
  146.             lapbstate(axp,LAPB_CONNECTED); /* Purge queues */
  147.             break;
  148.         case DISC:
  149.             free_q(&axp->txq);
  150.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  151.             stop_timer(&axp->t1);
  152.             stop_timer(&axp->t3);
  153.             axp->reason = LB_NORMAL;
  154.             lapbstate(axp,LAPB_DISCONNECTED);
  155.             break;
  156.         case DM:
  157.             axp->reason = LB_DM;
  158.             lapbstate(axp,LAPB_DISCONNECTED);
  159.             break;
  160.         case UA:
  161.             est_link(axp);
  162.             lapbstate(axp,LAPB_SETUP);    /* Re-establish */    
  163.             break;            
  164.         case FRMR:
  165.             est_link(axp);
  166.             lapbstate(axp,LAPB_SETUP);    /* Re-establish link */
  167.             break;
  168.         case RR:
  169.         case RNR:
  170.             axp->flags.remotebusy = (control == RNR) ? YES : NO;
  171.             if(poll)
  172.                 enq_resp(axp);
  173.             ackours(axp,nr);
  174.             break;
  175.         case REJ:
  176.             axp->flags.remotebusy = NO;
  177.             if(poll)
  178.                 enq_resp(axp);
  179.             ackours(axp,nr);
  180.             stop_timer(&axp->t1);
  181.             start_timer(&axp->t3);
  182.             /* This may or may not actually invoke transmission,
  183.              * depending on whether this REJ was caused by
  184.              * our losing his prior ACK.
  185.              */
  186.             inv_rex(axp);
  187.             break;    
  188.         case I:
  189.             ackours(axp,nr); /** == -1) */
  190.             if(len_p(axp->rxq) >= axp->window){
  191.                 /* Too bad he didn't listen to us; he'll
  192.                  * have to resend the frame later. This
  193.                  * drastic action is necessary to avoid
  194.                  * deadlock.
  195.                  */
  196.                 if(poll)
  197.                     sendctl(axp,LAPB_RESPONSE,RNR|pf);
  198.                 free_p(bp);
  199.                 bp = NULLBUF;
  200.                 break;
  201.             }
  202.             /* Reject or ignore I-frames with receive sequence number errors */
  203.             if(ns != axp->vr){
  204.                 if(axp->proto == V1 || !axp->flags.rejsent){
  205.                     axp->flags.rejsent = YES;
  206.                     sendctl(axp,LAPB_RESPONSE,REJ | pf);
  207.                 } else if(poll)
  208.                     enq_resp(axp);
  209.                 axp->response = 0;
  210.                 break;
  211.             }
  212.             axp->flags.rejsent = NO;
  213.             axp->vr = (axp->vr+1) & MMASK;
  214.             tmp = len_p(axp->rxq) >= axp->window ? RNR : RR;
  215.             if(poll){
  216.                 sendctl(axp,LAPB_RESPONSE,tmp|PF);
  217.             } else {
  218.                 axp->response = tmp;
  219.             }
  220.             procdata(axp,bp);
  221.             bp = NULLBUF;
  222.             break;
  223.         default:    /* All others ignored */
  224.             break;
  225.         }
  226.         break;
  227.     case LAPB_RECOVERY:
  228.         switch(type){
  229.         case SABM:
  230.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  231.             clr_ex(axp);
  232.             stop_timer(&axp->t1);
  233.             start_timer(&axp->t3);
  234.             axp->unack = axp->vr = axp->vs = 0;
  235.             lapbstate(axp,LAPB_CONNECTED); /* Purge queues */
  236.             break;
  237.         case DISC:
  238.             free_q(&axp->txq);
  239.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  240.             stop_timer(&axp->t1);
  241.             stop_timer(&axp->t3);
  242.             axp->response = UA;
  243.             axp->reason = LB_NORMAL;
  244.             lapbstate(axp,LAPB_DISCONNECTED);
  245.             break;
  246.         case DM:
  247.             axp->reason = LB_DM;
  248.             lapbstate(axp,LAPB_DISCONNECTED);
  249.             break;
  250.         case UA:
  251.             est_link(axp);
  252.             lapbstate(axp,LAPB_SETUP);    /* Re-establish */    
  253.             break;
  254.         case FRMR:
  255.             est_link(axp);
  256.             lapbstate(axp,LAPB_SETUP);    /* Re-establish link */
  257.             break;
  258.         case RR:
  259.         case RNR:
  260.             axp->flags.remotebusy = (control == RNR) ? YES : NO;
  261.             if(axp->proto == V1 || final){
  262.                 stop_timer(&axp->t1);
  263.                 ackours(axp,nr);
  264.                 if(axp->unack != 0){
  265.                     inv_rex(axp);
  266.                 } else {
  267.                     start_timer(&axp->t3);
  268.                     lapbstate(axp,LAPB_CONNECTED);
  269.                 }
  270.             } else {
  271.                 if(poll)
  272.                     enq_resp(axp);
  273.                 ackours(axp,nr);
  274.                 /* Keep timer running even if all frames
  275.                  * were acked, since we must see a Final
  276.                  */
  277.                 if(!run_timer(&axp->t1))
  278.                     start_timer(&axp->t1);
  279.             }
  280.             break;
  281.         case REJ:
  282.             axp->flags.remotebusy = NO;
  283.             /* Don't insist on a Final response from the old proto */
  284.             if(axp->proto == V1 || final){
  285.                 stop_timer(&axp->t1);
  286.                 ackours(axp,nr);
  287.                 if(axp->unack != 0){
  288.                     inv_rex(axp);
  289.                 } else {
  290.                     start_timer(&axp->t3);
  291.                     lapbstate(axp,LAPB_CONNECTED);
  292.                 }
  293.             } else {
  294.                 if(poll)
  295.                     enq_resp(axp);
  296.                 ackours(axp,nr);
  297.                 if(axp->unack != 0){
  298.                     /* This is certain to trigger output */
  299.                     inv_rex(axp);
  300.                 }
  301.                 /* A REJ that acks everything but doesn't
  302.                  * have the F bit set can cause a deadlock.
  303.                  * So make sure the timer is running.
  304.                  */
  305.                 if(!run_timer(&axp->t1))
  306.                     start_timer(&axp->t1);
  307.             }
  308.             break;
  309.         case I:
  310.             ackours(axp,nr); /** == -1) */
  311.             /* Make sure timer is running, since an I frame
  312.              * cannot satisfy a poll
  313.              */
  314.             if(!run_timer(&axp->t1))
  315.                 start_timer(&axp->t1);
  316.             if(len_p(axp->rxq) >= axp->window){
  317.                 /* Too bad he didn't listen to us; he'll
  318.                  * have to resend the frame later. This
  319.                  * drastic action is necessary to avoid
  320.                  * memory deadlock.
  321.                  */
  322.                 sendctl(axp,LAPB_RESPONSE,RNR | pf);
  323.                 free_p(bp);
  324.                 bp = NULLBUF;
  325.                 break;
  326.             }
  327.             /* Reject or ignore I-frames with receive sequence number errors */
  328.             if(ns != axp->vr){
  329.                 if(axp->proto == V1 || !axp->flags.rejsent){
  330.                     axp->flags.rejsent = YES;
  331.                     sendctl(axp,LAPB_RESPONSE,REJ | pf);
  332.                 } else if(poll)
  333.                     enq_resp(axp);
  334.  
  335.                 axp->response = 0;
  336.                 break;
  337.             }
  338.             axp->flags.rejsent = NO;
  339.             axp->vr = (axp->vr+1) & MMASK;
  340.             tmp = len_p(axp->rxq) >= axp->window ? RNR : RR;
  341.             if(poll){
  342.                 sendctl(axp,LAPB_RESPONSE,tmp|PF);
  343.             } else {
  344.                 axp->response = tmp;
  345.             }
  346.             procdata(axp,bp);
  347.             bp = NULLBUF;
  348.             break;
  349.         default:
  350.             break;        /* Ignored */
  351.         }
  352.         break;
  353.     }
  354.     free_p(bp);    /* In case anything's left */
  355.  
  356.     /* See if we can send some data, perhaps piggybacking an ack.
  357.      * If successful, lapb_output will clear axp->response.
  358.      */
  359.     lapb_output(axp);
  360.     if(axp->response != 0){
  361.         sendctl(axp,LAPB_RESPONSE,axp->response);
  362.         axp->response = 0;
  363.     }
  364.     return 0;
  365. }
  366. /* Handle incoming acknowledgements for frames we've sent.
  367.  * Free frames being acknowledged.
  368.  * Return -1 to cause a frame reject if number is bad, 0 otherwise
  369.  */
  370. static int
  371. ackours(axp,n)
  372. struct ax25_cb *axp;
  373. int16 n;
  374. {    
  375.     struct mbuf *bp;
  376.     int acked = 0;    /* Count of frames acked by this ACK */
  377.     int16 oldest;    /* Seq number of oldest unacked I-frame */
  378.     int32 rtt,abserr;
  379.  
  380.     /* Free up acknowledged frames by purging frames from the I-frame
  381.      * transmit queue. Start at the remote end's last reported V(r)
  382.      * and keep going until we reach the new sequence number.
  383.      * If we try to free a null pointer,
  384.      * then we have a frame reject condition.
  385.      */
  386.     oldest = (axp->vs - axp->unack) & MMASK;
  387.     while(axp->unack != 0 && oldest != n){
  388.         if((bp = dequeue(&axp->txq)) == NULLBUF){
  389.             /* Acking unsent frame */
  390.             return -1;
  391.         }
  392.         free_p(bp);
  393.         axp->unack--;
  394.         acked++;
  395.         if(axp->flags.rtt_run && axp->rtt_seq == oldest){
  396.             /* A frame being timed has been acked */
  397.             axp->flags.rtt_run = 0;
  398.             /* Update only if frame wasn't retransmitted */
  399.             if(!axp->flags.retrans){
  400.                 rtt = msclock() - axp->rtt_time;
  401.                 abserr = (rtt > axp->srt) ? rtt - axp->srt :
  402.                  axp->srt - rtt;
  403.  
  404.                 /* Run SRT and mdev integrators */
  405.                 axp->srt = ((axp->srt * 7) + rtt + 4) >> 3;
  406.                 axp->mdev = ((axp->mdev*3) + abserr + 2) >> 2;
  407.                 /* Update timeout */
  408.                 set_timer(&axp->t1,4*axp->mdev+axp->srt);
  409.             }
  410.         }
  411.         axp->flags.retrans = 0;
  412.         axp->retries = 0;
  413.         oldest = (oldest + 1) & MMASK;
  414.     }
  415.     if(axp->unack == 0){
  416.         /* All frames acked, stop timeout */
  417.         stop_timer(&axp->t1);
  418.         start_timer(&axp->t3);
  419.     } else if(acked != 0) { 
  420.         /* Partial ACK; restart timer */
  421.         start_timer(&axp->t1);
  422.     }
  423.     if(acked != 0){
  424.         /* If user has set a transmit upcall, indicate how many frames
  425.          * may be queued
  426.          */
  427.         if(axp->t_upcall != NULLVFP)
  428.             (*axp->t_upcall)(axp,axp->paclen * (axp->maxframe - axp->unack));
  429.     }
  430.     return 0;
  431. }
  432.  
  433. /* Establish data link */
  434. void
  435. est_link(axp)
  436. struct ax25_cb *axp;
  437. {
  438.     clr_ex(axp);
  439.     axp->retries = 0;
  440.     sendctl(axp,LAPB_COMMAND,SABM|PF);
  441.     stop_timer(&axp->t3);
  442.     start_timer(&axp->t1);
  443. }
  444. /* Clear exception conditions */
  445. static void
  446. clr_ex(axp)
  447. struct ax25_cb *axp;
  448. {
  449.     axp->flags.remotebusy = NO;
  450.     axp->flags.rejsent = NO;
  451.     axp->response = 0;
  452.     stop_timer(&axp->t3);
  453. }
  454. /* Enquiry response */
  455. static void
  456. enq_resp(axp)
  457. struct ax25_cb *axp;
  458. {
  459.     char ctl;
  460.  
  461.     ctl = len_p(axp->rxq) >= axp->window ? RNR|PF : RR|PF;    
  462.     sendctl(axp,LAPB_RESPONSE,ctl);
  463.     axp->response = 0;
  464.     stop_timer(&axp->t3);
  465. }
  466. /* Invoke retransmission */
  467. static void
  468. inv_rex(axp)
  469. struct ax25_cb *axp;
  470. {
  471.     axp->vs -= axp->unack;
  472.     axp->vs &= MMASK;
  473.     axp->unack = 0;
  474. }
  475. /* Send S or U frame to currently connected station */
  476. int
  477. sendctl(axp,cmdrsp,cmd)
  478. struct ax25_cb *axp;
  479. int cmdrsp;
  480. int cmd;
  481. {
  482.     if((ftype((char)cmd) & 0x3) == S)    /* Insert V(R) if S frame */
  483.         cmd |= (axp->vr << 5);
  484.     return sendframe(axp,cmdrsp,cmd,NULLBUF);
  485. }
  486. /* Start data transmission on link, if possible
  487.  * Return number of frames sent
  488.  */
  489. int
  490. lapb_output(axp)
  491. register struct ax25_cb *axp;
  492. {
  493.     register struct mbuf *bp;
  494.     struct mbuf *tbp;
  495.     char control;
  496.     int sent = 0;
  497.     int i;
  498.  
  499.     if(axp == NULLAX25
  500.      || (axp->state != LAPB_RECOVERY && axp->state != LAPB_CONNECTED)
  501.      || axp->flags.remotebusy)
  502.         return 0;
  503.  
  504.     /* Dig into the send queue for the first unsent frame */
  505.     bp = axp->txq;
  506.     for(i = 0; i < axp->unack; i++){
  507.         if(bp == NULLBUF)
  508.             break;    /* Nothing to do */
  509.         bp = bp->anext;
  510.     }
  511.     /* Start at first unsent I-frame, stop when either the
  512.      * number of unacknowledged frames reaches the maxframe limit,
  513.      * or when there are no more frames to send
  514.      */
  515.     while(bp != NULLBUF && axp->unack < axp->maxframe){
  516.         control = I | (axp->vs++ << 1) | (axp->vr << 5);
  517.         axp->vs &= MMASK;
  518.         dup_p(&tbp,bp,0,len_p(bp));
  519.         if(tbp == NULLBUF)
  520.             return sent;    /* Probably out of memory */
  521.         sendframe(axp,LAPB_COMMAND,control,tbp);
  522.         axp->unack++;
  523.         /* We're implicitly acking any data he's sent, so stop any
  524.          * delayed ack
  525.          */
  526.         axp->response = 0;
  527.         if(!run_timer(&axp->t1)){
  528.             stop_timer(&axp->t3);
  529.             start_timer(&axp->t1);
  530.         }
  531.         sent++;
  532.         bp = bp->anext;
  533.         if(!axp->flags.rtt_run){
  534.             /* Start round trip timer */
  535.             axp->rtt_seq = (control >> 1) & MMASK;
  536.             axp->rtt_time = msclock();
  537.             axp->flags.rtt_run = 1;
  538.         }
  539.     }
  540.     return sent;
  541. }
  542. /* Set new link state */
  543. void
  544. lapbstate(axp,s)
  545. struct ax25_cb *axp;
  546. int s;
  547. {
  548.     int oldstate;
  549.  
  550.     oldstate = axp->state;
  551.     axp->state = s;
  552.     if(s == LAPB_DISCONNECTED){
  553.         stop_timer(&axp->t1);
  554.         stop_timer(&axp->t3);
  555.         free_q(&axp->txq);
  556.     }
  557.     /* Don't bother the client unless the state is really changing */
  558.     if(oldstate != s && axp->s_upcall != NULLVFP)
  559.         (*axp->s_upcall)(axp,oldstate,s);
  560. }
  561. /* Process a valid incoming I frame */
  562. static void
  563. procdata(axp,bp)
  564. struct ax25_cb *axp;
  565. struct mbuf *bp;
  566. {
  567.     int pid;
  568.     int seq;
  569.  
  570.     /* Extract level 3 PID */
  571.     if((pid = PULLCHAR(&bp)) == -1)
  572.         return;    /* No PID */
  573.  
  574.     if(axp->segremain != 0){
  575.         /* Reassembly in progress; continue */
  576.         seq = PULLCHAR(&bp);
  577.         if(pid == PID_SEGMENT
  578.          && (seq & SEG_REM) == axp->segremain - 1){
  579.             /* Correct, in-order segment */
  580.             append(&axp->rxasm,bp);
  581.             if((axp->segremain = (seq & SEG_REM)) == 0){
  582.                 /* Done; kick it upstairs */
  583.                 bp = axp->rxasm;
  584.                 axp->rxasm = NULLBUF;
  585.                 pid = PULLCHAR(&bp);
  586.                 handleit(axp,pid,bp);
  587.             }
  588.         } else {
  589.             /* Error! */
  590.             free_p(axp->rxasm);
  591.             axp->rxasm = NULLBUF;
  592.             axp->segremain = 0;
  593.             free_p(bp);
  594.         }
  595.     } else {
  596.         /* No reassembly in progress */
  597.         if(pid == PID_SEGMENT){
  598.             /* Start reassembly */
  599.             seq = PULLCHAR(&bp);
  600.             if(!(seq & SEG_FIRST)){
  601.                 free_p(bp);    /* not first seg - error! */
  602.             } else {
  603.                 /* Put first segment on list */
  604.                 axp->segremain = seq & SEG_REM;
  605.                 axp->rxasm = bp;
  606.             }
  607.         } else {
  608.             /* Normal frame; send upstairs */
  609.             handleit(axp,pid,bp);
  610.         }
  611.     }
  612. }
  613. /* New-style frame segmenter. Returns queue of segmented fragments, or
  614.  * original packet if small enough
  615.  */
  616. struct mbuf *
  617. segmenter(bp,ssize)
  618. struct mbuf *bp;    /* Complete packet */
  619. int16 ssize;        /* Max size of frame segments */
  620. {
  621.     struct mbuf *result = NULLBUF;
  622.     struct mbuf *bptmp,*bp1;
  623.     int16 len,offset;
  624.     int segments;
  625.  
  626.     /* See if packet is too small to segment. Note 1-byte grace factor
  627.      * so the PID will not cause segmentation of a 256-byte IP datagram.
  628.      */
  629.     len = len_p(bp);
  630.     if(len <= ssize+1)
  631.         return bp;    /* Too small to segment */
  632.  
  633.     ssize -= 2;        /* ssize now equal to data portion size */
  634.     segments = 1 + (len - 1) / ssize;    /* # segments  */
  635.     offset = 0;
  636.  
  637.     while(segments != 0){
  638.         offset += dup_p(&bptmp,bp,offset,ssize);
  639.         if(bptmp == NULLBUF){
  640.             free_q(&result);
  641.             break;
  642.         }
  643.         /* Make room for segmentation header */
  644.         if((bp1 = pushdown(bptmp,2)) == NULLBUF){
  645.             free_p(bptmp);
  646.             free_q(&result);
  647.             break;
  648.         }
  649.         bp1->data[0] = PID_SEGMENT;
  650.         bp1->data[1] = --segments;
  651.         if(offset == ssize)
  652.             bp1->data[1] |= SEG_FIRST;
  653.         enqueue(&result,bp1);
  654.     }
  655.     free_p(bp);
  656.     return result;
  657. }
  658.  
  659. static void
  660. handleit(axp,pid,bp)
  661. struct ax25_cb *axp;
  662. int pid;
  663. struct mbuf *bp;
  664. {
  665.     struct axlink *ipp;
  666.  
  667.     for(ipp = Axlink;ipp->funct != NULL;ipp++){
  668.         if(ipp->pid == pid)
  669.             break;
  670.     }
  671.     if(ipp->funct != NULL)
  672.         (*ipp->funct)(axp->iface,axp,NULLCHAR,NULLCHAR,bp,0);
  673.     else
  674.         free_p(bp);
  675. }
  676.