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

TCP/IP协议栈

开发平台:

Visual C++

  1. #include <errno.h>
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "lapb.h"
  5. #include "ax25.h"
  6. #include "socket.h"
  7. #include "usock.h"
  8. char Ax25_eol[] = "r";
  9. static void autobind(struct usock *up);
  10. /* The following two variables are needed because there can be only one
  11.  * socket listening on each of the AX.25 modes (I and UI)
  12.  */
  13. int Axi_sock = -1; /* Socket number listening for AX25 connections */
  14. static int Axui_sock = -1; /* Socket number listening for AX25 UI frames */
  15. static struct mbuf *Bcq; /* Queue of incoming UI frames */
  16. /* Function that handles incoming UI frames from lapb.c */
  17. void
  18. beac_input(
  19. struct iface *iface,
  20. uint8 *src,
  21. struct mbuf **bpp
  22. ){
  23. struct mbuf *hdr;
  24. struct sockaddr_ax *sax;
  25. if(Axui_sock == -1){
  26. /* Nobody there to read it */
  27. free_p(bpp);
  28. } else {
  29. pushdown(&hdr,NULL,sizeof(struct sockaddr_ax));
  30. sax = (struct sockaddr_ax *)hdr->data;
  31. sax->sax_family = AF_AX25;
  32. memcpy(sax->ax25_addr,src,AXALEN);
  33. strncpy(sax->iface,iface->name,ILEN);
  34. hdr->next = (*bpp);
  35. *bpp = NULL;
  36. enqueue(&Bcq,&hdr);
  37. }
  38. }
  39. int
  40. so_ax_sock(
  41. struct usock *up,
  42. int protocol
  43. ){
  44. return 0;
  45. }
  46. int
  47. so_axui_sock(
  48. struct usock *up,
  49. int protocol
  50. ){
  51. return 0;
  52. }
  53. int
  54. so_axui_bind(
  55. struct usock *up
  56. ){
  57. if(Axui_sock != -1){
  58. errno = EADDRINUSE;
  59. return -1;
  60. }
  61. Axui_sock = up->index;
  62. return 0;
  63. }
  64. int
  65. so_ax_listen(
  66. struct usock *up,
  67. int backlog
  68. ){
  69. struct sockaddr_ax *local;
  70. if(up->name == NULL)
  71. autobind(up);
  72. if(up != itop(Axi_sock)){
  73. errno = EOPNOTSUPP;
  74. return -1;
  75. }
  76. local = (struct sockaddr_ax *)up->name;
  77. up->cb.ax25 = open_ax25(NULL,local->ax25_addr,NULL,
  78.  backlog ? AX_SERVER:AX_PASSIVE,0,
  79.  s_arcall,s_atcall,s_ascall,Axi_sock);
  80. return 0;
  81. }
  82. int
  83. so_ax_conn(
  84. struct usock *up
  85. ){
  86. struct sockaddr_ax *local,*remote,localtmp;
  87. struct ax25_cb *ax25;
  88. struct iface *iface;
  89. int s;
  90. s = up->index;
  91. remote = (struct sockaddr_ax *)up->peername;
  92. if((iface = if_lookup(remote->iface)) == NULL){
  93. errno = EINVAL;
  94. return -1;
  95. }
  96. local = (struct sockaddr_ax *)up->name;
  97. if(local == NULL){
  98. /* The local address was unspecified; set it from
  99.  * the interface we'll use
  100.  */
  101. localtmp.sax_family = AF_AX25;
  102. memcpy(localtmp.ax25_addr,iface->hwaddr,AXALEN);
  103. memcpy(localtmp.iface,remote->iface,ILEN);
  104. bind(s,(struct sockaddr *)&localtmp,sizeof(localtmp));
  105. local = (struct sockaddr_ax *)up->name;
  106. }
  107. /* If we already have an AX25 link we can use it */
  108. if((up->cb.ax25 = find_ax25(remote->ax25_addr)) != NULL
  109.    && up->cb.ax25->state != LAPB_DISCONNECTED &&
  110.    up->cb.ax25->user == -1) {
  111. up->cb.ax25->user = s;
  112. up->cb.ax25->r_upcall = s_arcall;
  113. up->cb.ax25->t_upcall = s_atcall;
  114. up->cb.ax25->s_upcall = s_ascall;
  115. if(up->cb.ax25->state == LAPB_CONNECTED
  116.    || up->cb.ax25->state == LAPB_RECOVERY)
  117.      return 0;
  118. } else {
  119. up->cb.ax25 = open_ax25(iface,local->ax25_addr,
  120.  remote->ax25_addr,AX_ACTIVE,
  121.  Axwindow,s_arcall,s_atcall,s_ascall,s);
  122. }
  123. /* Wait for the connection to complete */
  124. while((ax25 = up->cb.ax25) != NULL && ax25->state != LAPB_CONNECTED){
  125. if(up->noblock){
  126. errno = EWOULDBLOCK;
  127. return -1;
  128. } else if((errno = kwait(up)) != 0){
  129. return -1;
  130. }
  131. }
  132. if(ax25 == NULL){
  133. /* Connection probably already exists */
  134. free(up->peername);
  135. up->peername = NULL;
  136. errno = ECONNREFUSED;
  137. return -1;
  138. }
  139. return 0;
  140. }
  141. int
  142. so_axui_conn(
  143. struct usock *up
  144. ){
  145. if(up->name == NULL)
  146. autobind(up);
  147. return 0;
  148. }
  149. int
  150. so_ax_recv(
  151. struct usock *up,
  152. struct mbuf **bpp,
  153. struct sockaddr *from,
  154. int *fromlen
  155. ){
  156. struct ax25_cb *ax25;
  157. int cnt;
  158. while((ax25 = up->cb.ax25) != NULL
  159.  && (*bpp = recv_ax25(ax25,(uint16)0)) == NULL){
  160. if(up->noblock){
  161. errno = EWOULDBLOCK;
  162. return -1;
  163. } else if((errno = kwait(up)) != 0){
  164. return -1;
  165. }
  166. }
  167. if(ax25 == NULL){
  168. /* Connection went away */
  169. errno = ENOTCONN;
  170. return -1;
  171. }
  172. cnt = (*bpp)->cnt;
  173. return cnt;
  174. }
  175. int
  176. so_axui_recv(
  177. struct usock *up,
  178. struct mbuf **bpp,
  179. struct sockaddr *from,
  180. int *fromlen
  181. ){
  182. int s;
  183. s = up->index;
  184. while(s == Axui_sock && Bcq == NULL){
  185. if(up->noblock){
  186. errno = EWOULDBLOCK;
  187. return -1;
  188. } else if((errno = kwait(&Bcq)) != 0){
  189. return -1;
  190. }
  191. }
  192. if(s != Axui_sock){
  193. errno = ENOTCONN;
  194. return -1;
  195. }
  196. *bpp = dequeue(&Bcq);
  197. if(from != NULL && fromlen != NULL
  198.    && *fromlen >= sizeof(struct sockaddr_ax)){
  199. pullup(bpp,from,sizeof(struct sockaddr_ax));
  200. *fromlen = sizeof(struct sockaddr_ax);
  201. } else {
  202. pullup(bpp,NULL,sizeof(struct sockaddr_ax));
  203. }
  204. return len_p(*bpp);
  205. }
  206. int
  207. so_ax_send(
  208. struct usock *up,
  209. struct mbuf **bpp,
  210. struct sockaddr *to
  211. ){
  212. struct ax25_cb *ax25;
  213. if((ax25 = up->cb.ax25) == NULL){
  214. free_p(bpp);
  215. errno = ENOTCONN;
  216. return -1;
  217. }
  218. send_ax25(ax25,bpp,PID_NO_L3);
  219. while((ax25 = up->cb.ax25) != NULL &&
  220.  len_q(ax25->txq) * ax25->paclen > ax25->window){
  221. if(up->noblock){
  222. errno = EWOULDBLOCK;
  223. return -1;
  224. } else if((errno = kwait(up)) != 0){
  225. return -1;
  226. }
  227. }
  228. if(ax25 == NULL){
  229. errno = EBADF;
  230. return -1;
  231. }
  232. return 0;
  233. }
  234. int
  235. so_axui_send(
  236. struct usock *up,
  237. struct mbuf **bpp,
  238. struct sockaddr *to
  239. ){
  240. struct sockaddr_ax *local,*remote;
  241. local = (struct sockaddr_ax *)up->name;
  242. if(to != NULL)
  243. remote = (struct sockaddr_ax *)to;
  244. else if(up->peername != NULL){
  245. remote = (struct sockaddr_ax *)up->peername;
  246. } else {
  247. free_p(bpp);
  248. errno = ENOTCONN;
  249. return -1;
  250. }
  251. ax_output(if_lookup(remote->iface),remote->ax25_addr,
  252.   local->ax25_addr,PID_NO_L3,bpp);
  253. return 0;
  254. }
  255. int
  256. so_ax_qlen(
  257. struct usock *up,
  258. int rtx
  259. ){
  260. int len;
  261. if(up->cb.ax25 == NULL){
  262. errno = ENOTCONN;
  263. return -1;
  264. }
  265. switch(rtx){
  266. case 0:
  267. len = len_p(up->cb.ax25->rxq);
  268. break;
  269. case 1: /* Number of packets, not bytes */
  270. len = len_q(up->cb.ax25->txq);
  271. }
  272. return len;
  273. }
  274. int
  275. so_axui_qlen(
  276. struct usock *up,
  277. int rtx
  278. ){
  279. int len;
  280. switch(rtx){
  281. case 0:
  282. len = len_q(Bcq);
  283. break;
  284. case 1:
  285. len = 0;
  286. break;
  287. }
  288. return len;
  289. }
  290. int
  291. so_ax_kick(
  292. struct usock *up
  293. ){
  294. if(up->cb.ax25 != NULL)
  295. kick_ax25(up->cb.ax25);
  296. return 0;
  297. }
  298. int
  299. so_ax_shut(
  300. struct usock *up,
  301. int how
  302. ){
  303. if(up->cb.ax25 == NULL)
  304. return 0;
  305. switch(how){
  306. case 0:
  307. case 1: /* Attempt regular disconnect */
  308. disc_ax25(up->cb.ax25);
  309. break;
  310. case 2: /* Blow it away */
  311. reset_ax25(up->cb.ax25);
  312. up->cb.ax25 = NULL;
  313. break;
  314. }
  315. return 0;
  316. }
  317. int
  318. so_ax_close(
  319. struct usock *up
  320. ){
  321. if(up->cb.ax25 != NULL){
  322. /* Tell the CLOSED upcall there's no more socket */
  323. up->cb.ax25->user = -1;
  324. disc_ax25(up->cb.ax25);
  325. }
  326. return 0;
  327. }
  328. int
  329. so_axui_close(
  330. struct usock *up
  331. ){
  332. Axui_sock = -1;
  333. free_q(&Bcq);
  334. ksignal(&Bcq,0); /* Unblock any reads */
  335. return 0;
  336. }
  337. /* AX.25 receive upcall */
  338. void
  339. s_arcall(
  340. struct ax25_cb *axp,
  341. int cnt
  342. ){
  343. int ns;
  344. struct usock *up,*nup,*oup;
  345. union sp sp;
  346. up = itop(axp->user);
  347. /* When AX.25 data arrives for the first time the AX.25 listener
  348.    is notified, if active. If the AX.25 listener is a server its
  349.    socket is duplicated in the same manner as in s_tscall().
  350.  */
  351. if (Axi_sock != -1 && axp->user == -1) {
  352. oup = up = itop(Axi_sock);
  353. /* From now on, use the same upcalls as the listener */
  354. axp->t_upcall = up->cb.ax25->t_upcall;
  355. axp->r_upcall = up->cb.ax25->r_upcall;
  356. axp->s_upcall = up->cb.ax25->s_upcall;
  357. if (up->cb.ax25->flags.clone) {
  358. /* Clone the socket */
  359. ns = socket(AF_AX25,SOCK_STREAM,0);
  360. nup = itop(ns);
  361. ASSIGN(*nup,*up);
  362. axp->user = ns;
  363. nup->cb.ax25 = axp;
  364. /* Allocate new memory for the name areas */
  365. nup->name = mallocw(sizeof(struct sockaddr_ax));
  366. nup->peername = mallocw(sizeof(struct sockaddr_ax));
  367. /* Store the new socket # in the old one */
  368. up->rdysock = ns;
  369. up = nup;
  370. } else {
  371. axp->user = Axi_sock;
  372. del_ax25(up->cb.ax25);
  373. up->cb.ax25 = axp;
  374. /* Allocate space for the peer's name */
  375. up->peername = mallocw(sizeof(struct sockaddr_ax));
  376. /* Store the old socket # in the old socket */
  377. up->rdysock = Axi_sock;
  378. }
  379. /* Load the addresses. Memory for the name has already
  380.  * been allocated, either above or in the original bind.
  381.  */
  382. sp.ax = (struct sockaddr_ax *)up->name;
  383. sp.ax->sax_family = AF_AX25;
  384. memcpy(sp.ax->ax25_addr,axp->local,AXALEN);
  385. memcpy(sp.ax->iface,axp->iface->name,ILEN);
  386. up->namelen = sizeof(struct sockaddr_ax);
  387. sp.ax = (struct sockaddr_ax *)up->peername;
  388. sp.ax->sax_family = AF_AX25;
  389. memcpy(sp.ax->ax25_addr,axp->remote,AXALEN);
  390. memcpy(sp.ax->iface,axp->iface->name,ILEN);
  391. up->peernamelen = sizeof(struct sockaddr_ax);
  392. /* Wake up the guy accepting it, and let him run */
  393. ksignal(oup,1);
  394. kwait(NULL);
  395. return;
  396. }
  397. /* Wake up anyone waiting, and let them run */
  398. ksignal(up,1);
  399. kwait(NULL);
  400. }
  401. /* AX.25 transmit upcall */
  402. void
  403. s_atcall(
  404. struct ax25_cb *axp,
  405. int cnt
  406. ){
  407. /* Wake up anyone waiting, and let them run */
  408. ksignal(itop(axp->user),1);
  409. kwait(NULL);
  410. }
  411. /* AX25 state change upcall routine */
  412. void
  413. s_ascall(
  414. register struct ax25_cb *axp,
  415. int old,
  416. int new
  417. ){
  418. int s;
  419. struct usock *up;
  420. s = axp->user;
  421. up = itop(s);
  422. switch(new){
  423. case LAPB_DISCONNECTED:
  424. /* Clean up. If the user has already closed the socket,
  425.  * then up will be null (s was set to -1 by the close routine).
  426.  * If not, then this is an abnormal close (e.g., a reset)
  427.  * and clearing out the pointer in the socket structure will
  428.  * prevent any further operations on what will be a freed
  429.  * control block. Also wake up anybody waiting on events
  430.  * related to this block so they will notice it disappearing.
  431.  */
  432. if(up != NULL){
  433. up->errcodes[0] = axp->reason;
  434. up->cb.ax25 = NULL;
  435. }
  436. del_ax25(axp);
  437. break;
  438. default: /* Other transitions are ignored */
  439. break;
  440. }
  441. ksignal(up,0); /* In case anybody's waiting */
  442. }
  443. /* Issue an automatic bind of a local AX25 address */
  444. static void
  445. autobind(
  446. struct usock *up
  447. ){
  448. struct sockaddr_ax local;
  449. int s;
  450. s = up->index;
  451. local.sax_family = AF_AX25;
  452. memcpy(local.ax25_addr,Mycall,AXALEN);
  453. bind(s,(struct sockaddr *)&local,sizeof(struct sockaddr_ax));
  454. }
  455. int
  456. checkaxaddr(
  457. struct sockaddr *name,
  458. int namelen
  459. ){
  460. struct sockaddr_ax *sock;
  461. sock = (struct sockaddr_ax *)name;
  462. if(sock->sax_family != AF_AX25 || namelen != sizeof(struct sockaddr_ax))
  463. return -1;
  464. return 0;
  465. }
  466. char *
  467. axpsocket(
  468. struct sockaddr *p
  469. ){
  470. struct sockaddr_ax *axp;
  471. static char buf[30];
  472. char tmp[11];
  473. axp = (struct sockaddr_ax *)p;
  474. pax25(tmp,axp->ax25_addr);
  475. if(strlen(axp->iface) != 0)
  476. sprintf(buf,"%s on %s",tmp,axp->iface);
  477. else
  478. strcpy(buf,tmp);
  479. return buf;
  480. }
  481. char *
  482. axstate(
  483. struct usock *up
  484. ){
  485. return Ax25states[up->cb.ax25->state];
  486. }
  487. so_ax_stat(
  488. struct usock *up
  489. ){
  490. st_ax25(up->cb.ax25);
  491. return 0;
  492. }