nr_in.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation; either version 2 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
  8. * Copyright Darryl Miles G7LED (dlm@g7led.demon.co.uk)
  9. */
  10. #include <linux/errno.h>
  11. #include <linux/types.h>
  12. #include <linux/socket.h>
  13. #include <linux/in.h>
  14. #include <linux/kernel.h>
  15. #include <linux/timer.h>
  16. #include <linux/string.h>
  17. #include <linux/sockios.h>
  18. #include <linux/net.h>
  19. #include <linux/slab.h>
  20. #include <net/ax25.h>
  21. #include <linux/inet.h>
  22. #include <linux/netdevice.h>
  23. #include <linux/skbuff.h>
  24. #include <net/sock.h>
  25. #include <net/tcp_states.h>
  26. #include <linux/uaccess.h>
  27. #include <linux/fcntl.h>
  28. #include <linux/mm.h>
  29. #include <linux/interrupt.h>
  30. #include <net/netrom.h>
  31. static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
  32. {
  33. struct sk_buff *skbo, *skbn = skb;
  34. struct nr_sock *nr = nr_sk(sk);
  35. skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
  36. nr_start_idletimer(sk);
  37. if (more) {
  38. nr->fraglen += skb->len;
  39. skb_queue_tail(&nr->frag_queue, skb);
  40. return 0;
  41. }
  42. if (!more && nr->fraglen > 0) { /* End of fragment */
  43. nr->fraglen += skb->len;
  44. skb_queue_tail(&nr->frag_queue, skb);
  45. if ((skbn = alloc_skb(nr->fraglen, GFP_ATOMIC)) == NULL)
  46. return 1;
  47. skb_reset_transport_header(skbn);
  48. while ((skbo = skb_dequeue(&nr->frag_queue)) != NULL) {
  49. skb_copy_from_linear_data(skbo,
  50. skb_put(skbn, skbo->len),
  51. skbo->len);
  52. kfree_skb(skbo);
  53. }
  54. nr->fraglen = 0;
  55. }
  56. return sock_queue_rcv_skb(sk, skbn);
  57. }
  58. /*
  59. * State machine for state 1, Awaiting Connection State.
  60. * The handling of the timer(s) is in file nr_timer.c.
  61. * Handling of state 0 and connection release is in netrom.c.
  62. */
  63. static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
  64. int frametype)
  65. {
  66. switch (frametype) {
  67. case NR_CONNACK: {
  68. struct nr_sock *nr = nr_sk(sk);
  69. nr_stop_t1timer(sk);
  70. nr_start_idletimer(sk);
  71. nr->your_index = skb->data[17];
  72. nr->your_id = skb->data[18];
  73. nr->vs = 0;
  74. nr->va = 0;
  75. nr->vr = 0;
  76. nr->vl = 0;
  77. nr->state = NR_STATE_3;
  78. nr->n2count = 0;
  79. nr->window = skb->data[20];
  80. sk->sk_state = TCP_ESTABLISHED;
  81. if (!sock_flag(sk, SOCK_DEAD))
  82. sk->sk_state_change(sk);
  83. break;
  84. }
  85. case NR_CONNACK | NR_CHOKE_FLAG:
  86. nr_disconnect(sk, ECONNREFUSED);
  87. break;
  88. case NR_RESET:
  89. if (sysctl_netrom_reset_circuit)
  90. nr_disconnect(sk, ECONNRESET);
  91. break;
  92. default:
  93. break;
  94. }
  95. return 0;
  96. }
  97. /*
  98. * State machine for state 2, Awaiting Release State.
  99. * The handling of the timer(s) is in file nr_timer.c
  100. * Handling of state 0 and connection release is in netrom.c.
  101. */
  102. static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
  103. int frametype)
  104. {
  105. switch (frametype) {
  106. case NR_CONNACK | NR_CHOKE_FLAG:
  107. nr_disconnect(sk, ECONNRESET);
  108. break;
  109. case NR_DISCREQ:
  110. nr_write_internal(sk, NR_DISCACK);
  111. case NR_DISCACK:
  112. nr_disconnect(sk, 0);
  113. break;
  114. case NR_RESET:
  115. if (sysctl_netrom_reset_circuit)
  116. nr_disconnect(sk, ECONNRESET);
  117. break;
  118. default:
  119. break;
  120. }
  121. return 0;
  122. }
  123. /*
  124. * State machine for state 3, Connected State.
  125. * The handling of the timer(s) is in file nr_timer.c
  126. * Handling of state 0 and connection release is in netrom.c.
  127. */
  128. static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype)
  129. {
  130. struct nr_sock *nrom = nr_sk(sk);
  131. struct sk_buff_head temp_queue;
  132. struct sk_buff *skbn;
  133. unsigned short save_vr;
  134. unsigned short nr, ns;
  135. int queued = 0;
  136. nr = skb->data[18];
  137. ns = skb->data[17];
  138. switch (frametype) {
  139. case NR_CONNREQ:
  140. nr_write_internal(sk, NR_CONNACK);
  141. break;
  142. case NR_DISCREQ:
  143. nr_write_internal(sk, NR_DISCACK);
  144. nr_disconnect(sk, 0);
  145. break;
  146. case NR_CONNACK | NR_CHOKE_FLAG:
  147. case NR_DISCACK:
  148. nr_disconnect(sk, ECONNRESET);
  149. break;
  150. case NR_INFOACK:
  151. case NR_INFOACK | NR_CHOKE_FLAG:
  152. case NR_INFOACK | NR_NAK_FLAG:
  153. case NR_INFOACK | NR_NAK_FLAG | NR_CHOKE_FLAG:
  154. if (frametype & NR_CHOKE_FLAG) {
  155. nrom->condition |= NR_COND_PEER_RX_BUSY;
  156. nr_start_t4timer(sk);
  157. } else {
  158. nrom->condition &= ~NR_COND_PEER_RX_BUSY;
  159. nr_stop_t4timer(sk);
  160. }
  161. if (!nr_validate_nr(sk, nr)) {
  162. break;
  163. }
  164. if (frametype & NR_NAK_FLAG) {
  165. nr_frames_acked(sk, nr);
  166. nr_send_nak_frame(sk);
  167. } else {
  168. if (nrom->condition & NR_COND_PEER_RX_BUSY) {
  169. nr_frames_acked(sk, nr);
  170. } else {
  171. nr_check_iframes_acked(sk, nr);
  172. }
  173. }
  174. break;
  175. case NR_INFO:
  176. case NR_INFO | NR_NAK_FLAG:
  177. case NR_INFO | NR_CHOKE_FLAG:
  178. case NR_INFO | NR_MORE_FLAG:
  179. case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG:
  180. case NR_INFO | NR_CHOKE_FLAG | NR_MORE_FLAG:
  181. case NR_INFO | NR_NAK_FLAG | NR_MORE_FLAG:
  182. case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG | NR_MORE_FLAG:
  183. if (frametype & NR_CHOKE_FLAG) {
  184. nrom->condition |= NR_COND_PEER_RX_BUSY;
  185. nr_start_t4timer(sk);
  186. } else {
  187. nrom->condition &= ~NR_COND_PEER_RX_BUSY;
  188. nr_stop_t4timer(sk);
  189. }
  190. if (nr_validate_nr(sk, nr)) {
  191. if (frametype & NR_NAK_FLAG) {
  192. nr_frames_acked(sk, nr);
  193. nr_send_nak_frame(sk);
  194. } else {
  195. if (nrom->condition & NR_COND_PEER_RX_BUSY) {
  196. nr_frames_acked(sk, nr);
  197. } else {
  198. nr_check_iframes_acked(sk, nr);
  199. }
  200. }
  201. }
  202. queued = 1;
  203. skb_queue_head(&nrom->reseq_queue, skb);
  204. if (nrom->condition & NR_COND_OWN_RX_BUSY)
  205. break;
  206. skb_queue_head_init(&temp_queue);
  207. do {
  208. save_vr = nrom->vr;
  209. while ((skbn = skb_dequeue(&nrom->reseq_queue)) != NULL) {
  210. ns = skbn->data[17];
  211. if (ns == nrom->vr) {
  212. if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
  213. nrom->vr = (nrom->vr + 1) % NR_MODULUS;
  214. } else {
  215. nrom->condition |= NR_COND_OWN_RX_BUSY;
  216. skb_queue_tail(&temp_queue, skbn);
  217. }
  218. } else if (nr_in_rx_window(sk, ns)) {
  219. skb_queue_tail(&temp_queue, skbn);
  220. } else {
  221. kfree_skb(skbn);
  222. }
  223. }
  224. while ((skbn = skb_dequeue(&temp_queue)) != NULL) {
  225. skb_queue_tail(&nrom->reseq_queue, skbn);
  226. }
  227. } while (save_vr != nrom->vr);
  228. /*
  229. * Window is full, ack it immediately.
  230. */
  231. if (((nrom->vl + nrom->window) % NR_MODULUS) == nrom->vr) {
  232. nr_enquiry_response(sk);
  233. } else {
  234. if (!(nrom->condition & NR_COND_ACK_PENDING)) {
  235. nrom->condition |= NR_COND_ACK_PENDING;
  236. nr_start_t2timer(sk);
  237. }
  238. }
  239. break;
  240. case NR_RESET:
  241. if (sysctl_netrom_reset_circuit)
  242. nr_disconnect(sk, ECONNRESET);
  243. break;
  244. default:
  245. break;
  246. }
  247. return queued;
  248. }
  249. /* Higher level upcall for a LAPB frame - called with sk locked */
  250. int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb)
  251. {
  252. struct nr_sock *nr = nr_sk(sk);
  253. int queued = 0, frametype;
  254. if (nr->state == NR_STATE_0)
  255. return 0;
  256. frametype = skb->data[19];
  257. switch (nr->state) {
  258. case NR_STATE_1:
  259. queued = nr_state1_machine(sk, skb, frametype);
  260. break;
  261. case NR_STATE_2:
  262. queued = nr_state2_machine(sk, skb, frametype);
  263. break;
  264. case NR_STATE_3:
  265. queued = nr_state3_machine(sk, skb, frametype);
  266. break;
  267. }
  268. nr_kick(sk);
  269. return queued;
  270. }