From 605c811a4ad9bdb8a742f8c80dfdc21c00a0a3ab Mon Sep 17 00:00:00 2001 From: jvernet Date: Wed, 4 Oct 2017 18:22:48 +0200 Subject: [PATCH] Revert "SLIRP 0.9.1" This reverts commit 4682bb80a1afd69e365a0e448fcba7dd68f8c242. --- BasiliskII/src/slirp/COPYRIGHT | 5 +- BasiliskII/src/slirp/bootp.c | 48 +- BasiliskII/src/slirp/bootp.h | 10 +- BasiliskII/src/slirp/cksum.c | 20 +- BasiliskII/src/slirp/debug.c | 142 ++-- BasiliskII/src/slirp/debug.h | 16 +- BasiliskII/src/slirp/icmp_var.h | 8 +- BasiliskII/src/slirp/if.c | 97 ++- BasiliskII/src/slirp/if.h | 37 +- BasiliskII/src/slirp/ip.h | 52 +- BasiliskII/src/slirp/ip_icmp.c | 84 +-- BasiliskII/src/slirp/ip_icmp.h | 22 +- BasiliskII/src/slirp/ip_input.c | 101 ++- BasiliskII/src/slirp/ip_output.c | 51 +- BasiliskII/src/slirp/libslirp.h | 24 +- BasiliskII/src/slirp/main.h | 5 +- BasiliskII/src/slirp/mbuf.c | 95 ++- BasiliskII/src/slirp/mbuf.h | 33 +- BasiliskII/src/slirp/misc.c | 375 ++++------ BasiliskII/src/slirp/misc.h | 48 +- BasiliskII/src/slirp/sbuf.c | 64 +- BasiliskII/src/slirp/sbuf.h | 17 +- BasiliskII/src/slirp/slirp.c | 306 ++++---- BasiliskII/src/slirp/slirp.h | 178 ++--- BasiliskII/src/slirp/slirp_config.h | 85 +-- BasiliskII/src/slirp/socket.c | 224 +++--- BasiliskII/src/slirp/socket.h | 47 +- BasiliskII/src/slirp/tcp.h | 24 +- BasiliskII/src/slirp/tcp_input.c | 1036 ++++++++++++++------------- BasiliskII/src/slirp/tcp_output.c | 116 ++- BasiliskII/src/slirp/tcp_subr.c | 418 +++++------ BasiliskII/src/slirp/tcp_timer.c | 73 +- BasiliskII/src/slirp/tcp_timer.h | 19 +- BasiliskII/src/slirp/tcp_var.h | 9 +- BasiliskII/src/slirp/tcpip.h | 6 +- BasiliskII/src/slirp/tftp.c | 149 +--- BasiliskII/src/slirp/tftp.h | 15 +- BasiliskII/src/slirp/udp.c | 209 +++--- BasiliskII/src/slirp/udp.h | 37 +- 39 files changed, 2006 insertions(+), 2299 deletions(-) diff --git a/BasiliskII/src/slirp/COPYRIGHT b/BasiliskII/src/slirp/COPYRIGHT index 3f331ee0..b7d6568e 100644 --- a/BasiliskII/src/slirp/COPYRIGHT +++ b/BasiliskII/src/slirp/COPYRIGHT @@ -16,7 +16,7 @@ The copyright terms and conditions: ---BEGIN--- Copyright (c) 1995,1996 Danny Gasparovski. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -25,9 +25,6 @@ The copyright terms and conditions: 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - 3. All advertising materials mentioning features or use of this software - must display the following acknowledgment: - This product includes software developed by Danny Gasparovski. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY diff --git a/BasiliskII/src/slirp/bootp.c b/BasiliskII/src/slirp/bootp.c index 3ae3db20..a51b80c9 100644 --- a/BasiliskII/src/slirp/bootp.c +++ b/BasiliskII/src/slirp/bootp.c @@ -1,8 +1,8 @@ /* * QEMU BOOTP/DHCP server - * + * * Copyright (c) 2004 Fabrice Bellard - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights @@ -38,17 +38,8 @@ typedef struct { BOOTPClient bootp_clients[NB_ADDR]; -const char *bootp_filename; - static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; -#ifdef DEBUG -#define dprintf(fmt, args...) \ -if (slirp_debug & DBG_CALL) { fprintf(dfd, fmt, ## args); fflush(dfd); } -#else -#define dprintf(fmt, args...) -#endif - static BOOTPClient *get_new_addr(struct in_addr *paddr) { BOOTPClient *bc; @@ -89,7 +80,7 @@ static void dhcp_decode(const uint8_t *buf, int size, const uint8_t *p, *p_end; int len, tag; - *pmsg_type = 0; + *pmsg_type = 0; p = buf; p_end = buf + size; @@ -101,7 +92,7 @@ static void dhcp_decode(const uint8_t *buf, int size, while (p < p_end) { tag = p[0]; if (tag == RFC1533_PAD) { - p++; + p++; } else if (tag == RFC1533_END) { break; } else { @@ -109,7 +100,6 @@ static void dhcp_decode(const uint8_t *buf, int size, if (p >= p_end) break; len = *p++; - dprintf("dhcp: tag=0x%02x len=%d\n", tag, len); switch(tag) { case RFC2132_MSG_TYPE: @@ -136,20 +126,19 @@ static void bootp_reply(struct bootp_t *bp) /* extract exact DHCP msg type */ dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type); - dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type); - + if (dhcp_msg_type == 0) dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */ - - if (dhcp_msg_type != DHCPDISCOVER && + + if (dhcp_msg_type != DHCPDISCOVER && dhcp_msg_type != DHCPREQUEST) return; /* XXX: this is a hack to get the client mac address */ memcpy(client_ethaddr, bp->bp_hwaddr, 6); - + if ((m = m_get()) == NULL) return; - m->m_data += IF_MAXLINKHDR; + m->m_data += if_maxlinkhdr; rbp = (struct bootp_t *)m->m_data; m->m_data += sizeof(struct udpiphdr); memset(rbp, 0, sizeof(struct bootp_t)); @@ -157,10 +146,8 @@ static void bootp_reply(struct bootp_t *bp) if (dhcp_msg_type == DHCPDISCOVER) { new_addr: bc = get_new_addr(&daddr.sin_addr); - if (!bc) { - dprintf("no address left\n"); + if (!bc) return; - } memcpy(bc->macaddr, client_ethaddr, 6); } else { bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr); @@ -171,11 +158,6 @@ static void bootp_reply(struct bootp_t *bp) } } - if (bootp_filename) - snprintf(rbp->bp_file, sizeof(rbp->bp_file), "%s", bootp_filename); - - dprintf("offered addr=%08x\n", ntohl(daddr.sin_addr.s_addr)); - saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS); saddr.sin_port = htons(BOOTP_SERVER); @@ -203,7 +185,7 @@ static void bootp_reply(struct bootp_t *bp) *q++ = 1; *q++ = DHCPACK; } - + if (dhcp_msg_type == DHCPDISCOVER || dhcp_msg_type == DHCPREQUEST) { *q++ = RFC2132_SRV_ID; @@ -217,12 +199,12 @@ static void bootp_reply(struct bootp_t *bp) *q++ = 0xff; *q++ = 0xff; *q++ = 0x00; - + *q++ = RFC1533_GATEWAY; *q++ = 4; memcpy(q, &saddr.sin_addr, 4); q += 4; - + *q++ = RFC1533_DNS; *q++ = 4; dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS); @@ -244,8 +226,8 @@ static void bootp_reply(struct bootp_t *bp) } } *q++ = RFC1533_END; - - m->m_len = sizeof(struct bootp_t) - + + m->m_len = sizeof(struct bootp_t) - sizeof(struct ip) - sizeof(struct udphdr); udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); } diff --git a/BasiliskII/src/slirp/bootp.h b/BasiliskII/src/slirp/bootp.h index e48f53f3..54a86ca2 100644 --- a/BasiliskII/src/slirp/bootp.h +++ b/BasiliskII/src/slirp/bootp.h @@ -90,6 +90,10 @@ #define BOOTP_VENDOR_LEN 64 #define DHCP_OPT_LEN 312 +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + struct bootp_t { struct ip ip; struct udphdr udp; @@ -108,6 +112,10 @@ struct bootp_t { uint8_t bp_sname[64]; uint8_t bp_file[128]; uint8_t bp_vend[DHCP_OPT_LEN]; -}; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_RESET) +#endif void bootp_input(struct mbuf *m); diff --git a/BasiliskII/src/slirp/cksum.c b/BasiliskII/src/slirp/cksum.c index b98373b5..66d3f230 100644 --- a/BasiliskII/src/slirp/cksum.c +++ b/BasiliskII/src/slirp/cksum.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -41,7 +37,7 @@ * * This routine is very heavily used in the network * code and should be modified for each CPU to be as fast as possible. - * + * * XXX Since we will never span more than 1 mbuf, we can optimise this */ @@ -63,13 +59,13 @@ int cksum(struct mbuf *m, int len) u_int16_t s[2]; u_int32_t l; } l_util; - + if (m->m_len == 0) goto cont; w = mtod(m, u_int16_t *); - + mlen = m->m_len; - + if (len < mlen) mlen = len; len -= mlen; @@ -107,7 +103,7 @@ int cksum(struct mbuf *m, int len) while ((mlen -= 2) >= 0) { sum += *w++; } - + if (byte_swapped) { REDUCE; sum <<= 8; @@ -117,11 +113,11 @@ int cksum(struct mbuf *m, int len) sum += s_util.s; mlen = 0; } else - + mlen = -1; } else if (mlen == -1) s_util.c[0] = *(u_int8_t *)w; - + cont: #ifdef DEBUG if (len) { diff --git a/BasiliskII/src/slirp/debug.c b/BasiliskII/src/slirp/debug.c index 7c8581d6..916b9a8e 100644 --- a/BasiliskII/src/slirp/debug.c +++ b/BasiliskII/src/slirp/debug.c @@ -1,8 +1,8 @@ /* * Copyright (c) 1995 Danny Gasparovski. * Portions copyright (c) 2000 Kelly Price. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -16,11 +16,8 @@ int dostats = 0; #endif int slirp_debug = 0; -extern char *strerror _P((int)); - -/* Carry over one item from main.c so that the tty's restored. +/* Carry over one item from main.c so that the tty's restored. * Only done when the tty being used is /dev/tty --RedWolf */ -#ifndef CONFIG_QEMU extern struct termios slirp_tty_settings; extern int slirp_tty_restore; @@ -33,7 +30,7 @@ debug_init(file, dbg) /* Close the old debugging file */ if (dfd) fclose(dfd); - + dfd = fopen(file,"w"); if (dfd != NULL) { #if 0 @@ -59,7 +56,7 @@ dump_packet(dat, n) { u_char *pptr = (u_char *)dat; int j,k; - + n /= 16; n++; DEBUG_MISC((dfd, "PACKET DUMPED: \n")); @@ -71,30 +68,28 @@ dump_packet(dat, n) } } #endif -#endif -#ifdef LOG_ENABLED #if 0 /* * Statistic routines - * + * * These will print statistics to the screen, the debug file (dfd), or * a buffer, depending on "type", so that the stats can be sent over * the link as well. */ -static void +void ttystats(ttyp) struct ttys *ttyp; { struct slirp_ifstats *is = &ttyp->ifstats; char buff[512]; - + lprint(" \r\n"); - - if (IF_COMP & IF_COMPRESS) + + if (if_comp & IF_COMPRESS) strcpy(buff, "on"); - else if (IF_COMP & IF_NOCOMPRESS) + else if (if_comp & IF_NOCOMPRESS) strcpy(buff, "off"); else strcpy(buff, "off (for now)"); @@ -122,20 +117,20 @@ ttystats(ttyp) lprint(" %6d bad input packets\r\n", is->in_mbad); } -static void -allttystats(void) +void +allttystats() { struct ttys *ttyp; - + for (ttyp = ttys; ttyp; ttyp = ttyp->next) ttystats(ttyp); } #endif -static void -ipstats(void) +void +ipstats() { - lprint(" \r\n"); + lprint(" \r\n"); lprint("IP stats:\r\n"); lprint(" %6d total packets received (%d were unaligned)\r\n", @@ -156,14 +151,14 @@ ipstats(void) lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered); } -#ifndef CONFIG_QEMU -static void -vjstats(void) +#if 0 +void +vjstats() { lprint(" \r\n"); - + lprint("VJ compression stats:\r\n"); - + lprint(" %6d outbound packets (%d compressed)\r\n", comp_s.sls_packets, comp_s.sls_compressed); lprint(" %6d searches for connection stats (%d misses)\r\n", @@ -175,13 +170,13 @@ vjstats(void) } #endif -static void -tcpstats(void) +void +tcpstats() { lprint(" \r\n"); lprint("TCP stats:\r\n"); - + lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal); lprint(" %6d data packets (%d bytes)\r\n", tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte); @@ -194,8 +189,8 @@ tcpstats(void) lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup); lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl); lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin); - - lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal); + + lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal); lprint(" %6d acks (for %d bytes)\r\n", tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte); lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack); @@ -204,7 +199,7 @@ tcpstats(void) tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte); lprint(" %6d completely duplicate packets (%d bytes)\r\n", tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte); - + lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n", tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte); lprint(" %6d out-of-order packets (%d bytes)\r\n", @@ -217,7 +212,7 @@ tcpstats(void) lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum); lprint(" %6d discarded for bad header offset fields\r\n", tcpstat.tcps_rcvbadoff); - + lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt); lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts); lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects); @@ -236,15 +231,15 @@ tcpstats(void) lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack); lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat); lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss); - - + + /* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */ /* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */ } -static void -udpstats(void) +void +udpstats() { lprint(" \r\n"); @@ -257,8 +252,8 @@ udpstats(void) lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets); } -static void -icmpstats(void) +void +icmpstats() { lprint(" \r\n"); lprint("ICMP stats:\r\n"); @@ -270,23 +265,23 @@ icmpstats(void) lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect); } -static void -mbufstats(void) +void +mbufstats() { struct mbuf *m; int i; - + lprint(" \r\n"); - + lprint("Mbuf stats:\r\n"); lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max); - + i = 0; for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next) i++; lprint(" %6d mbufs on free list\r\n", i); - + i = 0; for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) i++; @@ -294,55 +289,59 @@ mbufstats(void) lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued); } -static void -sockstats(void) +void +sockstats() { + char addr[INET_ADDRSTRLEN]; char buff[256]; int n; struct socket *so; lprint(" \r\n"); - + lprint( "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n"); - + for (so = tcb.so_next; so != &tcb; so = so->so_next) { - + n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE"); while (n < 17) buff[n++] = ' '; buff[17] = 0; lprint("%s %3d %15s %5d ", buff, so->s, - inet_ntoa(so->so_laddr), ntohs(so->so_lport)); + inet_ntop(AF_INET, &so->so_laddr, addr, sizeof(addr)), + ntohs(so->so_lport)); lprint("%15s %5d %5d %5d\r\n", - inet_ntoa(so->so_faddr), ntohs(so->so_fport), + inet_ntop(AF_INET, &so->so_faddr, addr, sizeof(addr)), + ntohs(so->so_fport), so->so_rcv.sb_cc, so->so_snd.sb_cc); } - + for (so = udb.so_next; so != &udb; so = so->so_next) { - + n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000); while (n < 17) buff[n++] = ' '; buff[17] = 0; lprint("%s %3d %15s %5d ", buff, so->s, - inet_ntoa(so->so_laddr), ntohs(so->so_lport)); + inet_ntop(AF_INET, &so->so_laddr, addr, sizeof(addr)), + ntohs(so->so_lport)); lprint("%15s %5d %5d %5d\r\n", - inet_ntoa(so->so_faddr), ntohs(so->so_fport), + inet_ntop(AF_INET, &so->so_faddr, addr, sizeof(addr)), + ntohs(so->so_fport), so->so_rcv.sb_cc, so->so_snd.sb_cc); } } -#endif -#ifndef CONFIG_QEMU +#if 0 void slirp_exit(exit_status) int exit_status; { struct ttys *ttyp; - + DEBUG_CALL("slirp_exit"); DEBUG_ARG("exit_status = %d", exit_status); @@ -351,7 +350,7 @@ slirp_exit(exit_status) if (!dfd) debug_init("slirp_stats", 0xf); lprint_arg = (char **)&dfd; - + ipstats(); tcpstats(); udpstats(); @@ -361,35 +360,20 @@ slirp_exit(exit_status) allttystats(); vjstats(); } - + for (ttyp = ttys; ttyp; ttyp = ttyp->next) tty_detached(ttyp, 1); - + if (slirp_forked) { /* Menendez time */ if (kill(getppid(), SIGQUIT) < 0) lprint("Couldn't kill parent process %ld!\n", (long) getppid()); } - + /* Restore the terminal if we gotta */ if(slirp_tty_restore) tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */ exit(exit_status); } #endif - -void -slirp_stats(void) -{ -#ifdef LOG_ENABLED - ipstats(); - tcpstats(); - udpstats(); - icmpstats(); - mbufstats(); - sockstats(); -#else - lprint("SLIRP statistics code not compiled.\n"); -#endif -} diff --git a/BasiliskII/src/slirp/debug.h b/BasiliskII/src/slirp/debug.h index 8a523b2e..c5d42195 100644 --- a/BasiliskII/src/slirp/debug.h +++ b/BasiliskII/src/slirp/debug.h @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -36,5 +36,15 @@ extern int slirp_debug; #endif -void debug_init _P((char *, int)); +void debug_init(char *, int); +//void ttystats(struct ttys *); +void allttystats(void); +void ipstats(void); +void vjstats(void); +void tcpstats(void); +void udpstats(void); +void icmpstats(void); +void mbufstats(void); +void sockstats(void); +void slirp_exit(int); diff --git a/BasiliskII/src/slirp/icmp_var.h b/BasiliskII/src/slirp/icmp_var.h index cd865b79..9af222fb 100644 --- a/BasiliskII/src/slirp/icmp_var.h +++ b/BasiliskII/src/slirp/icmp_var.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -64,8 +60,6 @@ struct icmpstat { { "stats", CTLTYPE_STRUCT }, \ } -#ifdef LOG_ENABLED extern struct icmpstat icmpstat; -#endif #endif diff --git a/BasiliskII/src/slirp/if.c b/BasiliskII/src/slirp/if.c index 67a7b6ff..9185dcf6 100644 --- a/BasiliskII/src/slirp/if.c +++ b/BasiliskII/src/slirp/if.c @@ -7,7 +7,12 @@ #include -int if_queued = 0; /* Number of packets queued so far */ +size_t if_mtu, if_mru; +int if_comp; +int if_maxlinkhdr; +int if_queued = 0; /* Number of packets queued so far */ +int if_thresh = 10; /* Number of packets queued before we start sending + * (to prevent allocing too many mbufs) */ struct mbuf if_fastq; /* fast queue (for interactive data) */ struct mbuf if_batchq; /* queue for non-interactive data */ @@ -36,6 +41,23 @@ ifs_remque(ifm) void if_init() { +#if 0 + /* + * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP, + * and 8 bytes for PPP, but need to have it on an 8byte boundary + */ +#ifdef USE_PPP + if_maxlinkhdr = 48; +#else + if_maxlinkhdr = 40; +#endif +#else + /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */ + if_maxlinkhdr = 2 + 14 + 40; +#endif + if_mtu = 1500; + if_mru = 1500; + if_comp = IF_AUTOCOMP; if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq; if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq; // sl_compress_init(&comp_s); @@ -55,12 +77,12 @@ writen(fd, bptr, n) { int ret; int total; - + /* This should succeed most of the time */ ret = send(fd, bptr, n,0); if (ret == n || ret <= 0) return ret; - + /* Didn't write everything, go into the loop */ total = ret; while (n > total) { @@ -75,7 +97,7 @@ writen(fd, bptr, n) /* * if_input - read() the tty, do "top level" processing (ie: check for any escapes), * and pass onto (*ttyp->if_input) - * + * * XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet. */ #define INBUFF_SIZE 2048 /* XXX */ @@ -85,16 +107,17 @@ if_input(ttyp) { u_char if_inbuff[INBUFF_SIZE]; int if_n; - + DEBUG_CALL("if_input"); DEBUG_ARG("ttyp = %lx", (long)ttyp); - + if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0); - + DEBUG_MISC((dfd, " read %d bytes\n", if_n)); - + if (if_n <= 0) { - if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) { + int error = WSAGetLastError(); + if (if_n == 0 || (error != WSAEINTR && error != EAGAIN)) { if (ttyp->up) link_up--; tty_detached(ttyp, 0); @@ -116,19 +139,19 @@ if_input(ttyp) } } ttyp->ones = ttyp->zeros = 0; - + (*ttyp->if_input)(ttyp, if_inbuff, if_n); } -#endif - +#endif + /* * if_output: Queue packet into an output queue. - * There are 2 output queue's, if_fastq and if_batchq. + * There are 2 output queue's, if_fastq and if_batchq. * Each output queue is a doubly linked list of double linked lists * of mbufs, each list belonging to one "session" (socket). This * way, we can output packets fairly by sending one packet from each * session, instead of all the packets from one session, then all packets - * from the next session, etc. Packets on the if_fastq get absolute + * from the next session, etc. Packets on the if_fastq get absolute * priority, but if one session hogs the link, it gets "downgraded" * to the batchq until it runs out of packets, then it'll return * to the fastq (eg. if the user does an ls -alR in a telnet session, @@ -141,11 +164,11 @@ if_output(so, ifm) { struct mbuf *ifq; int on_fastq = 1; - + DEBUG_CALL("if_output"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("ifm = %lx", (long)ifm); - + /* * First remove the mbuf from m_usedlist, * since we're gonna use m_next and m_prev ourselves @@ -155,9 +178,9 @@ if_output(so, ifm) remque(ifm); ifm->m_flags &= ~M_USEDLIST; } - + /* - * See if there's already a batchq list for this session. + * See if there's already a batchq list for this session. * This can include an interactive session, which should go on fastq, * but gets too greedy... hence it'll be downgraded from fastq to batchq. * We mustn't put this packet back on the fastq (or we'll send it out of order) @@ -171,7 +194,7 @@ if_output(so, ifm) goto diddit; } } - + /* No match, check which queue to put it on */ if (so && (so->so_iptos & IPTOS_LOWDELAY)) { ifq = if_fastq.ifq_prev; @@ -187,15 +210,15 @@ if_output(so, ifm) } } else ifq = if_batchq.ifq_prev; - + /* Create a new doubly linked list for this session */ ifm->ifq_so = so; ifs_init(ifm); insque(ifm, ifq); - + diddit: ++if_queued; - + if (so) { /* Update *_queued */ so->so_queued++; @@ -207,12 +230,12 @@ diddit: * have been sent over the link * (XXX These are arbitrary numbers, probably not optimal..) */ - if (on_fastq && ((so->so_nqueued >= 6) && + if (on_fastq && ((so->so_nqueued >= 6) && (so->so_nqueued - so->so_queued) >= 3)) { - + /* Remove from current queue... */ remque(ifm->ifs_next); - + /* ...And insert in the new. That'll teach ya! */ insque(ifm->ifs_next, &if_batchq); } @@ -245,16 +268,16 @@ void if_start(void) { struct mbuf *ifm, *ifqt; - + DEBUG_CALL("if_start"); - + if (if_queued == 0) return; /* Nothing to do */ - + again: - /* check if we can really output */ - if (!slirp_can_output()) - return; + /* check if we can really output */ + if (!slirp_can_output()) + return; /* * See which queue to get next packet from @@ -268,7 +291,7 @@ if_start(void) ifm = next_m; else ifm = if_batchq.ifq_next; - + /* Set which packet to send on next iteration */ next_m = ifm->ifq_next; } @@ -276,24 +299,24 @@ if_start(void) ifqt = ifm->ifq_prev; remque(ifm); --if_queued; - + /* If there are more packets for this session, re-queue them */ if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { insque(ifm->ifs_next, ifqt); ifs_remque(ifm); } - + /* Update so_queued */ if (ifm->ifq_so) { if (--ifm->ifq_so->so_queued == 0) /* If there's no more queued, reset nqueued */ ifm->ifq_so->so_nqueued = 0; } - + /* Encapsulate the packet for sending */ - if_encap(ifm->m_data, ifm->m_len); + if_encap((uint8_t*)ifm->m_data, ifm->m_len); - m_free(ifm); + m_free(ifm); if (if_queued) goto again; diff --git a/BasiliskII/src/slirp/if.h b/BasiliskII/src/slirp/if.h index bed7152f..a2564ab1 100644 --- a/BasiliskII/src/slirp/if.h +++ b/BasiliskII/src/slirp/if.h @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -13,26 +13,15 @@ #define IF_AUTOCOMP 0x04 /* Autodetect (default) */ #define IF_NOCIDCOMP 0x08 /* CID compression */ -#define IF_MTU 1500 -#define IF_MRU 1500 -#define IF_COMP IF_AUTOCOMP /* Flags for compression */ - -#if 0 -/* - * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP, - * and 8 bytes for PPP, but need to have it on an 8byte boundary - */ -#ifdef USE_PPP -#define IF_MAXLINKHDR 48 -#else -#define IF_MAXLINKHDR 40 -#endif -#else - /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */ -#define IF_MAXLINKHDR (2 + 14 + 40) -#endif - +/* Needed for FreeBSD */ +#undef if_mtu +extern size_t if_mtu; +extern size_t if_mru; /* MTU and MRU */ +extern int if_comp; /* Flags for compression */ +extern int if_maxlinkhdr; extern int if_queued; /* Number of packets queued so far */ +extern int if_thresh; /* Number of packets queued before we start sending + * (to prevent allocing too many mbufs) */ extern struct mbuf if_fastq; /* fast queue (for interactive data) */ extern struct mbuf if_batchq; /* queue for non-interactive data */ @@ -40,7 +29,6 @@ extern struct mbuf *next_m; #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) -#ifdef LOG_ENABLED /* Interface statistics */ struct slirp_ifstats { u_int out_pkts; /* Output packets */ @@ -51,13 +39,12 @@ struct slirp_ifstats { u_int in_bytes; /* Input bytes */ u_int in_errpkts; /* Input Error Packets */ u_int in_errbytes; /* Input Error Bytes */ - + u_int bytes_saved; /* Number of bytes that compression "saved" */ /* ie: number of bytes that didn't need to be sent over the link * because of compression */ - + u_int in_mbad; /* Bad incoming packets */ }; -#endif #endif diff --git a/BasiliskII/src/slirp/ip.h b/BasiliskII/src/slirp/ip.h index a8cdb0d3..e0c7de96 100644 --- a/BasiliskII/src/slirp/ip.h +++ b/BasiliskII/src/slirp/ip.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -76,12 +72,16 @@ typedef u_int32_t n_long; /* long as received from the net */ /* * Structure of an internet header, naked of options. */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + struct ip { #ifdef WORDS_BIGENDIAN - u_int ip_v:4, /* version */ + u_char ip_v:4, /* version */ ip_hl:4; /* header length */ #else - u_int ip_hl:4, /* header length */ + u_char ip_hl:4, /* header length */ ip_v:4; /* version */ #endif u_int8_t ip_tos; /* type of service */ @@ -95,7 +95,11 @@ struct ip { u_int8_t ip_p; /* protocol */ u_int16_t ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ -}; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_RESET) +#endif #define IP_MAXPACKET 65535 /* maximum packet size */ @@ -139,15 +143,19 @@ struct ip { /* * Time stamp option structure. */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + struct ip_timestamp { u_int8_t ipt_code; /* IPOPT_TS */ u_int8_t ipt_len; /* size of structure (variable) */ u_int8_t ipt_ptr; /* index of current entry */ #ifdef WORDS_BIGENDIAN - u_int ipt_oflw:4, /* overflow counter */ + u_char ipt_oflw:4, /* overflow counter */ ipt_flg:4; /* flags, see below */ #else - u_int ipt_flg:4, /* flags, see below */ + u_char ipt_flg:4, /* flags, see below */ ipt_oflw:4; /* overflow counter */ #endif union ipt_timestamp { @@ -157,7 +165,11 @@ struct ip_timestamp { n_long ipt_time; } ipt_ta[1]; } ipt_timestamp; -}; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_RESET) +#endif /* flag bits for ipt_flg */ #define IPOPT_TS_TSONLY 0 /* timestamps only */ @@ -204,6 +216,10 @@ typedef caddr32_t ipasfragp_32; /* * Overlay for ip header used by other protocols (tcp, udp). */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + struct ipovly { caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ u_int8_t ih_x1; /* (unused) */ @@ -211,7 +227,11 @@ struct ipovly { u_int16_t ih_len; /* protocol length */ struct in_addr ih_src; /* source internet address */ struct in_addr ih_dst; /* destination internet address */ -}; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_RESET) +#endif /* * Ip reassembly queue structure. Each fragment @@ -237,10 +257,10 @@ struct ipq { */ struct ipasfrag { #ifdef WORDS_BIGENDIAN - u_int ip_v:4, + u_char ip_v:4, ip_hl:4; #else - u_int ip_hl:4, + u_char ip_hl:4, ip_v:4; #endif /* BUG : u_int changed to u_int8_t. @@ -272,7 +292,6 @@ struct ipoption { int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */ }; -#ifdef LOG_ENABLED /* * Structure attached to inpcb.ip_moptions and * passed to ip_output when IP multicast options are in use. @@ -307,9 +326,8 @@ struct ipstat { }; extern struct ipstat ipstat; -#endif - extern struct ipq ipq; /* ip reass. queue */ extern u_int16_t ip_id; /* ip packet ctr, for ids */ +extern int ip_defttl; /* default IP ttl */ #endif diff --git a/BasiliskII/src/slirp/ip_icmp.c b/BasiliskII/src/slirp/ip_icmp.c index d1da0a2f..55376a8b 100644 --- a/BasiliskII/src/slirp/ip_icmp.c +++ b/BasiliskII/src/slirp/ip_icmp.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -37,16 +33,14 @@ #include "slirp.h" #include "ip_icmp.h" -#ifdef LOG_ENABLED struct icmpstat icmpstat; -#endif /* The message sent when emulating PING */ -/* Be nice and tell them it's just a pseudo-ping packet */ -const char icmp_ping_msg[] = "This is a pseudo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n"; +/* Be nice and tell them it's just a psuedo-ping packet */ +char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n"; /* list of actions for icmp_error() on RX of an icmp message */ -static const int icmp_flush[19] = { +static int icmp_flush[19] = { /* ECHO REPLY (0) */ 0, 1, 1, @@ -65,7 +59,7 @@ static const int icmp_flush[19] = { /* INFO (15) */ 0, /* INFO REPLY (16) */ 0, /* ADDR MASK (17) */ 0, -/* ADDR MASK REPLY (18) */ 0 +/* ADDR MASK REPLY (18) */ 0 }; /* @@ -80,19 +74,19 @@ icmp_input(m, hlen) register struct ip *ip=mtod(m, struct ip *); int icmplen=ip->ip_len; /* int code; */ - + DEBUG_CALL("icmp_input"); DEBUG_ARG("m = %lx", (long )m); - DEBUG_ARG("m_len = %d", m->m_len); - - STAT(icmpstat.icps_received++); + DEBUG_ARG("m_len = %zu", m->m_len); + icmpstat.icps_received++; + /* * Locate icmp structure in mbuf, and check * that its not corrupted and of at least minimum length. */ if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */ - STAT(icmpstat.icps_tooshort++); + icmpstat.icps_tooshort++; freeit: m_freem(m); goto end_error; @@ -102,12 +96,12 @@ icmp_input(m, hlen) m->m_data += hlen; icp = mtod(m, struct icmp *); if (cksum(m, icmplen)) { - STAT(icmpstat.icps_checksum++); + icmpstat.icps_checksum++; goto freeit; } m->m_len += hlen; m->m_data -= hlen; - + /* icmpstat.icps_inhist[icp->icmp_type]++; */ /* code = icp->icmp_code; */ @@ -123,7 +117,7 @@ icmp_input(m, hlen) struct sockaddr_in addr; if ((so = socreate()) == NULL) goto freeit; if(udp_attach(so) == -1) { - DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n", + DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n", errno,strerror(errno))); sofree(so); m_free(m); @@ -137,7 +131,7 @@ icmp_input(m, hlen) so->so_iptos = ip->ip_tos; so->so_type = IPPROTO_ICMP; so->so_state = SS_ISFCONNECTED; - + /* Send the packet */ addr.sin_family = AF_INET; if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { @@ -159,7 +153,7 @@ icmp_input(m, hlen) (struct sockaddr *)&addr, sizeof(addr)) == -1) { DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n", errno,strerror(errno))); - icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); + icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); udp_detach(so); } } /* if ip->ip_dst.s_addr == alias_addr.s_addr */ @@ -172,12 +166,12 @@ icmp_input(m, hlen) case ICMP_TSTAMP: case ICMP_MASKREQ: case ICMP_REDIRECT: - STAT(icmpstat.icps_notsupp++); + icmpstat.icps_notsupp++; m_freem(m); break; - + default: - STAT(icmpstat.icps_badtype++); + icmpstat.icps_badtype++; m_freem(m); } /* swith */ @@ -201,18 +195,18 @@ end_error: * mbuf *msrc is used as a template, but is NOT m_free()'d. * It is reported as the bad ip packet. The header should * be fully correct and in host byte order. - * ICMP fragmentation is illegal. All machines must accept 576 bytes in one + * ICMP fragmentation is illegal. All machines must accept 576 bytes in one * packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548 */ #define ICMP_MAXDATALEN (IP_MSS-28) void -icmp_error(msrc, type, code, minsize, message) - struct mbuf *msrc; - u_char type; - u_char code; - int minsize; - char *message; +icmp_error( + struct mbuf *msrc, + u_char type, + u_char code, + int minsize, + char *message) { unsigned hlen, shlen, s_ip_len; register struct ip *ip; @@ -221,17 +215,17 @@ icmp_error(msrc, type, code, minsize, message) DEBUG_CALL("icmp_error"); DEBUG_ARG("msrc = %lx", (long )msrc); - DEBUG_ARG("msrc_len = %d", msrc->m_len); + DEBUG_ARG("msrc_len = %zu", msrc->m_len); if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error; /* check msrc */ if(!msrc) goto end_error; ip = mtod(msrc, struct ip *); -#if DEBUG - { char bufa[20], bufb[20]; - strcpy(bufa, inet_ntoa(ip->ip_src)); - strcpy(bufb, inet_ntoa(ip->ip_dst)); +#if DEBUG + { char bufa[INET_ADDRSTRLEN], bufb[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &ip->ip_src, bufa, sizeof(bufa)); + inet_ntop(AF_INET, &ip->ip_dst, bufb, sizeof(bufb)); DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb)); } #endif @@ -250,7 +244,7 @@ icmp_error(msrc, type, code, minsize, message) /* make a copy */ if(!(m=m_get())) goto end_error; /* get mbuf */ - { int new_m_size; + { u_int new_m_size; new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN; if(new_m_size>m->m_size) m_inc(m, new_m_size); } @@ -260,9 +254,9 @@ icmp_error(msrc, type, code, minsize, message) /* make the header of the reply packet */ ip = mtod(m, struct ip *); hlen= sizeof(struct ip ); /* no options in reply */ - + /* fill in icmp */ - m->m_data += hlen; + m->m_data += hlen; m->m_len -= hlen; icp = mtod(m, struct icmp *); @@ -271,7 +265,7 @@ icmp_error(msrc, type, code, minsize, message) else if(s_ip_len>ICMP_MAXDATALEN) /* maximum size */ s_ip_len=ICMP_MAXDATALEN; - m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */ + m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */ /* min. size = 8+sizeof(struct ip)+8 */ @@ -305,8 +299,8 @@ icmp_error(msrc, type, code, minsize, message) /* fill in ip */ ip->ip_hl = hlen >> 2; - ip->ip_len = m->m_len; - + ip->ip_len = (u_int16_t)m->m_len; + ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ ip->ip_ttl = MAXTTL; @@ -315,8 +309,8 @@ icmp_error(msrc, type, code, minsize, message) ip->ip_src = alias_addr; (void ) ip_output((struct socket *)NULL, m); - - STAT(icmpstat.icps_reflect++); + + icmpstat.icps_reflect++; end_error: return; @@ -373,5 +367,5 @@ icmp_reflect(m) (void ) ip_output((struct socket *)NULL, m); - STAT(icmpstat.icps_reflect++); + icmpstat.icps_reflect++; } diff --git a/BasiliskII/src/slirp/ip_icmp.h b/BasiliskII/src/slirp/ip_icmp.h index 8c9b5a1b..683dc87f 100644 --- a/BasiliskII/src/slirp/ip_icmp.h +++ b/BasiliskII/src/slirp/ip_icmp.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -47,6 +43,10 @@ typedef u_int32_t n_time; /* * Structure of an icmp header. */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + struct icmp { u_char icmp_type; /* type of message, see below */ u_char icmp_code; /* type sub code */ @@ -92,7 +92,11 @@ struct icmp { #define icmp_ip icmp_dun.id_ip.idi_ip #define icmp_mask icmp_dun.id_mask #define icmp_data icmp_dun.id_data -}; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_RESET) +#endif /* * Lower bounds on packet lengths for various types. @@ -157,8 +161,8 @@ struct icmp { (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) -void icmp_input _P((struct mbuf *, int)); -void icmp_error _P((struct mbuf *, u_char, u_char, int, char *)); -void icmp_reflect _P((struct mbuf *)); +void icmp_input(struct mbuf *, int); +void icmp_error(struct mbuf *, u_char, u_char, int, char *); +void icmp_reflect(struct mbuf *); #endif diff --git a/BasiliskII/src/slirp/ip_input.c b/BasiliskII/src/slirp/ip_input.c index b0468402..cac8493b 100644 --- a/BasiliskII/src/slirp/ip_input.c +++ b/BasiliskII/src/slirp/ip_input.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -37,7 +33,7 @@ /* * Changes and additions relating to SLiRP are * Copyright (c) 1995 Danny Gasparovski. - * + * * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -45,19 +41,10 @@ #include #include "ip_icmp.h" -#ifdef LOG_ENABLED +int ip_defttl; struct ipstat ipstat; -#endif - struct ipq ipq; -static struct ip *ip_reass(register struct ipasfrag *ip, - register struct ipq *fp); -static void ip_freef(struct ipq *fp); -static void ip_enq(register struct ipasfrag *p, - register struct ipasfrag *prev); -static void ip_deq(register struct ipasfrag *p); - /* * IP initialization: fill in IP protocol switch table. * All protocols not implemented in kernel go to raw IP protocol handler. @@ -69,6 +56,7 @@ ip_init() ip_id = tt.tv_sec & 0xffff; udp_init(); tcp_init(); + ip_defttl = IPDEFTTL; } /* @@ -80,38 +68,38 @@ ip_input(m) struct mbuf *m; { register struct ip *ip; - int hlen; - + u_int hlen; + DEBUG_CALL("ip_input"); DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("m_len = %d", m->m_len); - - STAT(ipstat.ips_total++); + DEBUG_ARG("m_len = %zu", m->m_len); + ipstat.ips_total++; + if (m->m_len < sizeof (struct ip)) { - STAT(ipstat.ips_toosmall++); + ipstat.ips_toosmall++; return; } - + ip = mtod(m, struct ip *); - + if (ip->ip_v != IPVERSION) { - STAT(ipstat.ips_badvers++); + ipstat.ips_badvers++; goto bad; } hlen = ip->ip_hl << 2; if (hlenm->m_len) {/* min header length */ - STAT(ipstat.ips_badhlen++); /* or packet too short */ + ipstat.ips_badhlen++; /* or packet too short */ goto bad; } /* keep ip header intact for ICMP reply - * ip->ip_sum = cksum(m, hlen); - * if (ip->ip_sum) { + * ip->ip_sum = cksum(m, hlen); + * if (ip->ip_sum) { */ if(cksum(m,hlen)) { - STAT(ipstat.ips_badsum++); + ipstat.ips_badsum++; goto bad; } @@ -120,7 +108,7 @@ ip_input(m) */ NTOHS(ip->ip_len); if (ip->ip_len < hlen) { - STAT(ipstat.ips_badlen++); + ipstat.ips_badlen++; goto bad; } NTOHS(ip->ip_id); @@ -133,7 +121,7 @@ ip_input(m) * Drop packet if shorter than we expect. */ if (m->m_len < ip->ip_len) { - STAT(ipstat.ips_tooshort++); + ipstat.ips_tooshort++; goto bad; } /* Should drop packet if mbuf too long? hmmm... */ @@ -162,7 +150,7 @@ ip_input(m) * (We could look in the reassembly queue to see * if the packet was previously fragmented, * but it's not worth the time; just let them time out.) - * + * * XXX This should fail, don't fragment yet */ if (ip->ip_off &~ IP_DF) { @@ -189,7 +177,7 @@ ip_input(m) ip->ip_len -= hlen; if (ip->ip_off & IP_MF) ((struct ipasfrag *)ip)->ipf_mff |= 1; - else + else ((struct ipasfrag *)ip)->ipf_mff &= ~1; ip->ip_off <<= 3; @@ -200,11 +188,11 @@ ip_input(m) * attempt reassembly; if it succeeds, proceed. */ if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { - STAT(ipstat.ips_fragments++); + ipstat.ips_fragments++; ip = ip_reass((struct ipasfrag *)ip, fp); if (ip == 0) return; - STAT(ipstat.ips_reassembled++); + ipstat.ips_reassembled++; m = dtom(ip); } else if (fp) @@ -216,7 +204,7 @@ ip_input(m) /* * Switch out to protocol's input routine. */ - STAT(ipstat.ips_delivered++); + ipstat.ips_delivered++; switch (ip->ip_p) { case IPPROTO_TCP: tcp_input(m, hlen, (struct socket *)NULL); @@ -228,7 +216,7 @@ ip_input(m) icmp_input(m, hlen); break; default: - STAT(ipstat.ips_noproto++); + ipstat.ips_noproto++; m_free(m); } return; @@ -243,14 +231,16 @@ bad: * reassembly of this datagram already exists, then it * is given as fp; otherwise have to make a chain. */ -static struct ip * -ip_reass(register struct ipasfrag *ip, register struct ipq *fp) +struct ip * +ip_reass(ip, fp) + register struct ipasfrag *ip; + register struct ipq *fp; { register struct mbuf *m = dtom(ip); register struct ipasfrag *q; int hlen = ip->ip_hl << 2; int i, next; - + DEBUG_CALL("ip_reass"); DEBUG_ARG("ip = %lx", (long)ip); DEBUG_ARG("fp = %lx", (long)fp); @@ -281,7 +271,7 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp) q = (struct ipasfrag *)fp; goto insert; } - + /* * Find a segment which begins after this one does. */ @@ -375,7 +365,7 @@ insert: ip = (struct ipasfrag *)(m->m_ext + delta); } - /* DEBUG_ARG("ip = %lx", (long)ip); + /* DEBUG_ARG("ip = %lx", (long)ip); * ip=(struct ipasfrag *)m->m_data; */ ip->ip_len = next; @@ -391,7 +381,7 @@ insert: return ((struct ip *)ip); dropfrag: - STAT(ipstat.ips_fragdropped++); + ipstat.ips_fragdropped++; m_freem(m); return (0); } @@ -400,8 +390,9 @@ dropfrag: * Free a fragment reassembly header and all * associated datagrams. */ -static void -ip_freef(struct ipq *fp) +void +ip_freef(fp) + struct ipq *fp; { register struct ipasfrag *q, *p; @@ -419,8 +410,9 @@ ip_freef(struct ipq *fp) * Put an ip fragment on a reassembly chain. * Like insque, but pointers in middle of structure. */ -static void -ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev) +void +ip_enq(p, prev) + register struct ipasfrag *p, *prev; { DEBUG_CALL("ip_enq"); DEBUG_ARG("prev = %lx", (long)prev); @@ -433,8 +425,9 @@ ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev) /* * To ip_enq as remque is to insque. */ -static void -ip_deq(register struct ipasfrag *p) +void +ip_deq(p) + register struct ipasfrag *p; { ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next; ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev; @@ -449,9 +442,9 @@ void ip_slowtimo() { register struct ipq *fp; - + DEBUG_CALL("ip_slowtimo"); - + fp = (struct ipq *) ipq.next; if (fp == 0) return; @@ -460,7 +453,7 @@ ip_slowtimo() --fp->ipq_ttl; fp = (struct ipq *) fp->next; if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { - STAT(ipstat.ips_fragtimeout++); + ipstat.ips_fragtimeout++; ip_freef((struct ipq *) fp->prev); } } @@ -667,7 +660,7 @@ bad: /* Not yet */ icmp_error(m, type, code, 0, 0); - STAT(ipstat.ips_badoptions++); + ipstat.ips_badoptions++; return (1); } @@ -695,6 +688,6 @@ ip_stripoptions(m, mopt) i = m->m_len - (sizeof (struct ip) + olen); memcpy(opts, opts + olen, (unsigned)i); m->m_len -= olen; - + ip->ip_hl = sizeof(struct ip) >> 2; } diff --git a/BasiliskII/src/slirp/ip_output.c b/BasiliskII/src/slirp/ip_output.c index a8a6067b..fb9a9420 100644 --- a/BasiliskII/src/slirp/ip_output.c +++ b/BasiliskII/src/slirp/ip_output.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -46,10 +42,6 @@ u_int16_t ip_id; -/* Number of packets queued before we start sending - * (to prevent allocing too many mbufs) */ -#define IF_THRESH 10 - /* * IP output. The packet in mbuf chain m contains a skeletal IP * header (with len, off, ttl, proto, tos, src, dst). @@ -63,13 +55,14 @@ ip_output(so, m0) { register struct ip *ip; register struct mbuf *m = m0; - register int hlen = sizeof(struct ip ); - int len, off, error = 0; + register u_int hlen = sizeof(struct ip); + u_int len, off; + int error = 0; DEBUG_CALL("ip_output"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("m0 = %lx", (long)m0); - + /* We do no options */ /* if (opt) { * m = ip_insertoptions(m, opt, &len); @@ -84,23 +77,23 @@ ip_output(so, m0) ip->ip_off &= IP_DF; ip->ip_id = htons(ip_id++); ip->ip_hl = hlen >> 2; - STAT(ipstat.ips_localout++); + ipstat.ips_localout++; /* * Verify that we have any chance at all of being able to queue * the packet or packet fragments */ /* XXX Hmmm... */ -/* if (if_queued > IF_THRESH && towrite <= 0) { +/* if (if_queued > if_thresh && towrite <= 0) { * error = ENOBUFS; * goto bad; * } */ - + /* * If small enough for interface, can just send directly. */ - if ((u_int16_t)ip->ip_len <= IF_MTU) { + if ((u_int16_t)ip->ip_len <= if_mtu) { ip->ip_len = htons((u_int16_t)ip->ip_len); ip->ip_off = htons((u_int16_t)ip->ip_off); ip->ip_sum = 0; @@ -116,11 +109,11 @@ ip_output(so, m0) */ if (ip->ip_off & IP_DF) { error = -1; - STAT(ipstat.ips_cantfrag++); + ipstat.ips_cantfrag++; goto bad; } - - len = (IF_MTU - hlen) &~ 7; /* ip databytes per packet */ + + len = (if_mtu - hlen) &~ 7; /* ip databytes per packet */ if (len < 8) { error = -1; goto bad; @@ -136,18 +129,18 @@ ip_output(so, m0) */ m0 = m; mhlen = sizeof (struct ip); - for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) { + for (off = hlen + len; off < ip->ip_len; off += len) { register struct ip *mhip; m = m_get(); if (m == 0) { error = -1; - STAT(ipstat.ips_odropped++); + ipstat.ips_odropped++; goto sendorfree; } - m->m_data += IF_MAXLINKHDR; + m->m_data += if_maxlinkhdr; mhip = mtod(m, struct ip *); *mhip = *ip; - + /* No options */ /* if (hlen > sizeof (struct ip)) { * mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); @@ -160,28 +153,28 @@ ip_output(so, m0) mhip->ip_off |= IP_MF; if (off + len >= (u_int16_t)ip->ip_len) len = (u_int16_t)ip->ip_len - off; - else + else mhip->ip_off |= IP_MF; mhip->ip_len = htons((u_int16_t)(len + mhlen)); - + if (m_copy(m, m0, off, len) < 0) { error = -1; goto sendorfree; } - + mhip->ip_off = htons((u_int16_t)mhip->ip_off); mhip->ip_sum = 0; mhip->ip_sum = cksum(m, mhlen); *mnext = m; mnext = &m->m_nextpkt; - STAT(ipstat.ips_ofragments++); + ipstat.ips_ofragments++; } /* * Update first fragment by trimming what's been copied out * and updating header, then send each fragment (in order). */ m = m0; - m_adj(m, hlen + firstlen - (u_int16_t)ip->ip_len); + m_adj(m, hlen + firstlen - ip->ip_len); ip->ip_len = htons((u_int16_t)m->m_len); ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF)); ip->ip_sum = 0; @@ -197,7 +190,7 @@ sendorfree: } if (error == 0) - STAT(ipstat.ips_fragmented++); + ipstat.ips_fragmented++; } done: diff --git a/BasiliskII/src/slirp/libslirp.h b/BasiliskII/src/slirp/libslirp.h index 7e4cfa98..8a1aa31e 100644 --- a/BasiliskII/src/slirp/libslirp.h +++ b/BasiliskII/src/slirp/libslirp.h @@ -1,33 +1,39 @@ #ifndef _LIBSLIRP_H #define _LIBSLIRP_H +#ifdef _WIN32 +#include +int inet_aton(const char *cp, struct in_addr *ia); +#else +#include +#include +#endif + #ifdef __cplusplus extern "C" { #endif -void slirp_init(void); +int slirp_init(void); -void slirp_select_fill(int *pnfds, - fd_set *readfds, fd_set *writefds, fd_set *xfds); +int slirp_select_fill(int *pnfds, + fd_set *readfds, fd_set *writefds, fd_set *xfds); void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds); -void slirp_input(const uint8_t *pkt, int pkt_len); +void slirp_input(const uint8 *pkt, int pkt_len); /* you must provide the following functions: */ int slirp_can_output(void); -void slirp_output(const uint8_t *pkt, int pkt_len); +void slirp_output(const uint8 *pkt, int pkt_len); -int slirp_redir(int is_udp, int host_port, +int slirp_redir(int is_udp, int host_port, struct in_addr guest_addr, int guest_port); -int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, +int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, int guest_port); extern const char *tftp_prefix; extern char slirp_hostname[33]; -void slirp_stats(void); - #ifdef __cplusplus } #endif diff --git a/BasiliskII/src/slirp/main.h b/BasiliskII/src/slirp/main.h index c01addac..181b6ae8 100644 --- a/BasiliskII/src/slirp/main.h +++ b/BasiliskII/src/slirp/main.h @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -42,6 +42,7 @@ extern char *username; extern char *socket_path; extern int towrite_max; extern int ppp_exit; +extern int so_options; extern int tcp_keepintvl; extern uint8_t client_ethaddr[6]; diff --git a/BasiliskII/src/slirp/mbuf.c b/BasiliskII/src/slirp/mbuf.c index 5d125542..5a16fab8 100644 --- a/BasiliskII/src/slirp/mbuf.c +++ b/BasiliskII/src/slirp/mbuf.c @@ -15,49 +15,54 @@ * the flags */ +#include #include struct mbuf *mbutl; char *mclrefcnt; int mbuf_alloced = 0; struct mbuf m_freelist, m_usedlist; -#define MBUF_THRESH 30 +int mbuf_thresh = 30; int mbuf_max = 0; +size_t msize; -/* - * Find a nice value for msize - * XXX if_maxlinkhdr already in mtu - */ -#define MSIZE (IF_MTU + IF_MAXLINKHDR + sizeof(struct m_hdr ) + 6) - -void -m_init() +void m_init() { m_freelist.m_next = m_freelist.m_prev = &m_freelist; m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist; + msize_init(); +} + +void msize_init() +{ + /* + * Find a nice value for msize + * XXX if_maxlinkhdr already in mtu + */ + msize = (if_mtu>if_mru?if_mtu:if_mru) + + if_maxlinkhdr + sizeof(struct m_hdr ) + 6; } /* * Get an mbuf from the free list, if there are none * malloc one - * + * * Because fragmentation can occur if we alloc new mbufs and * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE, * which tells m_free to actually free() it */ -struct mbuf * -m_get() +struct mbuf *m_get() { register struct mbuf *m; int flags = 0; - + DEBUG_CALL("m_get"); - + if (m_freelist.m_next == &m_freelist) { - m = (struct mbuf *)malloc(MSIZE); + m = (struct mbuf *)malloc(msize); if (m == NULL) goto end_error; mbuf_alloced++; - if (mbuf_alloced > MBUF_THRESH) + if (mbuf_alloced > mbuf_thresh) flags = M_DOFREE; if (mbuf_alloced > mbuf_max) mbuf_max = mbuf_alloced; @@ -65,13 +70,13 @@ m_get() m = m_freelist.m_next; remque(m); } - + /* Insert it in the used list */ insque(m,&m_usedlist); m->m_flags = (flags | M_USEDLIST); - + /* Initialise it */ - m->m_size = MSIZE - sizeof(struct m_hdr); + m->m_size = msize - sizeof(struct m_hdr); m->m_data = m->m_dat; m->m_len = 0; m->m_nextpkt = 0; @@ -81,19 +86,17 @@ end_error: return m; } -void -m_free(m) - struct mbuf *m; +void m_free(struct mbuf *m) { - + DEBUG_CALL("m_free"); DEBUG_ARG("m = %lx", (long )m); - + if(m) { /* Remove from m_usedlist */ if (m->m_flags & M_USEDLIST) remque(m); - + /* If it's M_EXT, free() it */ if (m->m_flags & M_EXT) free(m->m_ext); @@ -116,16 +119,14 @@ m_free(m) * the other.. if result is too big for one mbuf, malloc() * an M_EXT data segment */ -void -m_cat(m, n) - register struct mbuf *m, *n; +void m_cat(register struct mbuf *m, register struct mbuf *n) { /* * If there's no room, realloc */ if (M_FREEROOM(m) < n->m_len) m_inc(m,m->m_size+MINCSIZE); - + memcpy(m->m_data+m->m_len, n->m_data, n->m_len); m->m_len += n->m_len; @@ -134,23 +135,20 @@ m_cat(m, n) /* make m size bytes large */ -void -m_inc(m, size) - struct mbuf *m; - int size; +void m_inc(struct mbuf *m, u_int size) { - int datasize; + int datasize; /* some compiles throw up on gotos. This one we can fake. */ if(m->m_size>size) return; if (m->m_flags & M_EXT) { - datasize = m->m_data - m->m_ext; + datasize = m->m_data - m->m_ext; m->m_ext = (char *)realloc(m->m_ext,size); /* if (m->m_ext == NULL) * return (struct mbuf *)NULL; - */ - m->m_data = m->m_ext + datasize; + */ + m->m_data = m->m_ext + datasize; } else { char *dat; datasize = m->m_data - m->m_dat; @@ -159,22 +157,19 @@ m_inc(m, size) * return (struct mbuf *)NULL; */ memcpy(dat, m->m_dat, m->m_size); - + m->m_ext = dat; m->m_data = m->m_ext + datasize; m->m_flags |= M_EXT; } - + m->m_size = size; } -void -m_adj(m, len) - struct mbuf *m; - int len; +void m_adj(struct mbuf *m, int len) { if (m == NULL) return; @@ -194,9 +189,7 @@ m_adj(m, len) * Copy len bytes from m, starting off bytes into n */ int -m_copy(n, m, off, len) - struct mbuf *n, *m; - int off, len; +m_copy(struct mbuf *n, struct mbuf *m, u_int off, u_int len) { if (len > M_FREEROOM(n)) return -1; @@ -212,12 +205,10 @@ m_copy(n, m, off, len) * XXX This is a kludge, I should eliminate the need for it * Fortunately, it's not used often */ -struct mbuf * -dtom(dat) - void *dat; +struct mbuf *dtom(void *dat) { struct mbuf *m; - + DEBUG_CALL("dtom"); DEBUG_ARG("dat = %lx", (long )dat); @@ -231,9 +222,9 @@ dtom(dat) return m; } } - + DEBUG_ERROR((dfd, "dtom failed")); - + return (struct mbuf *)0; } diff --git a/BasiliskII/src/slirp/mbuf.h b/BasiliskII/src/slirp/mbuf.h index f9f21325..11b252bb 100644 --- a/BasiliskII/src/slirp/mbuf.h +++ b/BasiliskII/src/slirp/mbuf.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -67,14 +63,14 @@ struct m_hdr { struct mbuf *mh_prevpkt; /* Flags aren't used in the output queue */ int mh_flags; /* Misc flags */ - int mh_size; /* Size of data */ + size_t mh_size; /* Size of data */ struct socket *mh_so; - + caddr_t mh_data; /* Location of data */ - int mh_len; /* Amount of data in this mbuf */ + size_t mh_len; /* Amount of data in this mbuf */ }; -/* +/* * How much room is in the mbuf, from m_data to the end of the mbuf */ #define M_ROOM(m) ((m->m_flags & M_EXT)? \ @@ -126,7 +122,7 @@ struct mbuf { struct mbstat { int mbs_alloced; /* Number of mbufs allocated */ - + }; extern struct mbstat mbstat; @@ -134,13 +130,14 @@ extern int mbuf_alloced; extern struct mbuf m_freelist, m_usedlist; extern int mbuf_max; -void m_init _P((void)); -struct mbuf * m_get _P((void)); -void m_free _P((struct mbuf *)); -void m_cat _P((register struct mbuf *, register struct mbuf *)); -void m_inc _P((struct mbuf *, int)); -void m_adj _P((struct mbuf *, int)); -int m_copy _P((struct mbuf *, struct mbuf *, int, int)); -struct mbuf * dtom _P((void *)); +void m_init(void); +void msize_init(void); +struct mbuf * m_get(void); +void m_free(struct mbuf *); +void m_cat(register struct mbuf *, register struct mbuf *); +void m_inc(struct mbuf *, u_int); +void m_adj(struct mbuf *, int); +int m_copy(struct mbuf *, struct mbuf *, u_int, u_int); +struct mbuf * dtom(void *); #endif diff --git a/BasiliskII/src/slirp/misc.c b/BasiliskII/src/slirp/misc.c index 14808fe2..b80caf66 100644 --- a/BasiliskII/src/slirp/misc.c +++ b/BasiliskII/src/slirp/misc.c @@ -1,24 +1,23 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * + * * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ #define WANT_SYS_IOCTL_H +#include #include -u_int curtime, time_fasttimo, last_slowtimo; +u_int curtime, time_fasttimo, last_slowtimo, detach_time; +u_int detach_wait = 600000; /* 10 minutes */ #if 0 int x_port = -1; int x_display = 0; int x_screen = 0; -int -show_x(buff, inso) - char *buff; - struct socket *inso; +int show_x(char *buff, struct socket *inso) { if (x_port < 0) { lprint("X Redir: X not being redirected.\r\n"); @@ -30,7 +29,7 @@ show_x(buff, inso) if (x_display) lprint("X Redir: Redirecting to display %d\r\n", x_display); } - + return CFG_OK; } @@ -38,15 +37,10 @@ show_x(buff, inso) /* * XXX Allow more than one X redirection? */ -void -redir_x(inaddr, start_port, display, screen) - u_int32_t inaddr; - int start_port; - int display; - int screen; +void redir_x(u_int32_t inaddr, int start_port, int display, int screen) { int i; - + if (x_port >= 0) { lprint("X Redir: X already being redirected.\r\n"); show_x(0, 0); @@ -67,34 +61,33 @@ redir_x(inaddr, start_port, display, screen) #endif #ifndef HAVE_INET_ATON -int -inet_aton(cp, ia) - const char *cp; - struct in_addr *ia; +int inet_aton(const char *cp, struct in_addr *ia) { - u_int32_t addr = inet_addr(cp); - if (addr == 0xffffffff) - return 0; - ia->s_addr = addr; - return 1; + return inet_pton(AF_INET, cp, &ia->s_addr); } #endif /* * Get our IP address and put it in our_addr */ -void -getouraddr() +void getouraddr() { char buff[256]; - struct hostent *he = NULL; - if (gethostname(buff,256) == 0) - he = gethostbyname(buff); - if (he) - our_addr = *(struct in_addr *)he->h_addr; - if (our_addr.s_addr == 0) - our_addr.s_addr = loopback_addr.s_addr; + if (gethostname(buff, sizeof(buff)) == 0) + { + struct addrinfo hints = { 0 }; + hints.ai_flags = AI_NUMERICHOST; + hints.ai_family = AF_INET; + struct addrinfo* ai; + if (getaddrinfo(buff, NULL, &hints, &ai) == 0) + { + our_addr = *(struct in_addr *)ai->ai_addr->sa_data; + freeaddrinfo(ai); + } + } + if (our_addr.s_addr == 0) + our_addr.s_addr = loopback_addr.s_addr; } #if SIZEOF_CHAR_P == 8 @@ -104,10 +97,7 @@ struct quehead_32 { u_int32_t qh_rlink; }; -inline void -insque_32(a, b) - void *a; - void *b; +inline void insque_32(void *a, void *b) { register struct quehead_32 *element = (struct quehead_32 *) a; register struct quehead_32 *head = (struct quehead_32 *) b; @@ -118,9 +108,7 @@ insque_32(a, b) = (u_int32_t)element; } -inline void -remque_32(a) - void *a; +inline void remque_32(void *a) { register struct quehead_32 *element = (struct quehead_32 *) a; ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; @@ -135,9 +123,7 @@ struct quehead { struct quehead *qh_rlink; }; -inline void -insque(a, b) - void *a, *b; +void insque(void *a, void *b) { register struct quehead *element = (struct quehead *) a; register struct quehead *head = (struct quehead *) b; @@ -148,9 +134,7 @@ insque(a, b) = (struct quehead *)element; } -inline void -remque(a) - void *a; +void remque(void *a) { register struct quehead *element = (struct quehead *) a; ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; @@ -162,22 +146,16 @@ remque(a) /* #endif */ -int -add_exec(ex_ptr, do_pty, exec, addr, port) - struct ex_list **ex_ptr; - int do_pty; - char *exec; - int addr; - int port; +int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port) { struct ex_list *tmp_ptr; - + /* First, check if the port is "bound" */ for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr) return -1; } - + tmp_ptr = *ex_ptr; *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list)); (*ex_ptr)->ex_fport = port; @@ -197,9 +175,7 @@ add_exec(ex_ptr, do_pty, exec, addr, port) extern int sys_nerr; extern char *sys_errlist[]; -char * -strerror(error) - int error; +char *strerror(int error) { if (error < sys_nerr) return sys_errlist[error]; @@ -212,8 +188,7 @@ strerror(error) #ifdef _WIN32 -int -fork_exec(struct socket *so, const char *ex, int do_pty) +int fork_exec(struct socket *so, char *ex, int do_pty) { /* not implemented */ return 0; @@ -221,16 +196,13 @@ fork_exec(struct socket *so, const char *ex, int do_pty) #else -#ifndef CONFIG_QEMU -int -slirp_openpty(amaster, aslave) - int *amaster, *aslave; +int slirp_openpty(int *amaster, int *aslave) { register int master, slave; #ifdef HAVE_GRANTPT char *ptr; - + if ((master = open("/dev/ptmx", O_RDWR)) < 0 || grantpt(master) < 0 || unlockpt(master) < 0 || @@ -238,7 +210,7 @@ slirp_openpty(amaster, aslave) close(master); return -1; } - + if ((slave = open(ptr, O_RDWR)) < 0 || ioctl(slave, I_PUSH, "ptem") < 0 || ioctl(slave, I_PUSH, "ldterm") < 0 || @@ -247,16 +219,16 @@ slirp_openpty(amaster, aslave) close(slave); return -1; } - + *amaster = master; *aslave = slave; return 0; - + #else - + static char line[] = "/dev/ptyXX"; register const char *cp1, *cp2; - + for (cp1 = "pqrsPQRS"; *cp1; cp1++) { line[8] = *cp1; for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { @@ -286,7 +258,6 @@ slirp_openpty(amaster, aslave) return (-1); #endif } -#endif /* * XXX This is ugly @@ -294,57 +265,53 @@ slirp_openpty(amaster, aslave) * process, which connects to this socket, after which we * exec the wanted program. If something (strange) happens, * the accept() call could block us forever. - * + * * do_pty = 0 Fork/exec inetd style * do_pty = 1 Fork/exec using slirp.telnetd * do_ptr = 2 Fork/exec using pty */ -int -fork_exec(struct socket *so, const char *ex, int do_pty) +int fork_exec(struct socket *so, char *ex, int do_pty) { int s; struct sockaddr_in addr; - int addrlen = sizeof(addr); + socklen_t addrlen = sizeof(addr); int opt; - int master = -1; + int master; char *argv[256]; #if 0 char buff[256]; #endif /* don't want to clobber the original */ char *bptr; - const char *curarg; + char *curarg; int c, i, ret; - + DEBUG_CALL("fork_exec"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("ex = %lx", (long)ex); DEBUG_ARG("do_pty = %lx", (long)do_pty); - + if (do_pty == 2) { -#if 0 if (slirp_openpty(&master, &s) == -1) { lprint("Error: openpty failed: %s\n", strerror(errno)); return 0; } -#else - return 0; -#endif } else { + memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; - + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 || listen(s, 1) < 0) { lprint("Error: inet socket: %s\n", strerror(errno)); closesocket(s); - + return 0; } } - + switch(fork()) { case -1: lprint("Error: fork failed: %s\n", strerror(errno)); @@ -352,7 +319,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) if (do_pty == 2) close(master); return 0; - + case 0: /* Set the DISPLAY */ if (do_pty == 2) { @@ -374,7 +341,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) ret = connect(s, (struct sockaddr *)&addr, addrlen); } while (ret < 0 && errno == EINTR); } - + #if 0 if (x_port >= 0) { #ifdef HAVE_SETENV @@ -385,13 +352,13 @@ fork_exec(struct socket *so, const char *ex, int do_pty) putenv(buff); #endif } -#endif +#endif dup2(s, 0); dup2(s, 1); dup2(s, 2); - for (s = getdtablesize() - 1; s >= 3; s--) + for (s = 3; s <= 255; s++) close(s); - + i = 0; bptr = strdup(ex); /* No need to free() this */ if (do_pty == 1) { @@ -409,21 +376,21 @@ fork_exec(struct socket *so, const char *ex, int do_pty) *bptr++ = (char)0; argv[i++] = strdup(curarg); } while (c); - + argv[i] = 0; execvp(argv[0], argv); - + /* Ooops, failed, let's tell the user why */ { char buff[256]; - - sprintf(buff, "Error: execvp of %s failed: %s\n", + + sprintf(buff, "Error: execvp of %s failed: %s\n", argv[0], strerror(errno)); write(2, buff, strlen(buff)+1); } close(0); close(1); close(2); /* XXX */ exit(1); - + default: if (do_pty == 2) { close(s); @@ -446,36 +413,32 @@ fork_exec(struct socket *so, const char *ex, int do_pty) setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); } fd_nonblock(so->s); - + /* Append the telnet options now */ if (so->so_m != 0 && do_pty == 1) { sbappend(so, so->so_m); so->so_m = 0; } - + return 1; } } #endif #ifndef HAVE_STRDUP -char * -strdup(str) - const char *str; +char *strdup(const char *str) { char *bptr; - + bptr = (char *)malloc(strlen(str)+1); strcpy(bptr, str); - + return bptr; } #endif #if 0 -void -snooze_hup(num) - int num; +void snooze_hup(int num) { int s, ret; #ifndef NO_UNIX_SOCKETS @@ -483,7 +446,7 @@ snooze_hup(num) #endif struct sockaddr_in sock_in; char buff[256]; - + ret = -1; if (slirp_socket_passwd) { s = socket(AF_INET, SOCK_STREAM, 0); @@ -513,51 +476,48 @@ snooze_hup(num) #endif slirp_exit(0); } - - -void -snooze() + + +void snooze() { sigset_t s; int i; - + /* Don't need our data anymore */ /* XXX This makes SunOS barf */ /* brk(0); */ - + /* Close all fd's */ for (i = 255; i >= 0; i--) close(i); - + signal(SIGQUIT, slirp_exit); signal(SIGHUP, snooze_hup); sigemptyset(&s); - + /* Wait for any signal */ sigsuspend(&s); - + /* Just in case ... */ exit(255); } -void -relay(s) - int s; +void relay(int s) { char buf[8192]; int n; fd_set readfds; struct ttys *ttyp; - + /* Don't need our data anymore */ /* XXX This makes SunOS barf */ /* brk(0); */ - + signal(SIGQUIT, slirp_exit); signal(SIGHUP, slirp_exit); signal(SIGINT, slirp_exit); signal(SIGTERM, slirp_exit); - + /* Fudge to get term_raw and term_restore to work */ if (NULL == (ttyp = tty_attach (0, slirp_tty))) { lprint ("Error: tty_attach failed in misc.c:relay()\r\n"); @@ -566,18 +526,18 @@ relay(s) ttyp->fd = 0; ttyp->flags |= TTY_CTTY; term_raw(ttyp); - + while (1) { FD_ZERO(&readfds); - + FD_SET(0, &readfds); FD_SET(s, &readfds); - + n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0); - + if (n <= 0) slirp_exit(0); - + if (FD_ISSET(0, &readfds)) { n = read(0, buf, 8192); if (n <= 0) @@ -586,7 +546,7 @@ relay(s) if (n <= 0) slirp_exit(0); } - + if (FD_ISSET(s, &readfds)) { n = read(s, buf, 8192); if (n <= 0) @@ -596,43 +556,20 @@ relay(s) slirp_exit(0); } } - + /* Just in case.... */ exit(1); } #endif -#ifdef CONFIG_QEMU -extern void term_vprintf(const char *fmt, va_list ap); +int (*lprint_print)(void *, const char *, va_list); +char *lprint_ptr, *lprint_ptr2, **lprint_arg; void lprint(const char *format, ...) -{ - va_list args; - - va_start(args, format); - term_vprintf(format, args); - va_end(args); -} -#else -int (*lprint_print) _P((void *, const char *, va_list)); -char *lprint_ptr, *lprint_ptr2, **lprint_arg; - -void -#ifdef __STDC__ -lprint(const char *format, ...) -#else -lprint(va_alist) va_dcl -#endif { va_list args; - -#ifdef __STDC__ - va_start(args, format); -#else - char *format; - va_start(args); - format = va_arg(args, char *); -#endif + + va_start(args, format); #if 0 /* If we're printing to an sbuf, make sure there's enough room */ /* XXX +100? */ @@ -642,33 +579,33 @@ lprint(va_alist) va_dcl int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data; int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data; int deltap = lprint_ptr - lprint_sb->sb_data; - + lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data, lprint_sb->sb_datalen + TCP_SNDSPACE); - + /* Adjust all values */ lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw; lprint_sb->sb_rptr = lprint_sb->sb_data + deltar; lprint_ptr = lprint_sb->sb_data + deltap; - + lprint_sb->sb_datalen += TCP_SNDSPACE; } } -#endif +#endif if (lprint_print) lprint_ptr += (*lprint_print)(*lprint_arg, format, args); - + /* Check if they want output to be logged to file as well */ if (lfd) { - /* + /* * Remove \r's * otherwise you'll get ^M all over the file */ int len = strlen(format); char *bptr1, *bptr2; - + bptr1 = bptr2 = strdup(format); - + while (len--) { if (*bptr1 == '\r') memcpy(bptr1, bptr1+1, len+1); @@ -681,9 +618,7 @@ lprint(va_alist) va_dcl va_end(args); } -void -add_emu(buff) - char *buff; +void add_emu(char *buff) { u_int lport, fport; u_int8_t tos = 0, emu = 0; @@ -691,12 +626,12 @@ add_emu(buff) char *buff3 = buff4; struct emu_t *emup; struct socket *so; - + if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) { lprint("Error: Bad arguments\r\n"); return; } - + if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) { lport = 0; if (sscanf(buff1, "%d", &fport) != 1) { @@ -704,7 +639,7 @@ add_emu(buff) return; } } - + if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) { buff3 = 0; if (sscanf(buff2, "%256s", buff1) != 1) { @@ -712,7 +647,7 @@ add_emu(buff) return; } } - + if (buff3) { if (strcmp(buff3, "lowdelay") == 0) tos = IPTOS_LOWDELAY; @@ -723,7 +658,7 @@ add_emu(buff) return; } } - + if (strcmp(buff1, "ftp") == 0) emu = EMU_FTP; else if (strcmp(buff1, "irc") == 0) @@ -734,7 +669,7 @@ add_emu(buff) lprint("Error: Unknown service\r\n"); return; } - + /* First, check that it isn't already emulated */ for (emup = tcpemu; emup; emup = emup->next) { if (emup->lport == lport && emup->fport == fport) { @@ -742,7 +677,7 @@ add_emu(buff) return; } } - + /* link it */ emup = (struct emu_t *)malloc(sizeof (struct emu_t)); emup->lport = (u_int16_t)lport; @@ -751,7 +686,7 @@ add_emu(buff) emup->emu = emu; emup->next = tcpemu; tcpemu = emup; - + /* And finally, mark all current sessions, if any, as being emulated */ for (so = tcb.so_next; so != &tcb; so = so->so_next) { if ((lport && lport == ntohs(so->so_lport)) || @@ -762,10 +697,9 @@ add_emu(buff) so->so_iptos = tos; } } - + lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport); } -#endif #ifdef BAD_SPRINTF @@ -776,51 +710,33 @@ add_emu(buff) * Some BSD-derived systems have a sprintf which returns char * */ -int -vsprintf_len(string, format, args) - char *string; - const char *format; - va_list args; +int vsprintf_len(char *string, const char *format, va_list args) { vsprintf(string, format, args); return strlen(string); } -int -#ifdef __STDC__ -sprintf_len(char *string, const char *format, ...) -#else -sprintf_len(va_alist) va_dcl -#endif +int sprintf_len(char *string, const char *format, ...) { va_list args; -#ifdef __STDC__ va_start(args, format); -#else - char *string; - char *format; - va_start(args); - string = va_arg(args, char *); - format = va_arg(args, char *); -#endif vsprintf(string, format, args); + va_end(args); return strlen(string); } #endif -void -u_sleep(usec) - int usec; +void u_sleep(int usec) { struct timeval t; fd_set fdset; - + FD_ZERO(&fdset); - + t.tv_sec = 0; t.tv_usec = usec * 1000; - + select(0, &fdset, &fdset, &fdset, &t); } @@ -828,34 +744,30 @@ u_sleep(usec) * Set fd blocking and non-blocking */ -void -fd_nonblock(fd) - int fd; +void fd_nonblock(int fd) { -#ifdef FIONBIO - int opt = 1; - +#if defined USE_FIONBIO && defined FIONBIO + ioctlsockopt_t opt = 1; + ioctlsocket(fd, FIONBIO, &opt); #else int opt; - + opt = fcntl(fd, F_GETFL, 0); opt |= O_NONBLOCK; fcntl(fd, F_SETFL, opt); #endif } -void -fd_block(fd) - int fd; +void fd_block(int fd) { -#ifdef FIONBIO - int opt = 0; - +#if defined USE_FIONBIO && defined FIONBIO + ioctlsockopt_t opt = 0; + ioctlsocket(fd, FIONBIO, &opt); #else int opt; - + opt = fcntl(fd, F_GETFL, 0); opt &= ~O_NONBLOCK; fcntl(fd, F_SETFL, opt); @@ -867,22 +779,17 @@ fd_block(fd) /* * invoke RSH */ -int -rsh_exec(so,ns, user, host, args) - struct socket *so; - struct socket *ns; - char *user; - char *host; - char *args; +int rsh_exec(struct socket *so, struct socket *ns, + char *user, char *host, char *args) { int fd[2]; int fd0[2]; int s; char buff[256]; - + DEBUG_CALL("rsh_exec"); DEBUG_ARG("so = %lx", (long)so); - + if (pipe(fd)<0) { lprint("Error: pipe failed: %s\n", strerror(errno)); return 0; @@ -903,7 +810,7 @@ rsh_exec(so,ns, user, host, args) return 0; } #endif - + switch(fork()) { case -1: lprint("Error: fork failed: %s\n", strerror(errno)); @@ -912,11 +819,11 @@ rsh_exec(so,ns, user, host, args) close(fd0[0]); close(fd0[1]); return 0; - + case 0: close(fd[0]); close(fd0[0]); - + /* Set the DISPLAY */ if (x_port >= 0) { #ifdef HAVE_SETENV @@ -927,29 +834,29 @@ rsh_exec(so,ns, user, host, args) putenv(buff); #endif } - + dup2(fd0[1], 0); dup2(fd0[1], 1); dup2(fd[1], 2); for (s = 3; s <= 255; s++) close(s); - + execlp("rsh","rsh","-l", user, host, args, NULL); - + /* Ooops, failed, let's tell the user why */ - - sprintf(buff, "Error: execlp of %s failed: %s\n", + + sprintf(buff, "Error: execlp of %s failed: %s\n", "rsh", strerror(errno)); write(2, buff, strlen(buff)+1); close(0); close(1); close(2); /* XXX */ exit(1); - + default: close(fd[1]); close(fd0[1]); ns->s=fd[0]; so->s=fd0[0]; - + return 1; } } diff --git a/BasiliskII/src/slirp/misc.h b/BasiliskII/src/slirp/misc.h index e405e38d..381f5f3e 100644 --- a/BasiliskII/src/slirp/misc.h +++ b/BasiliskII/src/slirp/misc.h @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -12,22 +12,22 @@ struct ex_list { int ex_pty; /* Do we want a pty? */ int ex_addr; /* The last byte of the address */ int ex_fport; /* Port to telnet to */ - const char *ex_exec; /* Command line of what to exec */ + char *ex_exec; /* Command line of what to exec */ struct ex_list *ex_next; }; extern struct ex_list *exec_list; -extern u_int curtime, time_fasttimo, last_slowtimo; +extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait; -extern int (*lprint_print) _P((void *, const char *, va_list)); +extern int (*lprint_print)(void *, const char *, va_list); extern char *lprint_ptr, *lprint_ptr2, **lprint_arg; extern struct sbuf *lprint_sb; #ifndef HAVE_STRDUP -char *strdup _P((const char *)); +char *strdup(const char *); #endif -void do_wait _P((int)); +void do_wait(int); #define EMU_NONE 0x0 @@ -63,27 +63,25 @@ struct emu_t { struct emu_t *next; }; -#ifndef CONFIG_QEMU extern struct emu_t *tcpemu; -#endif extern int x_port, x_server, x_display; -int show_x _P((char *, struct socket *)); -void redir_x _P((u_int32_t, int, int, int)); -void getouraddr _P((void)); -inline void slirp_insque _P((void *, void *)); -inline void slirp_remque _P((void *)); -int add_exec _P((struct ex_list **, int, char *, int, int)); -int slirp_openpty _P((int *, int *)); -int fork_exec(struct socket *so, const char *ex, int do_pty); -void snooze_hup _P((int)); -void snooze _P((void)); -void relay _P((int)); -void add_emu _P((char *)); -void u_sleep _P((int)); -void fd_nonblock _P((int)); -void fd_block _P((int)); -int rsh_exec _P((struct socket *, struct socket *, char *, char *, char *)); +int show_x(char *, struct socket *); +void redir_x(u_int32_t, int, int, int); +void getouraddr(void); +void slirp_insque(void *, void *); +void slirp_remque(void *); +int add_exec(struct ex_list **, int, char *, int, int); +int slirp_openpty(int *, int *); +int fork_exec(struct socket *, char *, int); +void snooze_hup(int); +void snooze(void); +void relay(int); +void add_emu(char *); +void u_sleep(int); +void fd_nonblock(int); +void fd_block(int); +int rsh_exec(struct socket *, struct socket *, char *, char *, char *); #endif diff --git a/BasiliskII/src/slirp/sbuf.c b/BasiliskII/src/slirp/sbuf.c index 02c5fce0..278e3687 100644 --- a/BasiliskII/src/slirp/sbuf.c +++ b/BasiliskII/src/slirp/sbuf.c @@ -1,37 +1,31 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ +#include #include -static void sbappendsb(struct sbuf *sb, struct mbuf *m); - /* Done as a macro in socket.h */ /* int - * sbspace(struct sockbuff *sb) + * sbspace(struct sockbuff *sb) * { * return SB_DATALEN - sb->sb_cc; * } */ -void -sbfree(sb) - struct sbuf *sb; +void sbfree(struct sbuf *sb) { free(sb->sb_data); } -void -sbdrop(sb, num) - struct sbuf *sb; - int num; +void sbdrop(struct sbuf *sb, u_int num) { - /* + /* * We can only drop how much we have - * This should never succeed + * This should never succeed */ if(num > sb->sb_cc) num = sb->sb_cc; @@ -39,13 +33,10 @@ sbdrop(sb, num) sb->sb_rptr += num; if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen) sb->sb_rptr -= sb->sb_datalen; - + } -void -sbreserve(sb, size) - struct sbuf *sb; - int size; +void sbreserve(struct sbuf *sb, size_t size) { if (sb->sb_data) { /* Already alloced, realloc if necessary */ @@ -73,24 +64,21 @@ sbreserve(sb, size) * this prevents an unnecessary copy of the data * (the socket is non-blocking, so we won't hang) */ -void -sbappend(so, m) - struct socket *so; - struct mbuf *m; +void sbappend(struct socket *so, struct mbuf *m) { int ret = 0; - + DEBUG_CALL("sbappend"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("m = %lx", (long)m); - DEBUG_ARG("m->m_len = %d", m->m_len); - + DEBUG_ARG("m->m_len = %zu", m->m_len); + /* Shouldn't happen, but... e.g. foreign host closes connection */ if (m->m_len <= 0) { m_free(m); return; } - + /* * If there is urgent data, call sosendoob * if not all was sent, sowrite will take care of the rest @@ -102,16 +90,16 @@ sbappend(so, m) sosendoob(so); return; } - + /* * We only write if there's nothing in the buffer, * ottherwise it'll arrive out of order, and hence corrupt */ if (!so->so_rcv.sb_cc) ret = send(so->s, m->m_data, m->m_len, 0); - + if (ret <= 0) { - /* + /* * Nothing was written * It's possible that the socket has closed, but * we don't need to check because if it has closed, @@ -135,11 +123,10 @@ sbappend(so, m) * Copy the data from m into sb * The caller is responsible to make sure there's enough room */ -static void -sbappendsb(struct sbuf *sb, struct mbuf *m) +void sbappendsb(struct sbuf *sb, struct mbuf *m) { int len, n, nn; - + len = m->m_len; if (sb->sb_wptr < sb->sb_rptr) { @@ -172,15 +159,10 @@ sbappendsb(struct sbuf *sb, struct mbuf *m) * Don't update the sbuf rptr, this will be * done in sbdrop when the data is acked */ -void -sbcopy(sb, off, len, to) - struct sbuf *sb; - int off; - int len; - char *to; +void sbcopy(struct sbuf *sb, u_int off, u_int len, char *to) { char *from; - + from = sb->sb_rptr + off; if (from >= sb->sb_data + sb->sb_datalen) from -= sb->sb_datalen; @@ -198,4 +180,4 @@ sbcopy(sb, off, len, to) memcpy(to+off,sb->sb_data,len); } } - + diff --git a/BasiliskII/src/slirp/sbuf.h b/BasiliskII/src/slirp/sbuf.h index a4f10362..04f7981c 100644 --- a/BasiliskII/src/slirp/sbuf.h +++ b/BasiliskII/src/slirp/sbuf.h @@ -1,13 +1,15 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ #ifndef _SBUF_H_ #define _SBUF_H_ +#include + #define sbflush(sb) sbdrop((sb),(sb)->sb_cc) #define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc) @@ -21,10 +23,11 @@ struct sbuf { char *sb_data; /* Actual data */ }; -void sbfree _P((struct sbuf *)); -void sbdrop _P((struct sbuf *, int)); -void sbreserve _P((struct sbuf *, int)); -void sbappend _P((struct socket *, struct mbuf *)); -void sbcopy _P((struct sbuf *, int, int, char *)); +void sbfree(struct sbuf *); +void sbdrop(struct sbuf *, u_int); +void sbreserve(struct sbuf *, size_t); +void sbappend(struct socket *, struct mbuf *); +void sbappendsb(struct sbuf *, struct mbuf *); +void sbcopy(struct sbuf *, u_int, u_int, char *); #endif diff --git a/BasiliskII/src/slirp/slirp.c b/BasiliskII/src/slirp/slirp.c index 303f4825..dc2fdc65 100644 --- a/BasiliskII/src/slirp/slirp.c +++ b/BasiliskII/src/slirp/slirp.c @@ -12,7 +12,7 @@ struct in_addr special_addr; /* virtual address alias for host */ struct in_addr alias_addr; -static const uint8_t special_ethaddr[6] = { +const uint8_t special_ethaddr[6] = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 }; @@ -38,10 +38,10 @@ static int get_dns_addr(struct in_addr *pdns_addr) DWORD ret; IP_ADDR_STRING *pIPAddr; struct in_addr tmp_addr; - + FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO)); BufLen = sizeof(FIXED_INFO); - + if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) { if (FixedInfo) { GlobalFree(FixedInfo); @@ -49,7 +49,7 @@ static int get_dns_addr(struct in_addr *pdns_addr) } FixedInfo = GlobalAlloc(GPTR, BufLen); } - + if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) { printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret ); if (FixedInfo) { @@ -58,14 +58,14 @@ static int get_dns_addr(struct in_addr *pdns_addr) } return -1; } - + pIPAddr = &(FixedInfo->DnsServerList); inet_aton(pIPAddr->IpAddress.String, &tmp_addr); *pdns_addr = tmp_addr; #if 0 printf( "DNS Servers:\n" ); printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); - + pIPAddr = FixedInfo -> DnsServerList.Next; while ( pIPAddr ) { printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String ); @@ -84,18 +84,16 @@ static int get_dns_addr(struct in_addr *pdns_addr) static int get_dns_addr(struct in_addr *pdns_addr) { char buff[512]; - char buff2[256]; + char buff2[256+1]; FILE *f; int found = 0; struct in_addr tmp_addr; - + f = fopen("/etc/resolv.conf", "r"); if (!f) return -1; -#ifdef DEBUG lprint("IP address of your DNS(s): "); -#endif while (fgets(buff, 512, f) != NULL) { if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { if (!inet_aton(buff2, &tmp_addr)) @@ -105,20 +103,13 @@ static int get_dns_addr(struct in_addr *pdns_addr) /* If it's the first one, set it to dns_addr */ if (!found) *pdns_addr = tmp_addr; -#ifdef DEBUG else lprint(", "); -#endif if (++found > 3) { -#ifdef DEBUG lprint("(more)"); -#endif break; - } -#ifdef DEBUG - else + } else lprint("%s", inet_ntoa(tmp_addr)); -#endif } } fclose(f); @@ -130,16 +121,16 @@ static int get_dns_addr(struct in_addr *pdns_addr) #endif #ifdef _WIN32 -static void slirp_cleanup(void) +void slirp_cleanup(void) { WSACleanup(); } #endif -void slirp_init(void) +int slirp_init(void) { // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); - + #ifdef _WIN32 { WSADATA Data; @@ -159,14 +150,13 @@ void slirp_init(void) /* set default addresses */ inet_aton("127.0.0.1", &loopback_addr); - if (get_dns_addr(&dns_addr) < 0) { - dns_addr = loopback_addr; - fprintf (stderr, "Warning: No DNS servers found\n"); - } + if (get_dns_addr(&dns_addr) < 0) + return -1; inet_aton(CTL_SPECIAL, &special_addr); - alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); - getouraddr(); + alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); + getouraddr(); + return 0; } #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) @@ -189,57 +179,56 @@ static void updtime(void) static void updtime(void) { gettimeofday(&tt, 0); - + curtime = (u_int)tt.tv_sec * (u_int)1000; curtime += (u_int)tt.tv_usec / (u_int)1000; - + if ((tt.tv_usec % 1000) >= 500) curtime++; } #endif -void slirp_select_fill(int *pnfds, - fd_set *readfds, fd_set *writefds, fd_set *xfds) +int slirp_select_fill(int *pnfds, + fd_set *readfds, fd_set *writefds, fd_set *xfds) { struct socket *so, *so_next; - struct timeval timeout; int nfds; - int tmp_time; + int timeout, tmp_time; /* fail safe */ global_readfds = NULL; global_writefds = NULL; global_xfds = NULL; - + nfds = *pnfds; /* * First, TCP sockets */ do_slowtimo = 0; if (link_up) { - /* + /* * *_slowtimo needs calling if there are IP fragments * in the fragment queue, or there are TCP connections active */ do_slowtimo = ((tcb.so_next != &tcb) || ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next)); - + for (so = tcb.so_next; so != &tcb; so = so_next) { so_next = so->so_next; - + /* * See if we need a tcp_fasttimo */ if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) - time_fasttimo = curtime; /* Flag when we want a fasttimo */ - + time_fasttimo = curtime; /* Flag when we want a fasttimo */ + /* * NOFDREF can include still connecting to local-host, * newly socreated() sockets etc. Don't want to select these. */ if (so->so_state & SS_NOFDREF || so->s == -1) - continue; - + continue; + /* * Set for reading sockets which are accepting */ @@ -248,7 +237,7 @@ void slirp_select_fill(int *pnfds, UPD_NFDS(so->s); continue; } - + /* * Set for writing sockets which are connecting */ @@ -257,7 +246,7 @@ void slirp_select_fill(int *pnfds, UPD_NFDS(so->s); continue; } - + /* * Set for writing if we are connected, can send more, and * we have something to send @@ -266,7 +255,7 @@ void slirp_select_fill(int *pnfds, FD_SET(so->s, writefds); UPD_NFDS(so->s); } - + /* * Set for reading (and urgent data) if we are connected, can * receive more, and we have room for it XXX /2 ? @@ -277,13 +266,13 @@ void slirp_select_fill(int *pnfds, UPD_NFDS(so->s); } } - + /* * UDP sockets */ for (so = udb.so_next; so != &udb; so = so_next) { so_next = so->so_next; - + /* * See if it's timed out */ @@ -294,7 +283,7 @@ void slirp_select_fill(int *pnfds, } else do_slowtimo = 1; /* Let socket expire */ } - + /* * When UDP packets are received from over the * link, they're sendto()'d straight away, so @@ -311,51 +300,58 @@ void slirp_select_fill(int *pnfds, } } } - + /* * Setup timeout to use minimum CPU usage, especially when idle */ - /* - * First, see the timeout needed by *timo - */ - timeout.tv_sec = 0; - timeout.tv_usec = -1; - /* - * If a slowtimo is needed, set timeout to 500ms from the last - * slow timeout. If a fast timeout is needed, set timeout within - * 200ms of when it was requested. - */ - if (do_slowtimo) { - /* XXX + 10000 because some select()'s aren't that accurate */ - timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000; - if (timeout.tv_usec < 0) - timeout.tv_usec = 0; - else if (timeout.tv_usec > 510000) - timeout.tv_usec = 510000; + timeout = -1; + /* + * If a slowtimo is needed, set timeout to 5ms from the last + * slow timeout. If a fast timeout is needed, set timeout within + * 2ms of when it was requested. + */ +# define SLOW_TIMO 5 +# define FAST_TIMO 2 + if (do_slowtimo) { + timeout = (SLOW_TIMO - (curtime - last_slowtimo)) * 1000; + if (timeout < 0) + timeout = 0; + else if (timeout > (SLOW_TIMO * 1000)) + timeout = SLOW_TIMO * 1000; + /* Can only fasttimo if we also slowtimo */ if (time_fasttimo) { - tmp_time = (200 - (curtime - time_fasttimo)) * 1000; + tmp_time = (FAST_TIMO - (curtime - time_fasttimo)) * 1000; if (tmp_time < 0) - tmp_time = 0; - + tmp_time = 0; + /* Choose the smallest of the 2 */ - if (tmp_time < timeout.tv_usec) - timeout.tv_usec = (u_int)tmp_time; + if (tmp_time < timeout) + timeout = tmp_time; } } - *pnfds = nfds; -} + *pnfds = nfds; + + /* + * Adjust the timeout to make the minimum timeout + * 2ms (XXX?) to lessen the CPU load + */ + if (timeout < (FAST_TIMO * 1000)) + timeout = FAST_TIMO * 1000; + + return timeout; +} void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) { - struct socket *so, *so_next; - int ret; + struct socket *so, *so_next; + int ret; - global_readfds = readfds; - global_writefds = writefds; - global_xfds = xfds; + global_readfds = readfds; + global_writefds = writefds; + global_xfds = xfds; /* Update time */ updtime(); @@ -364,11 +360,11 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) * See if anything has timed out */ if (link_up) { - if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) { + if (time_fasttimo && ((curtime - time_fasttimo) >= FAST_TIMO)) { tcp_fasttimo(); time_fasttimo = 0; } - if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) { + if (do_slowtimo && ((curtime - last_slowtimo) >= SLOW_TIMO)) { ip_slowtimo(); tcp_slowtimo(); last_slowtimo = curtime; @@ -390,7 +386,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) * (and they can crash the program) */ if (so->so_state & SS_NOFDREF || so->s == -1) - continue; + continue; /* * Check for URG data @@ -398,7 +394,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) * test for readfds below if this succeeds */ if (FD_ISSET(so->s, xfds)) - sorecvoob(so); + sorecvoob(so); /* * Check sockets for reading */ @@ -414,82 +410,88 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) /* Output it if we read something */ if (ret > 0) - tcp_output(sototcpcb(so)); + tcp_output(sototcpcb(so)); } /* * Check sockets for writing */ if (FD_ISSET(so->s, writefds)) { - /* - * Check for non-blocking, still-connecting sockets - */ - if (so->so_state & SS_ISFCONNECTING) { - /* Connected */ - so->so_state &= ~SS_ISFCONNECTING; + /* + * Check for non-blocking, still-connecting sockets + */ + if (so->so_state & SS_ISFCONNECTING) { + /* Connected */ + so->so_state &= ~SS_ISFCONNECTING; - ret = send(so->s, &ret, 0, 0); - if (ret < 0) { - /* XXXXX Must fix, zero bytes is a NOP */ - if (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINPROGRESS || errno == ENOTCONN) - continue; + ret = send(so->s, (char*)&ret, 0, 0); + if (ret < 0) { + /* XXXXX Must fix, zero bytes is a NOP */ + int error = WSAGetLastError(); + if (error == EAGAIN || error == WSAEWOULDBLOCK || + error == WSAEINPROGRESS || error == WSAENOTCONN) + continue; - /* else failed */ - so->so_state = SS_NOFDREF; - } - /* else so->so_state &= ~SS_ISFCONNECTING; */ + /* else failed */ + so->so_state = SS_NOFDREF; + } + /* else so->so_state &= ~SS_ISFCONNECTING; */ - /* - * Continue tcp_input - */ - tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); - /* continue; */ - } else - ret = sowrite(so); - /* - * XXXXX If we wrote something (a lot), there - * could be a need for a window update. - * In the worst case, the remote will send - * a window probe to get things going again - */ + /* + * Continue tcp_input + */ + tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); + /* continue; */ + } + else + ret = sowrite(so); + /* + * XXXXX If we wrote something (a lot), there + * could be a need for a window update. + * In the worst case, the remote will send + * a window probe to get things going again + */ } /* * Probe a still-connecting, non-blocking socket * to check if it's still alive - */ + */ #ifdef PROBE_CONN if (so->so_state & SS_ISFCONNECTING) { - ret = recv(so->s, (char *)&ret, 0,0); + ret = recv(so->s, (char *)&ret, 0, 0); - if (ret < 0) { - /* XXX */ - if (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINPROGRESS || errno == ENOTCONN) - continue; /* Still connecting, continue */ + if (ret < 0) { + /* XXX */ + int error = WSAGetLastError(); + if (error == EAGAIN || error == WSAEWOULDBLOCK || + error == WSAEINPROGRESS || error == WSAENOTCONN) + continue; /* Still connecting, continue */ - /* else failed */ - so->so_state = SS_NOFDREF; + /* else failed */ + so->so_state = SS_NOFDREF; - /* tcp_input will take care of it */ - } else { - ret = send(so->s, &ret, 0,0); - if (ret < 0) { - /* XXX */ - if (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINPROGRESS || errno == ENOTCONN) - continue; - /* else failed */ - so->so_state = SS_NOFDREF; - } else - so->so_state &= ~SS_ISFCONNECTING; + /* tcp_input will take care of it */ + } + else { + ret = send(so->s, &ret, 0, 0); + if (ret < 0) { + /* XXX */ + int error = WSAGetLastError(); + if (error == EAGAIN || error == WSAEWOULDBLOCK || + error == WSAEINPROGRESS || error == WSAENOTCONN) + continue; + /* else failed */ + so->so_state = SS_NOFDREF; + } + else + so->so_state &= ~SS_ISFCONNECTING; - } - tcp_input((struct mbuf *)NULL, sizeof(struct ip),so); - } /* SS_ISFCONNECTING */ + } + tcp_input((struct mbuf *)NULL, sizeof(struct ip), so); + } /* SS_ISFCONNECTING */ #endif - } + } /* * Now UDP sockets. @@ -500,25 +502,25 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) so_next = so->so_next; if (so->s != -1 && FD_ISSET(so->s, readfds)) { - sorecvfrom(so); - } + sorecvfrom(so); + } } - } +} /* * See if we can start outputting */ if (if_queued && link_up) - if_start(); + if_start(); /* clear global file descriptor sets. * these reside on the stack in vl.c * so they're unusable if we're not in * slirp_select_fill or slirp_select_poll. */ - global_readfds = NULL; - global_writefds = NULL; - global_xfds = NULL; + global_readfds = NULL; + global_writefds = NULL; + global_xfds = NULL; } #define ETH_ALEN 6 @@ -530,7 +532,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) #define ARPOP_REQUEST 1 /* ARP request */ #define ARPOP_REPLY 2 /* ARP reply */ -struct ethhdr +struct ethhdr { unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ unsigned char h_source[ETH_ALEN]; /* source ether addr */ @@ -568,7 +570,7 @@ void arp_input(const uint8_t *pkt, int pkt_len) switch(ar_op) { case ARPOP_REQUEST: if (!memcmp(ah->ar_tip, &special_addr, 3)) { - if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS) + if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS) goto arp_ok; for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { if (ex_ptr->ex_addr == ah->ar_tip[3]) @@ -609,8 +611,8 @@ void slirp_input(const uint8_t *pkt, int pkt_len) if (pkt_len < ETH_HLEN) return; - - proto = ntohs(*(uint16_t *)(pkt + 12)); + + proto = (pkt[12] << 8) | pkt[13]; switch(proto) { case ETH_P_ARP: arp_input(pkt, pkt_len); @@ -651,24 +653,24 @@ void if_encap(const uint8_t *ip_data, int ip_data_len) slirp_output(buf, ip_data_len + ETH_HLEN); } -int slirp_redir(int is_udp, int host_port, +int slirp_redir(int is_udp, int host_port, struct in_addr guest_addr, int guest_port) { if (is_udp) { - if (!udp_listen(htons(host_port), guest_addr.s_addr, + if (!udp_listen(htons(host_port), guest_addr.s_addr, htons(guest_port), 0)) return -1; } else { - if (!solisten(htons(host_port), guest_addr.s_addr, + if (!solisten(htons(host_port), guest_addr.s_addr, htons(guest_port), 0)) return -1; } return 0; } -int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, +int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, int guest_port) { - return add_exec(&exec_list, do_pty, (char *)args, + return add_exec(&exec_list, do_pty, (char *)args, addr_low_byte, htons(guest_port)); } diff --git a/BasiliskII/src/slirp/slirp.h b/BasiliskII/src/slirp/slirp.h index b8d756e5..b845caa7 100644 --- a/BasiliskII/src/slirp/slirp.h +++ b/BasiliskII/src/slirp/slirp.h @@ -3,21 +3,12 @@ #define CONFIG_QEMU -//#define DEBUG 1 - -// Uncomment the following line to enable SLIRP statistics printing in Qemu -//#define LOG_ENABLED - -#ifdef LOG_ENABLED -#define STAT(expr) expr -#else -#define STAT(expr) do { } while(0) -#endif +#define DEBUG 1 #ifndef CONFIG_QEMU #include "version.h" #endif -#include "config-host.h" +#include "config.h" #include "slirp_config.h" #ifdef _WIN32 @@ -28,20 +19,31 @@ typedef uint16_t u_int16_t; typedef uint32_t u_int32_t; typedef uint64_t u_int64_t; typedef char *caddr_t; +typedef int socklen_t; +typedef unsigned long ioctlsockopt_t; -#define WIN32_LEAN_AND_MEAN -# include # include +# include # include # include -# define EWOULDBLOCK WSAEWOULDBLOCK -# define EINPROGRESS WSAEINPROGRESS -# define ENOTCONN WSAENOTCONN -# define EHOSTUNREACH WSAEHOSTUNREACH -# define ENETUNREACH WSAENETUNREACH -# define ECONNREFUSED WSAECONNREFUSED +# define USE_FIONBIO 1 + +/* Basilisk II Router defines those */ +# define udp_read_completion slirp_udp_read_completion +# define write_udp slirp_write_udp +# define init_udp slirp_init_udp +# define final_udp slirp_final_udp #else +# define WSAGetLastError() (int)(errno) +# define WSASetLastError(e) (void)(errno = (e)) +# define WSAEWOULDBLOCK EWOULDBLOCK +# define WSAEINPROGRESS EINPROGRESS +# define WSAENOTCONN ENOTCONN +# define WSAEHOSTUNREACH EHOSTUNREACH +# define WSAENETUNREACH ENETUNREACH +# define WSAECONNREFUSED ECONNREFUSED +typedef int ioctlsockopt_t; # define ioctlsocket ioctl # define closesocket(s) close(s) # define O_BINARY 0 @@ -51,8 +53,13 @@ typedef char *caddr_t; #ifdef HAVE_SYS_BITYPES_H # include #endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifndef _WIN32 #include +#endif #ifdef NEED_TYPEDEFS typedef char int8_t; @@ -83,6 +90,11 @@ typedef unsigned char u_int8_t; # endif #endif /* NEED_TYPEDEFS */ +/* Basilisk II types glue */ +typedef u_int8_t uint8; +typedef u_int16_t uint16; +typedef u_int32_t uint32; + #ifdef HAVE_UNISTD_H # include #endif @@ -117,17 +129,6 @@ typedef unsigned char u_int8_t; #ifndef _WIN32 #include -#endif - -#ifndef _P -#ifndef NO_PROTOTYPES -# define _P(x) x -#else -# define _P(x) () -#endif -#endif - -#ifndef _WIN32 #include #include #endif @@ -138,20 +139,23 @@ typedef unsigned char u_int8_t; /* Systems lacking strdup() definition in . */ #if defined(ultrix) -char *strdup _P((const char *)); +char *strdup(const char *); #endif /* Systems lacking malloc() definition in . */ #if defined(ultrix) || defined(hcx) -void *malloc _P((size_t arg)); -void free _P((void *ptr)); +void *malloc(size_t arg); +void free(void *ptr); #endif #ifndef HAVE_INET_ATON -int inet_aton _P((const char *cp, struct in_addr *ia)); +int inet_aton(const char *cp, struct in_addr *ia); #endif #include +#ifdef _WIN32 +#include +#endif #ifndef NO_UNIX_SOCKETS #include #endif @@ -183,11 +187,7 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #include #endif -#ifdef __STDC__ #include -#else -#include -#endif #include @@ -202,6 +202,20 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #include "debug.h" +#if defined __GNUC__ +#define PACKED__ __attribute__ ((packed)) +#elif defined _MSC_VER +#define PRAGMA_PACK_SUPPORTED 1 +#define PACK_RESET +#define PACKED__ +#elif defined __sgi +#define PRAGMA_PACK_SUPPORTED 1 +#define PACK_RESET 0 +#define PACKED__ +#else +#error "Packed attribute or pragma shall be supported" +#endif + #include "ip.h" #include "tcp.h" #include "tcp_timer.h" @@ -232,45 +246,47 @@ extern struct ttys *ttys_unit[MAX_INTERFACES]; #endif #ifndef FULL_BOLT -void if_start _P((void)); +void if_start(void); #else -void if_start _P((struct ttys *)); +void if_start(struct ttys *); #endif #ifdef BAD_SPRINTF # define vsprintf vsprintf_len # define sprintf sprintf_len - extern int vsprintf_len _P((char *, const char *, va_list)); - extern int sprintf_len _P((char *, const char *, ...)); + extern int vsprintf_len(char *, const char *, va_list); + extern int sprintf_len(char *, const char *, ...); #endif #ifdef DECLARE_SPRINTF # ifndef BAD_SPRINTF - extern int vsprintf _P((char *, const char *, va_list)); + extern int vsprintf(char *, const char *, va_list); # endif - extern int vfprintf _P((FILE *, const char *, va_list)); + extern int vfprintf(FILE *, const char *, va_list); #endif #ifndef HAVE_STRERROR - extern char *strerror _P((int error)); + extern char *strerror(int error); #endif #ifndef HAVE_INDEX - char *index _P((const char *, int)); + char *index(const char *, int); #endif #ifndef HAVE_GETHOSTID - long gethostid _P((void)); + long gethostid(void); #endif -void lprint _P((const char *, ...)); +void lprint(const char *, ...); + +extern int do_echo; #if SIZEOF_CHAR_P == 4 # define insque_32 insque # define remque_32 remque #else - inline void insque_32 _P((void *, void *)); - inline void remque_32 _P((void *)); + extern inline void insque_32(void *, void *); + extern inline void remque_32(void *); #endif #ifndef _WIN32 @@ -279,46 +295,51 @@ void lprint _P((const char *, ...)); #define DEFAULT_BAUD 115200 -#define SO_OPTIONS DO_KEEPALIVE -#define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL) - /* cksum.c */ int cksum(struct mbuf *m, int len); /* if.c */ -void if_init _P((void)); -void if_output _P((struct socket *, struct mbuf *)); +void if_init(void); +void if_output(struct socket *, struct mbuf *); /* ip_input.c */ -void ip_init _P((void)); -void ip_input _P((struct mbuf *)); -void ip_slowtimo _P((void)); -void ip_stripoptions _P((register struct mbuf *, struct mbuf *)); +void ip_init(void); +void ip_input(struct mbuf *); +struct ip * ip_reass(register struct ipasfrag *, register struct ipq *); +void ip_freef(struct ipq *); +void ip_enq(register struct ipasfrag *, register struct ipasfrag *); +void ip_deq(register struct ipasfrag *); +void ip_slowtimo(void); +void ip_stripoptions(register struct mbuf *, struct mbuf *); /* ip_output.c */ -int ip_output _P((struct socket *, struct mbuf *)); +int ip_output(struct socket *, struct mbuf *); /* tcp_input.c */ -void tcp_input _P((register struct mbuf *, int, struct socket *)); -int tcp_mss _P((register struct tcpcb *, u_int)); +int tcp_reass(register struct tcpcb *, register struct tcpiphdr *, struct mbuf *); +void tcp_input(register struct mbuf *, int, struct socket *); +void tcp_dooptions(struct tcpcb *, u_char *, int, struct tcpiphdr *); +void tcp_xmit_timer(register struct tcpcb *, int); +u_int tcp_mss(register struct tcpcb *, u_int); /* tcp_output.c */ -int tcp_output _P((register struct tcpcb *)); -void tcp_setpersist _P((register struct tcpcb *)); +int tcp_output(register struct tcpcb *); +void tcp_setpersist(register struct tcpcb *); /* tcp_subr.c */ -void tcp_init _P((void)); -void tcp_template _P((struct tcpcb *)); -void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int)); -struct tcpcb * tcp_newtcpcb _P((struct socket *)); -struct tcpcb * tcp_close _P((register struct tcpcb *)); -void tcp_sockclosed _P((struct tcpcb *)); -int tcp_fconnect _P((struct socket *)); -void tcp_connect _P((struct socket *)); -int tcp_attach _P((struct socket *)); -u_int8_t tcp_tos _P((struct socket *)); -int tcp_emu _P((struct socket *, struct mbuf *)); -int tcp_ctl _P((struct socket *)); +void tcp_init(void); +void tcp_template(struct tcpcb *); +void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int); +struct tcpcb * tcp_newtcpcb(struct socket *); +struct tcpcb * tcp_close(register struct tcpcb *); +void tcp_drain(void); +void tcp_sockclosed(struct tcpcb *); +int tcp_fconnect(struct socket *); +void tcp_connect(struct socket *); +int tcp_attach(struct socket *); +u_int8_t tcp_tos(struct socket *); +int tcp_emu(struct socket *, struct mbuf *); +int tcp_ctl(struct socket *); struct tcpcb *tcp_drop(struct tcpcb *tp, int err); #ifdef USE_PPP @@ -334,9 +355,4 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err); #define max(x,y) ((x) > (y) ? (x) : (y)) #endif -#ifdef _WIN32 -#undef errno -#define errno (WSAGetLastError()) -#endif - #endif diff --git a/BasiliskII/src/slirp/slirp_config.h b/BasiliskII/src/slirp/slirp_config.h index e7e95dd5..237268fa 100644 --- a/BasiliskII/src/slirp/slirp_config.h +++ b/BasiliskII/src/slirp/slirp_config.h @@ -40,11 +40,6 @@ */ #undef USE_LOWCPU -/* Define this if your compiler doesn't like prototypes */ -#ifndef __STDC__ -#define NO_PROTOTYPES -#endif - /*********************************************************/ /* * Autoconf defined configuration options @@ -54,40 +49,11 @@ /* Ignore this */ #undef DUMMY_PPP -/* Define if you have unistd.h */ -#define HAVE_UNISTD_H - -/* Define if you have stdlib.h */ -#define HAVE_STDLIB_H - -/* Define if you have sys/ioctl.h */ -#undef HAVE_SYS_IOCTL_H -#ifndef _WIN32 -#define HAVE_SYS_IOCTL_H -#endif - -/* Define if you have sys/filio.h */ -#undef HAVE_SYS_FILIO_H -#ifdef __APPLE__ -#define HAVE_SYS_FILIO_H -#endif - -/* Define if you have strerror */ -#define HAVE_STRERROR - -/* Define if you have strdup() */ -#define HAVE_STRDUP - -/* Define according to how time.h should be included */ +/* XXX: Define according to how time.h should be included */ +#undef TIME_WITH_SYS_TIME #define TIME_WITH_SYS_TIME 0 #undef HAVE_SYS_TIME_H -/* Define if you have sys/bitypes.h */ -#undef HAVE_SYS_BITYPES_H - -/* Define if the machine is big endian */ -//#undef WORDS_BIGENDIAN - /* Define if your sprintf returns char * instead of int */ #undef BAD_SPRINTF @@ -103,56 +69,17 @@ /* Define if a declaration of sprintf/fprintf is needed */ #undef DECLARE_SPRINTF -/* Define if you have a POSIX.1 sys/wait.h */ -#undef HAVE_SYS_WAIT_H - -/* Define if you have sys/select.h */ -#undef HAVE_SYS_SELECT_H -#ifndef _WIN32 -#define HAVE_SYS_SELECT_H -#endif - -/* Define if you have strings.h */ -#define HAVE_STRING_H - -/* Define if you have arpa/inet.h */ -#undef HAVE_ARPA_INET_H -#ifndef _WIN32 -#define HAVE_ARPA_INET_H -#endif - -/* Define if you have sys/signal.h */ -#undef HAVE_SYS_SIGNAL_H - /* Define if you have sys/stropts.h */ #undef HAVE_SYS_STROPTS_H -/* Define to whatever your compiler thinks inline should be */ -#define inline inline - -/* Define to whatever your compiler thinks const should be */ -#define const const - -/* Define if your compiler doesn't like prototypes */ -#undef NO_PROTOTYPES - /* Define if you don't have u_int32_t etc. typedef'd */ #undef NEED_TYPEDEFS #ifdef __sun__ #define NEED_TYPEDEFS #endif -/* Define to sizeof(char) */ -#define SIZEOF_CHAR 1 - -/* Define to sizeof(short) */ -#define SIZEOF_SHORT 2 - -/* Define to sizeof(int) */ -#define SIZEOF_INT 4 - /* Define to sizeof(char *) */ -#define SIZEOF_CHAR_P (HOST_LONG_BITS / 8) +#define SIZEOF_CHAR_P SIZEOF_VOID_P /* Define if you have random() */ #undef HAVE_RANDOM @@ -160,12 +87,6 @@ /* Define if you have srandom() */ #undef HAVE_SRANDOM -/* Define if you have inet_aton */ -#undef HAVE_INET_ATON -#ifndef _WIN32 -#define HAVE_INET_ATON -#endif - /* Define if you have setenv */ #undef HAVE_SETENV diff --git a/BasiliskII/src/slirp/socket.c b/BasiliskII/src/slirp/socket.c index 0c15132e..42ba31b2 100644 --- a/BasiliskII/src/slirp/socket.c +++ b/BasiliskII/src/slirp/socket.c @@ -1,11 +1,12 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ #define WANT_SYS_IOCTL_H +#include #include #include "ip_icmp.h" #include "main.h" @@ -13,16 +14,18 @@ #include #endif -static void sofcantrcvmore(struct socket *so); -static void sofcantsendmore(struct socket *so); +#ifdef _WIN32 +#define IS_EAGAIN(e) ((e) == WSAEINTR || (e) == EAGAIN) +#else +#define IS_EAGAIN(e) ((e) == EAGAIN) +#endif -#if 0 -static void +void so_init() { /* Nothing yet */ } -#endif + struct socket * solookup(head, laddr, lport, faddr, fport) @@ -33,19 +36,19 @@ solookup(head, laddr, lport, faddr, fport) u_int fport; { struct socket *so; - + for (so = head->so_next; so != head; so = so->so_next) { - if (so->so_lport == lport && + if (so->so_lport == lport && so->so_laddr.s_addr == laddr.s_addr && so->so_faddr.s_addr == faddr.s_addr && so->so_fport == fport) break; } - + if (so == head) return (struct socket *)NULL; return so; - + } /* @@ -57,7 +60,7 @@ struct socket * socreate() { struct socket *so; - + so = (struct socket *)malloc(sizeof(struct socket)); if(so) { memset(so, 0, sizeof(struct socket)); @@ -82,10 +85,10 @@ sofree(so) tcp_last_so = &tcb; else if (so == udp_last_so) udp_last_so = &udb; - + m_free(so->so_m); - - if(so->so_next && so->so_prev) + + if(so->so_next && so->so_prev) remque(so); /* crashes if so is not in a queue */ free(so); @@ -100,22 +103,23 @@ int soread(so) struct socket *so; { - int n, nn, lss, total; + int n, nn; + u_int lss, total; struct sbuf *sb = &so->so_snd; - int len = sb->sb_datalen - sb->sb_cc; + u_int len = sb->sb_datalen - sb->sb_cc; struct iovec iov[2]; - int mss = so->so_tcpcb->t_maxseg; - + u_int mss = so->so_tcpcb->t_maxseg; + DEBUG_CALL("soread"); DEBUG_ARG("so = %lx", (long )so); - - /* + + /* * No need to check if there's enough room to read. * soread wouldn't have been called if there weren't */ - + len = sb->sb_datalen - sb->sb_cc; - + iov[0].iov_base = sb->sb_wptr; if (sb->sb_wptr < sb->sb_rptr) { iov[0].iov_len = sb->sb_rptr - sb->sb_wptr; @@ -154,15 +158,16 @@ soread(so) n = 1; } } - + #ifdef HAVE_READV nn = readv(so->s, (struct iovec *)iov, n); DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); #else nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); -#endif +#endif if (nn <= 0) { - if (nn < 0 && (errno == EINTR || errno == EAGAIN)) + int error = WSAGetLastError(); + if (nn < 0 && IS_EAGAIN(error)) return 0; else { DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); @@ -171,7 +176,7 @@ soread(so) return -1; } } - + #ifndef HAVE_READV /* * If there was no error, try and read the second time round @@ -188,10 +193,10 @@ soread(so) if (ret > 0) nn += ret; } - + DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); #endif - + /* Update fields */ sb->sb_cc += nn; sb->sb_wptr += nn; @@ -199,10 +204,10 @@ soread(so) sb->sb_wptr -= sb->sb_datalen; return nn; } - + /* * Get urgent data - * + * * When the socket is created, we set it SO_OOBINLINE, * so when OOB data arrives, we soread() it and everything * in the send buffer is sent as urgent data @@ -215,13 +220,13 @@ sorecvoob(so) DEBUG_CALL("sorecvoob"); DEBUG_ARG("so = %lx", (long)so); - + /* * We take a guess at how much urgent data has arrived. * In most situations, when urgent data arrives, the next * read() should get all the urgent data. This guess will * be wrong however if more data arrives just after the - * urgent data, or the read() doesn't return all the + * urgent data, or the read() doesn't return all the * urgent data. */ soread(so); @@ -241,24 +246,24 @@ sosendoob(so) { struct sbuf *sb = &so->so_rcv; char buff[2048]; /* XXX Shouldn't be sending more oob data than this */ - + int n, len; - + DEBUG_CALL("sosendoob"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc); - + if (so->so_urgc > 2048) so->so_urgc = 2048; /* XXXX */ - + if (sb->sb_rptr < sb->sb_wptr) { /* We can send it directly */ n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */ so->so_urgc -= n; - + DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); } else { - /* + /* * Since there's no sendv or sendtov like writev, * we must copy all data to a linear buffer then * send it all @@ -278,20 +283,20 @@ sosendoob(so) #ifdef DEBUG if (n != len) DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n")); -#endif +#endif DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); } - + sb->sb_cc -= n; sb->sb_rptr += n; if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) sb->sb_rptr -= sb->sb_datalen; - + return n; } /* - * Write data from so_rcv to so's socket, + * Write data from so_rcv to so's socket, * updating all sbuf field as necessary */ int @@ -300,12 +305,12 @@ sowrite(so) { int n,nn; struct sbuf *sb = &so->so_rcv; - int len = sb->sb_cc; + u_int len = sb->sb_cc; struct iovec iov[2]; - + DEBUG_CALL("sowrite"); DEBUG_ARG("so = %lx", (long)so); - + if (so->so_urgc) { sosendoob(so); if (sb->sb_cc == 0) @@ -316,9 +321,9 @@ sowrite(so) * No need to check if there's something to write, * sowrite wouldn't have been called otherwise */ - + len = sb->sb_cc; - + iov[0].iov_base = sb->sb_rptr; if (sb->sb_rptr < sb->sb_wptr) { iov[0].iov_len = sb->sb_wptr - sb->sb_rptr; @@ -341,14 +346,17 @@ sowrite(so) #ifdef HAVE_READV nn = writev(so->s, (const struct iovec *)iov, n); - + DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); #else nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0); #endif /* This should never happen, but people tell me it does *shrug* */ - if (nn < 0 && (errno == EAGAIN || errno == EINTR)) - return 0; + if (nn < 0) { + int error = WSAGetLastError(); + if (IS_EAGAIN(error)) + return 0; + } if (nn <= 0) { DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n", @@ -357,7 +365,7 @@ sowrite(so) tcp_sockclosed(sototcpcb(so)); return -1; } - + #ifndef HAVE_READV if (n == 2 && nn == iov[0].iov_len) { int ret; @@ -367,20 +375,20 @@ sowrite(so) } DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); #endif - + /* Update sbuf */ sb->sb_cc -= nn; sb->sb_rptr += nn; if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) sb->sb_rptr -= sb->sb_datalen; - + /* * If in DRAIN mode, and there's no more data, set * it CANTSENDMORE */ if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0) sofcantsendmore(so); - + return nn; } @@ -392,25 +400,26 @@ sorecvfrom(so) struct socket *so; { struct sockaddr_in addr; - int addrlen = sizeof(struct sockaddr_in); - + socklen_t addrlen = sizeof(struct sockaddr_in); + DEBUG_CALL("sorecvfrom"); DEBUG_ARG("so = %lx", (long)so); - + if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ char buff[256]; int len; - - len = recvfrom(so->s, buff, 256, 0, + + len = recvfrom(so->s, buff, 256, 0, (struct sockaddr *)&addr, &addrlen); /* XXX Check if reply is "correct"? */ - + if(len == -1 || len == 0) { u_char code=ICMP_UNREACH_PORT; - if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; - + int error = WSAGetLastError(); + if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST; + else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET; + DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", errno,strerror(errno))); icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); @@ -422,36 +431,38 @@ sorecvfrom(so) udp_detach(so); } else { /* A "normal" UDP packet */ struct mbuf *m; - int len, n; + u_int len; + ioctlsockopt_t n; if (!(m = m_get())) return; - m->m_data += IF_MAXLINKHDR; - - /* + m->m_data += if_maxlinkhdr; + + /* * XXX Shouldn't FIONREAD packets destined for port 53, * but I don't know the max packet size for DNS lookups */ len = M_FREEROOM(m); /* if (so->so_fport != htons(53)) { */ ioctlsocket(so->s, FIONREAD, &n); - + if (n > len) { n = (m->m_data - m->m_dat) + m->m_len + n + 1; m_inc(m, n); len = M_FREEROOM(m); } /* } */ - + m->m_len = recvfrom(so->s, m->m_data, len, 0, (struct sockaddr *)&addr, &addrlen); - DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", + DEBUG_MISC((dfd, " did recvfrom %zu, errno = %d-%s\n", m->m_len, errno,strerror(errno))); if(m->m_len<0) { u_char code=ICMP_UNREACH_PORT; - if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; - + int error = WSAGetLastError(); + if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST; + else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET; + DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); m_free(m); @@ -474,8 +485,8 @@ sorecvfrom(so) * m->m_len = 0; * } */ - - /* + + /* * If this packet was destined for CTL_ADDR, * make it look like that's where it came from, done by udp_output */ @@ -498,7 +509,7 @@ sosendto(so, m) DEBUG_CALL("sosendto"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("m = %lx", (long)m); - + addr.sin_family = AF_INET; if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { /* It's an alias */ @@ -515,14 +526,16 @@ sosendto(so, m) addr.sin_addr = so->so_faddr; addr.sin_port = so->so_fport; - 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))); - + char addrstr[INET_ADDRSTRLEN]; + DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", + ntohs(addr.sin_port), inet_ntop(AF_INET, &addr.sin_addr, addrstr, sizeof(addrstr)))); + /* Don't care what port we get */ ret = sendto(so->s, m->m_data, m->m_len, 0, (struct sockaddr *)&addr, sizeof (struct sockaddr)); if (ret < 0) return -1; - + /* * Kill the socket if there's no reply in 4 minutes, * but only if it's an expirable socket @@ -545,58 +558,57 @@ solisten(port, laddr, lport, flags) { struct sockaddr_in addr; struct socket *so; - int s, addrlen = sizeof(addr), opt = 1; + int s; + socklen_t addrlen = sizeof(addr); + int opt = 1; DEBUG_CALL("solisten"); DEBUG_ARG("port = %d", port); DEBUG_ARG("laddr = %x", laddr); DEBUG_ARG("lport = %d", lport); DEBUG_ARG("flags = %x", flags); - + if ((so = socreate()) == NULL) { /* free(so); Not sofree() ??? free(NULL) == NOP */ return NULL; } - + /* Don't tcp_attach... we don't need so_snd nor so_rcv */ if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) { free(so); return NULL; } insque(so,&tcb); - - /* + + /* * SS_FACCEPTONCE sockets must time out. */ if (flags & SS_FACCEPTONCE) so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2; - + so->so_state = (SS_FACCEPTCONN|flags); so->so_lport = lport; /* Kept in network format */ so->so_laddr.s_addr = laddr; /* Ditto */ - + + memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = port; - + if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) || (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || (listen(s,1) < 0)) { - int tmperrno = errno; /* Don't clobber the real reason we failed */ - + int error = WSAGetLastError(); /* Don't clobber the real reason we failed */ + close(s); sofree(so); /* Restore the real errno */ -#ifdef _WIN32 - WSASetLastError(tmperrno); -#else - errno = tmperrno; -#endif + WSASetLastError(error); return NULL; } setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); - + getsockname(s,(struct sockaddr *)&addr,&addrlen); so->so_fport = addr.sin_port; if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) @@ -608,32 +620,30 @@ solisten(port, laddr, lport, flags) return so; } -#if 0 -/* +/* * Data is available in so_rcv * Just write() the data to the socket * XXX not yet... */ -static void +void sorwakeup(so) struct socket *so; { /* sowrite(so); */ /* FD_CLR(so->s,&writefds); */ } - + /* * Data has been freed in so_snd * We have room for a read() if we want to * For now, don't read, it'll be done in the main loop */ -static void +void sowwakeup(so) struct socket *so; { /* Nothing, yet */ } -#endif /* * Various session state calls @@ -658,8 +668,9 @@ soisfconnected(so) so->so_state |= SS_ISFCONNECTED; /* Clobber other states */ } -static void -sofcantrcvmore(struct socket *so) +void +sofcantrcvmore(so) + struct socket *so; { if ((so->so_state & SS_NOFDREF) == 0) { shutdown(so->s,0); @@ -674,8 +685,9 @@ sofcantrcvmore(struct socket *so) so->so_state |= SS_FCANTRCVMORE; } -static void -sofcantsendmore(struct socket *so) +void +sofcantsendmore(so) + struct socket *so; { if ((so->so_state & SS_NOFDREF) == 0) { shutdown(so->s,1); /* send FIN to fhost */ diff --git a/BasiliskII/src/slirp/socket.h b/BasiliskII/src/slirp/socket.h index 94fb8d8c..3b0fee16 100644 --- a/BasiliskII/src/slirp/socket.h +++ b/BasiliskII/src/slirp/socket.h @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -33,21 +33,21 @@ struct socket { struct in_addr so_laddr; /* local host table entry */ u_int16_t so_fport; /* foreign port */ u_int16_t so_lport; /* local port */ - + u_int8_t so_iptos; /* Type of service */ u_int8_t so_emu; /* Is the socket emulated? */ - + u_char so_type; /* Type of socket, UDP or TCP */ int so_state; /* internal state flags SS_*, below */ - + struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */ u_int so_expire; /* When the socket will expire */ - + int so_queued; /* Number of packets queued from this socket */ int so_nqueued; /* Number of packets queued in a row * Used to determine when to "downgrade" a session * from fastq to batchq */ - + struct sbuf so_rcv; /* Receive buffer */ struct sbuf so_snd; /* Send buffer */ void * extra; /* Extra pointer */ @@ -81,19 +81,24 @@ struct iovec { }; #endif -struct socket * solookup _P((struct socket *, struct in_addr, u_int, struct in_addr, u_int)); -struct socket * socreate _P((void)); -void sofree _P((struct socket *)); -int soread _P((struct socket *)); -void sorecvoob _P((struct socket *)); -int sosendoob _P((struct socket *)); -int sowrite _P((struct socket *)); -void sorecvfrom _P((struct socket *)); -int sosendto _P((struct socket *, struct mbuf *)); -struct socket * solisten _P((u_int, u_int32_t, u_int, int)); -void soisfconnecting _P((register struct socket *)); -void soisfconnected _P((register struct socket *)); -void soisfdisconnected _P((struct socket *)); -void sofwdrain _P((struct socket *)); +void so_init(void); +struct socket * solookup(struct socket *, struct in_addr, u_int, struct in_addr, u_int); +struct socket * socreate(void); +void sofree(struct socket *); +int soread(struct socket *); +void sorecvoob(struct socket *); +int sosendoob(struct socket *); +int sowrite(struct socket *); +void sorecvfrom(struct socket *); +int sosendto(struct socket *, struct mbuf *); +struct socket * solisten(u_int, u_int32_t, u_int, int); +void sorwakeup(struct socket *); +void sowwakeup(struct socket *); +void soisfconnecting(register struct socket *); +void soisfconnected(register struct socket *); +void sofcantrcvmore(struct socket *); +void sofcantsendmore(struct socket *); +void soisfdisconnected(struct socket *); +void sofwdrain(struct socket *); #endif /* _SOCKET_H_ */ diff --git a/BasiliskII/src/slirp/tcp.h b/BasiliskII/src/slirp/tcp.h index 11150766..24e7914a 100644 --- a/BasiliskII/src/slirp/tcp.h +++ b/BasiliskII/src/slirp/tcp.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -42,6 +38,8 @@ typedef u_int32_t tcp_seq; #define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */ #define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */ +extern size_t tcp_rcvspace; +extern size_t tcp_sndspace; extern struct socket *tcp_last_so; #define TCP_SNDSPACE 8192 @@ -51,16 +49,20 @@ extern struct socket *tcp_last_so; * TCP header. * Per RFC 793, September, 1981. */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + struct tcphdr { u_int16_t th_sport; /* source port */ u_int16_t th_dport; /* destination port */ tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ #ifdef WORDS_BIGENDIAN - u_int th_off:4, /* data offset */ + u_char th_off:4, /* data offset */ th_x2:4; /* (unused) */ #else - u_int th_x2:4, /* (unused) */ + u_char th_x2:4, /* (unused) */ th_off:4; /* data offset */ #endif u_int8_t th_flags; @@ -73,7 +75,11 @@ struct tcphdr { u_int16_t th_win; /* window */ u_int16_t th_sum; /* checksum */ u_int16_t th_urp; /* urgent pointer */ -}; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_RESET) +#endif #include "tcp_var.h" @@ -170,6 +176,6 @@ struct tcphdr { extern tcp_seq tcp_iss; /* tcp initial send seq # */ -extern const char * const tcpstates[]; +extern char *tcpstates[]; #endif diff --git a/BasiliskII/src/slirp/tcp_input.c b/BasiliskII/src/slirp/tcp_input.c index 17a9387f..5c06f16f 100644 --- a/BasiliskII/src/slirp/tcp_input.c +++ b/BasiliskII/src/slirp/tcp_input.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -37,17 +33,18 @@ /* * Changes and additions relating to SLiRP * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ +#include #include #include "ip_icmp.h" struct socket tcb; -#define TCPREXMTTHRESH 3 +int tcprexmtthresh = 3; struct socket *tcp_last_so = &tcb; tcp_seq tcp_iss; /* tcp initial send seq # */ @@ -79,8 +76,8 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ tp->t_flags |= TF_DELACK; \ (tp)->rcv_nxt += (ti)->ti_len; \ flags = (ti)->ti_flags & TH_FIN; \ - STAT(tcpstat.tcps_rcvpack++); \ - STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len); \ + tcpstat.tcps_rcvpack++;\ + tcpstat.tcps_rcvbyte += (ti)->ti_len;\ if (so->so_emu) { \ if (tcp_emu((so),(m))) sbappend((so), (m)); \ } else \ @@ -99,8 +96,8 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ tp->t_flags |= TF_DELACK; \ (tp)->rcv_nxt += (ti)->ti_len; \ flags = (ti)->ti_flags & TH_FIN; \ - STAT(tcpstat.tcps_rcvpack++); \ - STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len); \ + tcpstat.tcps_rcvpack++;\ + tcpstat.tcps_rcvbyte += (ti)->ti_len;\ if (so->so_emu) { \ if (tcp_emu((so),(m))) sbappend(so, (m)); \ } else \ @@ -112,18 +109,14 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ } \ } #endif -static void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, - struct tcpiphdr *ti); -static void tcp_xmit_timer(register struct tcpcb *tp, int rtt); -static int -tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, - struct mbuf *m) +int +tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf *m) { register struct tcpiphdr *q; struct socket *so = tp->t_socket; int flags; - + /* * Call with ti==0 after become established to * force pre-ESTABLISHED data up to user socket. @@ -151,8 +144,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, i = q->ti_seq + q->ti_len - ti->ti_seq; if (i > 0) { if (i >= ti->ti_len) { - STAT(tcpstat.tcps_rcvduppack++); - STAT(tcpstat.tcps_rcvdupbyte += ti->ti_len); + tcpstat.tcps_rcvduppack++; + tcpstat.tcps_rcvdupbyte += ti->ti_len; m_freem(m); /* * Try to present any queued data @@ -168,8 +161,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, } q = (struct tcpiphdr *)(q->ti_next); } - STAT(tcpstat.tcps_rcvoopack++); - STAT(tcpstat.tcps_rcvoobyte += ti->ti_len); + tcpstat.tcps_rcvoopack++; + tcpstat.tcps_rcvoobyte += ti->ti_len; REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ /* @@ -233,13 +226,9 @@ present: * TCP input routine, follows pages 65-76 of the * protocol specification dated September, 1981 very closely. */ -void -tcp_input(m, iphlen, inso) - register struct mbuf *m; - int iphlen; - struct socket *inso; +void tcp_input(register struct mbuf *m, int iphlen, struct socket *inso) { - struct ip save_ip, *ip; + struct ip save_ip, *ip; register struct tcpiphdr *ti; caddr_t optp = NULL; int optlen = 0; @@ -247,16 +236,18 @@ tcp_input(m, iphlen, inso) register struct tcpcb *tp = 0; register int tiflags; struct socket *so = 0; - int todrop, acked, ourfinisacked, needoutput = 0; -/* int dropsocket = 0; */ + int todrop; + u_int acked; + int ourfinisacked, needoutput = 0; + /* int dropsocket = 0; */ int iss = 0; u_long tiwin; int ret; -/* int ts_present = 0; */ + /* int ts_present = 0; */ DEBUG_CALL("tcp_input"); - DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", - (long )m, iphlen, (long )inso )); + DEBUG_ARGS((dfd, " m = %8lx iphlen = %2d inso = %lx\n", + (long)m, iphlen, (long)inso)); /* * If called with m == 0, then we're continuing the connect @@ -276,15 +267,15 @@ tcp_input(m, iphlen, inso) } - STAT(tcpstat.tcps_rcvtotal++); + tcpstat.tcps_rcvtotal++; /* * Get IP and TCP header together in first mbuf. * Note: IP leaves IP header in first mbuf. */ ti = mtod(m, struct tcpiphdr *); - if (iphlen > sizeof(struct ip )) { - ip_stripoptions(m, (struct mbuf *)0); - iphlen=sizeof(struct ip ); + if (iphlen > sizeof(struct ip)) { + ip_stripoptions(m, (struct mbuf *)0); + iphlen = sizeof(struct ip); } /* XXX Check if too short */ @@ -293,24 +284,28 @@ tcp_input(m, iphlen, inso) * Save a copy of the IP header in case we want restore it * for sending an ICMP error message in response. */ - ip=mtod(m, struct ip *); + ip = mtod(m, struct ip *); save_ip = *ip; - save_ip.ip_len+= iphlen; + save_ip.ip_len += iphlen; /* * Checksum extended TCP header and data. */ tlen = ((struct ip *)ti)->ip_len; - ti->ti_next = ti->ti_prev = 0; + //ti->ti_next = ti->ti_prev = 0; + + tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0; + memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); + ti->ti_x1 = 0; ti->ti_len = htons((u_int16_t)tlen); - len = sizeof(struct ip ) + tlen; + len = sizeof(struct ip) + tlen; /* keep checksum for ICMP reply * ti->ti_sum = cksum(m, len); * if (ti->ti_sum) { */ - if(cksum(m, len)) { - STAT(tcpstat.tcps_rcvbadsum++); - goto drop; + if (cksum(m, len)) { + tcpstat.tcps_rcvbadsum++; + goto drop; } /* @@ -318,15 +313,15 @@ tcp_input(m, iphlen, inso) * pull out TCP options and adjust length. XXX */ off = ti->ti_off << 2; - if (off < sizeof (struct tcphdr) || off > tlen) { - STAT(tcpstat.tcps_rcvbadoff++); - goto drop; + if (off < sizeof(struct tcphdr) || off > tlen) { + tcpstat.tcps_rcvbadoff++; + goto drop; } tlen -= off; ti->ti_len = tlen; - if (off > sizeof (struct tcphdr)) { - optlen = off - sizeof (struct tcphdr); - optp = mtod(m, caddr_t) + sizeof (struct tcpiphdr); + if (off > sizeof(struct tcphdr)) { + optlen = off - sizeof(struct tcphdr); + optp = mtod(m, caddr_t) + sizeof(struct tcpiphdr); /* * Do quick retrieval of timestamp options ("options @@ -335,17 +330,17 @@ tcp_input(m, iphlen, inso) * quickly get the values now and not bother calling * tcp_dooptions(), etc. */ -/* if ((optlen == TCPOLEN_TSTAMP_APPA || - * (optlen > TCPOLEN_TSTAMP_APPA && - * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && - * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && - * (ti->ti_flags & TH_SYN) == 0) { - * ts_present = 1; - * ts_val = ntohl(*(u_int32_t *)(optp + 4)); - * ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); - * optp = NULL; / * we've parsed the options * / - * } - */ + /* if ((optlen == TCPOLEN_TSTAMP_APPA || + * (optlen > TCPOLEN_TSTAMP_APPA && + * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && + * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && + * (ti->ti_flags & TH_SYN) == 0) { + * ts_present = 1; + * ts_val = ntohl(*(u_int32_t *)(optp + 4)); + * ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); + * optp = NULL; / * we've parsed the options * / + * } + */ } tiflags = ti->ti_flags; @@ -360,8 +355,8 @@ tcp_input(m, iphlen, inso) /* * Drop TCP, IP headers and TCP options. */ - m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); - m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + m->m_data += sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); + m->m_len -= sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); /* * Locate pcb for segment. @@ -369,14 +364,14 @@ tcp_input(m, iphlen, inso) findso: so = tcp_last_so; if (so->so_fport != ti->ti_dport || - so->so_lport != ti->ti_sport || - so->so_laddr.s_addr != ti->ti_src.s_addr || - so->so_faddr.s_addr != ti->ti_dst.s_addr) { + so->so_lport != ti->ti_sport || + so->so_laddr.s_addr != ti->ti_src.s_addr || + so->so_faddr.s_addr != ti->ti_dst.s_addr) { so = solookup(&tcb, ti->ti_src, ti->ti_sport, - ti->ti_dst, ti->ti_dport); + ti->ti_dst, ti->ti_dport); if (so) tcp_last_so = so; - STAT(tcpstat.tcps_socachemiss++); + ++tcpstat.tcps_socachemiss; } /* @@ -393,41 +388,41 @@ findso: * as if it was LISTENING, and continue... */ if (so == 0) { - if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN) - goto dropwithreset; + if ((tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) != TH_SYN) + goto dropwithreset; - if ((so = socreate()) == NULL) - goto dropwithreset; - if (tcp_attach(so) < 0) { - free(so); /* Not sofree (if it failed, it's not insqued) */ - goto dropwithreset; - } + if ((so = socreate()) == NULL) + goto dropwithreset; + if (tcp_attach(so) < 0) { + free(so); /* Not sofree (if it failed, it's not insqued) */ + goto dropwithreset; + } - sbreserve(&so->so_snd, TCP_SNDSPACE); - sbreserve(&so->so_rcv, TCP_RCVSPACE); + sbreserve(&so->so_snd, tcp_sndspace); + sbreserve(&so->so_rcv, tcp_rcvspace); - /* tcp_last_so = so; */ /* XXX ? */ - /* tp = sototcpcb(so); */ + /* tcp_last_so = so; */ /* XXX ? */ + /* tp = sototcpcb(so); */ - so->so_laddr = ti->ti_src; - so->so_lport = ti->ti_sport; - so->so_faddr = ti->ti_dst; - so->so_fport = ti->ti_dport; + so->so_laddr = ti->ti_src; + so->so_lport = ti->ti_sport; + so->so_faddr = ti->ti_dst; + so->so_fport = ti->ti_dport; - if ((so->so_iptos = tcp_tos(so)) == 0) - so->so_iptos = ((struct ip *)ti)->ip_tos; + if ((so->so_iptos = tcp_tos(so)) == 0) + so->so_iptos = ((struct ip *)ti)->ip_tos; - tp = sototcpcb(so); - tp->t_state = TCPS_LISTEN; + tp = sototcpcb(so); + tp->t_state = TCPS_LISTEN; } - /* - * If this is a still-connecting socket, this probably - * a retransmit of the SYN. Whether it's a retransmit SYN - * or something else, we nuke it. - */ - if (so->so_state & SS_ISFCONNECTING) - goto drop; + /* + * If this is a still-connecting socket, this probably + * a retransmit of the SYN. Whether it's a retransmit SYN + * or something else, we nuke it. + */ + if (so->so_state & SS_ISFCONNECTING) + goto drop; tp = sototcpcb(so); @@ -442,17 +437,17 @@ findso: * tiwin = ti->ti_win << tp->snd_scale; * else */ - tiwin = ti->ti_win; + tiwin = ti->ti_win; /* * Segment received on connection. * Reset idle time and keep-alive timer. */ tp->t_idle = 0; - if (SO_OPTIONS) - tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL; + if (so_options) + tp->t_timer[TCPT_KEEP] = tcp_keepintvl; else - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE; + tp->t_timer[TCPT_KEEP] = tcp_keepidle; /* * Process options if not in LISTEN state, @@ -460,60 +455,60 @@ findso: */ if (optp && tp->t_state != TCPS_LISTEN) tcp_dooptions(tp, (u_char *)optp, optlen, ti); -/* , */ -/* &ts_present, &ts_val, &ts_ecr); */ + /* , */ + /* &ts_present, &ts_val, &ts_ecr); */ - /* - * Header prediction: check for the two common cases - * of a uni-directional data xfer. If the packet has - * no control flags, is in-sequence, the window didn't - * change and we're not retransmitting, it's a - * candidate. If the length is zero and the ack moved - * forward, we're the sender side of the xfer. Just - * free the data acked & wake any higher level process - * that was blocked waiting for space. If the length - * is non-zero and the ack didn't move, we're the - * receiver side. If we're getting packets in-order - * (the reassembly queue is empty), add the data to - * the socket buffer and note that we need a delayed ack. - * - * XXX Some of these tests are not needed - * eg: the tiwin == tp->snd_wnd prevents many more - * predictions.. with no *real* advantage.. - */ + /* + * Header prediction: check for the two common cases + * of a uni-directional data xfer. If the packet has + * no control flags, is in-sequence, the window didn't + * change and we're not retransmitting, it's a + * candidate. If the length is zero and the ack moved + * forward, we're the sender side of the xfer. Just + * free the data acked & wake any higher level process + * that was blocked waiting for space. If the length + * is non-zero and the ack didn't move, we're the + * receiver side. If we're getting packets in-order + * (the reassembly queue is empty), add the data to + * the socket buffer and note that we need a delayed ack. + * + * XXX Some of these tests are not needed + * eg: the tiwin == tp->snd_wnd prevents many more + * predictions.. with no *real* advantage.. + */ if (tp->t_state == TCPS_ESTABLISHED && - (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && -/* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ - ti->ti_seq == tp->rcv_nxt && - tiwin && tiwin == tp->snd_wnd && - tp->snd_nxt == tp->snd_max) { + (tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) == TH_ACK && + /* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ + ti->ti_seq == tp->rcv_nxt && + tiwin && tiwin == tp->snd_wnd && + tp->snd_nxt == tp->snd_max) { /* * If last ACK falls within this segment's sequence numbers, * record the timestamp. */ -/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && - * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { - * tp->ts_recent_age = tcp_now; - * tp->ts_recent = ts_val; - * } - */ + /* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && + * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { + * tp->ts_recent_age = tcp_now; + * tp->ts_recent = ts_val; + * } + */ if (ti->ti_len == 0) { if (SEQ_GT(ti->ti_ack, tp->snd_una) && - SEQ_LEQ(ti->ti_ack, tp->snd_max) && - tp->snd_cwnd >= tp->snd_wnd) { + SEQ_LEQ(ti->ti_ack, tp->snd_max) && + tp->snd_cwnd >= tp->snd_wnd) { /* * this is a pure ack for outstanding data. */ - STAT(tcpstat.tcps_predack++); -/* if (ts_present) - * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); - * else - */ if (tp->t_rtt && - SEQ_GT(ti->ti_ack, tp->t_rtseq)) + ++tcpstat.tcps_predack; + /* if (ts_present) + * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); + * else + */ if (tp->t_rtt && +SEQ_GT(ti->ti_ack, tp->t_rtseq)) tcp_xmit_timer(tp, tp->t_rtt); acked = ti->ti_ack - tp->snd_una; - STAT(tcpstat.tcps_rcvackpack++); - STAT(tcpstat.tcps_rcvackbyte += acked); + tcpstat.tcps_rcvackpack++; + tcpstat.tcps_rcvackbyte += acked; sbdrop(&so->so_snd, acked); tp->snd_una = ti->ti_ack; m_freem(m); @@ -536,37 +531,39 @@ findso: * There's room in so_snd, sowwakup will read() * from the socket if we can */ -/* if (so->so_snd.sb_flags & SB_NOTIFY) - * sowwakeup(so); - */ - /* - * This is called because sowwakeup might have - * put data into so_snd. Since we don't so sowwakeup, - * we don't need this.. XXX??? - */ + /* if (so->so_snd.sb_flags & SB_NOTIFY) + * sowwakeup(so); + */ + /* + * This is called because sowwakeup might have + * put data into so_snd. Since we don't so sowwakeup, + * we don't need this.. XXX??? + */ if (so->so_snd.sb_cc) (void) tcp_output(tp); return; } - } else if (ti->ti_ack == tp->snd_una && - tp->seg_next == (tcpiphdrp_32)tp && - ti->ti_len <= sbspace(&so->so_rcv)) { + } + else if (ti->ti_ack == tp->snd_una && + tp->seg_next == (tcpiphdrp_32)tp && + ti->ti_len <= sbspace(&so->so_rcv)) { /* * this is a pure, in-sequence data packet * with nothing on the reassembly queue and * we have enough buffer space to take it. */ - STAT(tcpstat.tcps_preddat++); + ++tcpstat.tcps_preddat; tp->rcv_nxt += ti->ti_len; - STAT(tcpstat.tcps_rcvpack++); - STAT(tcpstat.tcps_rcvbyte += ti->ti_len); + tcpstat.tcps_rcvpack++; + tcpstat.tcps_rcvbyte += ti->ti_len; /* * Add data to socket buffer. */ if (so->so_emu) { - if (tcp_emu(so,m)) sbappend(so, m); - } else + if (tcp_emu(so, m)) sbappend(so, m); + } + else sbappend(so, m); /* @@ -574,16 +571,16 @@ findso: * if we can actually write() to the socket * XXX Need to check? It's be NON_BLOCKING */ -/* sorwakeup(so); */ + /* sorwakeup(so); */ - /* - * If this is a short packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - * - * It is better to not delay acks at all to maximize - * TCP throughput. See RFC 2581. - */ + /* + * If this is a short packet, then ACK now - with Nagel + * congestion avoidance sender won't send more until + * he gets an ACK. + * + * It is better to not delay acks at all to maximize + * TCP throughput. See RFC 2581. + */ tp->t_flags |= TF_ACKNOW; tcp_output(tp); return; @@ -596,139 +593,145 @@ findso: * but not less than advertised window. */ { int win; - win = sbspace(&so->so_rcv); - if (win < 0) - win = 0; - tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); + win = sbspace(&so->so_rcv); + if (win < 0) + win = 0; + tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); } switch (tp->t_state) { - /* - * If the state is LISTEN then ignore segment if it contains an RST. - * If the segment contains an ACK then it is bad and send a RST. - * If it does not contain a SYN then it is not interesting; drop it. - * Don't bother responding if the destination was a broadcast. - * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial - * tp->iss, and send a segment: - * - * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. - * Fill in remote peer address fields if not previously specified. - * Enter SYN_RECEIVED state, and process any other fields of this - * segment in this state. - */ + /* + * If the state is LISTEN then ignore segment if it contains an RST. + * If the segment contains an ACK then it is bad and send a RST. + * If it does not contain a SYN then it is not interesting; drop it. + * Don't bother responding if the destination was a broadcast. + * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial + * tp->iss, and send a segment: + * + * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. + * Fill in remote peer address fields if not previously specified. + * Enter SYN_RECEIVED state, and process any other fields of this + * segment in this state. + */ case TCPS_LISTEN: { - if (tiflags & TH_RST) - goto drop; - if (tiflags & TH_ACK) - goto dropwithreset; - if ((tiflags & TH_SYN) == 0) - goto drop; + if (tiflags & TH_RST) + goto drop; + if (tiflags & TH_ACK) + goto dropwithreset; + if ((tiflags & TH_SYN) == 0) + goto drop; - /* - * This has way too many gotos... - * But a bit of spaghetti code never hurt anybody :) - */ + /* + * This has way too many gotos... + * But a bit of spaghetti code never hurt anybody :) + */ - /* - * If this is destined for the control address, then flag to - * tcp_ctl once connected, otherwise connect - */ - if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) { - int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff; - if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) { + /* + * If this is destined for the control address, then flag to + * tcp_ctl once connected, otherwise connect + */ + if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) { + int lastbyte = ntohl(so->so_faddr.s_addr) & 0xff; + if (lastbyte != CTL_ALIAS && lastbyte != CTL_DNS) { #if 0 - if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) { - /* Command or exec adress */ - so->so_state |= SS_CTL; - } else + if (lastbyte == CTL_CMD || lastbyte == CTL_EXEC) { + /* Command or exec adress */ + so->so_state |= SS_CTL; + } + else #endif - { - /* May be an add exec */ - struct ex_list *ex_ptr; - for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if(ex_ptr->ex_fport == so->so_fport && - lastbyte == ex_ptr->ex_addr) { - so->so_state |= SS_CTL; - break; - } + { + /* May be an add exec */ + struct ex_list *ex_ptr; + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { + if (ex_ptr->ex_fport == so->so_fport && + lastbyte == ex_ptr->ex_addr) { + so->so_state |= SS_CTL; + break; + } + } + } + if (so->so_state & SS_CTL) goto cont_input; + } + /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ } - } - if(so->so_state & SS_CTL) goto cont_input; - } - /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ - } - if (so->so_emu & EMU_NOCONNECT) { - so->so_emu &= ~EMU_NOCONNECT; - goto cont_input; - } + if (so->so_emu & EMU_NOCONNECT) { + so->so_emu &= ~EMU_NOCONNECT; + goto cont_input; + } - if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { - u_char code=ICMP_UNREACH_NET; - DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", - errno,strerror(errno))); - if(errno == ECONNREFUSED) { - /* ACK the SYN, send RST to refuse the connection */ - tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0, - TH_RST|TH_ACK); - } else { - if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; - HTONL(ti->ti_seq); /* restore tcp header */ - HTONL(ti->ti_ack); - HTONS(ti->ti_win); - HTONS(ti->ti_urp); - m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); - m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); - *ip=save_ip; - icmp_error(m, ICMP_UNREACH,code, 0,strerror(errno)); - } - tp = tcp_close(tp); - m_free(m); - } else { - /* - * Haven't connected yet, save the current mbuf - * and ti, and return - * XXX Some OS's don't tell us whether the connect() - * succeeded or not. So we must time it out. - */ - so->so_m = m; - so->so_ti = ti; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->t_state = TCPS_SYN_RECEIVED; - } - return; + if (tcp_fconnect(so) == -1) { + int error = WSAGetLastError(); + if ((error != WSAEINPROGRESS) && (error != WSAEWOULDBLOCK)) { + u_char code = ICMP_UNREACH_NET; + DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n", + errno, strerror(errno))); + if (error == WSAECONNREFUSED) { + /* ACK the SYN, send RST to refuse the connection */ + tcp_respond(tp, ti, m, ti->ti_seq + 1, (tcp_seq)0, + TH_RST | TH_ACK); + } + else { + if (error == WSAEHOSTUNREACH) code = ICMP_UNREACH_HOST; + HTONL(ti->ti_seq); /* restore tcp header */ + HTONL(ti->ti_ack); + HTONS(ti->ti_win); + HTONS(ti->ti_urp); + m->m_data -= sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); + m->m_len += sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr); + *ip = save_ip; + icmp_error(m, ICMP_UNREACH, code, 0, strerror(errno)); + } + tp = tcp_close(tp); + m_free(m); + return; + } + } + + /* + * Haven't connected yet, save the current mbuf + * and ti, and return + * XXX Some OS's don't tell us whether the connect() + * succeeded or not. So we must time it out. + */ + so->so_m = m; + so->so_ti = ti; + tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tp->t_state = TCPS_SYN_RECEIVED; + return; cont_conn: - /* m==NULL - * Check if the connect succeeded - */ - if (so->so_state & SS_NOFDREF) { - tp = tcp_close(tp); - goto dropwithreset; - } + /* m==NULL + * Check if the connect succeeded + */ + if (so->so_state & SS_NOFDREF) { + tp = tcp_close(tp); + goto dropwithreset; + } cont_input: - tcp_template(tp); + tcp_template(tp); - if (optp) - tcp_dooptions(tp, (u_char *)optp, optlen, ti); - /* , */ - /* &ts_present, &ts_val, &ts_ecr); */ + if (optp) + tcp_dooptions(tp, (u_char *)optp, optlen, ti); + /* , */ + /* &ts_present, &ts_val, &ts_ecr); */ - if (iss) - tp->iss = iss; - else - tp->iss = tcp_iss; - tcp_iss += TCP_ISSINCR/2; - tp->irs = ti->ti_seq; - tcp_sendseqinit(tp); - tcp_rcvseqinit(tp); - tp->t_flags |= TF_ACKNOW; - tp->t_state = TCPS_SYN_RECEIVED; - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - STAT(tcpstat.tcps_accepts++); - goto trimthenstep6; + if (iss) + tp->iss = iss; + else + tp->iss = tcp_iss; + tcp_iss += TCP_ISSINCR / 2; + tp->irs = ti->ti_seq; + tcp_sendseqinit(tp); + tcp_rcvseqinit(tp); + tp->t_flags |= TF_ACKNOW; + tp->t_state = TCPS_SYN_RECEIVED; + tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tcpstat.tcps_accepts++; + goto trimthenstep6; } /* case TCPS_LISTEN */ /* @@ -745,13 +748,13 @@ findso: */ case TCPS_SYN_SENT: if ((tiflags & TH_ACK) && - (SEQ_LEQ(ti->ti_ack, tp->iss) || - SEQ_GT(ti->ti_ack, tp->snd_max))) + (SEQ_LEQ(ti->ti_ack, tp->iss) || + SEQ_GT(ti->ti_ack, tp->snd_max))) goto dropwithreset; if (tiflags & TH_RST) { if (tiflags & TH_ACK) - tp = tcp_drop(tp,0); /* XXX Check t_softerror! */ + tp = tcp_drop(tp, 0); /* XXX Check t_softerror! */ goto drop; } @@ -768,7 +771,7 @@ findso: tcp_rcvseqinit(tp); tp->t_flags |= TF_ACKNOW; if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { - STAT(tcpstat.tcps_connects++); + tcpstat.tcps_connects++; soisfconnected(so); tp->t_state = TCPS_ESTABLISHED; @@ -779,7 +782,7 @@ findso: * tp->rcv_scale = tp->request_r_scale; * } */ - (void) tcp_reass(tp, (struct tcpiphdr *)0, + (void)tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); /* * if we didn't have to retransmit the SYN, @@ -787,10 +790,11 @@ findso: */ if (tp->t_rtt) tcp_xmit_timer(tp, tp->t_rtt); - } else + } + else tp->t_state = TCPS_SYN_RECEIVED; -trimthenstep6: + trimthenstep6: /* * Advance ti->ti_seq to correspond to first data byte. * If data, trim to stay within window, @@ -802,8 +806,8 @@ trimthenstep6: m_adj(m, -todrop); ti->ti_len = tp->rcv_wnd; tiflags &= ~TH_FIN; - STAT(tcpstat.tcps_rcvpackafterwin++); - STAT(tcpstat.tcps_rcvbyteafterwin += todrop); + tcpstat.tcps_rcvpackafterwin++; + tcpstat.tcps_rcvbyteafterwin += todrop; } tp->snd_wl1 = ti->ti_seq - 1; tp->rcv_up = ti->ti_seq; @@ -819,31 +823,31 @@ trimthenstep6: * RFC 1323 PAWS: If we have a timestamp reply on this segment * and it's less than ts_recent, drop it. */ -/* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && - * TSTMP_LT(ts_val, tp->ts_recent)) { - * - */ /* Check to see if ts_recent is over 24 days old. */ -/* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { - */ /* - * * Invalidate ts_recent. If this segment updates - * * ts_recent, the age will be reset later and ts_recent - * * will get a valid value. If it does not, setting - * * ts_recent to zero will at least satisfy the - * * requirement that zero be placed in the timestamp - * * echo reply when ts_recent isn't valid. The - * * age isn't reset until we get a valid ts_recent - * * because we don't want out-of-order segments to be - * * dropped when ts_recent is old. - * */ -/* tp->ts_recent = 0; - * } else { - * tcpstat.tcps_rcvduppack++; - * tcpstat.tcps_rcvdupbyte += ti->ti_len; - * tcpstat.tcps_pawsdrop++; - * goto dropafterack; - * } - * } - */ + /* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && + * TSTMP_LT(ts_val, tp->ts_recent)) { + * + */ /* Check to see if ts_recent is over 24 days old. */ + /* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { + */ /* + * * Invalidate ts_recent. If this segment updates + * * ts_recent, the age will be reset later and ts_recent + * * will get a valid value. If it does not, setting + * * ts_recent to zero will at least satisfy the + * * requirement that zero be placed in the timestamp + * * echo reply when ts_recent isn't valid. The + * * age isn't reset until we get a valid ts_recent + * * because we don't want out-of-order segments to be + * * dropped when ts_recent is old. + * */ + /* tp->ts_recent = 0; + * } else { + * tcpstat.tcps_rcvduppack++; + * tcpstat.tcps_rcvdupbyte += ti->ti_len; + * tcpstat.tcps_pawsdrop++; + * goto dropafterack; + * } + * } + */ todrop = tp->rcv_nxt - ti->ti_seq; if (todrop > 0) { @@ -860,7 +864,7 @@ trimthenstep6: * Following if statement from Stevens, vol. 2, p. 960. */ if (todrop > ti->ti_len - || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { + || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { /* * Any valid FIN must be to the left of the window. * At this point the FIN must be a duplicate or out @@ -874,11 +878,12 @@ trimthenstep6: */ tp->t_flags |= TF_ACKNOW; todrop = ti->ti_len; - STAT(tcpstat.tcps_rcvduppack++); - STAT(tcpstat.tcps_rcvdupbyte += todrop); - } else { - STAT(tcpstat.tcps_rcvpartduppack++); - STAT(tcpstat.tcps_rcvpartdupbyte += todrop); + tcpstat.tcps_rcvduppack++; + tcpstat.tcps_rcvdupbyte += todrop; + } + else { + tcpstat.tcps_rcvpartduppack++; + tcpstat.tcps_rcvpartdupbyte += todrop; } m_adj(m, todrop); ti->ti_seq += todrop; @@ -895,9 +900,9 @@ trimthenstep6: * user processes are gone, then RST the other end. */ if ((so->so_state & SS_NOFDREF) && - tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { + tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { tp = tcp_close(tp); - STAT(tcpstat.tcps_rcvafterclose++); + tcpstat.tcps_rcvafterclose++; goto dropwithreset; } @@ -905,11 +910,11 @@ trimthenstep6: * If segment ends after window, drop trailing data * (and PUSH and FIN); if nothing left, just ACK. */ - todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); + todrop = (ti->ti_seq + ti->ti_len) - (tp->rcv_nxt + tp->rcv_wnd); if (todrop > 0) { - STAT(tcpstat.tcps_rcvpackafterwin++); + tcpstat.tcps_rcvpackafterwin++; if (todrop >= ti->ti_len) { - STAT(tcpstat.tcps_rcvbyteafterwin += ti->ti_len); + tcpstat.tcps_rcvbyteafterwin += ti->ti_len; /* * If a new connection request is received * while in TIME_WAIT, drop the old connection @@ -917,8 +922,8 @@ trimthenstep6: * are above the previous ones. */ if (tiflags & TH_SYN && - tp->t_state == TCPS_TIME_WAIT && - SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { + tp->t_state == TCPS_TIME_WAIT && + SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { iss = tp->rcv_nxt + TCP_ISSINCR; tp = tcp_close(tp); goto findso; @@ -932,54 +937,56 @@ trimthenstep6: */ if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { tp->t_flags |= TF_ACKNOW; - STAT(tcpstat.tcps_rcvwinprobe++); - } else + tcpstat.tcps_rcvwinprobe++; + } + else goto dropafterack; - } else - STAT(tcpstat.tcps_rcvbyteafterwin += todrop); + } + else + tcpstat.tcps_rcvbyteafterwin += todrop; m_adj(m, -todrop); ti->ti_len -= todrop; - tiflags &= ~(TH_PUSH|TH_FIN); + tiflags &= ~(TH_PUSH | TH_FIN); } /* * If last ACK falls within this segment's sequence numbers, * record its timestamp. */ -/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && - * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + - * ((tiflags & (TH_SYN|TH_FIN)) != 0))) { - * tp->ts_recent_age = tcp_now; - * tp->ts_recent = ts_val; - * } - */ + /* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && + * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + + * ((tiflags & (TH_SYN|TH_FIN)) != 0))) { + * tp->ts_recent_age = tcp_now; + * tp->ts_recent = ts_val; + * } + */ - /* - * If the RST bit is set examine the state: - * SYN_RECEIVED STATE: - * If passive open, return to LISTEN state. - * If active open, inform user that connection was refused. - * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: - * Inform user that connection was reset, and close tcb. - * CLOSING, LAST_ACK, TIME_WAIT STATES - * Close the tcb. - */ + /* + * If the RST bit is set examine the state: + * SYN_RECEIVED STATE: + * If passive open, return to LISTEN state. + * If active open, inform user that connection was refused. + * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: + * Inform user that connection was reset, and close tcb. + * CLOSING, LAST_ACK, TIME_WAIT STATES + * Close the tcb. + */ if (tiflags&TH_RST) switch (tp->t_state) { case TCPS_SYN_RECEIVED: -/* so->so_error = ECONNREFUSED; */ + /* so->so_error = ECONNREFUSED; */ goto close; case TCPS_ESTABLISHED: case TCPS_FIN_WAIT_1: case TCPS_FIN_WAIT_2: case TCPS_CLOSE_WAIT: -/* so->so_error = ECONNRESET; */ - close: - tp->t_state = TCPS_CLOSED; - STAT(tcpstat.tcps_drops++); - tp = tcp_close(tp); - goto drop; + /* so->so_error = ECONNRESET; */ + close: + tp->t_state = TCPS_CLOSED; + tcpstat.tcps_drops++; + tp = tcp_close(tp); + goto drop; case TCPS_CLOSING: case TCPS_LAST_ACK: @@ -993,7 +1000,7 @@ trimthenstep6: * error and we send an RST and drop the connection. */ if (tiflags & TH_SYN) { - tp = tcp_drop(tp,0); + tp = tcp_drop(tp, 0); goto dropwithreset; } @@ -1006,17 +1013,17 @@ trimthenstep6: * Ack processing. */ switch (tp->t_state) { - /* - * In SYN_RECEIVED state if the ack ACKs our SYN then enter - * ESTABLISHED state and continue processing, otherwise - * send an RST. una<=ack<=max - */ + /* + * In SYN_RECEIVED state if the ack ACKs our SYN then enter + * ESTABLISHED state and continue processing, otherwise + * send an RST. una<=ack<=max + */ case TCPS_SYN_RECEIVED: if (SEQ_GT(tp->snd_una, ti->ti_ack) || - SEQ_GT(ti->ti_ack, tp->snd_max)) + SEQ_GT(ti->ti_ack, tp->snd_max)) goto dropwithreset; - STAT(tcpstat.tcps_connects++); + tcpstat.tcps_connects++; tp->t_state = TCPS_ESTABLISHED; /* * The sent SYN is ack'ed with our sequence number +1 @@ -1025,21 +1032,24 @@ trimthenstep6: * SS_CTL since the buffer is empty otherwise. * tp->snd_una++; or: */ - tp->snd_una=ti->ti_ack; + tp->snd_una = ti->ti_ack; if (so->so_state & SS_CTL) { - /* So tcp_ctl reports the right state */ - ret = tcp_ctl(so); - if (ret == 1) { - soisfconnected(so); - so->so_state &= ~SS_CTL; /* success XXX */ - } else if (ret == 2) { - so->so_state = SS_NOFDREF; /* CTL_CMD */ - } else { - needoutput = 1; - tp->t_state = TCPS_FIN_WAIT_1; - } - } else { - soisfconnected(so); + /* So tcp_ctl reports the right state */ + ret = tcp_ctl(so); + if (ret == 1) { + soisfconnected(so); + so->so_state &= ~SS_CTL; /* success XXX */ + } + else if (ret == 2) { + so->so_state = SS_NOFDREF; /* CTL_CMD */ + } + else { + needoutput = 1; + tp->t_state = TCPS_FIN_WAIT_1; + } + } + else { + soisfconnected(so); } /* Do window scaling? */ @@ -1049,7 +1059,7 @@ trimthenstep6: * tp->rcv_scale = tp->request_r_scale; * } */ - (void) tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); + (void)tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); tp->snd_wl1 = ti->ti_seq - 1; /* Avoid ack processing; snd_una==ti_ack => dup ack */ goto synrx_to_est; @@ -1073,9 +1083,9 @@ trimthenstep6: if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { - STAT(tcpstat.tcps_rcvdupack++); - DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n", - (long )m, (long )so)); + tcpstat.tcps_rcvdupack++; + DEBUG_MISC((dfd, " dup ack m = %lx so = %lx \n", + (long)m, (long)so)); /* * If we have outstanding data (other than * a window probe), this is a completely @@ -1101,12 +1111,12 @@ trimthenstep6: * network. */ if (tp->t_timer[TCPT_REXMT] == 0 || - ti->ti_ack != tp->snd_una) + ti->ti_ack != tp->snd_una) tp->t_dupacks = 0; - else if (++tp->t_dupacks == TCPREXMTTHRESH) { + else if (++tp->t_dupacks == tcprexmtthresh) { tcp_seq onxt = tp->snd_nxt; u_int win = - min(tp->snd_wnd, tp->snd_cwnd) / 2 / + min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; if (win < 2) @@ -1116,18 +1126,20 @@ trimthenstep6: tp->t_rtt = 0; tp->snd_nxt = ti->ti_ack; tp->snd_cwnd = tp->t_maxseg; - (void) tcp_output(tp); + (void)tcp_output(tp); tp->snd_cwnd = tp->snd_ssthresh + - tp->t_maxseg * tp->t_dupacks; + tp->t_maxseg * tp->t_dupacks; if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; goto drop; - } else if (tp->t_dupacks > TCPREXMTTHRESH) { + } + else if (tp->t_dupacks > tcprexmtthresh) { tp->snd_cwnd += tp->t_maxseg; - (void) tcp_output(tp); + (void)tcp_output(tp); goto drop; } - } else + } + else tp->t_dupacks = 0; break; } @@ -1136,17 +1148,17 @@ trimthenstep6: * If the congestion window was inflated to account * for the other side's cached packets, retract it. */ - if (tp->t_dupacks > TCPREXMTTHRESH && - tp->snd_cwnd > tp->snd_ssthresh) + if (tp->t_dupacks > tcprexmtthresh && + tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; tp->t_dupacks = 0; if (SEQ_GT(ti->ti_ack, tp->snd_max)) { - STAT(tcpstat.tcps_rcvacktoomuch++); + tcpstat.tcps_rcvacktoomuch++; goto dropafterack; } acked = ti->ti_ack - tp->snd_una; - STAT(tcpstat.tcps_rcvackpack++); - STAT(tcpstat.tcps_rcvackbyte += acked); + tcpstat.tcps_rcvackpack++; + tcpstat.tcps_rcvackbyte += acked; /* * If we have a timestamp reply, update smoothed @@ -1157,12 +1169,12 @@ trimthenstep6: * timer backoff (cf., Phil Karn's retransmit alg.). * Recompute the initial retransmit timer. */ -/* if (ts_present) - * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); - * else - */ - if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) - tcp_xmit_timer(tp,tp->t_rtt); + /* if (ts_present) + * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); + * else + */ + if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) + tcp_xmit_timer(tp, tp->t_rtt); /* * If all outstanding data is acked, stop retransmit @@ -1173,7 +1185,8 @@ trimthenstep6: if (ti->ti_ack == tp->snd_max) { tp->t_timer[TCPT_REXMT] = 0; needoutput = 1; - } else if (tp->t_timer[TCPT_PERSIST] == 0) + } + else if (tp->t_timer[TCPT_PERSIST] == 0) tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; /* * When new data is acked, open the congestion window. @@ -1183,18 +1196,19 @@ trimthenstep6: * (maxseg^2 / cwnd per packet). */ { - register u_int cw = tp->snd_cwnd; - register u_int incr = tp->t_maxseg; + register u_int cw = tp->snd_cwnd; + register u_int incr = tp->t_maxseg; - if (cw > tp->snd_ssthresh) - incr = incr * incr / cw; - tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<snd_scale); + if (cw > tp->snd_ssthresh) + incr = incr * incr / cw; + tp->snd_cwnd = min(cw + incr, (u_int32_t) (TCP_MAXWIN << tp->snd_scale)); } if (acked > so->so_snd.sb_cc) { tp->snd_wnd -= so->so_snd.sb_cc; - sbdrop(&so->so_snd, (int )so->so_snd.sb_cc); + sbdrop(&so->so_snd, so->so_snd.sb_cc); ourfinisacked = 1; - } else { + } + else { sbdrop(&so->so_snd, acked); tp->snd_wnd -= acked; ourfinisacked = 0; @@ -1203,20 +1217,20 @@ trimthenstep6: * XXX sowwakup is called when data is acked and there's room for * for more data... it should read() the socket */ -/* if (so->so_snd.sb_flags & SB_NOTIFY) - * sowwakeup(so); - */ + /* if (so->so_snd.sb_flags & SB_NOTIFY) + * sowwakeup(so); + */ tp->snd_una = ti->ti_ack; if (SEQ_LT(tp->snd_nxt, tp->snd_una)) tp->snd_nxt = tp->snd_una; switch (tp->t_state) { - /* - * In FIN_WAIT_1 STATE in addition to the processing - * for the ESTABLISHED state if our FIN is now acknowledged - * then enter FIN_WAIT_2. - */ + /* + * In FIN_WAIT_1 STATE in addition to the processing + * for the ESTABLISHED state if our FIN is now acknowledged + * then enter FIN_WAIT_2. + */ case TCPS_FIN_WAIT_1: if (ourfinisacked) { /* @@ -1228,18 +1242,18 @@ trimthenstep6: */ if (so->so_state & SS_FCANTRCVMORE) { soisfdisconnected(so); - tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE; + tp->t_timer[TCPT_2MSL] = tcp_maxidle; } tp->t_state = TCPS_FIN_WAIT_2; } break; - /* - * In CLOSING STATE in addition to the processing for - * the ESTABLISHED state if the ACK acknowledges our FIN - * then enter the TIME-WAIT state, otherwise ignore - * the segment. - */ + /* + * In CLOSING STATE in addition to the processing for + * the ESTABLISHED state if the ACK acknowledges our FIN + * then enter the TIME-WAIT state, otherwise ignore + * the segment. + */ case TCPS_CLOSING: if (ourfinisacked) { tp->t_state = TCPS_TIME_WAIT; @@ -1249,12 +1263,12 @@ trimthenstep6: } break; - /* - * In LAST_ACK, we may still be waiting for data to drain - * and/or to be acked, as well as for the ack of our FIN. - * If our FIN is now acknowledged, delete the TCB, - * enter the closed state and return. - */ + /* + * In LAST_ACK, we may still be waiting for data to drain + * and/or to be acked, as well as for the ack of our FIN. + * If our FIN is now acknowledged, delete the TCB, + * enter the closed state and return. + */ case TCPS_LAST_ACK: if (ourfinisacked) { tp = tcp_close(tp); @@ -1262,11 +1276,11 @@ trimthenstep6: } break; - /* - * In TIME_WAIT state the only thing that should arrive - * is a retransmission of the remote FIN. Acknowledge - * it and restart the finack timer. - */ + /* + * In TIME_WAIT state the only thing that should arrive + * is a retransmission of the remote FIN. Acknowledge + * it and restart the finack timer. + */ case TCPS_TIME_WAIT: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; goto dropafterack; @@ -1279,13 +1293,13 @@ step6: * Don't look at window if no ACK: TAC's send garbage on first SYN. */ if ((tiflags & TH_ACK) && - (SEQ_LT(tp->snd_wl1, ti->ti_seq) || - (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) || - (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { + (SEQ_LT(tp->snd_wl1, ti->ti_seq) || + (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) || + (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { /* keep track of pure window updates */ if (ti->ti_len == 0 && - tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) - STAT(tcpstat.tcps_rcvwinupd++); + tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) + tcpstat.tcps_rcvwinupd++; tp->snd_wnd = tiwin; tp->snd_wl1 = ti->ti_seq; tp->snd_wl2 = ti->ti_ack; @@ -1298,7 +1312,7 @@ step6: * Process segments with URG. */ if ((tiflags & TH_URG) && ti->ti_urp && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { + TCPS_HAVERCVDFIN(tp->t_state) == 0) { /* * This is a kludge, but if we receive and accept * random urgent pointers, we'll crash in @@ -1324,21 +1338,22 @@ step6: * of data past the urgent section as the original * spec states (in one of two places). */ - if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) { + if (SEQ_GT(ti->ti_seq + ti->ti_urp, tp->rcv_up)) { tp->rcv_up = ti->ti_seq + ti->ti_urp; - so->so_urgc = so->so_rcv.sb_cc + + so->so_urgc = so->so_rcv.sb_cc + (tp->rcv_up - tp->rcv_nxt); /* -1; */ tp->rcv_up = ti->ti_seq + ti->ti_urp; } - } else + } + else /* * If no out of band data is expected, * pull receive urgent pointer along * with the receive window. */ if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) - tp->rcv_up = tp->rcv_nxt; + tp->rcv_up = tp->rcv_nxt; dodata: /* @@ -1350,7 +1365,7 @@ dodata: * connection then we just ignore the text. */ if ((ti->ti_len || (tiflags&TH_FIN)) && - TCPS_HAVERCVDFIN(tp->t_state) == 0) { + TCPS_HAVERCVDFIN(tp->t_state) == 0) { TCP_REASS(tp, ti, m, so, tiflags); /* * Note the amount of data that peer has sent into @@ -1358,7 +1373,8 @@ dodata: * buffer size. */ len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt); - } else { + } + else { m_free(m); tiflags &= ~TH_FIN; } @@ -1372,13 +1388,13 @@ dodata: /* * If we receive a FIN we can't send more data, * set it SS_FDRAIN - * Shutdown the socket if there is no rx data in the + * Shutdown the socket if there is no rx data in the * buffer. * soread() is called on completion of shutdown() and * will got to TCPS_LAST_ACK, and use tcp_output() * to send the FIN. */ -/* sofcantrcvmore(so); */ + /* sofcantrcvmore(so); */ sofwdrain(so); tp->t_flags |= TF_ACKNOW; @@ -1386,31 +1402,31 @@ dodata: } switch (tp->t_state) { - /* - * In SYN_RECEIVED and ESTABLISHED STATES - * enter the CLOSE_WAIT state. - */ + /* + * In SYN_RECEIVED and ESTABLISHED STATES + * enter the CLOSE_WAIT state. + */ case TCPS_SYN_RECEIVED: case TCPS_ESTABLISHED: - if(so->so_emu == EMU_CTL) /* no shutdown on socket */ - tp->t_state = TCPS_LAST_ACK; - else - tp->t_state = TCPS_CLOSE_WAIT; - break; + if (so->so_emu == EMU_CTL) /* no shutdown on socket */ + tp->t_state = TCPS_LAST_ACK; + else + tp->t_state = TCPS_CLOSE_WAIT; + break; - /* - * If still in FIN_WAIT_1 STATE FIN has not been acked so - * enter the CLOSING state. - */ + /* + * If still in FIN_WAIT_1 STATE FIN has not been acked so + * enter the CLOSING state. + */ case TCPS_FIN_WAIT_1: tp->t_state = TCPS_CLOSING; break; - /* - * In FIN_WAIT_2 state enter the TIME_WAIT state, - * starting the time-wait timer, turning off the other - * standard timers. - */ + /* + * In FIN_WAIT_2 state enter the TIME_WAIT state, + * starting the time-wait timer, turning off the other + * standard timers. + */ case TCPS_FIN_WAIT_2: tp->t_state = TCPS_TIME_WAIT; tcp_canceltimers(tp); @@ -1418,9 +1434,9 @@ dodata: soisfdisconnected(so); break; - /* - * In TIME_WAIT state restart the 2 MSL time_wait timer. - */ + /* + * In TIME_WAIT state restart the 2 MSL time_wait timer. + */ case TCPS_TIME_WAIT: tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; break; @@ -1434,15 +1450,15 @@ dodata: * * See above. */ -/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { - */ -/* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && - * (so->so_iptos & IPTOS_LOWDELAY) == 0) || - * ((so->so_iptos & IPTOS_LOWDELAY) && - * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { - */ + /* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { + */ + /* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && + * (so->so_iptos & IPTOS_LOWDELAY) == 0) || + * ((so->so_iptos & IPTOS_LOWDELAY) && + * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { + */ if (ti->ti_len && (unsigned)ti->ti_len <= 5 && - ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { + ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { tp->t_flags |= TF_ACKNOW; } @@ -1450,7 +1466,7 @@ dodata: * Return any desired output. */ if (needoutput || (tp->t_flags & TF_ACKNOW)) { - (void) tcp_output(tp); + (void)tcp_output(tp); } return; @@ -1463,7 +1479,7 @@ dropafterack: goto drop; m_freem(m); tp->t_flags |= TF_ACKNOW; - (void) tcp_output(tp); + (void)tcp_output(tp); return; dropwithreset: @@ -1472,8 +1488,8 @@ dropwithreset: tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST); else { if (tiflags & TH_SYN) ti->ti_len++; - tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0, - TH_RST|TH_ACK); + tcp_respond(tp, ti, m, ti->ti_seq + ti->ti_len, (tcp_seq)0, + TH_RST | TH_ACK); } return; @@ -1491,7 +1507,7 @@ drop: /* int *ts_present; * u_int32_t *ts_val, *ts_ecr; */ -static void +void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) { u_int16_t mss; @@ -1523,7 +1539,7 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) continue; memcpy((char *) &mss, (char *) cp + 2, sizeof(mss)); NTOHS(mss); - (void) tcp_mss(tp, mss); /* sets t_maxseg */ + tcp_mss(tp, mss); /* sets t_maxseg */ break; /* case TCPOPT_WINDOW: @@ -1544,7 +1560,7 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) * memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr)); * NTOHL(*ts_ecr); * - */ /* + */ /* * * A timestamp received in a SYN makes * * it ok to send timestamp requests and replies. * */ @@ -1568,14 +1584,10 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) #ifdef notdef -void -tcp_pulloutofband(so, ti, m) - struct socket *so; - struct tcpiphdr *ti; - register struct mbuf *m; +void tcp_pulloutofband(struct socket *so, struct tcpiphdr *ti, register struct mbuf *m) { int cnt = ti->ti_urp - 1; - + while (cnt >= 0) { if (m->m_len > cnt) { char *cp = mtod(m, caddr_t) + cnt; @@ -1602,16 +1614,15 @@ tcp_pulloutofband(so, ti, m) * and update averages and current timeout. */ -static void -tcp_xmit_timer(register struct tcpcb *tp, int rtt) +void tcp_xmit_timer(register struct tcpcb *tp, int rtt) { register short delta; DEBUG_CALL("tcp_xmit_timer"); DEBUG_ARG("tp = %lx", (long)tp); DEBUG_ARG("rtt = %d", rtt); - - STAT(tcpstat.tcps_rttupdated++); + + tcpstat.tcps_rttupdated++; if (tp->t_srtt != 0) { /* * srtt is stored as fixed point with 3 bits after the @@ -1639,7 +1650,7 @@ tcp_xmit_timer(register struct tcpcb *tp, int rtt) if ((tp->t_rttvar += delta) <= 0) tp->t_rttvar = 1; } else { - /* + /* * No rtt measurement yet - use the unsmoothed rtt. * Set the variance to half the rtt (so our first * retransmit happens at 3*rtt). @@ -1663,7 +1674,7 @@ tcp_xmit_timer(register struct tcpcb *tp, int rtt) */ TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ - + /* * We received an ack for a packet that wasn't retransmitted; * it is probably safe to discard any error indications we've @@ -1690,35 +1701,28 @@ tcp_xmit_timer(register struct tcpcb *tp, int rtt) * parameters from pre-set or cached values in the routing entry. */ -int -tcp_mss(tp, offer) - register struct tcpcb *tp; - u_int offer; +u_int tcp_mss(register struct tcpcb *tp, u_int offer) { struct socket *so = tp->t_socket; - int mss; - + u_int mss; + DEBUG_CALL("tcp_mss"); DEBUG_ARG("tp = %lx", (long)tp); DEBUG_ARG("offer = %d", offer); - - mss = min(IF_MTU, IF_MRU) - sizeof(struct tcpiphdr); + + mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr); if (offer) mss = min(mss, offer); mss = max(mss, 32); if (mss < tp->t_maxseg || offer != 0) tp->t_maxseg = mss; - + tp->snd_cwnd = mss; - - sbreserve(&so->so_snd, TCP_SNDSPACE + ((TCP_SNDSPACE % mss) ? - (mss - (TCP_SNDSPACE % mss)) : - 0)); - sbreserve(&so->so_rcv, TCP_RCVSPACE + ((TCP_RCVSPACE % mss) ? - (mss - (TCP_RCVSPACE % mss)) : - 0)); - + + sbreserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0)); + sbreserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0)); + DEBUG_MISC((dfd, " returning mss = %d\n", mss)); - + return mss; } diff --git a/BasiliskII/src/slirp/tcp_output.c b/BasiliskII/src/slirp/tcp_output.c index dba4ed7a..01df0118 100644 --- a/BasiliskII/src/slirp/tcp_output.c +++ b/BasiliskII/src/slirp/tcp_output.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -37,8 +33,8 @@ /* * Changes and additions relating to SLiRP * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -48,16 +44,16 @@ * Since this is only used in "stats socket", we give meaning * names instead of the REAL names */ -const char * const tcpstates[] = { +char *tcpstates[] = { /* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */ "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD", "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING", "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", }; -static const u_char tcp_outflags[TCP_NSTATES] = { +u_char tcp_outflags[TCP_NSTATES] = { TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, - TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, + TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK, }; @@ -67,9 +63,7 @@ static const u_char tcp_outflags[TCP_NSTATES] = { /* * Tcp output routine: figure out what should be sent and send it. */ -int -tcp_output(tp) - register struct tcpcb *tp; +int tcp_output(register struct tcpcb *tp) { register struct socket *so = tp->t_socket; register long len, win; @@ -79,10 +73,10 @@ tcp_output(tp) u_char opt[MAX_TCPOPTLEN]; unsigned optlen, hdrlen; int idle, sendalot; - + DEBUG_CALL("tcp_output"); DEBUG_ARG("tp = %lx", (long )tp); - + /* * Determine length of data that should be transmitted, * and flags that will be used. @@ -103,9 +97,9 @@ again: win = min(tp->snd_wnd, tp->snd_cwnd); flags = tcp_outflags[tp->t_state]; - + DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags)); - + /* * If in persist timeout with window of 0, send 1 byte. * Otherwise, if window is small but nonzero @@ -130,7 +124,7 @@ again: * to send then the probe will be the FIN * itself. */ - if (off < so->so_snd.sb_cc) + if (off < (int)so->so_snd.sb_cc) flags &= ~TH_FIN; win = 1; } else { @@ -158,7 +152,7 @@ again: tp->snd_nxt = tp->snd_una; } } - + if (len > tp->t_maxseg) { len = tp->t_maxseg; sendalot = 1; @@ -200,17 +194,17 @@ again: * window, then want to send a window update to peer. */ if (win > 0) { - /* + /* * "adv" is the amount we can increase the window, * taking into account that we are limited by * TCP_MAXWIN << tp->rcv_scale. */ - long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - + long adv = min(win, TCP_MAXWIN << tp->rcv_scale) - (tp->rcv_adv - tp->rcv_nxt); - if (adv >= (long) (2 * tp->t_maxseg)) + if (adv >= (long)(2 * tp->t_maxseg)) goto send; - if (2 * adv >= (long) so->so_rcv.sb_datalen) + if (2 * adv >= (long)so->so_rcv.sb_datalen) goto send; } @@ -263,8 +257,8 @@ again: /* * No reason to send a segment, just return. */ - STAT(tcpstat.tcps_didnuttin++); - + tcpstat.tcps_didnuttin++; + return (0); send: @@ -302,9 +296,9 @@ send: */ } } - + /* - * Send a timestamp and echo-reply if this is a SYN and our side + * Send a timestamp and echo-reply if this is a SYN and our side * wants to use timestamps (TF_REQ_TSTMP is set) or both our side * and our peer have sent timestamps in our SYN's. */ @@ -322,7 +316,7 @@ send: * } */ hdrlen += optlen; - + /* * Adjust data length if insertion of options will * bump the packet length beyond the t_maxseg length. @@ -339,13 +333,13 @@ send: */ if (len) { if (tp->t_force && len == 1) - STAT(tcpstat.tcps_sndprobe++); + tcpstat.tcps_sndprobe++; else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { - STAT(tcpstat.tcps_sndrexmitpack++); - STAT(tcpstat.tcps_sndrexmitbyte += len); + tcpstat.tcps_sndrexmitpack++; + tcpstat.tcps_sndrexmitbyte += len; } else { - STAT(tcpstat.tcps_sndpack++); - STAT(tcpstat.tcps_sndbyte += len); + tcpstat.tcps_sndpack++; + tcpstat.tcps_sndbyte += len; } m = m_get(); @@ -354,16 +348,16 @@ send: error = 1; goto out; } - m->m_data += IF_MAXLINKHDR; + m->m_data += if_maxlinkhdr; m->m_len = hdrlen; - - /* + + /* * This will always succeed, since we make sure our mbufs * are big enough to hold one MSS packet + header + ... etc. */ /* if (len <= MHLEN - hdrlen - max_linkhdr) { */ - sbcopy(&so->so_snd, off, (int) len, mtod(m, caddr_t) + hdrlen); + sbcopy(&so->so_snd, off, len, mtod(m, caddr_t) + hdrlen); m->m_len += len; /* } else { @@ -382,13 +376,13 @@ send: flags |= TH_PUSH; } else { if (tp->t_flags & TF_ACKNOW) - STAT(tcpstat.tcps_sndacks++); + tcpstat.tcps_sndacks++; else if (flags & (TH_SYN|TH_FIN|TH_RST)) - STAT(tcpstat.tcps_sndctrl++); + tcpstat.tcps_sndctrl++; else if (SEQ_GT(tp->snd_up, tp->snd_una)) - STAT(tcpstat.tcps_sndurg++); + tcpstat.tcps_sndurg++; else - STAT(tcpstat.tcps_sndwinup++); + tcpstat.tcps_sndwinup++; m = m_get(); if (m == NULL) { @@ -396,12 +390,12 @@ send: error = 1; goto out; } - m->m_data += IF_MAXLINKHDR; + m->m_data += if_maxlinkhdr; m->m_len = hdrlen; } ti = mtod(m, struct tcpiphdr *); - + memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr)); /* @@ -409,7 +403,7 @@ send: * window for use in delaying messages about window sizes. * If resending a FIN, be sure not to use a new sequence number. */ - if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && + if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && tp->snd_nxt == tp->snd_max) tp->snd_nxt--; /* @@ -439,17 +433,17 @@ send: * Calculate receive window. Don't shrink window, * but avoid silly window syndrome. */ - if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg) + if (win < (so->so_rcv.sb_datalen / 4) && win < tp->t_maxseg) win = 0; - if (win > (long)TCP_MAXWIN << tp->rcv_scale) - win = (long)TCP_MAXWIN << tp->rcv_scale; - if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) - win = (long)(tp->rcv_adv - tp->rcv_nxt); + if (win > (u_long) (TCP_MAXWIN << tp->rcv_scale)) + win = (u_long) (TCP_MAXWIN << tp->rcv_scale); + if (win < (tp->rcv_adv - tp->rcv_nxt)) + win = (tp->rcv_adv - tp->rcv_nxt); ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale)); - + if (SEQ_GT(tp->snd_up, tp->snd_una)) { ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq))); -#ifdef notdef +#ifdef notdef if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt)); #endif @@ -500,7 +494,7 @@ send: if (tp->t_rtt == 0) { tp->t_rtt = 1; tp->t_rtseq = startseq; - STAT(tcpstat.tcps_segstimed++); + tcpstat.tcps_segstimed++; } } @@ -531,14 +525,14 @@ send: * the template, but need a way to checksum without them. */ m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */ - + { + + ((struct ip *)ti)->ip_len = (u_int16_t) m->m_len; - ((struct ip *)ti)->ip_len = m->m_len; - - ((struct ip *)ti)->ip_ttl = IPDEFTTL; + ((struct ip *)ti)->ip_ttl = ip_defttl; ((struct ip *)ti)->ip_tos = so->so_iptos; - + /* #if BSD >= 43 */ /* Don't do IP options... */ /* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, @@ -547,7 +541,7 @@ send: error = ip_output(so, m); /* #else - * error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, + * error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, * so->so_options & SO_DONTROUTE); * #endif */ @@ -567,7 +561,7 @@ out: */ return (error); } - STAT(tcpstat.tcps_sndtotal++); + tcpstat.tcps_sndtotal++; /* * Data sent (as far as we can tell). @@ -585,9 +579,7 @@ out: return (0); } -void -tcp_setpersist(tp) - register struct tcpcb *tp; +void tcp_setpersist(register struct tcpcb *tp) { int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; diff --git a/BasiliskII/src/slirp/tcp_subr.c b/BasiliskII/src/slirp/tcp_subr.c index ba1296d4..70e04b5e 100644 --- a/BasiliskII/src/slirp/tcp_subr.c +++ b/BasiliskII/src/slirp/tcp_subr.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -37,26 +33,37 @@ /* * Changes and additions relating to SLiRP * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ #define WANT_SYS_IOCTL_H +#include #include /* patchable/settable parameters for tcp */ -/* Don't do rfc1323 performance enhancements */ -#define TCP_DO_RFC1323 0 +int tcp_mssdflt = TCP_MSS; +int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ; +int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */ +size_t tcp_rcvspace; /* You may want to change this */ +size_t tcp_sndspace; /* Keep small if you have an error prone link */ /* * Tcp initialization */ -void -tcp_init() +void tcp_init() { tcp_iss = 1; /* wrong */ tcb.so_next = tcb.so_prev = &tcb; + + /* tcp_rcvspace = our Window we advertise to the remote */ + tcp_rcvspace = TCP_RCVSPACE; + tcp_sndspace = TCP_SNDSPACE; + + /* Make sure tcp_sndspace is at least 2*MSS */ + if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr))) + tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)); } /* @@ -66,9 +73,7 @@ tcp_init() * necessary when the connection is used. */ /* struct tcpiphdr * */ -void -tcp_template(tp) - struct tcpcb *tp; +void tcp_template(struct tcpcb *tp) { struct socket *so = tp->t_socket; register struct tcpiphdr *n = &tp->t_template; @@ -81,7 +86,7 @@ tcp_template(tp) n->ti_dst = so->so_laddr; n->ti_sport = so->so_fport; n->ti_dport = so->so_lport; - + n->ti_seq = 0; n->ti_ack = 0; n->ti_x2 = 0; @@ -105,13 +110,8 @@ tcp_template(tp) * In any case the ack and sequence number of the transmitted * segment are as specified by the parameters. */ -void -tcp_respond(tp, ti, m, ack, seq, flags) - struct tcpcb *tp; - register struct tcpiphdr *ti; - register struct mbuf *m; - tcp_seq ack, seq; - int flags; +void tcp_respond(struct tcpcb *tp, register struct tcpiphdr *ti, + register struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags) { register int tlen; int win = 0; @@ -123,7 +123,7 @@ tcp_respond(tp, ti, m, ack, seq, flags) DEBUG_ARG("ack = %u", ack); DEBUG_ARG("seq = %u", seq); DEBUG_ARG("flags = %x", flags); - + if (tp) win = sbspace(&tp->t_socket->so_rcv); if (m == 0) { @@ -134,17 +134,17 @@ tcp_respond(tp, ti, m, ack, seq, flags) #else tlen = 0; #endif - m->m_data += IF_MAXLINKHDR; + m->m_data += if_maxlinkhdr; *mtod(m, struct tcpiphdr *) = *ti; ti = mtod(m, struct tcpiphdr *); flags = TH_ACK; } else { - /* + /* * ti points into m so the next line is just making * the mbuf point to ti */ m->m_data = (caddr_t)ti; - + m->m_len = sizeof (struct tcpiphdr); tlen = 0; #define xchg(a,b,type) { type t; t=a; a=b; b=t; } @@ -172,11 +172,11 @@ tcp_respond(tp, ti, m, ack, seq, flags) ti->ti_sum = cksum(m, tlen); ((struct ip *)ti)->ip_len = tlen; - if(flags & TH_RST) + if(flags & TH_RST) ((struct ip *)ti)->ip_ttl = MAXTTL; - else - ((struct ip *)ti)->ip_ttl = IPDEFTTL; - + else + ((struct ip *)ti)->ip_ttl = ip_defttl; + (void) ip_output((struct socket *)0, m); } @@ -185,40 +185,38 @@ tcp_respond(tp, ti, m, ack, seq, flags) * empty reassembly queue and hooking it to the argument * protocol control block. */ -struct tcpcb * -tcp_newtcpcb(so) - struct socket *so; +struct tcpcb *tcp_newtcpcb(struct socket *so) { register struct tcpcb *tp; - + tp = (struct tcpcb *)malloc(sizeof(*tp)); if (tp == NULL) return ((struct tcpcb *)0); - + memset((char *) tp, 0, sizeof(struct tcpcb)); tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp; - tp->t_maxseg = TCP_MSS; - - tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; + tp->t_maxseg = tcp_mssdflt; + + tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; tp->t_socket = so; - + /* * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives * reasonable initial retransmit time. */ tp->t_srtt = TCPTV_SRTTBASE; - tp->t_rttvar = TCPTV_SRTTDFLT << 2; + tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2; tp->t_rttmin = TCPTV_MIN; - TCPT_RANGESET(tp->t_rxtcur, + TCPT_RANGESET(tp->t_rxtcur, ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, TCPTV_MIN, TCPTV_REXMTMAX); tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; tp->t_state = TCPS_CLOSED; - + so->so_tcpcb = tp; return (tp); @@ -229,7 +227,7 @@ tcp_newtcpcb(so) * the specified error. If connection is synchronized, * then send a RST to peer. */ -struct tcpcb *tcp_drop(struct tcpcb *tp, int err) +struct tcpcb *tcp_drop(struct tcpcb *tp, int err) { /* tcp_drop(tp, errno) register struct tcpcb *tp; @@ -240,13 +238,13 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err) DEBUG_CALL("tcp_drop"); DEBUG_ARG("tp = %lx", (long)tp); DEBUG_ARG("errno = %d", errno); - + if (TCPS_HAVERCVDSYN(tp->t_state)) { tp->t_state = TCPS_CLOSED; (void) tcp_output(tp); - STAT(tcpstat.tcps_drops++); + tcpstat.tcps_drops++; } else - STAT(tcpstat.tcps_conndrops++); + tcpstat.tcps_conndrops++; /* if (errno == ETIMEDOUT && tp->t_softerror) * errno = tp->t_softerror; */ @@ -260,9 +258,7 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err) * discard internet protocol block * wake up any sleepers */ -struct tcpcb * -tcp_close(tp) - register struct tcpcb *tp; +struct tcpcb *tcp_close(register struct tcpcb *tp) { register struct tcpiphdr *t; struct socket *so = tp->t_socket; @@ -270,7 +266,7 @@ tcp_close(tp) DEBUG_CALL("tcp_close"); DEBUG_ARG("tp = %lx", (long )tp); - + /* free the reassembly queue, if any */ t = (struct tcpiphdr *) tp->seg_next; while (t != (struct tcpiphdr *)tp) { @@ -294,13 +290,11 @@ tcp_close(tp) sbfree(&so->so_rcv); sbfree(&so->so_snd); sofree(so); - STAT(tcpstat.tcps_closed++); + tcpstat.tcps_closed++; return ((struct tcpcb *)0); } -#ifdef notdef -void -tcp_drain() +void tcp_drain() { /* XXX */ } @@ -309,10 +303,10 @@ tcp_drain() * When a source quench is received, close congestion window * to one segment. We will gradually open it again as we proceed. */ -void -tcp_quench(i, errno) - int errno; +#ifdef notdef + +void tcp_quench(int i, int errno) { struct tcpcb *tp = intotcpcb(inp); @@ -336,14 +330,12 @@ tcp_quench(i, errno) * for peer to send FIN or not respond to keep-alives, etc. * We can let the user exit from the close as soon as the FIN is acked. */ -void -tcp_sockclosed(tp) - struct tcpcb *tp; +void tcp_sockclosed(struct tcpcb *tp) { DEBUG_CALL("tcp_sockclosed"); DEBUG_ARG("tp = %lx", (long)tp); - + switch (tp->t_state) { case TCPS_CLOSED: @@ -369,34 +361,34 @@ tcp_sockclosed(tp) tcp_output(tp); } -/* +/* * Connect to a host on the Internet * Called by tcp_input * Only do a connect, the tcp fields will be set in tcp_input * return 0 if there's a result of the connect, * else return -1 means we're still connecting * The return value is almost always -1 since the socket is - * nonblocking. Connect returns after the SYN is sent, and does + * nonblocking. Connect returns after the SYN is sent, and does * not wait for ACK+SYN. */ -int tcp_fconnect(so) - struct socket *so; +int tcp_fconnect(struct socket *so) { int ret=0; - + DEBUG_CALL("tcp_fconnect"); DEBUG_ARG("so = %lx", (long )so); if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) { int opt, s=so->s; struct sockaddr_in addr; + memset(&addr, 0, sizeof(struct sockaddr_in)); fd_nonblock(s); opt = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt )); opt = 1; setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); - + addr.sin_family = AF_INET; if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { /* It's an alias */ @@ -413,12 +405,14 @@ int tcp_fconnect(so) addr.sin_addr = so->so_faddr; addr.sin_port = so->so_fport; + char addrstr[INET_ADDRSTRLEN]; DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " - "addr.sin_addr.s_addr=%.16s\n", - ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); + "addr.sin_addr.s_addr=%.16s\n", + ntohs(addr.sin_port), inet_ntop(AF_INET, &addr.sin_addr, + addrstr, sizeof(addrstr)))); /* We don't care what port we get */ ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); - + /* * If it's not in progress, it failed, so we just return 0, * without clearing SS_NOFDREF @@ -431,29 +425,27 @@ int tcp_fconnect(so) /* * Accept the socket and connect to the local-host - * + * * We have a problem. The correct thing to do would be * to first connect to the local-host, and only if the * connection is accepted, then do an accept() here. - * But, a) we need to know who's trying to connect + * But, a) we need to know who's trying to connect * to the socket to be able to SYN the local-host, and * b) we are already connected to the foreign host by * the time it gets to accept(), so... We simply accept * here and SYN the local-host. - */ -void -tcp_connect(inso) - struct socket *inso; + */ +void tcp_connect(struct socket *inso) { struct socket *so; struct sockaddr_in addr; - int addrlen = sizeof(struct sockaddr_in); + socklen_t addrlen = sizeof(struct sockaddr_in); struct tcpcb *tp; int s, opt; DEBUG_CALL("tcp_connect"); DEBUG_ARG("inso = %lx", (long)inso); - + /* * If it's an SS_ACCEPTONCE socket, no need to socreate() * another socket, just use the accept() socket. @@ -474,8 +466,8 @@ tcp_connect(inso) so->so_laddr = inso->so_laddr; so->so_lport = inso->so_lport; } - - (void) tcp_mss(sototcpcb(so), 0); + + tcp_mss(sototcpcb(so), 0); if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { tcp_close(sototcpcb(so)); /* This will sofree() as well */ @@ -488,13 +480,13 @@ tcp_connect(inso) setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); opt = 1; setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); - + so->so_fport = addr.sin_port; so->so_faddr = addr.sin_addr; /* Translate connections from localhost to the real hostname */ if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) so->so_faddr = alias_addr; - + /* Close the accept() socket, set right state */ if (inso->so_state & SS_FACCEPTONCE) { closesocket(so->s); /* If we only accept once, close the accept() socket */ @@ -502,12 +494,12 @@ tcp_connect(inso) /* if it's not FACCEPTONCE, it's already NOFDREF */ } so->s = s; - + so->so_iptos = tcp_tos(so); tp = sototcpcb(so); tcp_template(tp); - + /* Compute window scaling to request. */ /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) @@ -515,11 +507,11 @@ tcp_connect(inso) */ /* soisconnecting(so); */ /* NOFDREF used instead */ - STAT(tcpstat.tcps_connattempt++); - + tcpstat.tcps_connattempt++; + tp->t_state = TCPS_SYN_SENT; tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->iss = tcp_iss; + tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2; tcp_sendseqinit(tp); tcp_output(tp); @@ -528,13 +520,11 @@ tcp_connect(inso) /* * Attach a TCPCB to a socket. */ -int -tcp_attach(so) - struct socket *so; +int tcp_attach(struct socket *so) { if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) return -1; - + insque(so, &tcb); return 0; @@ -543,7 +533,7 @@ tcp_attach(so) /* * Set the socket's type of service field */ -static const struct tos_t tcptos[] = { +struct tos_t tcptos[] = { {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ @@ -559,21 +549,16 @@ static const struct tos_t tcptos[] = { {0, 0, 0, 0} }; -#ifdef CONFIG_QEMU -static -#endif struct emu_t *tcpemu = 0; - + /* * Return TOS according to the above table */ -u_int8_t -tcp_tos(so) - struct socket *so; +u_int8_t tcp_tos(struct socket *so) { int i = 0; struct emu_t *emup; - + while(tcptos[i].tos) { if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) || (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) { @@ -582,7 +567,7 @@ tcp_tos(so) } i++; } - + /* Nope, lets see if there's a user-added one */ for (emup = tcpemu; emup; emup = emup->next) { if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) || @@ -591,73 +576,68 @@ tcp_tos(so) return emup->tos; } } - + return 0; } -#if 0 int do_echo = -1; -#endif /* * Emulate programs that try and connect to us * This includes ftp (the data connection is * initiated by the server) and IRC (DCC CHAT and * DCC SEND) for now - * + * * NOTE: It's possible to crash SLiRP by sending it * unstandard strings to emulate... if this is a problem, * more checks are needed here * * XXX Assumes the whole command came in one packet - * + * * XXX Some ftp clients will have their TOS set to * LOWDELAY and so Nagel will kick in. Because of this, * we'll get the first letter, followed by the rest, so * we simply scan for ORT instead of PORT... * DCC doesn't have this problem because there's other stuff * in the packet before the DCC command. - * - * Return 1 if the mbuf m is still valid and should be + * + * Return 1 if the mbuf m is still valid and should be * sbappend()ed - * + * * NOTE: if you return 0 you MUST m_free() the mbuf! */ -int -tcp_emu(so, m) - struct socket *so; - struct mbuf *m; +int tcp_emu(struct socket *so, struct mbuf *m) { u_int n1, n2, n3, n4, n5, n6; char buff[256]; u_int32_t laddr; u_int lport; char *bptr; - + DEBUG_CALL("tcp_emu"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("m = %lx", (long)m); - + switch(so->so_emu) { int x, i; - + case EMU_IDENT: /* * Identification protocol as per rfc-1413 */ - + { struct socket *tmpso; struct sockaddr_in addr; - int addrlen = sizeof(struct sockaddr_in); + socklen_t addrlen = sizeof(struct sockaddr_in); struct sbuf *so_rcv = &so->so_rcv; - + memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); so_rcv->sb_wptr += m->m_len; so_rcv->sb_rptr += m->m_len; m->m_data[m->m_len] = 0; /* NULL terminate */ if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { - if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) { + if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) { HTONS(n1); HTONS(n2); /* n2 is the one on our host */ @@ -680,7 +660,7 @@ tcp_emu(so, m) m_free(m); return 0; } - + #if 0 case EMU_RLOGIN: /* @@ -695,7 +675,7 @@ tcp_emu(so, m) char term[100]; struct sbuf *so_snd = &so->so_snd; struct sbuf *so_rcv = &so->so_rcv; - + /* First check if they have a priveladged port, or too much data has arrived */ if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { @@ -706,13 +686,13 @@ tcp_emu(so, m) m_free(m); return 0; } - + /* Append the current data */ memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); so_rcv->sb_wptr += m->m_len; so_rcv->sb_rptr += m->m_len; m_free(m); - + /* * Check if we have all the initial options, * and build argument list to rlogin while we're here @@ -744,10 +724,10 @@ tcp_emu(so, m) } } } - + if (n != 4) return 0; - + /* We have it, set our term variable and fork_exec() */ #ifdef HAVE_SETENV setenv("TERM", term, 1); @@ -757,15 +737,15 @@ tcp_emu(so, m) fork_exec(so, args, 2); term[0] = 0; so->so_emu = 0; - + /* And finally, send the client a 0 character */ so_snd->sb_wptr[0] = 0; so_snd->sb_wptr++; so_snd->sb_cc++; - + return 0; } - + case EMU_RSH: /* * rsh emulation @@ -779,7 +759,7 @@ tcp_emu(so, m) char *args; struct sbuf *so_snd = &so->so_snd; struct sbuf *so_rcv = &so->so_rcv; - + /* First check if they have a priveladged port, or too much data has arrived */ if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { @@ -790,13 +770,13 @@ tcp_emu(so, m) m_free(m); return 0; } - + /* Append the current data */ memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); so_rcv->sb_wptr += m->m_len; so_rcv->sb_rptr += m->m_len; m_free(m); - + /* * Check if we have all the initial options, * and build argument list to rlogin while we're here @@ -827,20 +807,20 @@ tcp_emu(so, m) ns->so_laddr=so->so_laddr; ns->so_lport=htons(port); - (void) tcp_mss(sototcpcb(ns), 0); + tcp_mss(sototcpcb(ns), 0); ns->so_faddr=so->so_faddr; ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */ - if (ns->so_faddr.s_addr == 0 || + if (ns->so_faddr.s_addr == 0 || ns->so_faddr.s_addr == loopback_addr.s_addr) ns->so_faddr = alias_addr; ns->so_iptos = tcp_tos(ns); tp = sototcpcb(ns); - + tcp_template(tp); - + /* Compute window scaling to request. */ /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) @@ -849,11 +829,11 @@ tcp_emu(so, m) /*soisfconnecting(ns);*/ - STAT(tcpstat.tcps_connattempt++); - + tcpstat.tcps_connattempt++; + tp->t_state = TCPS_SYN_SENT; tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; - tp->iss = tcp_iss; + tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2; tcp_sendseqinit(tp); tcp_output(tp); @@ -869,19 +849,19 @@ tcp_emu(so, m) } } } - + if (n != 4) return 0; - + rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args); so->so_emu = 0; so->extra=NULL; - + /* And finally, send the client a 0 character */ so_snd->sb_wptr[0] = 0; so_snd->sb_wptr++; so_snd->sb_cc++; - + return 0; } @@ -890,7 +870,7 @@ tcp_emu(so, m) int num; struct sbuf *so_snd = &so->so_snd; struct sbuf *so_rcv = &so->so_rcv; - + /* * If there is binary data here, we save it in so->so_m */ @@ -905,16 +885,16 @@ tcp_emu(so, m) } } } /* if(so->so_m==NULL) */ - + /* * Append the line */ sbappendsb(so_rcv, m); - + /* To avoid going over the edge of the buffer, we reset it */ if (so_snd->sb_cc == 0) so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data; - + /* * A bit of a hack: * If the first packet we get here is 1 byte long, then it @@ -933,13 +913,13 @@ tcp_emu(so, m) tcp_output(sototcpcb(so)); /* XXX */ } else m_free(m); - + num = 0; while (num < so->so_rcv.sb_cc) { if (*(so->so_rcv.sb_rptr + num) == '\n' || *(so->so_rcv.sb_rptr + num) == '\r') { int n; - + *(so_rcv->sb_rptr + num) = 0; if (ctl_password && !ctl_password_ok) { /* Need a password */ @@ -976,76 +956,76 @@ do_prompt: } return 0; } -#endif +#endif case EMU_FTP: /* ftp */ *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */ if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { /* * Need to emulate the PORT command - */ - x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]", + */ + x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]", &n1, &n2, &n3, &n4, &n5, &n6, buff); if (x < 6) return 1; - + laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); lport = htons((n5 << 8) | (n6)); - + if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) return 1; - + n6 = ntohs(so->so_fport); - + n5 = (n6 >> 8) & 0xff; n6 &= 0xff; - + laddr = ntohl(so->so_faddr.s_addr); - + n1 = ((laddr >> 24) & 0xff); n2 = ((laddr >> 16) & 0xff); n3 = ((laddr >> 8) & 0xff); n4 = (laddr & 0xff); - + m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", + m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", n1, n2, n3, n4, n5, n6, x==7?buff:""); return 1; } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { /* * Need to emulate the PASV response */ - x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]", + x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]", &n1, &n2, &n3, &n4, &n5, &n6, buff); if (x < 6) return 1; - + laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); lport = htons((n5 << 8) | (n6)); - + if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) return 1; - + n6 = ntohs(so->so_fport); - + n5 = (n6 >> 8) & 0xff; n6 &= 0xff; - + laddr = ntohl(so->so_faddr.s_addr); - + n1 = ((laddr >> 24) & 0xff); n2 = ((laddr >> 16) & 0xff); n3 = ((laddr >> 8) & 0xff); n4 = (laddr & 0xff); - + m->m_len = bptr - m->m_data; /* Adjust length */ m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", n1, n2, n3, n4, n5, n6, x==7?buff:""); - + return 1; } - + return 1; - + case EMU_KSH: /* * The kshell (Kerberos rsh) and shell services both pass @@ -1054,7 +1034,7 @@ do_prompt: * of the connection as a NUL-terminated decimal ASCII string. */ so->so_emu = 0; - for (lport = 0, i = 0; i < m->m_len-1; ++i) { + for (lport = 0, i = 0; i < (int) (m->m_len-1); ++i) { if (m->m_data[i] < '0' || m->m_data[i] > '9') return 1; /* invalid number */ lport *= 10; @@ -1064,7 +1044,7 @@ do_prompt: (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1; return 1; - + case EMU_IRC: /* * Need to emulate DCC CHAT, DCC SEND and DCC MOVE @@ -1072,12 +1052,12 @@ do_prompt: *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) return 1; - + /* The %256s is for the broken mIRC */ if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) return 1; - + m->m_len = bptr - m->m_data; /* Adjust length */ m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n", (unsigned long)ntohl(so->so_faddr.s_addr), @@ -1085,15 +1065,15 @@ do_prompt: } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) return 1; - + m->m_len = bptr - m->m_data; /* Adjust length */ - m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", + m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", buff, (unsigned long)ntohl(so->so_faddr.s_addr), ntohs(so->so_fport), n1, 1); } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) return 1; - + m->m_len = bptr - m->m_data; /* Adjust length */ m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n", buff, (unsigned long)ntohl(so->so_faddr.s_addr), @@ -1102,7 +1082,7 @@ do_prompt: return 1; case EMU_REALAUDIO: - /* + /* * RealAudio emulation - JP. We must try to parse the incoming * data and try to find the two characters that contain the * port number. Then we redirect an udp port and replace the @@ -1110,45 +1090,45 @@ do_prompt: * * The 1.0 beta versions of the player are not supported * any more. - * + * * A typical packet for player version 1.0 (release version): - * - * 0000:50 4E 41 00 05 + * + * 0000:50 4E 41 00 05 * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB - * + * * Now the port number 0x1BD7 is found at offset 0x04 of the * Now the port number 0x1BD7 is found at offset 0x04 of the * second packet. This time we received five bytes first and * then the rest. You never know how many bytes you get. * * A typical packet for player version 2.0 (beta): - * + * * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á. * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B - * + * * Port number 0x1BC1 is found at offset 0x0d. - * + * * This is just a horrible switch statement. Variable ra tells * us where we're going. */ - + bptr = m->m_data; while (bptr < m->m_data + m->m_len) { u_short p; static int ra = 0; - char ra_tbl[4]; - + char ra_tbl[4]; + ra_tbl[0] = 0x50; ra_tbl[1] = 0x4e; ra_tbl[2] = 0x41; ra_tbl[3] = 0; - + switch (ra) { case 0: case 2: @@ -1158,7 +1138,7 @@ do_prompt: continue; } break; - + case 1: /* * We may get 0x50 several times, ignore them @@ -1172,15 +1152,15 @@ do_prompt: continue; } break; - - case 4: - /* + + case 4: + /* * skip version number */ bptr++; break; - - case 5: + + case 5: /* * The difference between versions 1.0 and * 2.0 is here. For future versions of @@ -1190,19 +1170,19 @@ do_prompt: bptr += 8; else bptr += 4; - break; - + break; + case 6: /* This is the field containing the port * number that RA-player is listening to. */ - lport = (((u_char*)bptr)[0] << 8) + lport = (((u_char*)bptr)[0] << 8) + ((u_char *)bptr)[1]; - if (lport < 6970) + if (lport < 6970) lport += 256; /* don't know why */ if (lport < 6970 || lport > 7170) return 1; /* failed */ - + /* try to get udp port between 6970 - 7170 */ for (p = 6970; p < 7071; p++) { if (udp_listen( htons(p), @@ -1216,17 +1196,17 @@ do_prompt: p = 0; *(u_char *)bptr++ = (p >> 8) & 0xff; *(u_char *)bptr++ = p & 0xff; - ra = 0; + ra = 0; return 1; /* port redirected, we're done */ - break; - + break; + default: - ra = 0; + ra = 0; } ra++; } - return 1; - + return 1; + default: /* Ooops, not emulated, won't call tcp_emu again */ so->so_emu = 0; @@ -1239,19 +1219,17 @@ do_prompt: * Return 0 if this connections is to be closed, 1 otherwise, * return 2 if this is a command-line connection */ -int -tcp_ctl(so) - struct socket *so; +int tcp_ctl(struct socket *so) { struct sbuf *sb = &so->so_snd; int command; struct ex_list *ex_ptr; int do_pty; // struct socket *tmpso; - + DEBUG_CALL("tcp_ctl"); DEBUG_ARG("so = %lx", (long )so); - + #if 0 /* * Check if they're authorised @@ -1261,12 +1239,12 @@ tcp_ctl(so) sb->sb_wptr += sb->sb_cc; return 0; } -#endif +#endif command = (ntohl(so->so_faddr.s_addr) & 0xff); - + switch(command) { default: /* Check for exec's */ - + /* * Check if it's pty_exec */ @@ -1277,12 +1255,12 @@ tcp_ctl(so) goto do_exec; } } - + /* * Nothing bound.. */ /* tcp_fconnect(so); */ - + /* FALLTHROUGH */ case CTL_ALIAS: sb->sb_cc = sprintf(sb->sb_wptr, @@ -1293,12 +1271,12 @@ tcp_ctl(so) do_exec: DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec)); return(fork_exec(so, ex_ptr->ex_exec, do_pty)); - + #if 0 case CTL_CMD: for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { - if (tmpso->so_emu == EMU_CTL && - !(tmpso->so_tcpcb? + if (tmpso->so_emu == EMU_CTL && + !(tmpso->so_tcpcb? (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK)) :0)) { /* Ooops, control connection already active */ diff --git a/BasiliskII/src/slirp/tcp_timer.c b/BasiliskII/src/slirp/tcp_timer.c index 244bad6a..ab9aa580 100644 --- a/BasiliskII/src/slirp/tcp_timer.c +++ b/BasiliskII/src/slirp/tcp_timer.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,14 +32,14 @@ #include -#ifdef LOG_ENABLED +int tcp_keepidle = TCPTV_KEEP_IDLE; +int tcp_keepintvl = TCPTV_KEEPINTVL; +int tcp_maxidle; +int so_options = DO_KEEPALIVE; + struct tcpstat tcpstat; /* tcp statistics */ -#endif - u_int32_t tcp_now; /* for RFC 1323 timestamps */ -static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer); - /* * Fast timeout routine for processing delayed acks */ @@ -54,7 +50,7 @@ tcp_fasttimo() register struct tcpcb *tp; DEBUG_CALL("tcp_fasttimo"); - + so = tcb.so_next; if (so) for (; so != &tcb; so = so->so_next) @@ -62,7 +58,7 @@ tcp_fasttimo() (tp->t_flags & TF_DELACK)) { tp->t_flags &= ~TF_DELACK; tp->t_flags |= TF_ACKNOW; - STAT(tcpstat.tcps_delack++); + tcpstat.tcps_delack++; (void) tcp_output(tp); } } @@ -80,7 +76,8 @@ tcp_slowtimo() register int i; DEBUG_CALL("tcp_slowtimo"); - + + tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl; /* * Search through tcb's and update active timers. */ @@ -126,19 +123,21 @@ tcp_canceltimers(tp) tp->t_timer[i] = 0; } -const int tcp_backoff[TCP_MAXRXTSHIFT + 1] = +int tcp_backoff[TCP_MAXRXTSHIFT + 1] = { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; /* * TCP timer processing. */ -static struct tcpcb * -tcp_timers(register struct tcpcb *tp, int timer) +struct tcpcb * +tcp_timers(tp, timer) + register struct tcpcb *tp; + int timer; { register int rexmt; - + DEBUG_CALL("tcp_timers"); - + switch (timer) { /* @@ -149,8 +148,8 @@ tcp_timers(register struct tcpcb *tp, int timer) */ case TCPT_2MSL: if (tp->t_state != TCPS_TIME_WAIT && - tp->t_idle <= TCP_MAXIDLE) - tp->t_timer[TCPT_2MSL] = TCPTV_KEEPINTVL; + tp->t_idle <= tcp_maxidle) + tp->t_timer[TCPT_2MSL] = tcp_keepintvl; else tp = tcp_close(tp); break; @@ -161,12 +160,12 @@ tcp_timers(register struct tcpcb *tp, int timer) * to a longer retransmit interval and retransmit one segment. */ case TCPT_REXMT: - + /* * XXXXX If a packet has timed out, then remove all the queued * packets for that session. */ - + if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) { /* * This is a hack to suit our terminal server here at the uni of canberra @@ -175,33 +174,33 @@ tcp_timers(register struct tcpcb *tp, int timer) * keep retransmitting it, it'll keep eating the zeroes, so we keep * retransmitting, and eventually the connection dies... * (this only happens on incoming data) - * + * * So, if we were gonna drop the connection from too many retransmits, * don't... instead halve the t_maxseg, which might break up the NULLs and * let them through - * + * * *sigh* */ - + tp->t_maxseg >>= 1; if (tp->t_maxseg < 32) { /* * We tried our best, now the connection must die! */ tp->t_rxtshift = TCP_MAXRXTSHIFT; - STAT(tcpstat.tcps_timeoutdrop++); + tcpstat.tcps_timeoutdrop++; tp = tcp_drop(tp, tp->t_softerror); /* tp->t_softerror : ETIMEDOUT); */ /* XXX */ return (tp); /* XXX */ } - + /* * Set rxtshift to 6, which is still at the maximum * backoff time */ tp->t_rxtshift = 6; } - STAT(tcpstat.tcps_rexmttimeo++); + tcpstat.tcps_rexmttimeo++; rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; TCPT_RANGESET(tp->t_rxtcur, rexmt, (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ @@ -237,7 +236,7 @@ tcp_timers(register struct tcpcb *tp, int timer) * size increase exponentially with time. If the * window is larger than the path can handle, this * exponential growth results in dropped packet(s) - * almost immediately. To get more time between + * almost immediately. To get more time between * drops but still "push" the network to take advantage * of improving conditions, we switch from exponential * to linear window opening at some threshold size. @@ -264,7 +263,7 @@ tcp_timers(register struct tcpcb *tp, int timer) * Force a byte to be output, if possible. */ case TCPT_PERSIST: - STAT(tcpstat.tcps_persisttimeo++); + tcpstat.tcps_persisttimeo++; tcp_setpersist(tp); tp->t_force = 1; (void) tcp_output(tp); @@ -276,13 +275,13 @@ tcp_timers(register struct tcpcb *tp, int timer) * or drop connection if idle for too long. */ case TCPT_KEEP: - STAT(tcpstat.tcps_keeptimeo++); + tcpstat.tcps_keeptimeo++; if (tp->t_state < TCPS_ESTABLISHED) goto dropit; /* if (tp->t_socket->so_options & SO_KEEPALIVE && */ - if ((SO_OPTIONS) && tp->t_state <= TCPS_CLOSE_WAIT) { - if (tp->t_idle >= TCPTV_KEEP_IDLE + TCP_MAXIDLE) + if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) { + if (tp->t_idle >= tcp_keepidle + tcp_maxidle) goto dropit; /* * Send a packet designed to force a response @@ -296,7 +295,7 @@ tcp_timers(register struct tcpcb *tp, int timer) * by the protocol spec, this requires the * correspondent TCP to respond. */ - STAT(tcpstat.tcps_keepprobe++); + tcpstat.tcps_keepprobe++; #ifdef TCP_COMPAT_42 /* * The keepalive packet must have nonzero length @@ -308,13 +307,13 @@ tcp_timers(register struct tcpcb *tp, int timer) tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL, tp->rcv_nxt, tp->snd_una - 1, 0); #endif - tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL; + tp->t_timer[TCPT_KEEP] = tcp_keepintvl; } else - tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE; + tp->t_timer[TCPT_KEEP] = tcp_keepidle; break; dropit: - STAT(tcpstat.tcps_keepdrops++); + tcpstat.tcps_keepdrops++; tp = tcp_drop(tp, 0); /* ETIMEDOUT); */ break; } diff --git a/BasiliskII/src/slirp/tcp_timer.h b/BasiliskII/src/slirp/tcp_timer.h index f251846b..73fe2089 100644 --- a/BasiliskII/src/slirp/tcp_timer.h +++ b/BasiliskII/src/slirp/tcp_timer.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -126,12 +122,17 @@ char *tcptimers[] = (tv) = (tvmax); \ } -extern const int tcp_backoff[]; +extern int tcp_keepidle; /* time before keepalive probes begin */ +extern int tcp_keepintvl; /* time between keepalive probes */ +extern int tcp_maxidle; /* time to drop after starting probes */ +extern int tcp_ttl; /* time to live for TCP segs */ +extern int tcp_backoff[]; struct tcpcb; -void tcp_fasttimo _P((void)); -void tcp_slowtimo _P((void)); -void tcp_canceltimers _P((struct tcpcb *)); +void tcp_fasttimo(void); +void tcp_slowtimo(void); +void tcp_canceltimers(struct tcpcb *); +struct tcpcb * tcp_timers(register struct tcpcb *, int); #endif diff --git a/BasiliskII/src/slirp/tcp_var.h b/BasiliskII/src/slirp/tcp_var.h index 82380f93..c8e99ae0 100644 --- a/BasiliskII/src/slirp/tcp_var.h +++ b/BasiliskII/src/slirp/tcp_var.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -185,7 +181,6 @@ typedef u_int32_t mbufp_32; #endif #define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) -#ifdef LOG_ENABLED /* * TCP statistics. * Many of these should be kept per connection, @@ -248,8 +243,6 @@ struct tcpstat { }; extern struct tcpstat tcpstat; /* tcp statistics */ -#endif - extern u_int32_t tcp_now; /* for RFC 1323 timestamps */ #endif diff --git a/BasiliskII/src/slirp/tcpip.h b/BasiliskII/src/slirp/tcpip.h index 82708b09..dff5a3c9 100644 --- a/BasiliskII/src/slirp/tcpip.h +++ b/BasiliskII/src/slirp/tcpip.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/BasiliskII/src/slirp/tftp.c b/BasiliskII/src/slirp/tftp.c index 562ae895..3ba2971c 100644 --- a/BasiliskII/src/slirp/tftp.c +++ b/BasiliskII/src/slirp/tftp.c @@ -1,8 +1,8 @@ /* * tftp.c - a simple, read-only tftp server for qemu - * + * * Copyright (c) 2004 Magnus Damm - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights @@ -26,15 +26,15 @@ struct tftp_session { int in_use; - unsigned char filename[TFTP_FILENAME_MAX]; - + char filename[TFTP_FILENAME_MAX]; + struct in_addr client_ip; u_int16_t client_port; - + int timestamp; }; -static struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; +struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; const char *tftp_prefix; @@ -102,15 +102,8 @@ static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr, { int fd; int bytes_read = 0; - char buffer[1024]; - int n; - n = snprintf(buffer, sizeof(buffer), "%s/%s", - tftp_prefix, spt->filename); - if (n >= sizeof(buffer)) - return -1; - - fd = open(buffer, O_RDONLY | O_BINARY); + fd = open(spt->filename, O_RDONLY | O_BINARY); if (fd < 0) { return -1; @@ -127,53 +120,13 @@ static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr, return bytes_read; } -static int tftp_send_oack(struct tftp_session *spt, - const char *key, uint32_t value, - struct tftp_t *recv_tp) -{ - struct sockaddr_in saddr, daddr; - struct mbuf *m; - struct tftp_t *tp; - int n = 0; - - m = m_get(); - - if (!m) - return -1; - - memset(m->m_data, 0, m->m_size); - - m->m_data += IF_MAXLINKHDR; - tp = (void *)m->m_data; - m->m_data += sizeof(struct udpiphdr); - - tp->tp_op = htons(TFTP_OACK); - n += sprintf(tp->x.tp_buf + n, "%s", key) + 1; - n += sprintf(tp->x.tp_buf + n, "%u", value) + 1; - - saddr.sin_addr = recv_tp->ip.ip_dst; - saddr.sin_port = recv_tp->udp.uh_dport; - - daddr.sin_addr = spt->client_ip; - daddr.sin_port = spt->client_port; - - m->m_len = sizeof(struct tftp_t) - 514 + n - - sizeof(struct ip) - sizeof(struct udphdr); - udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); - - return 0; -} - - - -static int tftp_send_error(struct tftp_session *spt, +static int tftp_send_error(struct tftp_session *spt, u_int16_t errorcode, const char *msg, struct tftp_t *recv_tp) { struct sockaddr_in saddr, daddr; struct mbuf *m; struct tftp_t *tp; - int nobytes; m = m_get(); @@ -183,13 +136,14 @@ static int tftp_send_error(struct tftp_session *spt, memset(m->m_data, 0, m->m_size); - m->m_data += IF_MAXLINKHDR; + m->m_data += if_maxlinkhdr; tp = (void *)m->m_data; m->m_data += sizeof(struct udpiphdr); - + tp->tp_op = htons(TFTP_ERROR); tp->x.tp_error.tp_error_code = htons(errorcode); - strcpy(tp->x.tp_error.tp_msg, msg); + strncpy((char *)tp->x.tp_error.tp_msg, msg, sizeof(tp->x.tp_error.tp_msg)); + tp->x.tp_error.tp_msg[sizeof(tp->x.tp_error.tp_msg)-1] = 0; saddr.sin_addr = recv_tp->ip.ip_dst; saddr.sin_port = recv_tp->udp.uh_dport; @@ -197,9 +151,7 @@ static int tftp_send_error(struct tftp_session *spt, daddr.sin_addr = spt->client_ip; daddr.sin_port = spt->client_port; - nobytes = 2; - - m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) - + m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) - sizeof(struct ip) - sizeof(struct udphdr); udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); @@ -209,7 +161,7 @@ static int tftp_send_error(struct tftp_session *spt, return 0; } -static int tftp_send_data(struct tftp_session *spt, +static int tftp_send_data(struct tftp_session *spt, u_int16_t block_nr, struct tftp_t *recv_tp) { @@ -230,10 +182,10 @@ static int tftp_send_data(struct tftp_session *spt, memset(m->m_data, 0, m->m_size); - m->m_data += IF_MAXLINKHDR; + m->m_data += if_maxlinkhdr; tp = (void *)m->m_data; m->m_data += sizeof(struct udpiphdr); - + tp->tp_op = htons(TFTP_DATA); tp->x.tp_data.tp_block_nr = htons(block_nr); @@ -255,7 +207,7 @@ static int tftp_send_data(struct tftp_session *spt, return -1; } - m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - + m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - sizeof(struct ip) - sizeof(struct udphdr); udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); @@ -285,7 +237,7 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) spt = &tftp_sessions[s]; src = tp->x.tp_buf; - dst = spt->filename; + dst = (u_int8_t *)spt->filename; n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp); /* get name */ @@ -297,30 +249,28 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) else { return; } - + if (src[k] == '\0') { break; } } - + if (k >= n) { return; } - + k++; - + /* check mode */ if ((n - k) < 6) { return; } - + if (memcmp(&src[k], "octet\0", 6) != 0) { tftp_send_error(spt, 4, "Unsupported transfer mode", tp); return; } - k += 6; /* skipping octet */ - /* do sanity checks on the filename */ if ((spt->filename[0] != '/') @@ -332,60 +282,19 @@ static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) /* only allow exported prefixes */ - if (!tftp_prefix) { + if (!tftp_prefix + || (strncmp(spt->filename, tftp_prefix, strlen(tftp_prefix)) != 0)) { tftp_send_error(spt, 2, "Access violation", tp); return; } /* check if the file exists */ - - if (tftp_read_data(spt, 0, spt->filename, 0) < 0) { + + if (tftp_read_data(spt, 0, (u_int8_t *)spt->filename, 0) < 0) { tftp_send_error(spt, 1, "File not found", tp); return; } - if (src[n - 1] != 0) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - while (k < n) { - const char *key, *value; - - key = src + k; - k += strlen(key) + 1; - - if (k >= n) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } - - value = src + k; - k += strlen(value) + 1; - - if (strcmp(key, "tsize") == 0) { - int tsize = atoi(value); - struct stat stat_p; - - if (tsize == 0 && tftp_prefix) { - char buffer[1024]; - int len; - - len = snprintf(buffer, sizeof(buffer), "%s/%s", - tftp_prefix, spt->filename); - - if (stat(buffer, &stat_p) == 0) - tsize = stat_p.st_size; - else { - tftp_send_error(spt, 1, "File not found", tp); - return; - } - } - - tftp_send_oack(spt, "tsize", tsize, tp); - } - } - tftp_send_data(spt, 1, tp); } @@ -399,8 +308,8 @@ static void tftp_handle_ack(struct tftp_t *tp, int pktlen) return; } - if (tftp_send_data(&tftp_sessions[s], - ntohs(tp->x.tp_data.tp_block_nr) + 1, + if (tftp_send_data(&tftp_sessions[s], + ntohs(tp->x.tp_data.tp_block_nr) + 1, tp) < 0) { return; } diff --git a/BasiliskII/src/slirp/tftp.h b/BasiliskII/src/slirp/tftp.h index 8f2675e0..b150a049 100644 --- a/BasiliskII/src/slirp/tftp.h +++ b/BasiliskII/src/slirp/tftp.h @@ -9,25 +9,32 @@ #define TFTP_DATA 3 #define TFTP_ACK 4 #define TFTP_ERROR 5 -#define TFTP_OACK 6 #define TFTP_FILENAME_MAX 512 +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + struct tftp_t { struct ip ip; struct udphdr udp; u_int16_t tp_op; union { - struct { + struct { u_int16_t tp_block_nr; u_int8_t tp_buf[512]; } tp_data; - struct { + struct { u_int16_t tp_error_code; u_int8_t tp_msg[512]; } tp_error; u_int8_t tp_buf[512 + 2]; } x; -}; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_RESET) +#endif void tftp_input(struct mbuf *m); diff --git a/BasiliskII/src/slirp/udp.c b/BasiliskII/src/slirp/udp.c index c48923b0..9d805ff3 100644 --- a/BasiliskII/src/slirp/udp.c +++ b/BasiliskII/src/slirp/udp.c @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -37,31 +33,27 @@ /* * Changes and additions relating to SLiRP * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ +#include #include #include "ip_icmp.h" -#ifdef LOG_ENABLED struct udpstat udpstat; -#endif struct socket udb; -static u_int8_t udp_tos(struct socket *so); -static void udp_emu(struct socket *so, struct mbuf *m); - /* * UDP protocol implementation. * Per RFC 768, August, 1980. */ #ifndef COMPAT_42 -#define UDPCKSUM 1 +int udpcksum = 1; #else -#define UDPCKSUM 0 /* XXX */ +int udpcksum = 0; /* XXX */ #endif struct socket *udp_last_so = &udb; @@ -71,8 +63,8 @@ udp_init() { udb.so_next = udb.so_prev = &udb; } -/* m->m_data points at ip packet header - * m->m_len length ip packet +/* m->m_data points at ip packet header + * m->m_len length ip packet * ip->ip_len length data (IPDU) */ void @@ -84,14 +76,14 @@ udp_input(m, iphlen) register struct udphdr *uh; /* struct mbuf *opts = 0;*/ int len; - struct ip save_ip; + struct ip save_ip; struct socket *so; - + DEBUG_CALL("udp_input"); DEBUG_ARG("m = %lx", (long)m); DEBUG_ARG("iphlen = %d", iphlen); - - STAT(udpstat.udps_ipackets++); + + udpstat.udps_ipackets++; /* * Strip IP options, if any; should skip this, @@ -118,34 +110,34 @@ udp_input(m, iphlen) if (ip->ip_len != len) { if (len > ip->ip_len) { - STAT(udpstat.udps_badlen++); + udpstat.udps_badlen++; goto bad; } m_adj(m, len - ip->ip_len); ip->ip_len = len; } - + /* * Save a copy of the IP header in case we want restore it * for sending an ICMP error message in response. */ - save_ip = *ip; + save_ip = *ip; save_ip.ip_len+= iphlen; /* tcp_input subtracts this */ /* * Checksum extended UDP header and data. */ - if (UDPCKSUM && uh->uh_sum) { + if (udpcksum && uh->uh_sum) { ((struct ipovly *)ip)->ih_next = 0; ((struct ipovly *)ip)->ih_prev = 0; ((struct ipovly *)ip)->ih_x1 = 0; ((struct ipovly *)ip)->ih_len = uh->uh_ulen; /* keep uh_sum for ICMP reply - * uh->uh_sum = cksum(m, len + sizeof (struct ip)); - * if (uh->uh_sum) { + * uh->uh_sum = cksum(m, len + sizeof (struct ip)); + * if (uh->uh_sum) { */ if(cksum(m, len + sizeof(struct ip))) { - STAT(udpstat.udps_badsum++); + udpstat.udps_badsum++; goto bad; } } @@ -173,7 +165,7 @@ udp_input(m, iphlen) if (so->so_lport != uh->uh_sport || so->so_laddr.s_addr != ip->ip_src.s_addr) { struct socket *tmp; - + for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { if (tmp->so_lport == uh->uh_sport && tmp->so_laddr.s_addr == ip->ip_src.s_addr) { @@ -186,11 +178,11 @@ udp_input(m, iphlen) if (tmp == &udb) { so = NULL; } else { - STAT(udpstat.udpps_pcbcachemiss++); + udpstat.udpps_pcbcachemiss++; udp_last_so = so; } } - + if (so == NULL) { /* * If there's no socket for this packet, @@ -198,22 +190,22 @@ udp_input(m, iphlen) */ if ((so = socreate()) == NULL) goto bad; if(udp_attach(so) == -1) { - DEBUG_MISC((dfd," udp_attach errno = %d-%s\n", + DEBUG_MISC((dfd," udp_attach errno = %d-%s\n", errno,strerror(errno))); sofree(so); goto bad; } - + /* * Setup fields */ /* udp_last_so = so; */ so->so_laddr = ip->ip_src; so->so_lport = uh->uh_sport; - + if ((so->so_iptos = udp_tos(so)) == 0) so->so_iptos = ip->ip_tos; - + /* * XXXXX Here, check if it's in udpexec_list, * and if it is, do the fork_exec() etc. @@ -238,7 +230,7 @@ udp_input(m, iphlen) m->m_data -= iphlen; *ip=save_ip; DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno))); - icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); + icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); } m_free(so->so_m); /* used for ICMP if error on sorecvfrom */ @@ -256,7 +248,7 @@ bad: return; } -int udp_output2(struct socket *so, struct mbuf *m, +int udp_output2(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr, struct sockaddr_in *daddr, int iptos) { @@ -274,16 +266,19 @@ int udp_output2(struct socket *so, struct mbuf *m, */ m->m_data -= sizeof(struct udpiphdr); m->m_len += sizeof(struct udpiphdr); - + /* * Fill in mbuf with extended UDP header * and addresses and length put into network format. */ ui = mtod(m, struct udpiphdr *); - ui->ui_next = ui->ui_prev = 0; + //ui->ui_next = ui->ui_prev = 0; + + memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); + ui->ui_x1 = 0; ui->ui_pr = IPPROTO_UDP; - ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ + ui->ui_len = htons((u_short) (m->m_len - sizeof(struct ip))); /* + sizeof (struct udphdr)); */ /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ ui->ui_src = saddr->sin_addr; ui->ui_dst = daddr->sin_addr; @@ -295,23 +290,23 @@ int udp_output2(struct socket *so, struct mbuf *m, * Stuff checksum and output datagram. */ ui->ui_sum = 0; - if (UDPCKSUM) { + if (udpcksum) { if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0) ui->ui_sum = 0xffff; } - ((struct ip *)ui)->ip_len = m->m_len; + ((struct ip *)ui)->ip_len = (u_int16_t) m->m_len; - ((struct ip *)ui)->ip_ttl = IPDEFTTL; + ((struct ip *)ui)->ip_ttl = ip_defttl; ((struct ip *)ui)->ip_tos = iptos; - - STAT(udpstat.udps_opackets++); - + + udpstat.udps_opackets++; + error = ip_output(so, m); - + return (error); } -int udp_output(struct socket *so, struct mbuf *m, +int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *addr) { @@ -325,7 +320,7 @@ int udp_output(struct socket *so, struct mbuf *m, } daddr.sin_addr = so->so_laddr; daddr.sin_port = so->so_lport; - + return udp_output2(so, m, &saddr, &daddr, so->so_iptos); } @@ -334,25 +329,22 @@ udp_attach(so) struct socket *so; { struct sockaddr_in addr; - + if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) { /* * Here, we bind() the socket. Although not really needed * (sendto() on an unbound socket will bind it), it's done * here so that emulation of ytalk etc. don't have to do it */ + memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; if(bind(so->s, (struct sockaddr *)&addr, sizeof(addr))<0) { - int lasterrno=errno; + int error = WSAGetLastError(); closesocket(so->s); so->s=-1; -#ifdef _WIN32 - WSASetLastError(lasterrno); -#else - errno=lasterrno; -#endif + WSASetLastError(error); } else { /* success, insert in queue */ so->so_expire = curtime + SO_EXPIRE; @@ -372,7 +364,7 @@ udp_detach(so) sofree(so); } -static const struct tos_t udptos[] = { +struct tos_t udptos[] = { {0, 53, IPTOS_LOWDELAY, 0}, /* DNS */ {517, 517, IPTOS_LOWDELAY, EMU_TALK}, /* talk */ {518, 518, IPTOS_LOWDELAY, EMU_NTALK}, /* ntalk */ @@ -380,11 +372,12 @@ static const struct tos_t udptos[] = { {0, 0, 0, 0} }; -static u_int8_t -udp_tos(struct socket *so) +u_int8_t +udp_tos(so) + struct socket *so; { int i = 0; - + while(udptos[i].tos) { if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) || (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) { @@ -393,7 +386,7 @@ udp_tos(struct socket *so) } i++; } - + return 0; } @@ -404,27 +397,29 @@ udp_tos(struct socket *so) /* * Here, talk/ytalk/ntalk requests must be emulated */ -static void -udp_emu(struct socket *so, struct mbuf *m) +void +udp_emu(so, m) + struct socket *so; + struct mbuf *m; { struct sockaddr_in addr; - int addrlen = sizeof(addr); + socklen_t addrlen = sizeof(addr); #ifdef EMULATE_TALK CTL_MSG_OLD *omsg; CTL_MSG *nmsg; char buff[sizeof(CTL_MSG)]; u_char type; - + struct talk_request { struct talk_request *next; struct socket *udp_so; struct socket *tcp_so; } *req; - - static struct talk_request *req_tbl = 0; - + + static struct talk_request *req_tbl = 0; + #endif - + struct cu_header { uint16_t d_family; // destination family uint16_t d_port; // destination port @@ -451,7 +446,7 @@ struct cu_header { */ if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) return; - + #define IS_OLD (so->so_emu == EMU_TALK) #define COPY_MSG(dest, src) { dest->type = src->type; \ @@ -474,7 +469,7 @@ struct cu_header { OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port; OTOSIN(omsg, ctl_addr)->sin_addr = our_addr; strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD); - } else { /* new talk */ + } else { /* new talk */ omsg = (CTL_MSG_OLD *) buff; nmsg = mtod(m, CTL_MSG *); type = nmsg->type; @@ -482,10 +477,10 @@ struct cu_header { OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr; strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD); } - - if (type == LOOK_UP) + + if (type == LOOK_UP) return; /* for LOOK_UP this is enough */ - + if (IS_OLD) { /* make a copy of the message */ COPY_MSG(nmsg, omsg); nmsg->vers = 1; @@ -504,75 +499,75 @@ struct cu_header { * ports, 517 and 518. This is why we have two copies * of the message, one in old talk and one in new talk * format. - */ + */ if (type == ANNOUNCE) { int s; u_short temp_port; - + for(req = req_tbl; req; req = req->next) if (so == req->udp_so) break; /* found it */ - + if (!req) { /* no entry for so, create new */ req = (struct talk_request *) malloc(sizeof(struct talk_request)); req->udp_so = so; - req->tcp_so = solisten(0, - OTOSIN(omsg, addr)->sin_addr.s_addr, + req->tcp_so = solisten(0, + OTOSIN(omsg, addr)->sin_addr.s_addr, OTOSIN(omsg, addr)->sin_port, SS_FACCEPTONCE); req->next = req_tbl; req_tbl = req; - } - + } + /* replace port number in addr field */ addrlen = sizeof(addr); - getsockname(req->tcp_so->s, + getsockname(req->tcp_so->s, (struct sockaddr *) &addr, - &addrlen); + &addrlen); OTOSIN(omsg, addr)->sin_port = addr.sin_port; OTOSIN(omsg, addr)->sin_addr = our_addr; OTOSIN(nmsg, addr)->sin_port = addr.sin_port; - OTOSIN(nmsg, addr)->sin_addr = our_addr; - + OTOSIN(nmsg, addr)->sin_addr = our_addr; + /* send LEAVE_INVITEs */ temp_port = OTOSIN(omsg, ctl_addr)->sin_port; OTOSIN(omsg, ctl_addr)->sin_port = 0; OTOSIN(nmsg, ctl_addr)->sin_port = 0; - omsg->type = nmsg->type = LEAVE_INVITE; - + omsg->type = nmsg->type = LEAVE_INVITE; + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); addr.sin_addr = our_addr; addr.sin_family = AF_INET; addr.sin_port = htons(517); - sendto(s, (char *)omsg, sizeof(*omsg), 0, + sendto(s, (char *)omsg, sizeof(*omsg), 0, (struct sockaddr *)&addr, sizeof(addr)); addr.sin_port = htons(518); sendto(s, (char *)nmsg, sizeof(*nmsg), 0, (struct sockaddr *) &addr, sizeof(addr)); closesocket(s) ; - omsg->type = nmsg->type = ANNOUNCE; + omsg->type = nmsg->type = ANNOUNCE; OTOSIN(omsg, ctl_addr)->sin_port = temp_port; OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; } - - /* + + /* * If it is a DELETE message, we send a copy to the * local daemons. Then we delete the entry corresponding * to our socket from the request table. */ - + if (type == DELETE) { struct talk_request *temp_req, *req_next; int s; u_short temp_port; - + temp_port = OTOSIN(omsg, ctl_addr)->sin_port; OTOSIN(omsg, ctl_addr)->sin_port = 0; OTOSIN(nmsg, ctl_addr)->sin_port = 0; - + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); addr.sin_addr = our_addr; addr.sin_family = AF_INET; @@ -583,7 +578,7 @@ struct cu_header { sendto(s, (char *)nmsg, sizeof(*nmsg), 0, (struct sockaddr *)&addr, sizeof(addr)); closesocket(s); - + OTOSIN(omsg, ctl_addr)->sin_port = temp_port; OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; @@ -606,18 +601,18 @@ struct cu_header { } } } - - return; + + return; #endif - + case EMU_CUSEEME: - + /* * Cu-SeeMe emulation. * Hopefully the packet is more that 16 bytes long. We don't * do any other tests, just replace the address and port * fields. - */ + */ if (m->m_len >= sizeof (*cu_head)) { if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) return; @@ -625,7 +620,7 @@ struct cu_header { cu_head->s_port = addr.sin_port; cu_head->so_addr = our_addr.s_addr; } - + return; } } @@ -639,8 +634,9 @@ udp_listen(port, laddr, lport, flags) { struct sockaddr_in addr; struct socket *so; - int addrlen = sizeof(struct sockaddr_in), opt = 1; - + socklen_t addrlen = sizeof(struct sockaddr_in); + int opt = 1; + if ((so = socreate()) == NULL) { free(so); return NULL; @@ -649,6 +645,7 @@ udp_listen(port, laddr, lport, flags) so->so_expire = curtime + SO_EXPIRE; insque(so,&udb); + memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = port; @@ -659,20 +656,20 @@ udp_listen(port, laddr, lport, flags) } setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); /* setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); */ - + getsockname(so->s,(struct sockaddr *)&addr,&addrlen); so->so_fport = addr.sin_port; if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) so->so_faddr = alias_addr; else so->so_faddr = addr.sin_addr; - + so->so_lport = lport; so->so_laddr.s_addr = laddr; if (flags != SS_FACCEPTONCE) so->so_expire = 0; - + so->so_state = SS_ISFCONNECTED; - + return so; } diff --git a/BasiliskII/src/slirp/udp.h b/BasiliskII/src/slirp/udp.h index 4f69b098..7d844efe 100644 --- a/BasiliskII/src/slirp/udp.h +++ b/BasiliskII/src/slirp/udp.h @@ -10,11 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -46,12 +42,20 @@ extern struct socket *udp_last_so; * Udp protocol header. * Per RFC 768, September, 1981. */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + struct udphdr { u_int16_t uh_sport; /* source port */ u_int16_t uh_dport; /* destination port */ int16_t uh_ulen; /* udp length */ u_int16_t uh_sum; /* udp checksum */ -}; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_RESET) +#endif /* * UDP kernel structures and variables. @@ -72,7 +76,6 @@ struct udpiphdr { #define ui_ulen ui_u.uh_ulen #define ui_sum ui_u.uh_sum -#ifdef LOG_ENABLED struct udpstat { /* input statistics: */ u_long udps_ipackets; /* total input packets */ @@ -86,7 +89,6 @@ struct udpstat { /* output statistics: */ u_long udps_opackets; /* total output packets */ }; -#endif /* * Names for UDP sysctl objects @@ -94,20 +96,19 @@ struct udpstat { #define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ #define UDPCTL_MAXID 2 -#ifdef LOG_ENABLED extern struct udpstat udpstat; -#endif - extern struct socket udb; struct mbuf; -void udp_init _P((void)); -void udp_input _P((register struct mbuf *, int)); -int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *)); -int udp_attach _P((struct socket *)); -void udp_detach _P((struct socket *)); -struct socket * udp_listen _P((u_int, u_int32_t, u_int, int)); -int udp_output2(struct socket *so, struct mbuf *m, +void udp_init(void); +void udp_input(register struct mbuf *, int); +int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *); +int udp_attach(struct socket *); +void udp_detach(struct socket *); +u_int8_t udp_tos(struct socket *); +void udp_emu(struct socket *, struct mbuf *); +struct socket * udp_listen(u_int, u_int32_t, u_int, int); +int udp_output2(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr, struct sockaddr_in *daddr, int iptos); #endif