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

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Low level AX.25 routines:
  2.  *  callsign conversion
  3.  *  control block management
  4.  *
  5.  * Copyright 1991 Phil Karn, KA9Q
  6.  */
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "mbuf.h"
  10. #include "timer.h"
  11. #include "ax25.h"
  12. #include "lapb.h"
  13. #include <ctype.h>
  14. struct ax25_cb *Ax25_cb;
  15. /* Default AX.25 parameters */
  16. int32 T3init = 0; /* No keep-alive polling */
  17. uint16 Maxframe = 1; /* Stop and wait */
  18. uint16 N2 = 10; /* 10 retries */
  19. uint16 Axwindow = 2048; /* 2K incoming text before RNR'ing */
  20. uint16 Paclen = 256; /* 256-byte I fields */
  21. uint16 Pthresh = 128; /* Send polls for packets larger than this */
  22. int32 Axirtt = 5000; /* Initial round trip estimate, ms */
  23. uint16 Axversion = V1; /* Protocol version */
  24. int32 Blimit = 30; /* Retransmission backoff limit */
  25. /* Look up entry in connection table */
  26. struct ax25_cb *
  27. find_ax25(addr)
  28. register uint8 *addr;
  29. {
  30. register struct ax25_cb *axp;
  31. struct ax25_cb *axlast = NULL;
  32. /* Search list */
  33. for(axp = Ax25_cb; axp != NULL; axlast=axp,axp = axp->next){
  34. if(addreq(axp->remote,addr)){
  35. if(axlast != NULL){
  36. /* Move entry to top of list to speed
  37.  * future searches
  38.  */
  39. axlast->next = axp->next;
  40. axp->next = Ax25_cb;
  41. Ax25_cb = axp;
  42. }
  43. return axp;
  44. }
  45. }
  46. return NULL;
  47. }
  48. /* Remove entry from connection table */
  49. void
  50. del_ax25(conn)
  51. struct ax25_cb *conn;
  52. {
  53. register struct ax25_cb *axp;
  54. struct ax25_cb *axlast = NULL;
  55. for(axp = Ax25_cb; axp != NULL; axlast=axp,axp = axp->next){
  56. if(axp == conn)
  57. break;
  58. }
  59. if(axp == NULL)
  60. return; /* Not found */
  61. /* Remove from list */
  62. if(axlast != NULL)
  63. axlast->next = axp->next;
  64. else
  65. Ax25_cb = axp->next;
  66. /* Timers should already be stopped, but just in case... */
  67. stop_timer(&axp->t1);
  68. stop_timer(&axp->t3);
  69. /* Free allocated resources */
  70. free_q(&axp->txq);
  71. free_q(&axp->rxasm);
  72. free_q(&axp->rxq);
  73. free(axp);
  74. }
  75. /* Create an ax25 control block. Allocate a new structure, if necessary,
  76.  * and fill it with all the defaults. The caller
  77.  * is still responsible for filling in the reply address
  78.  */
  79. struct ax25_cb *
  80. cr_ax25(addr)
  81. uint8 *addr;
  82. {
  83. register struct ax25_cb *axp;
  84. if(addr == NULL)
  85. return NULL;
  86. if((axp = find_ax25(addr)) == NULL){
  87. /* Not already in table; create an entry
  88.  * and insert it at the head of the chain
  89.  */
  90. axp = (struct ax25_cb *)callocw(1,sizeof(struct ax25_cb));
  91. axp->next = Ax25_cb;
  92. Ax25_cb = axp;
  93. }
  94. axp->user = -1;
  95. axp->state = LAPB_DISCONNECTED;
  96. axp->maxframe = Maxframe;
  97. axp->window = Axwindow;
  98. axp->paclen = Paclen;
  99. axp->proto = Axversion; /* Default, can be changed by other end */
  100. axp->pthresh = Pthresh;
  101. axp->n2 = N2;
  102. axp->srt = Axirtt;
  103. set_timer(&axp->t1,2*axp->srt);
  104. axp->t1.func = recover;
  105. axp->t1.arg = axp;
  106. set_timer(&axp->t3,T3init);
  107. axp->t3.func = pollthem;
  108. axp->t3.arg = axp;
  109. /* Always to a receive and state upcall as default */
  110. axp->r_upcall = s_arcall;
  111. axp->s_upcall = s_ascall;
  112. return axp;
  113. }
  114. /*
  115.  * setcall - convert callsign plus substation ID of the form
  116.  * "KA9Q-0" to AX.25 (shifted) address format
  117.  *   Address extension bit is left clear
  118.  *   Return -1 on error, 0 if OK
  119.  */
  120. int
  121. setcall(out,call)
  122. uint8 *out;
  123. char *call;
  124. {
  125. int csize;
  126. unsigned ssid;
  127. register int i;
  128. register char *dp;
  129. char c;
  130. if(out == NULL || call == NULL || *call == '')
  131. return -1;
  132. /* Find dash, if any, separating callsign from ssid
  133.  * Then compute length of callsign field and make sure
  134.  * it isn't excessive
  135.  */
  136. dp = strchr(call,'-');
  137. if(dp == NULL)
  138. csize = strlen(call);
  139. else
  140. csize = dp - call;
  141. if(csize > ALEN)
  142. return -1;
  143. /* Now find and convert ssid, if any */
  144. if(dp != NULL){
  145. dp++; /* skip dash */
  146. ssid = atoi(dp);
  147. if(ssid > 15)
  148. return -1;
  149. } else
  150. ssid = 0;
  151. /* Copy upper-case callsign, left shifted one bit */
  152. for(i=0;i<csize;i++){
  153. c = *call++;
  154. if(islower(c))
  155. c = toupper(c);
  156. *out++ = c << 1;
  157. }
  158. /* Pad with shifted spaces if necessary */
  159. for(;i<ALEN;i++)
  160. *out++ = ' ' << 1;
  161. /* Insert substation ID field and set reserved bits */
  162. *out = 0x60 | (ssid << 1);
  163. return 0;
  164. }
  165. int
  166. addreq(a,b)
  167. register uint8 *a,*b;
  168. {
  169. if(memcmp(a,b,ALEN) != 0 || ((a[ALEN] ^ b[ALEN]) & SSID) != 0)
  170. return 0;
  171. else
  172. return 1;
  173. }
  174. /* Convert encoded AX.25 address to printable string */
  175. char *
  176. pax25(e,addr)
  177. char *e;
  178. uint8 *addr;
  179. {
  180. register int i;
  181. char c;
  182. char *cp;
  183. cp = e;
  184. for(i=ALEN;i != 0;i--){
  185. c = (*addr++ >> 1) & 0x7f;
  186. if(c != ' ')
  187. *cp++ = c;
  188. }
  189. if((*addr & SSID) != 0)
  190. sprintf(cp,"-%d",(*addr >> 1) & 0xf); /* ssid */
  191. else
  192. *cp = '';
  193. return e;
  194. }
  195. /* Figure out the frame type from the control field
  196.  * This is done by masking out any sequence numbers and the
  197.  * poll/final bit after determining the general class (I/S/U) of the frame
  198.  */
  199. uint16
  200. ftype(control)
  201. register int control;
  202. {
  203. if((control & 1) == 0) /* An I-frame is an I-frame... */
  204. return I;
  205. if(control & 2) /* U-frames use all except P/F bit for type */
  206. return (uint16)control & ~PF;
  207. else /* S-frames use low order 4 bits for type */
  208. return (uint16)control & 0xf;
  209. }
  210. void
  211. lapb_garbage(red)
  212. int red;
  213. {
  214. register struct ax25_cb *axp;
  215. for(axp=Ax25_cb;axp != NULL;axp = axp->next){
  216. mbuf_crunch(&axp->rxq);
  217. mbuf_crunch(&axp->rxasm);
  218. }
  219. }