ax25hdr.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:2k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

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