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

TCP/IP协议栈

开发平台:

Visual C++

  1. /*
  2.  * nr4subr.c:  subroutines for net/rom transport layer.
  3.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  4.  * non-commercial distribution only.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "mbuf.h"
  10. #include "timer.h"
  11. #include "ax25.h"
  12. #include "netrom.h"
  13. #include "nr4.h"
  14. #include "lapb.h"
  15. #include <ctype.h>
  16. /* Get a free circuit table entry, and allocate a circuit descriptor.
  17.  * Initialize control block circuit number and ID fields.
  18.  * Return a pointer to the circuit control block if successful,
  19.  * NULL if not.
  20.  */
  21. struct nr4cb *
  22. new_n4circ()
  23. {
  24. int i ;
  25. struct nr4cb *cb ;
  26. for (i = 0 ; i <  NR4MAXCIRC ; i++) /* find a free circuit */
  27. if (Nr4circuits[i].ccb == NULL)
  28. break ;
  29. if (i == NR4MAXCIRC) /* no more circuits */
  30. return NULL ;
  31. cb = Nr4circuits[i].ccb =
  32.  (struct nr4cb *)callocw(1,sizeof(struct nr4cb));
  33. cb->mynum = i ;
  34. cb->myid = Nr4circuits[i].cid ;
  35. return cb ;
  36. }
  37. /* Set the window size for a circuit and allocate the buffers for
  38.  * the transmit and receive windows.  Set the control block window
  39.  * parameter.  Return 0 if successful, -1 if not.
  40.  */
  41. int
  42. init_nr4window(cb, window)
  43. struct nr4cb *cb ;
  44. unsigned window ;
  45. {
  46. if (window == 0 || window > NR4MAXWIN) /* reject silly window sizes */
  47. return -1 ;
  48. cb->txbufs =
  49.  (struct nr4txbuf *)callocw(window,sizeof(struct nr4txbuf));
  50. cb->rxbufs =
  51.  (struct nr4rxbuf *)callocw(window,sizeof(struct nr4rxbuf));
  52. cb->window = window ;
  53. return 0 ;
  54. }
  55. /* Free a circuit.  Deallocate the control block and buffers, and
  56.  * increment the circuit ID.  No return value.
  57.  */
  58. void
  59. free_n4circ(cb)
  60. struct nr4cb *cb ;
  61. {
  62. unsigned circ ;
  63. if (cb == NULL)
  64. return ;
  65. circ = cb->mynum ;
  66. if (cb->txbufs != (struct nr4txbuf *)0)
  67. free(cb->txbufs) ;
  68. if (cb->rxbufs != (struct nr4rxbuf *)0)
  69. free(cb->rxbufs) ;
  70. /* Better be safe than sorry: */
  71. free_q(&cb->txq) ;
  72. free_q(&cb->rxq) ;
  73. free(cb) ;
  74. if (circ > NR4MAXCIRC) /* Shouldn't happen. */
  75. return ;
  76. Nr4circuits[circ].ccb = NULL ;
  77. Nr4circuits[circ].cid++ ;
  78. }
  79. /* See if any open circuit matches the given parameters.  This is used
  80.  * to prevent opening multiple circuits on a duplicate connect request.
  81.  * Returns the control block address if a match is found, or NULL
  82.  * otherwise.
  83.  */
  84. struct nr4cb *
  85. match_n4circ(index, id, user, node)
  86. int index ; /* index of remote circuit */
  87. int id ; /* id of remote circuit */
  88. uint8 *user ; /* address of remote user */
  89. uint8 *node ; /* address of originating node */
  90. {
  91. int i ;
  92. struct nr4cb *cb ;
  93. for (i = 0 ; i < NR4MAXCIRC ; i++) {
  94. if ((cb = Nr4circuits[i].ccb) == NULL)
  95. continue ; /* not an open circuit */
  96. if (cb->yournum == index && cb->yourid == id
  97.     && addreq(cb->remote.user,user)
  98.     && addreq(cb->remote.node,node))
  99. return cb ;
  100. }
  101. /* if we get to here, we didn't find a match */
  102. return NULL ;
  103. }
  104. /* Validate the index and id of a local circuit, returning the control
  105.  * block if it is valid, or NULL if it is not.
  106.  */
  107. struct nr4cb *
  108. get_n4circ(index, id)
  109. int index ; /* local circuit index */
  110. int id ; /* local circuit id */
  111. {
  112. struct nr4cb *cb ;
  113. if (index >= NR4MAXCIRC)
  114. return NULL ;
  115. if ((cb = Nr4circuits[index].ccb) == NULL)
  116. return NULL ;
  117. if (cb->myid == id)
  118. return cb ;
  119. else
  120. return NULL ;
  121. }
  122. /* Return 1 if b is "between" (modulo the size of an unsigned char)
  123.  * a and c, 0 otherwise.
  124.  */
  125. int
  126. nr4between(a, b, c)
  127. unsigned a, b, c ;
  128. {
  129. if ((a <= b && b < c) || (c < a && a <= b) || (b < c && c < a))
  130. return 1 ;
  131. else
  132. return 0 ;
  133. }
  134. /* Set up default timer values, etc., in newly connected control block.
  135.  */
  136. void
  137. nr4defaults(cb)
  138. struct nr4cb *cb ;
  139. {
  140. int i ;
  141. struct timer *t ;
  142. if (cb == NULL)
  143. return ;
  144. /* Set up the ACK and CHOKE timers */
  145. set_timer(&cb->tack,Nr4acktime) ;
  146. cb->tack.func = nr4ackit ;
  147. cb->tack.arg = cb ;
  148. set_timer(&cb->tchoke,Nr4choketime) ;
  149. cb->tchoke.func = nr4unchoke ;
  150. cb->tchoke.arg = cb ;
  151. cb->rxpastwin = cb->window ;
  152. /* Don't actually set the timers, since this is done */
  153. /* in nr4sbuf */
  154. for (i = 0 ; i < cb->window ; i++) {
  155. t = &cb->txbufs[i].tretry ;
  156. t->func = nr4txtimeout ;
  157. t->arg = cb ;
  158. }
  159. }
  160. /* See if this control block address is valid */
  161. int
  162. nr4valcb(cb)
  163. struct nr4cb *cb ;
  164. {
  165. int i ;
  166. if (cb == NULL)
  167. return 0 ;
  168. for (i = 0 ; i < NR4MAXCIRC ; i++)
  169. if (Nr4circuits[i].ccb == cb)
  170. return 1 ;
  171. return 0 ;
  172. }
  173. void
  174. nr_garbage(red)
  175. int red;
  176. {
  177. int i;
  178. struct nr4cb *ncp;
  179. for(i=0;i<NR4MAXCIRC;i++){
  180. ncp = Nr4circuits[i].ccb;
  181. if(ncp != NULL)
  182. mbuf_crunch(&ncp->rxq);
  183. }
  184. }