rose_subr.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * ROSE release 003
  3.  *
  4.  * This code REQUIRES 2.1.15 or higher/ NET3.038
  5.  *
  6.  * This module:
  7.  * This module is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License
  9.  * as published by the Free Software Foundation; either version
  10.  * 2 of the License, or (at your option) any later version.
  11.  *
  12.  * History
  13.  * ROSE 001 Jonathan(G4KLX) Cloned from nr_subr.c
  14.  * ROSE 002 Jonathan(G4KLX) Centralised disconnect processing.
  15.  * ROSE 003 Jonathan(G4KLX) Added use count to neighbours.
  16.  */
  17. #include <linux/errno.h>
  18. #include <linux/types.h>
  19. #include <linux/socket.h>
  20. #include <linux/in.h>
  21. #include <linux/kernel.h>
  22. #include <linux/sched.h>
  23. #include <linux/timer.h>
  24. #include <linux/string.h>
  25. #include <linux/sockios.h>
  26. #include <linux/net.h>
  27. #include <net/ax25.h>
  28. #include <linux/inet.h>
  29. #include <linux/netdevice.h>
  30. #include <linux/skbuff.h>
  31. #include <net/sock.h>
  32. #include <asm/segment.h>
  33. #include <asm/system.h>
  34. #include <linux/fcntl.h>
  35. #include <linux/mm.h>
  36. #include <linux/interrupt.h>
  37. #include <net/rose.h>
  38. /*
  39.  * This routine purges all of the queues of frames.
  40.  */
  41. void rose_clear_queues(struct sock *sk)
  42. {
  43. skb_queue_purge(&sk->write_queue);
  44. skb_queue_purge(&sk->protinfo.rose->ack_queue);
  45. }
  46. /*
  47.  * This routine purges the input queue of those frames that have been
  48.  * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
  49.  * SDL diagram.
  50.  */
  51. void rose_frames_acked(struct sock *sk, unsigned short nr)
  52. {
  53. struct sk_buff *skb;
  54. /*
  55.  * Remove all the ack-ed frames from the ack queue.
  56.  */
  57. if (sk->protinfo.rose->va != nr) {
  58. while (skb_peek(&sk->protinfo.rose->ack_queue) != NULL && sk->protinfo.rose->va != nr) {
  59. skb = skb_dequeue(&sk->protinfo.rose->ack_queue);
  60. kfree_skb(skb);
  61. sk->protinfo.rose->va = (sk->protinfo.rose->va + 1) % ROSE_MODULUS;
  62. }
  63. }
  64. }
  65. void rose_requeue_frames(struct sock *sk)
  66. {
  67. struct sk_buff *skb, *skb_prev = NULL;
  68. /*
  69.  * Requeue all the un-ack-ed frames on the output queue to be picked
  70.  * up by rose_kick. This arrangement handles the possibility of an
  71.  * empty output queue.
  72.  */
  73. while ((skb = skb_dequeue(&sk->protinfo.rose->ack_queue)) != NULL) {
  74. if (skb_prev == NULL)
  75. skb_queue_head(&sk->write_queue, skb);
  76. else
  77. skb_append(skb_prev, skb);
  78. skb_prev = skb;
  79. }
  80. }
  81. /*
  82.  * Validate that the value of nr is between va and vs. Return true or
  83.  * false for testing.
  84.  */
  85. int rose_validate_nr(struct sock *sk, unsigned short nr)
  86. {
  87. unsigned short vc = sk->protinfo.rose->va;
  88. while (vc != sk->protinfo.rose->vs) {
  89. if (nr == vc) return 1;
  90. vc = (vc + 1) % ROSE_MODULUS;
  91. }
  92. if (nr == sk->protinfo.rose->vs) return 1;
  93. return 0;
  94. }
  95. /* 
  96.  *  This routine is called when the packet layer internally generates a
  97.  *  control frame.
  98.  */
  99. void rose_write_internal(struct sock *sk, int frametype)
  100. {
  101. struct sk_buff *skb;
  102. unsigned char  *dptr;
  103. unsigned char  lci1, lci2;
  104. char buffer[100];
  105. int len, faclen = 0;
  106. int ax25_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + 1;
  107. len = ax25_header_len + ROSE_MIN_LEN;
  108. switch (frametype) {
  109. case ROSE_CALL_REQUEST:
  110. len   += 1 + ROSE_ADDR_LEN + ROSE_ADDR_LEN;
  111. faclen = rose_create_facilities(buffer, sk->protinfo.rose);
  112. len   += faclen;
  113. break;
  114. case ROSE_CALL_ACCEPTED:
  115. case ROSE_RESET_REQUEST:
  116. len   += 2;
  117. break;
  118. case ROSE_CLEAR_REQUEST:
  119. len   += 3;
  120. /* facilities */
  121. faclen = 3 + 2 + AX25_ADDR_LEN + 3 + ROSE_ADDR_LEN;
  122. dptr = buffer;
  123. *dptr++ = faclen-1; /* Facilities length */
  124. *dptr++ = 0;
  125. *dptr++ = FAC_NATIONAL;
  126. *dptr++ = FAC_NATIONAL_FAIL_CALL;
  127. *dptr++ = AX25_ADDR_LEN;
  128. memcpy(dptr, &rose_callsign, AX25_ADDR_LEN);
  129. dptr += AX25_ADDR_LEN;
  130. *dptr++ = FAC_NATIONAL_FAIL_ADD;
  131. *dptr++ = ROSE_ADDR_LEN + 1;
  132. *dptr++ = ROSE_ADDR_LEN * 2;
  133. memcpy(dptr, &sk->protinfo.rose->source_addr, ROSE_ADDR_LEN);
  134. len   += faclen;
  135. break;
  136. }
  137. if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
  138. return;
  139. /*
  140.  * Space for AX.25 header and PID.
  141.  */
  142. skb_reserve(skb, ax25_header_len);
  143. dptr = skb_put(skb, len - ax25_header_len);
  144. lci1 = (sk->protinfo.rose->lci >> 8) & 0x0F;
  145. lci2 = (sk->protinfo.rose->lci >> 0) & 0xFF;
  146. switch (frametype) {
  147. case ROSE_CALL_REQUEST:
  148. *dptr++ = ROSE_GFI | lci1;
  149. *dptr++ = lci2;
  150. *dptr++ = frametype;
  151. *dptr++ = 0xAA;
  152. memcpy(dptr, &sk->protinfo.rose->dest_addr,  ROSE_ADDR_LEN);
  153. dptr   += ROSE_ADDR_LEN;
  154. memcpy(dptr, &sk->protinfo.rose->source_addr, ROSE_ADDR_LEN);
  155. dptr   += ROSE_ADDR_LEN;
  156. memcpy(dptr, buffer, faclen);
  157. dptr   += faclen;
  158. break;
  159. case ROSE_CALL_ACCEPTED:
  160. *dptr++ = ROSE_GFI | lci1;
  161. *dptr++ = lci2;
  162. *dptr++ = frametype;
  163. *dptr++ = 0x00; /* Address length */
  164. *dptr++ = 0; /* Facilities length */
  165. break;
  166. case ROSE_CLEAR_REQUEST:
  167. *dptr++ = ROSE_GFI | lci1;
  168. *dptr++ = lci2;
  169. *dptr++ = frametype;
  170. *dptr++ = sk->protinfo.rose->cause;
  171. *dptr++ = sk->protinfo.rose->diagnostic;
  172. *dptr++ = 0x00; /* Address length */
  173. memcpy(dptr, buffer, faclen);
  174. dptr   += faclen;
  175. break;
  176. case ROSE_RESET_REQUEST:
  177. *dptr++ = ROSE_GFI | lci1;
  178. *dptr++ = lci2;
  179. *dptr++ = frametype;
  180. *dptr++ = ROSE_DTE_ORIGINATED;
  181. *dptr++ = 0;
  182. break;
  183. case ROSE_RR:
  184. case ROSE_RNR:
  185. *dptr++ = ROSE_GFI | lci1;
  186. *dptr++ = lci2;
  187. *dptr   = frametype;
  188. *dptr++ |= (sk->protinfo.rose->vr << 5) & 0xE0;
  189. break;
  190. case ROSE_CLEAR_CONFIRMATION:
  191. case ROSE_RESET_CONFIRMATION:
  192. *dptr++ = ROSE_GFI | lci1;
  193. *dptr++ = lci2;
  194. *dptr++  = frametype;
  195. break;
  196. default:
  197. printk(KERN_ERR "ROSE: rose_write_internal - invalid frametype %02Xn", frametype);
  198. kfree_skb(skb);
  199. return;
  200. }
  201. rose_transmit_link(skb, sk->protinfo.rose->neighbour);
  202. }
  203. int rose_decode(struct sk_buff *skb, int *ns, int *nr, int *q, int *d, int *m)
  204. {
  205. unsigned char *frame;
  206. frame = skb->data;
  207. *ns = *nr = *q = *d = *m = 0;
  208. switch (frame[2]) {
  209. case ROSE_CALL_REQUEST:
  210. case ROSE_CALL_ACCEPTED:
  211. case ROSE_CLEAR_REQUEST:
  212. case ROSE_CLEAR_CONFIRMATION:
  213. case ROSE_RESET_REQUEST:
  214. case ROSE_RESET_CONFIRMATION:
  215. return frame[2];
  216. default:
  217. break;
  218. }
  219. if ((frame[2] & 0x1F) == ROSE_RR  ||
  220.     (frame[2] & 0x1F) == ROSE_RNR) {
  221. *nr = (frame[2] >> 5) & 0x07;
  222. return frame[2] & 0x1F;
  223. }
  224. if ((frame[2] & 0x01) == ROSE_DATA) {
  225. *q  = (frame[0] & ROSE_Q_BIT) == ROSE_Q_BIT;
  226. *d  = (frame[0] & ROSE_D_BIT) == ROSE_D_BIT;
  227. *m  = (frame[2] & ROSE_M_BIT) == ROSE_M_BIT;
  228. *nr = (frame[2] >> 5) & 0x07;
  229. *ns = (frame[2] >> 1) & 0x07;
  230. return ROSE_DATA;
  231. }
  232. return ROSE_ILLEGAL;
  233. }
  234. static int rose_parse_national(unsigned char *p, struct rose_facilities_struct *facilities, int len)
  235. {
  236. unsigned char *pt;
  237. unsigned char l, lg, n = 0;
  238. int fac_national_digis_received = 0;
  239. do {
  240. switch (*p & 0xC0) {
  241. case 0x00:
  242. p   += 2;
  243. n   += 2;
  244. len -= 2;
  245. break;
  246. case 0x40:
  247. if (*p == FAC_NATIONAL_RAND)
  248. facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF);
  249. p   += 3;
  250. n   += 3;
  251. len -= 3;
  252. break;
  253. case 0x80:
  254. p   += 4;
  255. n   += 4;
  256. len -= 4;
  257. break;
  258. case 0xC0:
  259. l = p[1];
  260. if (*p == FAC_NATIONAL_DEST_DIGI) {
  261. if (!fac_national_digis_received) {
  262. memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN);
  263. facilities->source_ndigis = 1;
  264. }
  265. }
  266. else if (*p == FAC_NATIONAL_SRC_DIGI) {
  267. if (!fac_national_digis_received) {
  268. memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN);
  269. facilities->dest_ndigis = 1;
  270. }
  271. }
  272. else if (*p == FAC_NATIONAL_FAIL_CALL) {
  273. memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN);
  274. }
  275. else if (*p == FAC_NATIONAL_FAIL_ADD) {
  276. memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN);
  277. }
  278. else if (*p == FAC_NATIONAL_DIGIS) {
  279. fac_national_digis_received = 1;
  280. facilities->source_ndigis = 0;
  281. facilities->dest_ndigis   = 0;
  282. for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) {
  283. if (pt[6] & AX25_HBIT)
  284. memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN);
  285. else
  286. memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN);
  287. }
  288. }
  289. p   += l + 2;
  290. n   += l + 2;
  291. len -= l + 2;
  292. break;
  293. }
  294. } while (*p != 0x00 && len > 0);
  295. return n;
  296. }
  297. static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *facilities, int len)
  298. {
  299. unsigned char l, n = 0;
  300. char callsign[11];
  301. do {
  302. switch (*p & 0xC0) {
  303. case 0x00:
  304. p   += 2;
  305. n   += 2;
  306. len -= 2;
  307. break;
  308. case 0x40:
  309. p   += 3;
  310. n   += 3;
  311. len -= 3;
  312. break;
  313. case 0x80:
  314. p   += 4;
  315. n   += 4;
  316. len -= 4;
  317. break;
  318. case 0xC0:
  319. l = p[1];
  320. if (*p == FAC_CCITT_DEST_NSAP) {
  321. memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
  322. memcpy(callsign, p + 12,   l - 10);
  323. callsign[l - 10] = '';
  324. facilities->source_call = *asc2ax(callsign);
  325. }
  326. if (*p == FAC_CCITT_SRC_NSAP) {
  327. memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN);
  328. memcpy(callsign, p + 12, l - 10);
  329. callsign[l - 10] = '';
  330. facilities->dest_call = *asc2ax(callsign);
  331. }
  332. p   += l + 2;
  333. n   += l + 2;
  334. len -= l + 2;
  335. break;
  336. }
  337. } while (*p != 0x00 && len > 0);
  338. return n;
  339. }
  340. int rose_parse_facilities(unsigned char *p, struct rose_facilities_struct *facilities)
  341. {
  342. int facilities_len, len;
  343. facilities_len = *p++;
  344. if (facilities_len == 0)
  345. return 0;
  346. while (facilities_len > 0) {
  347. if (*p == 0x00) {
  348. facilities_len--;
  349. p++;
  350. switch (*p) {
  351. case FAC_NATIONAL: /* National */
  352. len = rose_parse_national(p + 1, facilities, facilities_len - 1);
  353. facilities_len -= len + 1;
  354. p += len + 1;
  355. break;
  356. case FAC_CCITT: /* CCITT */
  357. len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1);
  358. facilities_len -= len + 1;
  359. p += len + 1;
  360. break;
  361. default:
  362. printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02Xn", *p);
  363. facilities_len--;
  364. p++;
  365. break;
  366. }
  367. }
  368. else break; /* Error in facilities format */
  369. }
  370. return 1;
  371. }
  372. int rose_create_facilities(unsigned char *buffer, rose_cb *rose)
  373. {
  374. unsigned char *p = buffer + 1;
  375. char *callsign;
  376. int len, nb;
  377. /* National Facilities */
  378. if (rose->rand != 0 || rose->source_ndigis == 1 || rose->dest_ndigis == 1) {
  379. *p++ = 0x00;
  380. *p++ = FAC_NATIONAL;
  381. if (rose->rand != 0) {
  382. *p++ = FAC_NATIONAL_RAND;
  383. *p++ = (rose->rand >> 8) & 0xFF;
  384. *p++ = (rose->rand >> 0) & 0xFF;
  385. }
  386. /* Sent before older facilities */
  387. if ((rose->source_ndigis > 0) || (rose->dest_ndigis > 0)) {
  388. int maxdigi = 0;
  389. *p++ = FAC_NATIONAL_DIGIS;
  390. *p++ = AX25_ADDR_LEN * (rose->source_ndigis + rose->dest_ndigis);
  391. for (nb = 0 ; nb < rose->source_ndigis ; nb++) {
  392. if (++maxdigi >= ROSE_MAX_DIGIS)
  393. break;
  394. memcpy(p, &rose->source_digis[nb], AX25_ADDR_LEN);
  395. p[6] |= AX25_HBIT;
  396. p += AX25_ADDR_LEN;
  397. }
  398. for (nb = 0 ; nb < rose->dest_ndigis ; nb++) {
  399. if (++maxdigi >= ROSE_MAX_DIGIS)
  400. break;
  401. memcpy(p, &rose->dest_digis[nb], AX25_ADDR_LEN);
  402. p[6] &= ~AX25_HBIT;
  403. p += AX25_ADDR_LEN;
  404. }
  405. }
  406. /* For compatibility */
  407. if (rose->source_ndigis > 0) {
  408. *p++ = FAC_NATIONAL_SRC_DIGI;
  409. *p++ = AX25_ADDR_LEN;
  410. memcpy(p, &rose->source_digis[0], AX25_ADDR_LEN);
  411. p   += AX25_ADDR_LEN;
  412. }
  413. /* For compatibility */
  414. if (rose->dest_ndigis > 0) {
  415. *p++ = FAC_NATIONAL_DEST_DIGI;
  416. *p++ = AX25_ADDR_LEN;
  417. memcpy(p, &rose->dest_digis[0], AX25_ADDR_LEN);
  418. p   += AX25_ADDR_LEN;
  419. }
  420. }
  421. *p++ = 0x00;
  422. *p++ = FAC_CCITT;
  423. *p++ = FAC_CCITT_DEST_NSAP;
  424. callsign = ax2asc(&rose->dest_call);
  425. *p++ = strlen(callsign) + 10;
  426. *p++ = (strlen(callsign) + 9) * 2; /* ??? */
  427. *p++ = 0x47; *p++ = 0x00; *p++ = 0x11;
  428. *p++ = ROSE_ADDR_LEN * 2;
  429. memcpy(p, &rose->dest_addr, ROSE_ADDR_LEN);
  430. p   += ROSE_ADDR_LEN;
  431. memcpy(p, callsign, strlen(callsign));
  432. p   += strlen(callsign);
  433. *p++ = FAC_CCITT_SRC_NSAP;
  434. callsign = ax2asc(&rose->source_call);
  435. *p++ = strlen(callsign) + 10;
  436. *p++ = (strlen(callsign) + 9) * 2; /* ??? */
  437. *p++ = 0x47; *p++ = 0x00; *p++ = 0x11;
  438. *p++ = ROSE_ADDR_LEN * 2;
  439. memcpy(p, &rose->source_addr, ROSE_ADDR_LEN);
  440. p   += ROSE_ADDR_LEN;
  441. memcpy(p, callsign, strlen(callsign));
  442. p   += strlen(callsign);
  443. len       = p - buffer;
  444. buffer[0] = len - 1;
  445. return len;
  446. }
  447. void rose_disconnect(struct sock *sk, int reason, int cause, int diagnostic)
  448. {
  449. rose_stop_timer(sk);
  450. rose_stop_idletimer(sk);
  451. rose_clear_queues(sk);
  452. sk->protinfo.rose->lci   = 0;
  453. sk->protinfo.rose->state = ROSE_STATE_0;
  454. if (cause != -1)
  455. sk->protinfo.rose->cause = cause;
  456. if (diagnostic != -1)
  457. sk->protinfo.rose->diagnostic = diagnostic;
  458. sk->state     = TCP_CLOSE;
  459. sk->err       = reason;
  460. sk->shutdown |= SEND_SHUTDOWN;
  461. if (!sk->dead)
  462. sk->state_change(sk);
  463. sk->dead  = 1;
  464. }