home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / AX25HDR.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  3KB  |  112 lines

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