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

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Application programming interface routines - based loosely on the
  2.  * "socket" model in Berkeley UNIX.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include <stdio.h>
  7. #ifdef __STDC__
  8. #include <stdarg.h>
  9. #endif
  10. #include <errno.h>
  11. #include "global.h"
  12. #include "mbuf.h"
  13. #include "netuser.h"
  14. #include "proc.h"
  15. #include "lzw.h"
  16. #include "usock.h"
  17. #include "socket.h"
  18. char *Socktypes[] = {
  19. "Not Used",
  20. "TCP",
  21. "UDP",
  22. "AX25 I",
  23. "AX25 UI",
  24. "Raw IP",
  25. "NETROM3",
  26. "NETROM",
  27. "Loc St",
  28. "Loc Dg"
  29. };
  30. char *Sock_errlist[] = {
  31. "operation would block",
  32. "not connected",
  33. "socket type not supported",
  34. "address family not supported",
  35. "is connected",
  36. "operation not supported",
  37. "alarm",
  38. "abort",
  39. "interrupt",
  40. "connection refused",
  41. "message size",
  42. "address in use"
  43. };
  44. char Badsocket[] = "Bad socket";
  45. struct usock **Usock; /* Socket entry array */
  46. /* Initialize user socket array */
  47. void
  48. sockinit(void)
  49. {
  50. if(Usock != (struct usock **)NULL)
  51. return; /* Already initialized */
  52. Usock = (struct usock **)callocw(Nsock,sizeof(struct usock *));
  53. }
  54. /* Create a user socket, return socket index
  55.  * The mapping to actual protocols is as follows:
  56.  *
  57.  *
  58.  * ADDRESS FAMILY Stream Datagram Raw     Seq. Packet
  59.  *
  60.  * AF_INET TCP UDP IP
  61.  * AF_AX25 I-frames UI-frames
  62.  * AF_NETROM NET/ROM L3  NET/ROM L4
  63.  * AF_LOCAL stream loopback packet loopback
  64.  */
  65. int
  66. socket(
  67. int af, /* Address family */
  68. int type, /* Stream or datagram */
  69. int protocol /* Used for raw IP sockets */
  70. ){
  71. register struct usock *up;
  72. struct socklink *sp;
  73. int s;
  74. for(s=0;s<Nsock;s++)
  75. if(Usock[s] == NULL)
  76. break;
  77. if(s == Nsock){
  78. errno = EMFILE;
  79. return -1;
  80. }
  81. Usock[s] = up = (struct usock *)calloc(1,sizeof(struct usock));
  82. s =_mk_fd(s,_FL_SOCK);
  83. up->index = s;
  84. up->refcnt = 1;
  85. errno = 0;
  86. up->rdysock = -1;
  87. up->owner = Curproc;
  88. switch(af){
  89. case AF_LOCAL:
  90. switch(type){
  91. case SOCK_STREAM:
  92. up->type = TYPE_LOCAL_STREAM;
  93. break;
  94. case SOCK_DGRAM:
  95. up->type = TYPE_LOCAL_DGRAM;
  96. break;
  97. default:
  98. errno = ESOCKTNOSUPPORT;
  99. break;
  100. }
  101. break;
  102. case AF_AX25:
  103. switch(type){
  104. case SOCK_STREAM:
  105. up->type = TYPE_AX25I;
  106. break;
  107. case SOCK_DGRAM:
  108. up->type = TYPE_AX25UI;
  109. break;
  110. default:
  111. errno = ESOCKTNOSUPPORT;
  112. break;
  113. }
  114. break;
  115. case AF_NETROM:
  116. switch(type){
  117. case SOCK_RAW:
  118. up->type = TYPE_NETROML3;
  119. break;
  120. case SOCK_SEQPACKET:
  121. up->type = TYPE_NETROML4;
  122. break;
  123. default:
  124. errno = ESOCKTNOSUPPORT;
  125. break;
  126. }
  127. break;
  128. case AF_INET:
  129. switch(type){
  130. case SOCK_STREAM:
  131. up->type = TYPE_TCP;
  132. break;
  133. case SOCK_DGRAM:
  134. up->type = TYPE_UDP;
  135. break;
  136. case SOCK_RAW:
  137. up->type = TYPE_RAW;
  138. break;
  139. default:
  140. errno = ESOCKTNOSUPPORT;
  141. break;
  142. }
  143. break;
  144. default:
  145. errno = EAFNOSUPPORT;
  146. break;
  147. }
  148. /* Look for entry in protocol table */
  149. for(sp = Socklink;sp->type != -1;sp++){
  150. if(up->type == sp->type)
  151. break;
  152. }
  153. up->sp = sp;
  154. if(sp->type == -1 || sp->socket == NULL
  155.   ||(*sp->socket)(up,protocol) == -1){
  156. errno = ESOCKTNOSUPPORT;
  157. return -1;
  158. }
  159. return s;
  160. }
  161. /* Attach a local address/port to a socket. If not issued before a connect
  162.  * or listen, will be issued automatically
  163.  */
  164. int
  165. bind(
  166. int s, /* Socket index */
  167. struct sockaddr *name, /* Local name */
  168. int namelen /* Length of name */
  169. ){
  170. register struct usock *up;
  171. struct socklink *sp;
  172. if((up = itop(s)) == NULL){
  173. errno = EBADF;
  174. return -1;
  175. }
  176. if(name == NULL){
  177. errno = EFAULT;
  178. return -1;
  179. }
  180. if(up->name != NULL){
  181. /* Bind has already been issued */
  182. errno = EINVAL;
  183. return -1;
  184. }
  185. sp = up->sp;
  186. if(sp->check != NULL && (*sp->check)(name,namelen) == -1){
  187. /* Incorrect length or family for chosen protocol */
  188. errno = EAFNOSUPPORT;
  189. return -1;
  190. }
  191. /* Stash name in an allocated block */
  192. up->namelen = namelen;
  193. up->name = mallocw(namelen);
  194. memcpy(up->name,name,namelen);
  195. /* a bind routine is optional - don't fail if it isn't present */
  196. if(sp->bind != NULL && (*sp->bind)(up) == -1){
  197. errno = EOPNOTSUPP;
  198. return -1;
  199. }
  200. return 0;
  201. }
  202. /* Post a listen on a socket */
  203. int
  204. listen(
  205. int s, /* Socket index */
  206. int backlog /* 0 for a single connection, !=0 for multiple connections */
  207. ){
  208. register struct usock *up;
  209. struct socklink *sp;
  210. if((up = itop(s)) == NULL){
  211. errno = EBADF;
  212. return -1;
  213. }
  214. if(up->cb.p != NULL){
  215. errno = EISCONN;
  216. return -1;
  217. }
  218. sp = up->sp;
  219. /* Fail if listen routine isn't present */
  220. if(sp->listen == NULL || (*sp->listen)(up,backlog) == -1){
  221. errno = EOPNOTSUPP;
  222. return -1;
  223. }
  224. return 0;
  225. }
  226. /* Initiate active open. For datagram sockets, merely bind the remote address. */
  227. int
  228. connect(
  229. int s, /* Socket index */
  230. struct sockaddr *peername, /* Peer name */
  231. int peernamelen /* Length of peer name */
  232. ){
  233. register struct usock *up;
  234. struct socklink *sp;
  235. if((up = itop(s)) == NULL){
  236. errno = EBADF;
  237. return -1;
  238. }
  239. if(peername == NULL){
  240. /* Connect must specify a remote address */
  241. errno = EFAULT;
  242. return -1;
  243. }
  244. sp = up->sp;
  245. /* Check name format, if checking routine is available */
  246. if(sp->check != NULL && (*sp->check)(peername,peernamelen) == -1){
  247. errno = EAFNOSUPPORT;
  248. return -1;
  249. }
  250. if(up->peername != NULL)
  251. free(up->peername);
  252. up->peername = mallocw(peernamelen);
  253. memcpy(up->peername,peername,peernamelen);
  254. up->peernamelen = peernamelen;
  255. /* a connect routine is optional - don't fail if it isn't present */
  256. if(sp->connect != NULL && (*sp->connect)(up) == -1){
  257. return -1;
  258. }
  259. return 0;
  260. }
  261. /* Wait for a connection. Valid only for connection-oriented sockets. */
  262. int
  263. accept(
  264. int s, /* Socket index */
  265. struct sockaddr *peername, /* Peer name */
  266. int *peernamelen /* Length of peer name */
  267. ){
  268. int i;
  269. register struct usock *up;
  270. struct socklink *sp;
  271. if((up = itop(s)) == NULL){
  272. errno = EBADF;
  273. return -1;
  274. }
  275. if(up->cb.p == NULL){
  276. errno = EOPNOTSUPP;
  277. return -1;
  278. }
  279. sp = up->sp;
  280. /* Fail if accept flag isn't set */
  281. if(sp->accept == FALSE){
  282. errno = EOPNOTSUPP;
  283. return -1;
  284. }
  285. /* Wait for the state-change upcall routine to signal us */
  286. while(up->cb.p != NULL && up->rdysock == -1){
  287. if(up->noblock){
  288. errno = EWOULDBLOCK;
  289. return -1;
  290. } else if((errno = kwait(up)) != 0){
  291. return -1;
  292. }
  293. }
  294. if(up->cb.p == NULL){
  295. /* Blown away */
  296. errno = EBADF;
  297. return -1;
  298. }
  299. i = up->rdysock;
  300. up->rdysock = -1;
  301. up = itop(i);
  302. if(peername != NULL && peernamelen != NULL){
  303. *peernamelen = min(up->peernamelen,*peernamelen);
  304. memcpy(peername,up->peername,*peernamelen);
  305. }
  306. return i;
  307. }
  308. /* Low-level receive routine. Passes mbuf back to user; more efficient than
  309.  * higher-level functions recv() and recvfrom(). Datagram sockets ignore
  310.  * the len parameter.
  311.  */
  312. int
  313. recv_mbuf(
  314. int s, /* Socket index */
  315. struct mbuf **bpp, /* Place to stash receive buffer */
  316. int flags, /* Unused; will control out-of-band data, etc */
  317. struct sockaddr *from, /* Peer address (only for datagrams) */
  318. int *fromlen /* Length of peer address */
  319. ){
  320. register struct usock *up;
  321. struct socklink *sp;
  322. if((up = itop(s)) == NULL){
  323. errno = EBADF;
  324. return -1;
  325. }
  326. sp = up->sp;
  327. /* Fail if recv routine isn't present */
  328. if(sp->recv == NULL){
  329. errno = EOPNOTSUPP;
  330. return -1;
  331. }
  332. return (*sp->recv)(up,bpp,from,fromlen);
  333. }
  334. /* Low level send routine; user supplies mbuf for transmission. More
  335.  * efficient than send() or sendto(), the higher level interfaces.
  336.  * The "to" and "tolen" parameters are ignored on connection-oriented
  337.  * sockets.
  338.  *
  339.  * In case of error, bp is freed so the caller doesn't have to worry about it.
  340.  */
  341. int
  342. send_mbuf(
  343. int s, /* Socket index */
  344. struct mbuf **bpp, /* Buffer to send */
  345. int flags, /* not currently used */
  346. struct sockaddr *to, /* Destination, only for datagrams */
  347. int tolen /* Length of destination */
  348. ){
  349. register struct usock *up;
  350. int cnt;
  351. struct socklink *sp;
  352. if((up = itop(s)) == NULL){
  353. free_p(bpp);
  354. errno = EBADF;
  355. return -1;
  356. }
  357. sp = up->sp;
  358. /* Fail if send routine isn't present (shouldn't happen) */
  359. if(sp->send == NULL){
  360. free_p(bpp);
  361. return -1;
  362. }
  363. /* If remote address is supplied, check it */
  364. if(to != NULL && (sp->check != NULL)
  365.  && (*sp->check)(to,tolen) == -1){
  366. free_p(bpp);
  367. errno = EAFNOSUPPORT;
  368. return -1;
  369. }
  370. /* The proto send routine is expected to free the buffer
  371.  * we pass it even if the send fails
  372.  */
  373. if((cnt = (*sp->send)(up,bpp,to)) == -1){
  374. errno = EOPNOTSUPP;
  375. return -1;
  376. }
  377. return cnt;
  378. }
  379. /* Return local name passed in an earlier bind() call */
  380. int
  381. getsockname(
  382. int s, /* Socket index */
  383. struct sockaddr *name, /* Place to stash name */
  384. int *namelen /* Length of same */
  385. ){
  386. register struct usock *up;
  387. if((up = itop(s)) == NULL){
  388. errno = EBADF;
  389. return -1;
  390. }
  391. if(name == NULL || namelen == (int *)NULL){
  392. errno = EFAULT;
  393. return -1;
  394. }
  395. if(up->name == NULL){
  396. /* Not bound yet */
  397. *namelen = 0;
  398. return 0;
  399. }
  400. if(up->name != NULL){
  401. *namelen = min(*namelen,up->namelen);
  402. memcpy(name,up->name,*namelen);
  403. }
  404. return 0;
  405. }
  406. /* Get remote name, returning result of earlier connect() call. */
  407. int
  408. getpeername(
  409. int s, /* Socket index */
  410. struct sockaddr *peername, /* Place to stash name */
  411. int *peernamelen /* Length of same */
  412. ){
  413. register struct usock *up;
  414. if((up = itop(s)) == NULL){
  415. errno = EBADF;
  416. return -1;
  417. }
  418. if(up->peername == NULL){
  419. errno = ENOTCONN;
  420. return -1;
  421. }
  422. if(peername == NULL || peernamelen == (int *)NULL){
  423. errno = EFAULT;
  424. return -1;
  425. }
  426. *peernamelen = min(*peernamelen,up->peernamelen);
  427. memcpy(peername,up->peername,*peernamelen);
  428. return 0;
  429. }
  430. /* Return length of protocol queue, either send or receive. */
  431. int
  432. socklen(
  433. int s, /* Socket index */
  434. int rtx /* 0 = receive queue, 1 = transmit queue */
  435. ){
  436. register struct usock *up;
  437. struct socklink *sp;
  438. int len = -1;
  439. if((up = itop(s)) == NULL){
  440. errno = EBADF;
  441. return -1;
  442. }
  443. if(up->cb.p == NULL){
  444. errno = ENOTCONN;
  445. return -1;
  446. }
  447. if(rtx < 0 || rtx > 1){
  448. errno = EINVAL;
  449. return -1;
  450. }
  451. sp = up->sp;
  452. /* Fail if qlen routine isn't present */
  453. if(sp->qlen == NULL || (len = (*sp->qlen)(up,rtx)) == -1){
  454. errno = EOPNOTSUPP;
  455. return -1;
  456. }
  457. return len;
  458. }
  459. /* Force retransmission. Valid only for connection-oriented sockets. */
  460. int
  461. sockkick(
  462. int s /* Socket index */
  463. ){
  464. register struct usock *up;
  465. struct socklink *sp;
  466. if((up = itop(s)) == NULL){
  467. errno = EBADF;
  468. return -1;
  469. }
  470. sp = up->sp;
  471. /* Fail if kick routine isn't present */
  472. if(sp->kick == NULL){
  473. errno = EOPNOTSUPP;
  474. return -1;
  475. }
  476.   if((*sp->kick)(up) == -1)
  477. return -1;
  478. return 0;
  479. }
  480. /* Change owner of socket, return previous owner */
  481. struct proc *
  482. sockowner(
  483. int s, /* Socket index */
  484. struct proc *newowner /* Process table address of new owner */
  485. ){
  486. register struct usock *up;
  487. struct proc *pp;
  488. if((up = itop(s)) == NULL){
  489. errno = EBADF;
  490. return NULL;
  491. }
  492. pp = up->owner;
  493. if(newowner != NULL)
  494. up->owner = newowner;
  495. return pp;
  496. }
  497. /* Close down a socket three ways. Type 0 means "no more receives"; this
  498.  * replaces the incoming data upcall with a routine that discards further
  499.  * data. Type 1 means "no more sends", and obviously corresponds to sending
  500.  * a TCP FIN. Type 2 means "no more receives or sends". This I interpret
  501.  * as "abort the connection".
  502.  */
  503. int
  504. shutdown(
  505. int s, /* Socket index */
  506. int how /* (see above) */
  507. ){
  508. register struct usock *up;
  509. struct socklink *sp;
  510. if((up = itop(s)) == NULL){
  511. errno = EBADF;
  512. return -1;
  513. }
  514. if(up->cb.p == NULL){
  515. errno = ENOTCONN;
  516. return -1;
  517. }
  518. sp = up->sp;
  519. /* Just close the socket if special shutdown routine not present */
  520. if(sp->shut == NULL){
  521. close_s(s);
  522. } else if((*sp->shut)(up,how) == -1){
  523. return -1;
  524. }
  525. ksignal(up,0);
  526. return 0;
  527. }
  528. /* Close a socket, freeing it for reuse. Try to do a graceful close on a
  529.  * TCP socket, if possible
  530.  */
  531. int
  532. close_s(
  533. int s /* Socket index */
  534. ){
  535. register struct usock *up;
  536. struct socklink *sp;
  537. if((up = itop(s)) == NULL){
  538. errno = EBADF;
  539. return -1;
  540. }
  541. if(--up->refcnt > 0)
  542. return 0; /* Others are still using it */
  543. /* Call proto-specific close routine if there is one */
  544. if((sp = up->sp) != NULL && sp->close != NULL)
  545. (*sp->close)(up);
  546. free(up->name);
  547. free(up->peername);
  548. ksignal(up,0); /* Wake up anybody doing an accept() or recv() */
  549. Usock[_fd_seq(up->index)] = NULL;
  550. free(up);
  551. return 0;
  552. }
  553. /* Increment reference count for specified socket */
  554. int
  555. usesock(int s)
  556. {
  557. struct usock *up;
  558. if((up = itop(s)) == NULL){
  559. errno = EBADF;
  560. return -1;
  561. }
  562. up->refcnt++;
  563. return 0;
  564. }
  565. /* Blow away all sockets belonging to a certain process. Used by killproc(). */
  566. void
  567. freesock(struct proc *pp)
  568. {
  569. register struct usock *up;
  570. register int i;
  571. for(i=0;i < Nsock;i++){
  572. up = Usock[i];
  573. if(up != NULL && up->type != NOTUSED && up->owner == pp)
  574. shutdown(i,2);
  575. }
  576. }
  577. /* Set Internet type-of-service to be used */
  578. int
  579. settos(int s, int tos)
  580. {
  581. struct usock *up;
  582. if((up = itop(s)) == NULL){
  583. errno = EBADF;
  584. return -1;
  585. }
  586. up->tos = tos;
  587. return 0;
  588. }
  589. /* Return a pair of mutually connected sockets in sv[0] and sv[1] */
  590. int
  591. socketpair(
  592. int af,
  593. int type,
  594. int protocol,
  595. int sv[]
  596. ){
  597. struct usock *up0, *up1;
  598. if(sv == NULL){
  599. errno = EFAULT;
  600. return -1;
  601. }
  602. if(af != AF_LOCAL){
  603. errno = EAFNOSUPPORT;
  604. return -1;
  605. }
  606. if(type != SOCK_STREAM && type != SOCK_DGRAM){
  607. errno = ESOCKTNOSUPPORT;
  608. return -1;
  609. }
  610. if((sv[0] = socket(af,type,protocol)) == -1)
  611. return -1;
  612. if((sv[1] = socket(af,type,protocol)) == -1){
  613. close_s(sv[0]);
  614. return -1;
  615. }
  616. up0 = itop(sv[0]);
  617. up1 = itop(sv[1]);
  618. up0->cb.local->peer = up1;
  619. up1->cb.local->peer = up0;
  620. return sv[1];
  621. }
  622. /* Return end-of-line convention for socket */
  623. char *
  624. eolseq(int s)
  625. {
  626. struct usock *up;
  627. if((up = itop(s)) == NULL){
  628. errno = EBADF;
  629. return NULL;
  630. }
  631. return up->sp->eol;
  632. }