home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / s920603.zip / AX25HDR.C < prev    next >
C/C++ Source or Header  |  1992-04-08  |  3KB  |  108 lines

  1. /* AX25 header conversion routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "ax25.h"
  7.  
  8. /* Convert a host-format AX.25 header into a mbuf ready for transmission */
  9. struct mbuf *
  10. htonax25(hdr,bp)
  11. register struct ax25 *hdr;
  12. struct mbuf *bp;
  13. {
  14.     register char *cp;
  15.     register int16 i;
  16.  
  17.     if(hdr == (struct ax25 *)NULL || hdr->ndigis > MAXDIGIS)
  18.         return NULLBUF;
  19.  
  20.     /* Allocate space for return buffer */
  21.     i = AXALEN * (2 + hdr->ndigis);
  22.     bp = pushdown(bp,i);
  23.  
  24.     /* Now convert */
  25.     cp = bp->data;        /* cp -> dest field */
  26.  
  27.     /* Generate destination field */
  28.     memcpy(cp,hdr->dest,AXALEN);
  29.     if(hdr->cmdrsp == LAPB_COMMAND)
  30.         cp[ALEN] |= C;    /* Command frame sets C bit in dest */
  31.     else
  32.         cp[ALEN] &= ~C;
  33.     cp[ALEN] &= ~E;    /* Dest E-bit is always off */
  34.  
  35.     cp += AXALEN;        /* cp -> source field */
  36.  
  37.     /* Generate source field */
  38.     memcpy(cp,hdr->source,AXALEN);
  39.     if(hdr->cmdrsp == LAPB_RESPONSE)
  40.         cp[ALEN] |= C;
  41.     else
  42.         cp[ALEN] &= ~C;
  43.     /* Set E bit on source address if no digis */
  44.     if(hdr->ndigis == 0){
  45.         cp[ALEN] |= E;
  46.         return bp;
  47.     }
  48.  
  49.     cp += AXALEN;        /* cp -> first digi field */
  50.  
  51.     /* All but last digi get copied with E bit off */
  52.     for(i=0; i < hdr->ndigis; i++){
  53.         memcpy(cp,hdr->digis[i],AXALEN);
  54.         if(i < hdr->ndigis - 1)
  55.             cp[ALEN] &= ~E;
  56.         else
  57.             cp[ALEN] |= E;    /* Last digipeater has E bit set */
  58.         if(i < hdr->nextdigi)
  59.             cp[ALEN] |= REPEATED;
  60.         else
  61.             cp[ALEN] &= ~REPEATED;
  62.         cp += AXALEN;        /* cp -> next digi field */
  63.     }
  64.     return bp;
  65. }
  66. /* Convert a network-format AX.25 header into a host format structure
  67.  * Return -1 if error, number of addresses if OK
  68.  */
  69. int
  70. ntohax25(hdr,bpp)
  71. register struct ax25 *hdr;    /* Output structure */
  72. struct mbuf **bpp;
  73. {
  74.     register char *axp;
  75.  
  76.     if(pullup(bpp,hdr->dest,AXALEN) < AXALEN)
  77.         return -1;
  78.  
  79.     if(pullup(bpp,hdr->source,AXALEN) < AXALEN)
  80.         return -1;
  81.  
  82.     /* Process C bits to get command/response indication */
  83.     if((hdr->source[ALEN] & C) == (hdr->dest[ALEN] & C))
  84.         hdr->cmdrsp = LAPB_UNKNOWN;
  85.     else if(hdr->source[ALEN] & C)
  86.         hdr->cmdrsp = LAPB_RESPONSE;
  87.     else
  88.         hdr->cmdrsp = LAPB_COMMAND;
  89.  
  90.     hdr->ndigis = 0;
  91.     hdr->nextdigi = 0;
  92.     if(hdr->source[ALEN] & E)
  93.         return 2;    /* No digis */
  94.  
  95.     /* Count and process the digipeaters */
  96.     axp = hdr->digis[0];
  97.     while(hdr->ndigis < MAXDIGIS && pullup(bpp,axp,AXALEN) == AXALEN){
  98.         hdr->ndigis++;
  99.         if(axp[ALEN] & REPEATED)
  100.             hdr->nextdigi++;
  101.         if(axp[ALEN] & E)    /* Last one */
  102.             return hdr->ndigis + 2;            
  103.         axp += AXALEN;
  104.     }
  105.     return -1;    /* Too many digis */
  106. }
  107.  
  108.