|
|
1.1 root 1: /*
2: * Copyright (c) 1995 Danny Gasparovski.
3: *
4: * Please read the file COPYRIGHT for the
5: * terms and conditions of the copyright.
6: */
7:
8: #define WANT_SYS_IOCTL_H
9: #include <stdlib.h>
10: #include <slirp.h>
11: #include "ip_icmp.h"
12: #include "main.h"
13: #ifdef __sun__
14: #include <sys/filio.h>
15: #endif
16:
17: void
18: so_init()
19: {
20: /* Nothing yet */
21: }
22:
23:
24: struct socket *
25: solookup(head, laddr, lport, faddr, fport)
26: struct socket *head;
27: struct in_addr laddr;
28: u_int lport;
29: struct in_addr faddr;
30: u_int fport;
31: {
32: struct socket *so;
33:
34: for (so = head->so_next; so != head; so = so->so_next) {
35: if (so->so_lport == lport &&
36: so->so_laddr.s_addr == laddr.s_addr &&
37: so->so_faddr.s_addr == faddr.s_addr &&
38: so->so_fport == fport)
39: break;
40: }
41:
42: if (so == head)
43: return (struct socket *)NULL;
44: return so;
45:
46: }
47:
48: /*
49: * Create a new socket, initialise the fields
50: * It is the responsibility of the caller to
51: * insque() it into the correct linked-list
52: */
53: struct socket *
54: socreate()
55: {
56: struct socket *so;
57:
58: so = (struct socket *)malloc(sizeof(struct socket));
59: if(so) {
60: memset(so, 0, sizeof(struct socket));
61: so->so_state = SS_NOFDREF;
62: so->s = -1;
63: }
64: return(so);
65: }
66:
67: /*
68: * remque and free a socket, clobber cache
69: */
70: void
71: sofree(so)
72: struct socket *so;
73: {
74: if (so->so_emu==EMU_RSH && so->extra) {
75: sofree(so->extra);
76: so->extra=NULL;
77: }
78: if (so == tcp_last_so)
79: tcp_last_so = &tcb;
80: else if (so == udp_last_so)
81: udp_last_so = &udb;
82:
83: m_free(so->so_m);
84:
85: if(so->so_next && so->so_prev)
86: remque(so); /* crashes if so is not in a queue */
87:
88: free(so);
89: }
90:
91: /*
92: * Read from so's socket into sb_snd, updating all relevant sbuf fields
93: * NOTE: This will only be called if it is select()ed for reading, so
94: * a read() of 0 (or less) means it's disconnected
95: */
96: int
97: soread(so)
98: struct socket *so;
99: {
100: int n, nn, lss, total;
101: struct sbuf *sb = &so->so_snd;
102: int len = sb->sb_datalen - sb->sb_cc;
103: struct iovec iov[2];
104: int mss = so->so_tcpcb->t_maxseg;
105:
106: DEBUG_CALL("soread");
107: DEBUG_ARG("so = %lx", (long )so);
108:
109: /*
110: * No need to check if there's enough room to read.
111: * soread wouldn't have been called if there weren't
112: */
113:
114: len = sb->sb_datalen - sb->sb_cc;
115:
116: iov[0].iov_base = sb->sb_wptr;
117: if (sb->sb_wptr < sb->sb_rptr) {
118: iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
119: /* Should never succeed, but... */
120: if (iov[0].iov_len > len)
121: iov[0].iov_len = len;
122: if (iov[0].iov_len > mss)
123: iov[0].iov_len -= iov[0].iov_len%mss;
124: n = 1;
125: } else {
126: iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
127: /* Should never succeed, but... */
128: if (iov[0].iov_len > len) iov[0].iov_len = len;
129: len -= iov[0].iov_len;
130: if (len) {
131: iov[1].iov_base = sb->sb_data;
132: iov[1].iov_len = sb->sb_rptr - sb->sb_data;
133: if(iov[1].iov_len > len)
134: iov[1].iov_len = len;
135: total = iov[0].iov_len + iov[1].iov_len;
136: if (total > mss) {
137: lss = total%mss;
138: if (iov[1].iov_len > lss) {
139: iov[1].iov_len -= lss;
140: n = 2;
141: } else {
142: lss -= iov[1].iov_len;
143: iov[0].iov_len -= lss;
144: n = 1;
145: }
146: } else
147: n = 2;
148: } else {
149: if (iov[0].iov_len > mss)
150: iov[0].iov_len -= iov[0].iov_len%mss;
151: n = 1;
152: }
153: }
154:
155: #ifdef HAVE_READV
156: nn = readv(so->s, (struct iovec *)iov, n);
157: DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
158: #else
159: nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
160: #endif
161: if (nn <= 0) {
162: if (nn < 0 && (errno == EINTR || errno == EAGAIN))
163: return 0;
164: else {
165: DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
166: sofcantrcvmore(so);
167: tcp_sockclosed(sototcpcb(so));
168: return -1;
169: }
170: }
171:
172: #ifndef HAVE_READV
173: /*
174: * If there was no error, try and read the second time round
175: * We read again if n = 2 (ie, there's another part of the buffer)
176: * and we read as much as we could in the first read
177: * We don't test for <= 0 this time, because there legitimately
178: * might not be any more data (since the socket is non-blocking),
179: * a close will be detected on next iteration.
180: * A return of -1 wont (shouldn't) happen, since it didn't happen above
181: */
182: if (n == 2 && nn == iov[0].iov_len) {
183: int ret;
184: ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
185: if (ret > 0)
186: nn += ret;
187: }
188:
189: DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
190: #endif
191:
192: /* Update fields */
193: sb->sb_cc += nn;
194: sb->sb_wptr += nn;
195: if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
196: sb->sb_wptr -= sb->sb_datalen;
197: return nn;
198: }
199:
200: /*
201: * Get urgent data
202: *
203: * When the socket is created, we set it SO_OOBINLINE,
204: * so when OOB data arrives, we soread() it and everything
205: * in the send buffer is sent as urgent data
206: */
207: void
208: sorecvoob(so)
209: struct socket *so;
210: {
211: struct tcpcb *tp = sototcpcb(so);
212:
213: DEBUG_CALL("sorecvoob");
214: DEBUG_ARG("so = %lx", (long)so);
215:
216: /*
217: * We take a guess at how much urgent data has arrived.
218: * In most situations, when urgent data arrives, the next
219: * read() should get all the urgent data. This guess will
220: * be wrong however if more data arrives just after the
221: * urgent data, or the read() doesn't return all the
222: * urgent data.
223: */
224: soread(so);
225: tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
226: tp->t_force = 1;
227: tcp_output(tp);
228: tp->t_force = 0;
229: }
230:
231: /*
232: * Send urgent data
233: * There's a lot duplicated code here, but...
234: */
235: int
236: sosendoob(so)
237: struct socket *so;
238: {
239: struct sbuf *sb = &so->so_rcv;
240: char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
241:
242: int n, len;
243:
244: DEBUG_CALL("sosendoob");
245: DEBUG_ARG("so = %lx", (long)so);
246: DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
247:
248: if (so->so_urgc > 2048)
249: so->so_urgc = 2048; /* XXXX */
250:
251: if (sb->sb_rptr < sb->sb_wptr) {
252: /* We can send it directly */
253: n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
254: so->so_urgc -= n;
255:
256: DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
257: } else {
258: /*
259: * Since there's no sendv or sendtov like writev,
260: * we must copy all data to a linear buffer then
261: * send it all
262: */
263: len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
264: if (len > so->so_urgc) len = so->so_urgc;
265: memcpy(buff, sb->sb_rptr, len);
266: so->so_urgc -= len;
267: if (so->so_urgc) {
268: n = sb->sb_wptr - sb->sb_data;
269: if (n > so->so_urgc) n = so->so_urgc;
270: memcpy((buff + len), sb->sb_data, n);
271: so->so_urgc -= n;
272: len += n;
273: }
274: n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
275: #ifdef DEBUG
276: if (n != len)
277: DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
278: #endif
279: DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
280: }
281:
282: sb->sb_cc -= n;
283: sb->sb_rptr += n;
284: if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
285: sb->sb_rptr -= sb->sb_datalen;
286:
287: return n;
288: }
289:
290: /*
291: * Write data from so_rcv to so's socket,
292: * updating all sbuf field as necessary
293: */
294: int
295: sowrite(so)
296: struct socket *so;
297: {
298: int n,nn;
299: struct sbuf *sb = &so->so_rcv;
300: int len = sb->sb_cc;
301: struct iovec iov[2];
302:
303: DEBUG_CALL("sowrite");
304: DEBUG_ARG("so = %lx", (long)so);
305:
306: if (so->so_urgc) {
307: sosendoob(so);
308: if (sb->sb_cc == 0)
309: return 0;
310: }
311:
312: /*
313: * No need to check if there's something to write,
314: * sowrite wouldn't have been called otherwise
315: */
316:
317: len = sb->sb_cc;
318:
319: iov[0].iov_base = sb->sb_rptr;
320: if (sb->sb_rptr < sb->sb_wptr) {
321: iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
322: /* Should never succeed, but... */
323: if (iov[0].iov_len > len) iov[0].iov_len = len;
324: n = 1;
325: } else {
326: iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
327: if (iov[0].iov_len > len) iov[0].iov_len = len;
328: len -= iov[0].iov_len;
329: if (len) {
330: iov[1].iov_base = sb->sb_data;
331: iov[1].iov_len = sb->sb_wptr - sb->sb_data;
332: if (iov[1].iov_len > len) iov[1].iov_len = len;
333: n = 2;
334: } else
335: n = 1;
336: }
337: /* Check if there's urgent data to send, and if so, send it */
338:
339: #ifdef HAVE_READV
340: nn = writev(so->s, (const struct iovec *)iov, n);
341:
342: DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
343: #else
344: nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0);
345: #endif
346: /* This should never happen, but people tell me it does *shrug* */
347: if (nn < 0 && (errno == EAGAIN || errno == EINTR))
348: return 0;
349:
350: if (nn <= 0) {
351: DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
352: so->so_state, errno));
353: sofcantsendmore(so);
354: tcp_sockclosed(sototcpcb(so));
355: return -1;
356: }
357:
358: #ifndef HAVE_READV
359: if (n == 2 && nn == iov[0].iov_len) {
360: int ret;
361: ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0);
362: if (ret > 0)
363: nn += ret;
364: }
365: DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
366: #endif
367:
368: /* Update sbuf */
369: sb->sb_cc -= nn;
370: sb->sb_rptr += nn;
371: if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
372: sb->sb_rptr -= sb->sb_datalen;
373:
374: /*
375: * If in DRAIN mode, and there's no more data, set
376: * it CANTSENDMORE
377: */
378: if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
379: sofcantsendmore(so);
380:
381: return nn;
382: }
383:
384: /*
385: * recvfrom() a UDP socket
386: */
387: void
388: sorecvfrom(so)
389: struct socket *so;
390: {
391: struct sockaddr_in addr;
392: socklen_t addrlen = sizeof(struct sockaddr_in);
393:
394: DEBUG_CALL("sorecvfrom");
395: DEBUG_ARG("so = %lx", (long)so);
396:
397: if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
398: char buff[256];
399: int len;
400:
401: len = recvfrom(so->s, buff, 256, 0,
402: (struct sockaddr *)&addr, &addrlen);
403: /* XXX Check if reply is "correct"? */
404:
405: if(len == -1 || len == 0) {
406: u_char code=ICMP_UNREACH_PORT;
407:
408: if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
409: else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
410:
411: DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
412: errno,strerror(errno)));
413: icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
414: } else {
415: icmp_reflect(so->so_m);
416: so->so_m = 0; /* Don't m_free() it again! */
417: }
418: /* No need for this socket anymore, udp_detach it */
419: udp_detach(so);
420: } else { /* A "normal" UDP packet */
421: struct mbuf *m;
422: int len;
423: ioctlsockopt_t n;
424:
425: if (!(m = m_get())) return;
426: m->m_data += if_maxlinkhdr;
427:
428: /*
429: * XXX Shouldn't FIONREAD packets destined for port 53,
430: * but I don't know the max packet size for DNS lookups
431: */
432: len = M_FREEROOM(m);
433: /* if (so->so_fport != htons(53)) { */
434: ioctlsocket(so->s, FIONREAD, &n);
435:
436: if (n > len) {
437: n = (m->m_data - m->m_dat) + m->m_len + n + 1;
438: m_inc(m, n);
439: len = M_FREEROOM(m);
440: }
441: /* } */
442:
443: m->m_len = recvfrom(so->s, m->m_data, len, 0,
444: (struct sockaddr *)&addr, &addrlen);
445: DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
446: m->m_len, errno,strerror(errno)));
447: if(m->m_len<0) {
448: u_char code=ICMP_UNREACH_PORT;
449:
450: if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
451: else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
452:
453: DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
454: icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
455: m_free(m);
456: } else {
457: /*
458: * Hack: domain name lookup will be used the most for UDP,
459: * and since they'll only be used once there's no need
460: * for the 4 minute (or whatever) timeout... So we time them
461: * out much quicker (10 seconds for now...)
462: */
463: if (so->so_expire) {
464: if (so->so_fport == htons(53))
465: so->so_expire = curtime + SO_EXPIREFAST;
466: else
467: so->so_expire = curtime + SO_EXPIRE;
468: }
469:
470: /* if (m->m_len == len) {
471: * m_inc(m, MINCSIZE);
472: * m->m_len = 0;
473: * }
474: */
475:
476: /*
477: * If this packet was destined for CTL_ADDR,
478: * make it look like that's where it came from, done by udp_output
479: */
480: udp_output(so, m, &addr);
481: } /* rx error */
482: } /* if ping packet */
483: }
484:
485: /*
486: * sendto() a socket
487: */
488: int
489: sosendto(so, m)
490: struct socket *so;
491: struct mbuf *m;
492: {
493: int ret;
494: struct sockaddr_in addr;
495:
496: DEBUG_CALL("sosendto");
497: DEBUG_ARG("so = %lx", (long)so);
498: DEBUG_ARG("m = %lx", (long)m);
499:
500: addr.sin_family = AF_INET;
501: if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
502: /* It's an alias */
503: switch(ntohl(so->so_faddr.s_addr) & 0xff) {
504: case CTL_DNS:
505: addr.sin_addr = dns_addr;
506: break;
507: case CTL_ALIAS:
508: default:
509: addr.sin_addr = loopback_addr;
510: break;
511: }
512: } else
513: addr.sin_addr = so->so_faddr;
514: addr.sin_port = so->so_fport;
515:
516: DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
517:
518: /* Don't care what port we get */
519: ret = sendto(so->s, m->m_data, m->m_len, 0,
520: (struct sockaddr *)&addr, sizeof (struct sockaddr));
521: if (ret < 0)
522: return -1;
523:
524: /*
525: * Kill the socket if there's no reply in 4 minutes,
526: * but only if it's an expirable socket
527: */
528: if (so->so_expire)
529: so->so_expire = curtime + SO_EXPIRE;
530: so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */
531: return 0;
532: }
533:
534: /*
535: * XXX This should really be tcp_listen
536: */
537: struct socket *
538: solisten(port, laddr, lport, flags)
539: u_int port;
540: u_int32_t laddr;
541: u_int lport;
542: int flags;
543: {
544: struct sockaddr_in addr;
545: struct socket *so;
546: int s;
547: socklen_t addrlen = sizeof(addr);
548: int opt = 1;
549:
550: DEBUG_CALL("solisten");
551: DEBUG_ARG("port = %d", port);
552: DEBUG_ARG("laddr = %x", laddr);
553: DEBUG_ARG("lport = %d", lport);
554: DEBUG_ARG("flags = %x", flags);
555:
556: if ((so = socreate()) == NULL) {
557: /* free(so); Not sofree() ??? free(NULL) == NOP */
558: return NULL;
559: }
560:
561: /* Don't tcp_attach... we don't need so_snd nor so_rcv */
562: if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
563: free(so);
564: return NULL;
565: }
566: insque(so,&tcb);
567:
568: /*
569: * SS_FACCEPTONCE sockets must time out.
570: */
571: if (flags & SS_FACCEPTONCE)
572: so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
573:
574: so->so_state = (SS_FACCEPTCONN|flags);
575: so->so_lport = lport; /* Kept in network format */
576: so->so_laddr.s_addr = laddr; /* Ditto */
577:
578: memset(&addr, 0, sizeof(struct sockaddr_in));
579: addr.sin_family = AF_INET;
580: addr.sin_addr.s_addr = INADDR_ANY;
581: addr.sin_port = port;
582:
583: if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
584: (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
585: (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
586: (listen(s,1) < 0)) {
587: int tmperrno = errno; /* Don't clobber the real reason we failed */
588:
589: close(s);
590: sofree(so);
591: /* Restore the real errno */
592: #ifdef _WIN32
593: WSASetLastError(tmperrno);
594: #else
595: errno = tmperrno;
596: #endif
597: return NULL;
598: }
599: setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
600:
601: getsockname(s,(struct sockaddr *)&addr,&addrlen);
602: so->so_fport = addr.sin_port;
603: if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
604: so->so_faddr = alias_addr;
605: else
606: so->so_faddr = addr.sin_addr;
607:
608: so->s = s;
609: return so;
610: }
611:
612: /*
613: * Data is available in so_rcv
614: * Just write() the data to the socket
615: * XXX not yet...
616: */
617: void
618: sorwakeup(so)
619: struct socket *so;
620: {
621: /* sowrite(so); */
622: /* FD_CLR(so->s,&writefds); */
623: }
624:
625: /*
626: * Data has been freed in so_snd
627: * We have room for a read() if we want to
628: * For now, don't read, it'll be done in the main loop
629: */
630: void
631: sowwakeup(so)
632: struct socket *so;
633: {
634: /* Nothing, yet */
635: }
636:
637: /*
638: * Various session state calls
639: * XXX Should be #define's
640: * The socket state stuff needs work, these often get call 2 or 3
641: * times each when only 1 was needed
642: */
643: void
644: soisfconnecting(so)
645: register struct socket *so;
646: {
647: so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
648: SS_FCANTSENDMORE|SS_FWDRAIN);
649: so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
650: }
651:
652: void
653: soisfconnected(so)
654: register struct socket *so;
655: {
656: so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
657: so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
658: }
659:
660: void
661: sofcantrcvmore(so)
662: struct socket *so;
663: {
664: if ((so->so_state & SS_NOFDREF) == 0) {
665: shutdown(so->s,0);
666: if(global_writefds) {
667: FD_CLR(so->s,global_writefds);
668: }
669: }
670: so->so_state &= ~(SS_ISFCONNECTING);
671: if (so->so_state & SS_FCANTSENDMORE)
672: so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */
673: else
674: so->so_state |= SS_FCANTRCVMORE;
675: }
676:
677: void
678: sofcantsendmore(so)
679: struct socket *so;
680: {
681: if ((so->so_state & SS_NOFDREF) == 0) {
682: shutdown(so->s,1); /* send FIN to fhost */
683: if (global_readfds) {
684: FD_CLR(so->s,global_readfds);
685: }
686: if (global_xfds) {
687: FD_CLR(so->s,global_xfds);
688: }
689: }
690: so->so_state &= ~(SS_ISFCONNECTING);
691: if (so->so_state & SS_FCANTRCVMORE)
692: so->so_state = SS_NOFDREF; /* as above */
693: else
694: so->so_state |= SS_FCANTSENDMORE;
695: }
696:
697: void
698: soisfdisconnected(so)
699: struct socket *so;
700: {
701: /* so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */
702: /* close(so->s); */
703: /* so->so_state = SS_ISFDISCONNECTED; */
704: /*
705: * XXX Do nothing ... ?
706: */
707: }
708:
709: /*
710: * Set write drain mode
711: * Set CANTSENDMORE once all data has been write()n
712: */
713: void
714: sofwdrain(so)
715: struct socket *so;
716: {
717: if (so->so_rcv.sb_cc)
718: so->so_state |= SS_FWDRAIN;
719: else
720: sofcantsendmore(so);
721: }
722:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.