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

TCP/IP协议栈

开发平台:

Visual C++

  1. #include <errno.h>
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "ax25.h"
  5. #include "netrom.h"
  6. #include "nr4.h"
  7. #include "socket.h"
  8. #include "usock.h"
  9. static void autobind(struct usock *up);
  10. static void s_nrcall(struct nr4cb *cb,uint16 cnt);
  11. static void s_nscall(struct nr4cb *cb,int old,int new);
  12. static void s_ntcall(struct nr4cb *cb,uint16 cnt);
  13. int
  14. so_n3_sock(up,protocol)
  15. struct usock *up;
  16. int protocol;
  17. {
  18. up->cb.rnr = raw_nr((char)protocol);
  19. return 0;
  20. }
  21. int
  22. so_n4_sock(up,protocol)
  23. struct usock *up;
  24. int protocol;
  25. {
  26. return 0;
  27. }
  28. int
  29. so_n4_listen(up,backlog)
  30. struct usock *up;
  31. int backlog;
  32. {
  33. struct sockaddr_nr *local;
  34. int s;
  35. s = up->index;
  36. if(up->name == NULL)
  37. autobind(up);
  38. local = (struct sockaddr_nr *)up->name;
  39. up->cb.nr4 = open_nr4(&local->nr_addr,NULL,
  40.  backlog ? AX_SERVER:AX_PASSIVE,s_nrcall,s_ntcall,s_nscall,s);
  41. return 0;
  42. }
  43. int
  44. so_n3_conn(up)
  45. struct usock *up;
  46. {
  47. if(up->name != NULL)
  48. autobind(up);
  49. return 0;
  50. }
  51. int
  52. so_n4_conn(up)
  53. struct usock *up;
  54. {
  55. struct sockaddr_nr *local,*remote;
  56. struct nr4cb *nr4;
  57. int s;
  58. s = up->index;
  59. if(up->name != NULL)
  60. autobind(up);
  61. local = (struct sockaddr_nr *)up->name;
  62. remote = (struct sockaddr_nr *)up->peername;
  63. up->cb.nr4 = open_nr4(&local->nr_addr,&remote->nr_addr,
  64.  AX_ACTIVE,s_nrcall,s_ntcall,s_nscall,s);
  65. /* Wait for the connection to complete */
  66. while((nr4 = up->cb.nr4) != NULL && nr4->state != NR4STCON){
  67. if(up->noblock){
  68. errno = EWOULDBLOCK;
  69. return -1;
  70. } else if((errno = kwait(up)) != 0){
  71. return -1;
  72. }
  73. }
  74. if(nr4 == NULL){
  75. /* Connection probably already exists */
  76. free(up->peername);
  77. up->peername = NULL;
  78. errno = ECONNREFUSED;
  79. return -1;
  80. }
  81. return 0;
  82. }
  83. int
  84. so_n3_recv(up,bpp,from,fromlen)
  85. struct usock *up;
  86. struct mbuf **bpp;
  87. struct sockaddr *from;
  88. int *fromlen;
  89. {
  90. int cnt;
  91. struct raw_nr *rnr;
  92. struct sockaddr_nr *remote;
  93. struct nr3hdr n3hdr;
  94. while((rnr = up->cb.rnr) != NULL
  95.  && rnr->rcvq == NULL){
  96. if(up->noblock){
  97. errno = EWOULDBLOCK;
  98. return -1;
  99. } else if((errno = kwait(up)) != 0){
  100. return -1;
  101. }
  102. }
  103. if(rnr == NULL){
  104. /* Connection went away */
  105. errno = ENOTCONN;
  106. return -1;
  107. }
  108. *bpp = dequeue(&rnr->rcvq);
  109. ntohnr3(&n3hdr,bpp);
  110. cnt = len_p(*bpp);
  111. if(from != NULL && fromlen != NULL
  112.    && *fromlen >= sizeof(struct sockaddr_nr)){
  113. remote = (struct sockaddr_nr *)from;
  114. remote->nr_family = AF_NETROM;
  115. /* The callsign of the local user is not part of
  116.    NET/ROM level 3, so that field is not used here */
  117. memcpy(remote->nr_addr.node,n3hdr.source,AXALEN);
  118. *fromlen = sizeof(struct sockaddr_nr);
  119. }
  120. return cnt;
  121. }
  122. int
  123. so_n4_recv(up,bpp,from,fromlen)
  124. struct usock *up;
  125. struct mbuf **bpp;
  126. struct sockaddr *from;
  127. int *fromlen;
  128. {
  129. struct nr4cb *nr4;
  130. while((nr4 = up->cb.nr4) != NULL
  131.  && (*bpp = recv_nr4(nr4,(uint16)0)) == NULL){
  132. if(up->noblock){
  133. errno = EWOULDBLOCK;
  134. return -1;
  135. } else if((errno = kwait(up)) != 0){
  136. return -1;
  137. }
  138. }
  139. if(nr4 == NULL){
  140. /* Connection went away */
  141. errno = ENOTCONN;
  142. return -1;
  143. }
  144. return (*bpp)->cnt;
  145. }
  146. int
  147. so_n3_send(
  148. struct usock *up,
  149. struct mbuf **bpp,
  150. struct sockaddr *to
  151. ){
  152. struct sockaddr_nr *remote;
  153. if(len_p(*bpp) > NR4MAXINFO) {
  154. free_p(bpp);
  155. errno = EMSGSIZE;
  156. return -1;
  157. }
  158. if(to != NULL) {
  159. remote = (struct sockaddr_nr *)to;
  160. } else if(up->peername != NULL) {
  161. remote = (struct sockaddr_nr *)up->peername;
  162. } else {
  163. free_p(bpp);
  164. errno = ENOTCONN;
  165. return -1;
  166. }
  167. /* The NETROM username is always ignored in outgoing traffic */
  168. nr_sendraw(remote->nr_addr.node,up->cb.rnr->protocol,
  169.  up->cb.rnr->protocol,bpp);
  170. return 0;
  171. }
  172. int
  173. so_n4_send(
  174. struct usock *up,
  175. struct mbuf **bpp,
  176. struct sockaddr *to
  177. ){
  178. struct nr4cb *nr4;
  179. if((nr4 = up->cb.nr4) == NULL) {
  180. free_p(bpp);
  181. errno = ENOTCONN;
  182. return -1;
  183. }
  184. if(len_p(*bpp) > NR4MAXINFO){ /* reject big packets */
  185. free_p(bpp);
  186. errno = EMSGSIZE;
  187. return -1;
  188. }
  189. send_nr4(nr4,bpp);
  190. while((nr4 = up->cb.nr4) != NULL && nr4->nbuffered >= nr4->window){
  191. if(up->noblock){
  192. errno = EWOULDBLOCK;
  193. return -1;
  194. } else if((errno = kwait(up)) != 0){
  195. return -1;
  196. }
  197. }
  198. if(nr4 == NULL){
  199. errno = EBADF;
  200. return -1;
  201. }
  202. return 0;
  203. }
  204. int
  205. so_n3_qlen(up,rtx)
  206. struct usock *up;
  207. int rtx;
  208. {
  209. int len;
  210. switch(rtx){
  211. case 0:
  212. len = len_q(up->cb.rnr->rcvq);
  213. break;
  214. case 1:
  215. len = 0;
  216. }
  217. return len;
  218. }
  219. int
  220. so_n4_qlen(up,rtx)
  221. struct usock *up;
  222. int rtx;
  223. {
  224. int len;
  225. switch(rtx){
  226. case 0:
  227. len = len_p(up->cb.nr4->rxq);
  228. break;
  229. case 1: /* Number of packets, not bytes */
  230. len = len_q(up->cb.nr4->txq);
  231. break;
  232. }
  233. return len;
  234. }
  235. int
  236. so_n4_kick(up)
  237. struct usock *up;
  238. {
  239. if(up->cb.nr4 == NULL){
  240. errno = ENOTCONN;
  241. return -1;
  242. }
  243. kick_nr4(up->cb.nr4);
  244. return 0;
  245. }
  246. int
  247. so_n4_shut(up,how)
  248. struct usock *up;
  249. int how;
  250. {
  251. switch(how){
  252. case 0:
  253. case 1: /* Attempt regular disconnect */
  254. disc_nr4(up->cb.nr4);
  255. break;
  256. case 2: /* Blow it away */
  257. reset_nr4(up->cb.nr4);
  258. up->cb.nr4 = NULL;
  259. break;
  260. }
  261. return 0;
  262. }
  263. int
  264. so_n3_close(up)
  265. struct usock *up;
  266. {
  267. del_rnr(up->cb.rnr);
  268. return 0;
  269. }
  270. int
  271. so_n4_close(up)
  272. struct usock *up;
  273. {
  274. if(up->cb.nr4 != NULL){
  275. /* Tell the TCP_CLOSED upcall there's no more socket */
  276. up->cb.nr4->user = -1;
  277. disc_nr4(up->cb.nr4);
  278. }
  279. return 0;
  280. }
  281. /* Issue an automatic bind of a local NETROM address */
  282. static void
  283. autobind(up)
  284. struct usock *up;
  285. {
  286. struct sockaddr_nr local;
  287. int s;
  288. s = up->index;
  289. local.nr_family = AF_NETROM;
  290. memcpy(local.nr_addr.user,Mycall,AXALEN);
  291. memcpy(local.nr_addr.node,Mycall,AXALEN);
  292. bind(s,(struct sockaddr *)&local,sizeof(struct sockaddr_nr));
  293. }
  294. /* NET/ROM receive upcall routine */
  295. static void
  296. s_nrcall(cb,cnt)
  297. struct nr4cb *cb;
  298. uint16 cnt;
  299. {
  300. /* Wake up anybody waiting for data, and let them run */
  301. ksignal(itop(cb->user),1);
  302. kwait(NULL);
  303. }
  304. /* NET/ROM transmit upcall routine */
  305. static void
  306. s_ntcall(cb,cnt)
  307. struct nr4cb *cb;
  308. uint16 cnt;
  309. {
  310. /* Wake up anybody waiting to send data, and let them run */
  311. ksignal(itop(cb->user),1);
  312. kwait(NULL);
  313. }
  314. /* NET/ROM state change upcall routine */
  315. static void
  316. s_nscall(cb,old,new)
  317. struct nr4cb *cb;
  318. int old,new;
  319. {
  320. int s,ns;
  321. struct usock *up,*nup,*oup;
  322. union sp sp;
  323. s = cb->user;
  324. oup = up = itop(s);
  325.   if(new == NR4STDISC && up != NULL){
  326. /* Clean up. If the user has already closed the socket,
  327.  * then up will be null (s was set to -1 by the close routine).
  328.  * If not, then this is an abnormal close (e.g., a reset)
  329.  * and clearing out the pointer in the socket structure will
  330.  * prevent any further operations on what will be a freed
  331.  * control block. Also wake up anybody waiting on events
  332.  * related to this cb so they will notice it disappearing.
  333.  */
  334.   up->cb.nr4 = NULL;
  335.   up->errcodes[0] = cb->dreason;
  336.   }
  337.   if(new == NR4STCON && old == NR4STDISC){
  338. /* Handle an incoming connection. If this is a server cb,
  339.  * then we're being handed a "clone" cb and we need to
  340.  * create a new socket structure for it. In either case,
  341.  * find out who we're talking to and wake up the guy waiting
  342.  * for the connection.
  343.  */
  344. if(cb->clone){
  345. /* Clone the socket */
  346. ns = socket(AF_NETROM,SOCK_SEQPACKET,0);
  347. nup = itop(ns);
  348. ASSIGN(*nup,*up);
  349. cb->user = ns;
  350. nup->cb.nr4 = cb;
  351. cb->clone = 0; /* to avoid getting here again */
  352. /* Allocate new memory for the name areas */
  353. nup->name = mallocw(sizeof(struct sockaddr_nr));
  354. nup->peername = mallocw(sizeof(struct sockaddr_nr));
  355. /* Store the new socket # in the old one */
  356. up->rdysock = ns;
  357. up = nup;
  358. s = ns;
  359. } else {
  360. /* Allocate space for the peer's name */
  361. up->peername = mallocw(sizeof(struct sockaddr_nr));
  362. /* Store the old socket # in the old socket */
  363. up->rdysock = s;
  364. }
  365. /* Load the addresses. Memory for the name has already
  366.  * been allocated, either above or in the original bind.
  367.  */
  368. sp.sa = up->name;
  369. sp.nr->nr_family = AF_NETROM;
  370. ASSIGN(sp.nr->nr_addr,up->cb.nr4->local);
  371. up->namelen = sizeof(struct sockaddr_nr);
  372. sp.sa = up->peername;
  373. sp.nr->nr_family = AF_NETROM;
  374. ASSIGN(sp.nr->nr_addr,up->cb.nr4->remote);
  375. up->peernamelen = sizeof(struct sockaddr_nr);
  376. /* Wake up the guy accepting it, and let him run */
  377. ksignal(oup,1);
  378. kwait(NULL);
  379. }
  380.   /* Ignore all other state transitions */
  381. ksignal(up,0); /* In case anybody's waiting */
  382. }
  383. int
  384. checknraddr(name,namelen)
  385. struct sockaddr *name;
  386. int namelen;
  387. {
  388. struct sockaddr_nr *sock;
  389. sock = (struct sockaddr_nr *)name;
  390. if(sock->nr_family != AF_NETROM || namelen != sizeof(struct sockaddr_nr))
  391. return -1;
  392. return 0;
  393. }
  394. char *
  395. nrpsocket(p)
  396. struct sockaddr *p;
  397. {
  398. struct sockaddr_nr *nrp;
  399. static char buf[30];
  400. char tmp[11];
  401. nrp = (struct sockaddr_nr *)p;
  402. pax25(tmp,nrp->nr_addr.user);
  403. sprintf(buf,"%s @ ",tmp);
  404. pax25(tmp,nrp->nr_addr.node);
  405. strcat(buf,tmp);
  406. return buf;
  407. }
  408. char *
  409. nrstate(up)
  410. struct usock *up;
  411. {
  412. return Nr4states[up->cb.nr4->state];
  413. }
  414. int
  415. so_n4_stat(up)
  416. struct usock *up;
  417. {
  418. donrdump(up->cb.nr4);
  419. return 0;
  420. }