x25_in.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:10k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * X.25 Packet Layer release 002
  3.  *
  4.  * This is ALPHA test software. This code may break your machine, randomly fail to work with new 
  5.  * releases, misbehave and/or generally screw up. It might even work. 
  6.  *
  7.  * This code REQUIRES 2.1.15 or higher
  8.  *
  9.  * This module:
  10.  * This module is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License
  12.  * as published by the Free Software Foundation; either version
  13.  * 2 of the License, or (at your option) any later version.
  14.  *
  15.  * History
  16.  * X.25 001 Jonathan Naylor   Started coding.
  17.  * X.25 002 Jonathan Naylor   Centralised disconnection code.
  18.  *   New timer architecture.
  19.  * 2000-03-20 Daniela Squassoni Disabling/enabling of facilities 
  20.  *   negotiation.
  21.  * 2000-11-10 Henner Eisen   Check and reset for out-of-sequence
  22.  *   i-frames.
  23.  */
  24. #include <linux/errno.h>
  25. #include <linux/types.h>
  26. #include <linux/socket.h>
  27. #include <linux/in.h>
  28. #include <linux/kernel.h>
  29. #include <linux/sched.h>
  30. #include <linux/timer.h>
  31. #include <linux/string.h>
  32. #include <linux/sockios.h>
  33. #include <linux/net.h>
  34. #include <linux/inet.h>
  35. #include <linux/netdevice.h>
  36. #include <linux/skbuff.h>
  37. #include <net/sock.h>
  38. #include <net/ip.h> /* For ip_rcv */
  39. #include <asm/segment.h>
  40. #include <asm/system.h>
  41. #include <linux/fcntl.h>
  42. #include <linux/mm.h>
  43. #include <linux/interrupt.h>
  44. #include <net/x25.h>
  45. static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
  46. {
  47. struct sk_buff *skbo, *skbn = skb;
  48. if (more) {
  49. sk->protinfo.x25->fraglen += skb->len;
  50. skb_queue_tail(&sk->protinfo.x25->fragment_queue, skb);
  51. skb_set_owner_r(skb, sk);
  52. return 0;
  53. }
  54. if (!more && sk->protinfo.x25->fraglen > 0) { /* End of fragment */
  55. int len = sk->protinfo.x25->fraglen + skb->len;
  56. if ((skbn = alloc_skb(len, GFP_ATOMIC)) == NULL){
  57. kfree_skb(skb);
  58. return 1;
  59. }
  60. skb_queue_tail(&sk->protinfo.x25->fragment_queue, skb);
  61. skbn->h.raw = skbn->data;
  62. skbo = skb_dequeue(&sk->protinfo.x25->fragment_queue);
  63. memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
  64. kfree_skb(skbo);
  65. while ((skbo = skb_dequeue(&sk->protinfo.x25->fragment_queue)) != NULL) {
  66. skb_pull(skbo, (sk->protinfo.x25->neighbour->extended) ? X25_EXT_MIN_LEN : X25_STD_MIN_LEN);
  67. memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
  68. kfree_skb(skbo);
  69. }
  70. sk->protinfo.x25->fraglen = 0;
  71. }
  72. skb_set_owner_r(skbn, sk);
  73. skb_queue_tail(&sk->receive_queue, skbn);
  74. if (!sk->dead)
  75. sk->data_ready(sk,skbn->len);
  76. return 0;
  77. }
  78. /*
  79.  * State machine for state 1, Awaiting Call Accepted State.
  80.  * The handling of the timer(s) is in file x25_timer.c.
  81.  * Handling of state 0 and connection release is in af_x25.c.
  82.  */
  83. static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
  84. {
  85. x25_address source_addr, dest_addr;
  86. switch (frametype) {
  87. case X25_CALL_ACCEPTED:
  88. x25_stop_timer(sk);
  89. sk->protinfo.x25->condition = 0x00;
  90. sk->protinfo.x25->vs        = 0;
  91. sk->protinfo.x25->va        = 0;
  92. sk->protinfo.x25->vr        = 0;
  93. sk->protinfo.x25->vl        = 0;
  94. sk->protinfo.x25->state     = X25_STATE_3;
  95. sk->state                   = TCP_ESTABLISHED;
  96. /*
  97.  * Parse the data in the frame.
  98.  */
  99. skb_pull(skb, X25_STD_MIN_LEN);
  100. skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
  101. skb_pull(skb, x25_parse_facilities(skb, &sk->protinfo.x25->facilities, &sk->protinfo.x25->vc_facil_mask));
  102. /*
  103.  * Copy any Call User Data.
  104.  */
  105. if (skb->len >= 0) {
  106. memcpy(sk->protinfo.x25->calluserdata.cuddata, skb->data, skb->len);
  107. sk->protinfo.x25->calluserdata.cudlength = skb->len;
  108. }
  109. if (!sk->dead)
  110. sk->state_change(sk);
  111. break;
  112. case X25_CLEAR_REQUEST:
  113. x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
  114. x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
  115. break;
  116. default:
  117. break;
  118. }
  119. return 0;
  120. }
  121. /*
  122.  * State machine for state 2, Awaiting Clear Confirmation State.
  123.  * The handling of the timer(s) is in file x25_timer.c
  124.  * Handling of state 0 and connection release is in af_x25.c.
  125.  */
  126. static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype)
  127. {
  128. switch (frametype) {
  129. case X25_CLEAR_REQUEST:
  130. x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
  131. x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
  132. break;
  133. case X25_CLEAR_CONFIRMATION:
  134. x25_disconnect(sk, 0, 0, 0);
  135. break;
  136. default:
  137. break;
  138. }
  139. return 0;
  140. }
  141. /*
  142.  * State machine for state 3, Connected State.
  143.  * The handling of the timer(s) is in file x25_timer.c
  144.  * Handling of state 0 and connection release is in af_x25.c.
  145.  */
  146. static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype, int ns, int nr, int q, int d, int m)
  147. {
  148. int queued = 0;
  149. int modulus;
  150. modulus = (sk->protinfo.x25->neighbour->extended) ? X25_EMODULUS : X25_SMODULUS;
  151. switch (frametype) {
  152. case X25_RESET_REQUEST:
  153. x25_write_internal(sk, X25_RESET_CONFIRMATION);
  154. x25_stop_timer(sk);
  155. sk->protinfo.x25->condition = 0x00;
  156. sk->protinfo.x25->vs        = 0;
  157. sk->protinfo.x25->vr        = 0;
  158. sk->protinfo.x25->va        = 0;
  159. sk->protinfo.x25->vl        = 0;
  160. x25_requeue_frames(sk);
  161. break;
  162. case X25_CLEAR_REQUEST:
  163. x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
  164. x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
  165. break;
  166. case X25_RR:
  167. case X25_RNR:
  168. if (!x25_validate_nr(sk, nr)) {
  169. x25_clear_queues(sk);
  170. x25_write_internal(sk, X25_RESET_REQUEST);
  171. x25_start_t22timer(sk);
  172. sk->protinfo.x25->condition = 0x00;
  173. sk->protinfo.x25->vs        = 0;
  174. sk->protinfo.x25->vr        = 0;
  175. sk->protinfo.x25->va        = 0;
  176. sk->protinfo.x25->vl        = 0;
  177. sk->protinfo.x25->state     = X25_STATE_4;
  178. } else {
  179. x25_frames_acked(sk, nr);
  180. if (frametype == X25_RNR) {
  181. sk->protinfo.x25->condition |= X25_COND_PEER_RX_BUSY;
  182. } else {
  183. sk->protinfo.x25->condition &= ~X25_COND_PEER_RX_BUSY;
  184. }
  185. }
  186. break;
  187. case X25_DATA: /* XXX */
  188. sk->protinfo.x25->condition &= ~X25_COND_PEER_RX_BUSY;
  189. if ((ns!=sk->protinfo.x25->vr) || 
  190.     !x25_validate_nr(sk, nr)) {
  191. x25_clear_queues(sk);
  192. x25_write_internal(sk, X25_RESET_REQUEST);
  193. x25_start_t22timer(sk);
  194. sk->protinfo.x25->condition = 0x00;
  195. sk->protinfo.x25->vs        = 0;
  196. sk->protinfo.x25->vr        = 0;
  197. sk->protinfo.x25->va        = 0;
  198. sk->protinfo.x25->vl        = 0;
  199. sk->protinfo.x25->state     = X25_STATE_4;
  200. break;
  201. }
  202. x25_frames_acked(sk, nr);
  203. if (ns == sk->protinfo.x25->vr) {
  204. if (x25_queue_rx_frame(sk, skb, m) == 0) {
  205. sk->protinfo.x25->vr = (sk->protinfo.x25->vr + 1) % modulus;
  206. queued = 1;
  207. } else {
  208. /* Should never happen */
  209. x25_clear_queues(sk);
  210. x25_write_internal(sk, X25_RESET_REQUEST);
  211. x25_start_t22timer(sk);
  212. sk->protinfo.x25->condition = 0x00;
  213. sk->protinfo.x25->vs        = 0;
  214. sk->protinfo.x25->vr        = 0;
  215. sk->protinfo.x25->va        = 0;
  216. sk->protinfo.x25->vl        = 0;
  217. sk->protinfo.x25->state     = X25_STATE_4;
  218. break;
  219. }
  220. if (atomic_read(&sk->rmem_alloc) > (sk->rcvbuf / 2))
  221. sk->protinfo.x25->condition |= X25_COND_OWN_RX_BUSY;
  222. }
  223. /*
  224.  * If the window is full Ack it immediately, else
  225.  * start the holdback timer.
  226.  */
  227. if (((sk->protinfo.x25->vl + sk->protinfo.x25->facilities.winsize_in) % modulus) == sk->protinfo.x25->vr) {
  228. sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
  229. x25_stop_timer(sk);
  230. x25_enquiry_response(sk);
  231. } else {
  232. sk->protinfo.x25->condition |= X25_COND_ACK_PENDING;
  233. x25_start_t2timer(sk);
  234. }
  235. break;
  236. case X25_INTERRUPT_CONFIRMATION:
  237. sk->protinfo.x25->intflag = 0;
  238. break;
  239. case X25_INTERRUPT:
  240. if (sk->urginline) {
  241. queued = (sock_queue_rcv_skb(sk, skb) == 0);
  242. } else {
  243. skb_set_owner_r(skb, sk);
  244. skb_queue_tail(&sk->protinfo.x25->interrupt_in_queue, skb);
  245. queued = 1;
  246. }
  247. if (sk->proc != 0) {
  248. if (sk->proc > 0)
  249. kill_proc(sk->proc, SIGURG, 1);
  250. else
  251. kill_pg(-sk->proc, SIGURG, 1);
  252. sock_wake_async(sk->socket, 3, POLL_PRI);
  253. }
  254. x25_write_internal(sk, X25_INTERRUPT_CONFIRMATION);
  255. break;
  256. default:
  257. printk(KERN_WARNING "x25: unknown %02X in state 3n", frametype);
  258. break;
  259. }
  260. return queued;
  261. }
  262. /*
  263.  * State machine for state 4, Awaiting Reset Confirmation State.
  264.  * The handling of the timer(s) is in file x25_timer.c
  265.  * Handling of state 0 and connection release is in af_x25.c.
  266.  */
  267. static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
  268. {
  269. switch (frametype) {
  270. case X25_RESET_REQUEST:
  271. x25_write_internal(sk, X25_RESET_CONFIRMATION);
  272. case X25_RESET_CONFIRMATION:
  273. x25_stop_timer(sk);
  274. sk->protinfo.x25->condition = 0x00;
  275. sk->protinfo.x25->va        = 0;
  276. sk->protinfo.x25->vr        = 0;
  277. sk->protinfo.x25->vs        = 0;
  278. sk->protinfo.x25->vl        = 0;
  279. sk->protinfo.x25->state     = X25_STATE_3;
  280. x25_requeue_frames(sk);
  281. break;
  282. case X25_CLEAR_REQUEST:
  283. x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
  284. x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
  285. break;
  286. default:
  287. break;
  288. }
  289. return 0;
  290. }
  291. /* Higher level upcall for a LAPB frame */
  292. int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb)
  293. {
  294. int queued = 0, frametype, ns, nr, q, d, m;
  295. if (sk->protinfo.x25->state == X25_STATE_0)
  296. return 0;
  297. frametype = x25_decode(sk, skb, &ns, &nr, &q, &d, &m);
  298. switch (sk->protinfo.x25->state) {
  299. case X25_STATE_1:
  300. queued = x25_state1_machine(sk, skb, frametype);
  301. break;
  302. case X25_STATE_2:
  303. queued = x25_state2_machine(sk, skb, frametype);
  304. break;
  305. case X25_STATE_3:
  306. queued = x25_state3_machine(sk, skb, frametype, ns, nr, q, d, m);
  307. break;
  308. case X25_STATE_4:
  309. queued = x25_state4_machine(sk, skb, frametype);
  310. break;
  311. }
  312. x25_kick(sk);
  313. return queued;
  314. }
  315. int x25_backlog_rcv(struct sock *sk, struct sk_buff *skb)
  316. {
  317. int queued;
  318. queued = x25_process_rx_frame(sk,skb);
  319. if(!queued) kfree_skb(skb);
  320. return 0;
  321. }