From a4f1f570c8960d56b4263813be3c77b4832879f8 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 11 Mar 2017 21:06:59 +0200 Subject: [PATCH] Slirp Basilisk II merge. --- cfgfile.cpp | 7 +- custom.cpp | 42 ++- drawing.cpp | 3 + ethernet.cpp | 1 + fpp.cpp | 200 ++++++------ fpp_native.cpp | 318 +++++++++--------- fpp_softfloat.cpp | 271 ++++++++++++---- gfxboard.cpp | 1 + include/fpp.h | 7 +- include/inputdevice.h | 6 +- slirp/debug.h | 28 +- slirp/icmp_var.h | 3 +- slirp/if.cpp | 9 +- slirp/if.h | 4 +- slirp/ip_icmp.cpp | 42 ++- slirp/ip_icmp.h | 11 +- slirp/ip_input.cpp | 6 +- slirp/ip_output.cpp | 11 +- slirp/mbuf.cpp | 2 +- slirp/mbuf.h | 24 +- slirp/misc.cpp | 153 +++------ slirp/misc.h | 38 +-- slirp/sbuf.cpp | 2 +- slirp/sbuf.h | 14 +- slirp/slirp.cpp | 174 +++++----- slirp/slirp.h | 151 ++++----- slirp/slirp_config.h | 8 - slirp/socket.cpp | 62 ++-- slirp/socket.h | 38 +-- slirp/tcp.h | 4 +- slirp/tcp_input.cpp | 734 +++++++++++++++++++++--------------------- slirp/tcp_output.cpp | 22 +- slirp/tcp_subr.cpp | 23 +- slirp/tcp_timer.h | 8 +- slirp/tftp.cpp | 3 - slirp/udp.cpp | 54 ++-- slirp/udp.h | 18 +- slirp_uae.cpp | 1 + 38 files changed, 1313 insertions(+), 1190 deletions(-) diff --git a/cfgfile.cpp b/cfgfile.cpp index 764d175b..db3fa7c5 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -1327,10 +1327,10 @@ static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const rb->device_order = _tstol(s); s = cfgfile_option_get(value, _T("mid")); if (s) - rb->manufacturer = _tstol(s); + rb->manufacturer = (uae_u16)_tstol(s); s = cfgfile_option_get(value, _T("pid")); if (s) - rb->product = _tstol(s); + rb->product = (uae_u8)_tstol(s); s = cfgfile_option_get(value, _T("no_reset_unmap")); if (s) rb->no_reset_unmap = true; @@ -1908,6 +1908,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite(f, _T("genlock_mix"), _T("%d"), p->genlock_mix); cfgfile_dwrite(f, _T("genlock_scale"), _T("%d"), p->genlock_scale); cfgfile_dwrite_str(f, _T("monitoremu"), specialmonitors[p->monitoremu]); + cfgfile_dwrite_bool(f, _T("lightpen_crosshair"), p->lightpen_crosshair); cfgfile_dwrite_bool (f, _T("show_leds"), !!(p->leds_on_screen & STATUSLINE_CHIPSET)); cfgfile_dwrite_bool (f, _T("show_leds_rtg"), !!(p->leds_on_screen & STATUSLINE_RTG)); @@ -4759,6 +4760,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH || cfgfile_yesno(option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite) || cfgfile_yesno(option, value, _T("synchronize_clock"), &p->tod_hack) || cfgfile_yesno(option, value, _T("keyboard_connected"), &p->keyboard_connected) + || cfgfile_yesno(option, value, _T("lightpen_crosshair"), &p->lightpen_crosshair) || cfgfile_yesno (option, value, _T("kickshifter"), &p->kickshifter) || cfgfile_yesno (option, value, _T("ks_write_enabled"), &p->rom_readwrite) @@ -6849,6 +6851,7 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->sana2 = 0; p->clipboard_sharing = false; p->native_code = false; + p->lightpen_crosshair = true; p->cs_compatible = CP_GENERIC; p->cs_rtc = 2; diff --git a/custom.cpp b/custom.cpp index a6cec001..74336904 100644 --- a/custom.cpp +++ b/custom.cpp @@ -59,6 +59,8 @@ #define SPRBORDER 0 +static int denise_resolution_min = 0; + extern uae_u16 serper; STATIC_INLINE bool nocustom (void) @@ -992,7 +994,7 @@ static uae_u64 fetched_aga[MAX_PLANES]; #endif /* Expansions from bplcon0/bplcon1. */ -static int toscr_res, toscr_res2p; +static int toscr_res, toscr_res2p, toscr_res_mult; static int toscr_nr_planes, toscr_nr_planes2, toscr_nr_planes_agnus, toscr_nr_planes_shifter; static int fetchwidth; static int toscr_delay[2], toscr_delay_adjusted[2], toscr_delay_sh[2]; @@ -1371,7 +1373,7 @@ static void fetch (int nr, int fm, bool modulo, int hpos) #ifdef AGA case 1: fetched_aga[nr] = chipmem_lget_indirect (p); - last_custom_value1 = fetched_aga[nr]; + last_custom_value1 = (uae_u32)fetched_aga[nr]; fetched[nr] = (uae_u16)fetched_aga[nr]; break; case 2: @@ -1807,6 +1809,11 @@ static void update_denise (int hpos) flush_display (fetchmode); toscr_res = GET_RES_DENISE (bplcon0d); toscr_res2p = 2 << toscr_res; + if (toscr_res < denise_resolution_min) { + toscr_res_mult = denise_resolution_min - toscr_res; + } else { + toscr_res_mult = 0; + } delay_cycles = (hpos * 2) << toscr_res; if (bplcon0dd != bplcon0d) { record_color_change2 (hpos, 0x100 + 0x1000, bplcon0d); @@ -1926,7 +1933,7 @@ STATIC_INLINE void long_fetch_32 (int plane, int nwords, int weird_number_of_bit int tmp_nbits = out_nbits; uae_u64 shiftbuffer; uae_u32 outval = outword[plane]; - uae_u32 fetchval = fetched_aga[plane]; + uae_u32 fetchval = (uae_u32)fetched_aga[plane]; uae_u32 *dataptr = (uae_u32 *)(line_data[next_lineno] + 2 * plane * MAX_WORDS_PER_LINE + 4 * out_offs); if (dma) { @@ -2071,10 +2078,10 @@ STATIC_INLINE void long_fetch_64 (int plane, int nwords, int weird_number_of_bit t = (shiftbuffer >> shift) & 0xffff; #else if (64 - shift > 0) { - t = shiftbuffer[1] << (64 - shift); + t = (uae_u32)(shiftbuffer[1] << (64 - shift)); t |= shiftbuffer[0] >> shift; } else { - t = shiftbuffer[1] >> (shift - 64); + t = (uae_u32)(shiftbuffer[1] >> (shift - 64)); } t &= 0xffff; #endif @@ -2242,6 +2249,7 @@ static void maybe_finish_last_fetch (int pos, int fm) bitplane_overrun = 0; bitplane_overrun_hpos = left; } + SET_LINE_CYCLEBASED; bitplane_overrun_cycle_diagram_shift = fetchunit - (bitplane_overrun_fetch_cycle & fetchstart_mask); finish_last_fetch(pos, fm, true); } @@ -2321,7 +2329,7 @@ static void do_overrun_fetch(int until, int fm) flush_display(fm); #endif - if ((bitplane_overrun_fetch_cycle & fetchunit_mask) == 0) { + if ((bitplane_overrun_fetch_cycle & fetchunit_mask) == fetchunit_mask) { bitplane_overrun--; if (hit && warned > 0) { warned--; @@ -4277,9 +4285,9 @@ static void init_hz (bool checkvposw) sprite_vblank_endline = VBLANK_SPRITE_PAL; equ_vblank_endline = EQU_ENDLINE_PAL; equ_vblank_toggle = true; - vblank_hz_shf = (double)clk / ((maxvpos + 0) * maxhpos); - vblank_hz_lof = (double)clk / ((maxvpos + 1) * maxhpos); - vblank_hz_lace = (double)clk / ((maxvpos + 0.5) * maxhpos); + vblank_hz_shf = (float)((double)clk / ((maxvpos + 0) * maxhpos)); + vblank_hz_lof = (float)((double)clk / ((maxvpos + 1) * maxhpos)); + vblank_hz_lace = (float)((double)clk / ((maxvpos + 0.5) * maxhpos)); } else { maxvpos = MAXVPOS_NTSC; maxhpos = MAXHPOS_NTSC; @@ -4288,9 +4296,9 @@ static void init_hz (bool checkvposw) sprite_vblank_endline = VBLANK_SPRITE_NTSC; equ_vblank_endline = EQU_ENDLINE_NTSC; equ_vblank_toggle = false; - vblank_hz_shf = (double)clk / ((maxvpos + 0) * (maxhpos + 0.5)); - vblank_hz_lof = (double)clk / ((maxvpos + 1) * (maxhpos + 0.5)); - vblank_hz_lace = (double)clk / ((maxvpos + 0.5) * (maxhpos + 0.5)); + vblank_hz_shf = (float)((double)clk / ((maxvpos + 0) * (maxhpos + 0.5))); + vblank_hz_lof = (float)((double)clk / ((maxvpos + 1) * (maxhpos + 0.5))); + vblank_hz_lace = (float)((double)clk / ((maxvpos + 0.5) * (maxhpos + 0.5))); } maxvpos_nom = maxvpos; @@ -4301,7 +4309,7 @@ static void init_hz (bool checkvposw) if (vpos_count < 10) vpos_count = 10; vblank_hz = (isntsc ? 15734.0 : 15625.0) / vpos_count; - vblank_hz_nom = vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = vblank_hz; + vblank_hz_nom = vblank_hz_shf = vblank_hz_lof = vblank_hz_lace = (float)vblank_hz; maxvpos_nom = vpos_count - (lof_current ? 1 : 0); if ((maxvpos_nom >= 256 && maxvpos_nom <= 313) || (beamcon0 & 0x80)) { maxvpos_display = maxvpos_nom; @@ -4328,9 +4336,9 @@ static void init_hz (bool checkvposw) htotal = MAXHPOS - 1; maxhpos = htotal + 1; vblank_hz_nom = vblank_hz = 227.0 * 312.0 * 50.0 / (maxvpos * maxhpos); - vblank_hz_shf = vblank_hz; - vblank_hz_lof = 227.0 * 313.0 * 50.0 / (maxvpos * maxhpos);; - vblank_hz_lace = 227.0 * 312.5 * 50.0 / (maxvpos * maxhpos);; + vblank_hz_shf = (float)vblank_hz; + vblank_hz_lof = (float)(227.0 * 313.0 * 50.0 / (maxvpos * maxhpos)); + vblank_hz_lace = (float)(227.0 * 312.5 * 50.0 / (maxvpos * maxhpos)); if ((beamcon0 & 0x1000) && (beamcon0 & 0x0200)) { // VARVBEN + VARVSYEN minfirstline = vsstop > vbstop ? vsstop : vbstop; @@ -8214,7 +8222,7 @@ static void hsync_handler_post (bool onvsync) if (cia_hsync < maxhpos) { int newcount; CIAA_tod_inc (cia_hsync); - newcount = (vblank_hz * (2 * maxvpos + (interlace_seen ? 1 : 0)) * (2 * maxhpos + (islinetoggle () ? 1 : 0))) / ((currprefs.cs_ciaatod == 2 ? 60 : 50) * 4); + newcount = (int)((vblank_hz * (2 * maxvpos + (interlace_seen ? 1 : 0)) * (2 * maxhpos + (islinetoggle () ? 1 : 0))) / ((currprefs.cs_ciaatod == 2 ? 60 : 50) * 4)); cia_hsync += newcount; } else { cia_hsync -= maxhpos; diff --git a/drawing.cpp b/drawing.cpp index bb504cb3..c67818e7 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -3506,6 +3506,9 @@ static void draw_lightpen_cursor (int x, int y, int line, int onscreen) int color1 = onscreen ? 0xff0 : 0xf00; int color2 = 0x000; + if (!currprefs.lightpen_crosshair) + return; + xlinebuffer = gfxvidinfo.drawbuffer.linemem; if (xlinebuffer == 0) xlinebuffer = row_map[line]; diff --git a/ethernet.cpp b/ethernet.cpp index 8747c20d..5ec46cb8 100644 --- a/ethernet.cpp +++ b/ethernet.cpp @@ -1,3 +1,4 @@ + #include "sysconfig.h" #include "sysdeps.h" diff --git a/fpp.cpp b/fpp.cpp index 46623643..a12c3334 100644 --- a/fpp.cpp +++ b/fpp.cpp @@ -66,7 +66,11 @@ FPP_FROM_EXTEN fpp_from_exten_fmovem; FPP_A fpp_normalize; FPP_A fpp_get_internal_overflow; FPP_A fpp_get_internal_underflow; -FPP_PACKG fpp_get_exceptional_operand_grs; +FPP_A fpp_get_internal_round_all; +FPP_A fpp_get_internal_round; +FPP_A fpp_get_internal_round_exten; +FPP_A fpp_get_internal; +FPP_GET32 fpp_get_internal_grs; FPP_A fpp_round_single; FPP_A fpp_round_double; @@ -345,7 +349,7 @@ static void fp_unimp_instruction_exception_pending(void) { if (regs.fp_unimp_ins) { if (warned > 0) { - write_log (_T("FPU UNIMPLEMENTED INSTRUCTION EXCEPTION\n")); + write_log (_T("FPU UNIMPLEMENTED INSTRUCTION/FPU DISABLED EXCEPTION\n")); } regs.fpu_exp_pre = true; Exception(11); @@ -406,13 +410,13 @@ static void fpsr_check_arithmetic_exception(uae_u32 mask, fpdata *src, uae_u32 o regs.fp_ea = ea; // data for FSAVE stack frame - regs.fpu_exp_state = 2; // 68060 EXCP frame, 68040 BUSY frame, 6888x IDLE frame - + fpdata eo; uae_u32 opclass = (extra >> 13) & 7; + reset_fsave_data(); + if (currprefs.fpu_model == 68881 || currprefs.fpu_model == 68882) { // fsave data for 68881 and 68882 - fpdata eo; if (opclass == 3) { // 011 fsave_data.ccr = ((uae_u32)extra << 16) | extra; @@ -435,43 +439,78 @@ static void fpsr_check_arithmetic_exception(uae_u32 mask, fpdata *src, uae_u32 o } else if (currprefs.cpu_model == 68060) { // fsave data for 68060 + regs.fpu_exp_state = 2; // 68060 EXCP frame fsave_data.v = regs.fp_exp_pend & 7; + fpp_from_exten_fmovem(src, &fsave_data.eo[0], &fsave_data.eo[1], &fsave_data.eo[2]); } else { + // fsave data for 68040 + regs.fpu_exp_state = 1; // 68040 UNIMP frame + uae_u32 reg = (extra >> 7) & 7; uae_u32 size = (extra >> 10) & 7; - bool exp_e3 = false; - // fsave data for 68040 fsave_data.fpiarcu = regs.fpiar; + if (regs.fp_exp_pend == 54) { // SNAN (undocumented) + fsave_data.wbte15 = 1; + fsave_data.grs = 7; + } else { + fsave_data.grs = 1; + } + if (opclass == 3) { // OPCLASS 011 fsave_data.cmdreg1b = extra; fsave_data.e1 = 1; fsave_data.t = 1; + fsave_data.wbte15 = (regs.fp_exp_pend == 51 || regs.fp_exp_pend == 54) ? 1 : 0; // UNFL, SNAN + + if (fpp_is_snan(src)) { + fpp_unset_snan(src); + } fpp_from_exten_fmovem(src, &fsave_data.et[0], &fsave_data.et[1], &fsave_data.et[2]); - fsave_data.stag = get_ftag(src, size); + fsave_data.stag = get_ftag(src, -1); } else { // OPCLASS 000 and 010 + fsave_data.cmdreg1b = extra; + fsave_data.e1 = 1; + fsave_data.wbte15 = (regs.fp_exp_pend == 54) ? 1 : 0; // SNAN (undocumented) + if (regs.fp_exp_pend == 51 || regs.fp_exp_pend == 53 || regs.fp_exp_pend == 49) { // UNFL, OVFL, INEX - if((extra & 0x30) == 0x20 || (extra & 0x3f) == 0x04) { // FADD, FSUB, FMUL, FDIV, FSQRT - exp_e3 = true; + if ((extra & 0x30) == 0x20 || (extra & 0x3f) == 0x04) { // FADD, FSUB, FMUL, FDIV, FSQRT + regs.fpu_exp_state = 2; // 68040 BUSY frame + fsave_data.e3 = 1; + fsave_data.e1 = 0; + fsave_data.cmdreg3b = (extra & 0x3C3) | ((extra & 0x038)>>1) | ((extra & 0x004)<<3); + if (regs.fp_exp_pend == 51) { // UNFL + fpp_get_internal(&eo); + } else { // OVFL, INEX + fpp_get_internal_round(&eo); + } + fsave_data.grs = fpp_get_internal_grs(); + fpp_from_exten_fmovem(&eo, &fsave_data.wbt[0], &fsave_data.wbt[1], &fsave_data.wbt[2]); + fsave_data.wbte15 = (regs.fp_exp_pend == 51) ? 1 : 0; // UNFL + // src and dst is stored (undocumented) + fpp_from_exten_fmovem(src, &fsave_data.et[0], &fsave_data.et[1], &fsave_data.et[2]); + fsave_data.stag = get_ftag(src, (opclass == 0) ? -1 : size); + if (fp_is_dyadic(extra)) { + fpp_from_exten_fmovem(®s.fp[reg], &fsave_data.fpt[0], &fsave_data.fpt[1], &fsave_data.fpt[2]); + fsave_data.dtag = get_ftag(®s.fp[reg], -1); + } + } else { // FMOVE to register, FABS, FNEG + fpp_get_internal_round_exten(&eo); + fsave_data.grs = fpp_get_internal_grs(); + fpp_from_exten_fmovem(&eo, &fsave_data.fpt[0], &fsave_data.fpt[1], &fsave_data.fpt[2]); + fpp_get_internal_round_all(&eo); // weird + fpp_from_exten_fmovem(&eo, &fsave_data.et[0], &fsave_data.et[1], &fsave_data.et[2]); // undocumented + fsave_data.stag = get_ftag(src, (opclass == 0) ? -1 : size); } - } - if (exp_e3) { - fsave_data.cmdreg3b = (extra & 0x3C3) | ((extra & 0x038) >> 1) | ((extra & 0x004) << 3); - fsave_data.e3 = 1; - fpp_get_exceptional_operand_grs(&fsave_data.wbt[0], &fsave_data.wbt[1], &fsave_data.wbt[2], &fsave_data.grs); - fsave_data.wbte15 = (regs.fp_exp_pend == 51) ? 1 : 0; // UNFL - } else { - fsave_data.cmdreg1b = extra; - fsave_data.e1 = 1; + } else { // SNAN, OPERR, DZ fpp_from_exten_fmovem(src, &fsave_data.et[0], &fsave_data.et[1], &fsave_data.et[2]); - fsave_data.stag = get_ftag(src, size); + fsave_data.stag = get_ftag(src, (opclass == 0) ? -1 : size); if (fp_is_dyadic(extra)) { fpp_from_exten_fmovem(®s.fp[reg], &fsave_data.fpt[0], &fsave_data.fpt[1], &fsave_data.fpt[2]); fsave_data.dtag = get_ftag(®s.fp[reg], -1); } } - } } } @@ -507,6 +546,9 @@ static uae_u32 fpsr_make_status(void) { uae_u32 exception; + if (!currprefs.fpu_exceptions) + return 0; + // get external status fpp_get_status(®s.fpsr); @@ -527,10 +569,7 @@ static uae_u32 fpsr_make_status(void) if (currprefs.cpu_model >= 68040 && currprefs.fpu_model) exception |= regs.fpsr & (FPSR_OVFL | FPSR_UNFL); - if (currprefs.fpu_exceptions) - return exception; - - return 0; + return exception; } static int fpsr_set_bsun(void) @@ -730,7 +769,7 @@ static void fp_unimp_instruction(uae_u16 opcode, uae_u16 extra, uae_u32 ea, uaec if (currprefs.cpu_model == 68060) { // fsave data for 68060 - fsave_data.v = 0; // really? + reset_fsave_data(); } else if(currprefs.cpu_model == 68040) { // fsave data for 68040 fsave_data.fpiarcu = regs.fpiar; @@ -781,7 +820,12 @@ static void fp_unimp_datatype(uae_u16 opcode, uae_u16 extra, uae_u32 ea, uaecptr if (currprefs.cpu_model == 68060) { // fsave data for 68060 - fsave_data.v = 7; // vector & 0x7 + if (packed) { + regs.fpu_exp_state = 1; // 68060 IDLE frame + } else { + fsave_data.v = 7; // vector & 0x7 + fpp_from_exten_fmovem(src, &fsave_data.eo[0], &fsave_data.eo[1], &fsave_data.eo[2]); + } } else if (currprefs.cpu_model == 68040) { // fsave data for 68040 fsave_data.cmdreg1b = extra; @@ -1056,6 +1100,18 @@ static void fpu_null (void) /* E = MAX & F # 0 -> NotANumber */ /* E = biased by 127 (single) ,1023 (double) ,16383 (extended) */ +#if 1 + +void to_pack_softfloat (fpdata *fp, uae_u32 *wrd); + +static void to_pack (fpdata *fpd, uae_u32 *wrd) +{ + to_pack_softfloat(fpd, wrd); +} + + +#else + static void to_pack (fpdata *fpd, uae_u32 *wrd) { fptype d; @@ -1111,81 +1167,7 @@ static void to_pack (fpdata *fpd, uae_u32 *wrd) fpp_from_native(d, fpd); } -#if 0 -static void from_pack (fpdata *src, uae_u32 *wrd, int kfactor) -{ - int i, j, t; - int exp; - int ndigits; - char *cp, *strp; - char str[100]; - fptype fp; - - if (fpp_is_nan (src)) { - // copy bit by bit, handle signaling nan - fpp_from_exten(src, &wrd[0], &wrd[1], &wrd[2]); - return; - } - if (fpp_is_infinity (src)) { - // extended exponent and all 0 packed fraction - fpp_from_exten(src, &wrd[0], &wrd[1], &wrd[2]); - wrd[1] = wrd[2] = 0; - return; - } - - wrd[0] = wrd[1] = wrd[2] = 0; - - uae_u32 w[3]; - - if (!currprefs.fpu_softfloat) { - fpp_from_exten_fmovem(src, &w[0], &w[1], &w[2]); - } else { - w[0] = src->fpx.high << 16; - w[1] = src->fpx.low >> 32; - w[2] = src->fpx.low; - } - - int exp = ((w[0] >> 16) & 0x7fff) - 0x3fff; - - if (kfactor <= 0) { - ndigits = exp + (-kfactor) + 1; - } else { - if (kfactor > 17) { - kfactor = 17; - fpsr_set_exception(FPSR_OPERR); - } - ndigits = kfactor; - } - - if (ndigits < 0) - ndigits = 0; - if (ndigits > 16) - ndigits = 16; - - // negative mantissa - if (w[0] & 0x80000000) - wrd[0] |= 0x80000000; - // negative exponent - if (exp < 0) - wrd[0] |= 0x40000000; - - - // store first digit of mantissa - wrd[0] |= *cp++ - '0'; - - // store rest of mantissa - for (j = 1; j < 3; j++) { - for (i = 0; i < 8; i++) { - wrd[j] <<= 4; - if (*cp >= '0' && *cp <= '9') - wrd[j] |= *cp++ - '0'; - } - } - - -} - -#else +#endif static void from_pack (fpdata *src, uae_u32 *wrd, int kfactor) { @@ -1338,11 +1320,12 @@ static void from_pack (fpdata *src, uae_u32 *wrd, int kfactor) } wrd[0] |= t << 16; } -#endif // 68040/060 does not support denormals static bool normalize_or_fault_if_no_denormal_support(uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc, fpdata *src) { + if (!currprefs.fpu_softfloat) + return false; if (fpp_is_unnormal(src) || fpp_is_denormal(src)) { if (currprefs.cpu_model >= 68040 && currprefs.fpu_model && currprefs.fpu_no_unimplemented) { fp_unimp_datatype(opcode, extra, ea, oldpc, src, NULL); @@ -1355,6 +1338,8 @@ static bool normalize_or_fault_if_no_denormal_support(uae_u16 opcode, uae_u16 ex } static bool normalize_or_fault_if_no_denormal_support_dst(uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc, fpdata *dst, fpdata *src) { + if (!currprefs.fpu_softfloat) + return false; if (fpp_is_unnormal(dst) || fpp_is_denormal(dst)) { if (currprefs.cpu_model >= 68040 && currprefs.fpu_model && currprefs.fpu_no_unimplemented) { fp_unimp_datatype(opcode, extra, ea, oldpc, src, NULL); @@ -1369,7 +1354,7 @@ static bool normalize_or_fault_if_no_denormal_support_dst(uae_u16 opcode, uae_u1 // 68040/060 does not support packed decimal format static bool fault_if_no_packed_support(uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc, fpdata *src, uae_u32 *packed) { - if (currprefs.cpu_model >= 68040 && currprefs.fpu_model) { + if (currprefs.cpu_model >= 68040 && currprefs.fpu_model && currprefs.fpu_no_unimplemented) { fp_unimp_datatype(opcode, extra, ea, oldpc, src, packed); return true; } @@ -1379,13 +1364,12 @@ static bool fault_if_no_packed_support(uae_u16 opcode, uae_u16 extra, uaecptr ea // 68040 does not support move to integer format static bool fault_if_68040_integer_nonmaskable(uae_u16 opcode, uae_u16 extra, uaecptr ea, uaecptr oldpc, fpdata *src) { - if (currprefs.cpu_model == 68040 && currprefs.fpu_model) { + if (currprefs.cpu_model == 68040 && currprefs.fpu_model && currprefs.fpu_exceptions) { fpsr_make_status(); if (regs.fpsr & (FPSR_SNAN | FPSR_OPERR)) { fpsr_check_arithmetic_exception(FPSR_SNAN | FPSR_OPERR, src, opcode, extra, ea); fp_exception_pending(false); // post - if (currprefs.fpu_exceptions) - return true; + return true; } } return false; @@ -1776,7 +1760,7 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o return 1; } -STATIC_INLINE int get_fp_ad (uae_u32 opcode, uae_u32 * ad) +static int get_fp_ad (uae_u32 opcode, uae_u32 * ad) { int mode; int reg; diff --git a/fpp_native.cpp b/fpp_native.cpp index 19cdcb02..32b4f2b4 100644 --- a/fpp_native.cpp +++ b/fpp_native.cpp @@ -17,11 +17,8 @@ #include "sysconfig.h" #include "sysdeps.h" -#ifdef _MSC_VER -#pragma fenv_access(on) -#endif - -#define USE_HOST_ROUNDING +#define USE_HOST_ROUNDING 1 +#define SOFTFLOAT_CONVERSIONS 1 #include "options.h" #include "memory.h" @@ -55,7 +52,7 @@ static uae_u32 xhex_ln_2[] ={0xd1cf79ac, 0xb17217f7, 0x3ffe}; static uae_u32 xhex_inf[] ={0x00000000, 0x00000000, 0x7fff}; static uae_u32 xhex_nan[] ={0xffffffff, 0xffffffff, 0x7fff}; static uae_u32 xhex_snan[] ={0xffffffff, 0xbfffffff, 0x7fff}; -#if USE_LONG_DOUBLE +#ifdef USE_LONG_DOUBLE static long double *fp_pi = (long double *)xhex_pi; static long double *fp_exp_1 = (long double *)xhex_exp_1; static long double *fp_l2_e = (long double *)xhex_l2_e; @@ -175,7 +172,7 @@ static void set_fpucw_x87(uae_u32 m68k_cw) // RN, RZ, RM, RP static const unsigned int fp87_round[4] = { _RC_NEAR, _RC_CHOP, _RC_DOWN, _RC_UP }; // Extend X, Single S, Double D, Undefined - static const unsigned int fp87_prec[4] = { _PC_64, _PC_24, _PC_53, 0 }; + static const unsigned int fp87_prec[4] = { _PC_53, _PC_24, _PC_53, 0 }; int round = (m68k_cw >> 4) & 3; #ifdef WIN64 // x64 only sets SSE2, must also call x87_fldcw_code() to set FPU rounding mode. @@ -188,10 +185,14 @@ static void set_fpucw_x87(uae_u32 m68k_cw) #endif #endif static const uae_u16 x87_cw_tab[] = { +#ifdef USE_LONG_DOUBLE 0x137f, 0x1f7f, 0x177f, 0x1b7f, /* Extended */ +#else + 0x127f, 0x1e7f, 0x167f, 0x1a7f, /* Double */ +#endif 0x107f, 0x1c7f, 0x147f, 0x187f, /* Single */ 0x127f, 0x1e7f, 0x167f, 0x1a7f, /* Double */ - 0x137f, 0x1f7f, 0x177f, 0x1b7f /* undefined */ + 0x127f, 0x1e7f, 0x167f, 0x1a7f, /* undefined (Double) */ }; x87_cw = x87_cw_tab[(m68k_cw >> 4) & 0xf]; #if defined(X86_MSVC_ASSEMBLY) && 0 @@ -219,11 +220,7 @@ static void fp_set_mode(uae_u32 mode_control) return; switch(mode_control & FPCR_ROUNDING_PRECISION) { case FPCR_PRECISION_EXTENDED: // X -#ifdef USE_LONG_DOUBLE fpu_prec = 80; -#else - fpu_prec = 64; -#endif break; case FPCR_PRECISION_SINGLE: // S fpu_prec = 32; @@ -233,7 +230,7 @@ static void fp_set_mode(uae_u32 mode_control) fpu_prec = 64; break; } -#ifdef USE_HOST_ROUNDING +#if USE_HOST_ROUNDING if ((mode_control & FPCR_ROUNDING_MODE) != (fpu_mode_control & FPCR_ROUNDING_MODE)) { switch(mode_control & FPCR_ROUNDING_MODE) { case FPCR_ROUND_NEAR: // to neareset @@ -258,6 +255,8 @@ static void fp_set_mode(uae_u32 mode_control) static void fp_get_status(uae_u32 *status) { + // These can't be properly emulated using host FPU. +#if 0 int exp_flags = fetestexcept(FE_ALL_EXCEPT); if (exp_flags) { if (exp_flags & FE_INEXACT) @@ -272,11 +271,14 @@ static void fp_get_status(uae_u32 *status) *status |= FPSR_OPERR; } /* FIXME: how to detect SNAN? */ +#endif } static void fp_clear_status(void) { +#if 0 feclearexcept (FE_ALL_EXCEPT); +#endif } /* Functions for detecting float type */ @@ -421,7 +423,7 @@ static void fp_from_exten(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wr #else // if !USE_LONG_DOUBLE static void fp_to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) { -#if 1 +#if SOFTFLOAT_CONVERSIONS floatx80 fx80; fx80.high = wrd1 >> 16; fx80.low = (((uae_u64)wrd2) << 32) | wrd3; @@ -441,7 +443,7 @@ static void fp_to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) } static void fp_from_exten(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3) { -#if 1 +#if SOFTFLOAT_CONVERSIONS uae_u32 w1, w2; fp_from_double(fpd, &w1, &w2); floatx80 f = float64_to_floatx80(((uae_u64)w1 << 32) | w2, &fs); @@ -479,6 +481,20 @@ static void fp_from_exten(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wr } #endif // !USE_LONG_DOUBLE +#if USE_HOST_ROUNDING == 0 +#ifdef USE_LONG_DOUBLE +#define fp_round_to_minus_infinity(x) floorl(x) +#define fp_round_to_plus_infinity(x) ceill(x) +#define fp_round_to_zero(x) ((x) >= 0.0 ? floorl(x) : ceill(x)) +#define fp_round_to_nearest(x) roundl(x) +#else // if !USE_LONG_DOUBLE +#define fp_round_to_minus_infinity(x) floor(x) +#define fp_round_to_plus_infinity(x) ceil(x) +#define fp_round_to_zero(x) ((x) >= 0.0 ? floor(x) : ceil(x)) +#define fp_round_to_nearest(x) round(x) +#endif // !USE_LONG_DOUBLE +#endif // USE_HOST_ROUNDING + static uae_s64 fp_to_int(fpdata *src, int size) { static const fptype fxsizes[6] = @@ -517,14 +533,10 @@ static uae_s64 fp_to_int(fpdata *src, int size) fp = fxsizes[size * 2 + 1]; fpsr_set_exception(FPSR_OPERR); } -#ifdef USE_HOST_ROUNDING -#ifdef USE_LONG_DOUBLE +#if USE_HOST_ROUNDING return lrintl(fp); #else - return lrint(fp); -#endif -#else - tointtype result = (int)fp; + uae_s64 result = (int)fp; switch (regs.fpcr & 0x30) { case FPCR_ROUND_ZERO: @@ -556,13 +568,8 @@ static void fp_round32(fpdata *fpd) { int expon; float mant; -#ifdef USE_LONG_DOUBLE mant = (float)(frexpl(fpd->fp, &expon) * 2.0); fpd->fp = ldexpl((fptype)mant, expon - 1); -#else - mant = (float)(frexp(fpd->fp, &expon) * 2.0); - fpd->fp = ldexp((fptype)mant, expon - 1); -#endif } // round to double with extended precision exponent @@ -570,13 +577,8 @@ static void fp_round64(fpdata *fpd) { int expon; double mant; -#ifdef USE_LONG_DOUBLE mant = (double)(frexpl(fpd->fp, &expon) * 2.0); fpd->fp = ldexpl((fptype)mant, expon - 1); -#else - mant = (double)(frexp(fpd->fp, &expon) * 2.0); - fpd->fp = ldexp((fptype)mant, expon - 1); -#endif } // round to float @@ -615,7 +617,7 @@ static const TCHAR *fp_print(fpdata *fpd, int mode) } else { if(n) fpd->fp *= -1.0; -#if USE_LONG_DOUBLE +#ifdef USE_LONG_DOUBLE _stprintf(fsout, _T("#%Le"), fpd->fp); #else _stprintf(fsout, _T("#%e"), fpd->fp); @@ -627,6 +629,23 @@ static const TCHAR *fp_print(fpdata *fpd, int mode) return fsout; } +static void fp_round_prec(fpdata *fpd, int prec) +{ + if (prec == 64) { + fp_round_double(fpd); + } else if (prec == 32) { + fp_round_single(fpd); + } +} + +static void fp_round(fpdata *fpd) +{ + if (!currprefs.fpu_strict) + return; + fp_round_prec(fpd, fpu_prec); +} + + static void fp_set_prec(int prec) { #if 0 @@ -659,11 +678,7 @@ static void fp_reset_prec(fpdata *fpd) int prec = temp_prec; if (temp_prec == 0) prec = fpu_prec; - if (prec == 64) { - fp_round_double(fpd); - } else if (prec == 32) { - fp_round_single(fpd); - } + fp_round_prec(fpd, prec); #endif } @@ -676,69 +691,10 @@ static void fp_move(fpdata *a, fpdata *b, int prec) fp_reset_prec(a); } -#ifdef USE_LONG_DOUBLE - -STATIC_INLINE fptype fp_int(fpdata *a, fpdata *b) -{ -#ifdef USE_HOST_ROUNDING - a->fp = rintl(b->dst); -#else - switch (regs.fpcr & FPCR_ROUNDING_MODE) - { - case FPCR_ROUND_NEAR: - return fp_round_to_nearest(a); - case FPCR_ROUND_ZERO: - return fp_round_to_zero(a); - case FPCR_ROUND_MINF: - return fp_round_to_minus_infinity(a); - case FPCR_ROUND_PINF: - return fp_round_to_plus_infinity(a); - default: /* never reached */ - return a; - } -#endif -} -STATIC_INLINE fptype fp_mod(fptype a, fptype b, uae_u64 *q, uae_s8 *s) -{ - fptype quot; -#ifdef USE_HOST_ROUNDING - quot = truncl(a / b); -#else - quot = fp_round_to_zero(a / b); -#endif - if (quot < 0.0) { - *s = 1; - quot = -quot; - } else { - *s = 0; - } - *q = (uae_u64)quot; - return fmodl(a, b); -} -STATIC_INLINE fptype fp_rem(fptype a, fptype b, uae_u64 *q, uae_s8 *s) -{ - fptype quot; -#ifdef USE_HOST_ROUNDING - quot = roundl(a / b); -#else - quot = fp_round_to_nearest(a / b); -#endif - if (quot < 0.0) { - *s = 1; - quot = -quot; - } else { - *s = 0; - } - *q = (uae_u64)quot; - return remainderl(a, b); -} - -#else // if !USE_LONG_DOUBLE - static void fp_int(fpdata *a, fpdata *b) { fptype bb = b->fp; -#ifdef USE_HOST_ROUNDING +#if USE_HOST_ROUNDING a->fp = rintl(bb); #else switch (regs.fpcr & FPCR_ROUNDING_MODE) @@ -761,12 +717,14 @@ static void fp_getexp(fpdata *a, fpdata *b) { int expon; frexpl(b->fp, &expon); - a->fp = (double) (expon - 1); + a->fp = (fptype) (expon - 1); + fp_round(a); } static void fp_getman(fpdata *a, fpdata *b) { int expon; a->fp = frexpl(b->fp, &expon) * 2.0; + fp_round(a); } static void fp_div(fpdata *a, fpdata *b, int prec) { @@ -777,7 +735,7 @@ static void fp_div(fpdata *a, fpdata *b, int prec) static void fp_mod(fpdata *a, fpdata *b, uae_u64 *q, uae_u8 *s) { fptype quot; -#ifdef USE_HOST_ROUNDING +#if USE_HOST_ROUNDING quot = truncl(a->fp / b->fp); #else quot = fp_round_to_zero(a->fp / b->fp); @@ -790,11 +748,13 @@ static void fp_mod(fpdata *a, fpdata *b, uae_u64 *q, uae_u8 *s) } *q = (uae_u64)quot; a->fp = fmodl(a->fp, b->fp); + fp_round(a); } + static void fp_rem(fpdata *a, fpdata *b, uae_u64 *q, uae_u8 *s) { fptype quot; -#ifdef USE_HOST_ROUNDING +#if USE_HOST_ROUNDING quot = roundl(a->fp / b->fp); #else quot = fp_round_to_nearest(a->fp / b->fp); @@ -807,26 +767,27 @@ static void fp_rem(fpdata *a, fpdata *b, uae_u64 *q, uae_u8 *s) } *q = (uae_u64)quot; a->fp = remainderl(a->fp, b->fp); + fp_round(a); } static void fp_scale(fpdata *a, fpdata *b) { a->fp = ldexpl(a->fp, (int)b->fp); + fp_round(a); } -#endif // !USE_LONG_DOUBLE - static void fp_sinh(fpdata *a, fpdata *b) { a->fp = sinhl(b->fp); } static void fp_intrz(fpdata *a, fpdata *b) { -#ifdef USE_HOST_ROUNDING +#if USE_HOST_ROUNDING a->fp = truncl(b->fp); #else a->fp = fp_round_to_zero (b->fp); #endif + fp_round(a); } static void fp_sqrt(fpdata *a, fpdata *b, int prec) { @@ -837,58 +798,72 @@ static void fp_sqrt(fpdata *a, fpdata *b, int prec) static void fp_lognp1(fpdata *a, fpdata *b) { a->fp = log1pl(b->fp); + fp_round(a); } static void fp_etoxm1(fpdata *a, fpdata *b) { a->fp = expm1l(b->fp); + fp_round(a); } static void fp_tanh(fpdata *a, fpdata *b) { a->fp = tanhl(b->fp); + fp_round(a); } static void fp_atan(fpdata *a, fpdata *b) { a->fp = atanl(b->fp); + fp_round(a); } static void fp_atanh(fpdata *a, fpdata *b) { a->fp = atanhl(b->fp); + fp_round(a); } static void fp_sin(fpdata *a, fpdata *b) { a->fp = sinl(b->fp); + fp_round(a); } static void fp_asin(fpdata *a, fpdata *b) { a->fp = asinl(b->fp); + fp_round(a); } static void fp_tan(fpdata *a, fpdata *b) { a->fp = tanl(b->fp); + fp_round(a); } static void fp_etox(fpdata *a, fpdata *b) { a->fp = expl(b->fp); + fp_round(a); } static void fp_twotox(fpdata *a, fpdata *b) { a->fp = powl(2.0, b->fp); + fp_round(a); } static void fp_tentox(fpdata *a, fpdata *b) { a->fp = powl(10.0, b->fp); + fp_round(a); } static void fp_logn(fpdata *a, fpdata *b) { a->fp = logl(b->fp); + fp_round(a); } static void fp_log10(fpdata *a, fpdata *b) { a->fp = log10l(b->fp); + fp_round(a); } static void fp_log2(fpdata *a, fpdata *b) { a->fp = log2l(b->fp); + fp_round(a); } static void fp_abs(fpdata *a, fpdata *b, int prec) { @@ -899,6 +874,7 @@ static void fp_abs(fpdata *a, fpdata *b, int prec) static void fp_cosh(fpdata *a, fpdata *b) { a->fp = coshl(b->fp); + fp_round(a); } static void fp_neg(fpdata *a, fpdata *b, int prec) { @@ -909,10 +885,12 @@ static void fp_neg(fpdata *a, fpdata *b, int prec) static void fp_acos(fpdata *a, fpdata *b) { a->fp = acosl(b->fp); + fp_round(a); } static void fp_cos(fpdata *a, fpdata *b) { a->fp = cosl(b->fp); + fp_round(a); } static void fp_sub(fpdata *a, fpdata *b, int prec) { @@ -934,14 +912,24 @@ static void fp_mul(fpdata *a, fpdata *b, int prec) } static void fp_sglmul(fpdata *a, fpdata *b) { - a->fp = a->fp * b->fp; - fpp_round32(a); + fptype z; + float mant; + int expon; + /* FIXME: truncate mantissa of a and b to single precision */ + z = a->fp * b->fp; + + mant = (float)(frexpl(z, &expon) * 2.0); + a->fp = ldexpl((fptype)mant, expon - 1); } static void fp_sgldiv(fpdata *a, fpdata *b) { - // not exact - a->fp = a->fp / b->fp; - fpp_round32(a); + fptype z; + float mant; + int expon; + z = a->fp / b->fp; + + mant = (float)(frexpl(z, &expon) * 2.0); + a->fp = ldexpl((fptype)mant, expon - 1); } static void fp_normalize(fpdata *a) @@ -950,45 +938,50 @@ static void fp_normalize(fpdata *a) static void fp_cmp(fpdata *a, fpdata *b) { - bool a_neg = fpp_is_neg(a); - bool b_neg = fpp_is_neg(b); - bool a_inf = fpp_is_infinity(a); - bool b_inf = fpp_is_infinity(b); - bool a_zero = fpp_is_zero(a); - bool b_zero = fpp_is_zero(b); - bool a_nan = fpp_is_nan(a); - bool b_nan = fpp_is_nan(b); fptype v = 1.0; - - if (a_nan || b_nan) { - // FCMP never returns N + NaN - v = *fp_nan; - } else if (a_zero && b_zero) { - if ((a_neg && b_neg) || (a_neg && !b_neg)) - v = -0.0; - else - v = 0.0; - } else if (a_zero && b_inf) { - if (!b_neg) - v = -1.0; - else - v = 1.0; - } else if (a_inf && b_zero) { - if (!a_neg) - v = -1.0; - else - v = 1.0; - } else if (a_inf && b_inf) { - if (a_neg == b_neg) - v = 0.0; - if ((a_neg && b_neg) || (a_neg && !b_neg)) - v = -v; - } else if (a_inf) { - if (a_neg) - v = -1.0; - } else if (b_inf) { - if (!b_neg) - v = -1.0; + if (currprefs.fpu_strict) { + bool a_neg = fpp_is_neg(a); + bool b_neg = fpp_is_neg(b); + bool a_inf = fpp_is_infinity(a); + bool b_inf = fpp_is_infinity(b); + bool a_zero = fpp_is_zero(a); + bool b_zero = fpp_is_zero(b); + bool a_nan = fpp_is_nan(a); + bool b_nan = fpp_is_nan(b); + + if (a_nan || b_nan) { + // FCMP never returns N + NaN + v = *fp_nan; + } else if (a_zero && b_zero) { + if ((a_neg && b_neg) || (a_neg && !b_neg)) + v = -0.0; + else + v = 0.0; + } else if (a_zero && b_inf) { + if (!b_neg) + v = -1.0; + else + v = 1.0; + } else if (a_inf && b_zero) { + if (!a_neg) + v = -1.0; + else + v = 1.0; + } else if (a_inf && b_inf) { + if (a_neg == b_neg) + v = 0.0; + if ((a_neg && b_neg) || (a_neg && !b_neg)) + v = -v; + } else if (a_inf) { + if (a_neg) + v = -1.0; + } else if (b_inf) { + if (!b_neg) + v = -1.0; + } else { + v = a->fp - b->fp; + fp_clear_status(); + } } else { v = a->fp - b->fp; fp_clear_status(); @@ -1013,12 +1006,29 @@ static void fp_get_internal_underflow(fpdata *fpd) fpd->fp = 0; } -static void fp_get_exceptional_operand_grs(uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3, uae_u32 *grs) +static void fp_get_internal_round_all(fpdata *fpd) { - *wrd1 = 0; - *wrd2 = 0; - *wrd3 = 0; - *grs = 0; + fpd->fp = 0; +} + +static void fp_get_internal_round(fpdata *fpd) +{ + fpd->fp = 0; +} + +static void fp_get_internal_round_exten(fpdata *fpd) +{ + fpd->fp = 0; +} + +static void fp_get_internal(fpdata *fpd) +{ + fpd->fp = 0; +} + +static uae_u32 fp_get_internal_grs(void) +{ + return 0; } void fp_init_native(void) @@ -1063,7 +1073,11 @@ void fp_init_native(void) fpp_normalize = fp_normalize; fpp_get_internal_overflow = fp_get_internal_overflow; fpp_get_internal_underflow = fp_get_internal_underflow; - fpp_get_exceptional_operand_grs = fp_get_exceptional_operand_grs; + fpp_get_internal_round_all = fp_get_internal_round_all; + fpp_get_internal_round = fp_get_internal_round; + fpp_get_internal_round_exten = fp_get_internal_round_exten; + fpp_get_internal = fp_get_internal; + fpp_get_internal_grs = fp_get_internal_grs; fpp_int = fp_int; fpp_sinh = fp_sinh; diff --git a/fpp_softfloat.cpp b/fpp_softfloat.cpp index 862c35e9..a51c65bf 100644 --- a/fpp_softfloat.cpp +++ b/fpp_softfloat.cpp @@ -95,13 +95,12 @@ STATIC_INLINE void fp_clear_status(void) } -static const TCHAR *fp_print(fpdata *fpd, int mode) +static const TCHAR *fp_printx80(floatx80 *fx, int mode) { static TCHAR fsout[32]; flag n, u, d; fptype result = 0.0; int i; - floatx80 *fx = &fpd->fpx; if (mode < 0) { _stprintf(fsout, _T("%04X-%08X-%08X"), fx->high, (uae_u32)(fx->low >> 32), (uae_u32)fx->low); @@ -144,6 +143,11 @@ static const TCHAR *fp_print(fpdata *fpd, int mode) return fsout; } +static const TCHAR *fp_print(fpdata *fpd, int mode) +{ + return fp_printx80(&fpd->fpx, mode); +} + /* Functions for detecting float type */ static bool fp_is_snan(fpdata *fpd) { @@ -341,64 +345,37 @@ static uae_s64 to_int(fpdata *src, int size) } static void from_int(fpdata *fpd, uae_s32 src) { - fpd->fpx = int32_to_floatx80(src, &fs); + fpd->fpx = int32_to_floatx80(src); } /* Functions for returning exception state data */ static void fp_get_internal_overflow(fpdata *fpd) - { - if (floatx80_internal_exp > (0x7fff + 0x6000)) { // catastrophic - floatx80_internal_exp = 0; - } else { - floatx80_internal_exp -= 0x6000; - } - - fpd->fpx.high = ((uint16_t)floatx80_internal_exp) & 0x7fff; - fpd->fpx.high |= ((uint16_t)floatx80_internal_sign) << 15; - fpd->fpx.low = floatx80_internal_sig; - } - +{ + fpd->fpx = getFloatInternalOverflow(); +} static void fp_get_internal_underflow(fpdata *fpd) { - if (floatx80_internal_exp < (0x0000 - 0x6000)) { // catastrophic - floatx80_internal_exp = 0; - } else { - floatx80_internal_exp += 0x6000; - } - - fpd->fpx.high = ((uint16_t)floatx80_internal_exp) & 0x7fff; - fpd->fpx.high |= ((uint16_t)floatx80_internal_sign) << 15; - fpd->fpx.low = floatx80_internal_sig; + fpd->fpx = getFloatInternalUnderflow(); } - -static void fp_get_exceptional_operand_grs(uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3, uae_u32 *grs) +static void fp_get_internal_round_all(fpdata *fpd) { - *wrd1 = (((uae_u32)floatx80_internal_exp) & 0x7fff) << 16; - *wrd1 |= floatx80_internal_sign ? 0x80000000 : 0x000000000; - *wrd2 = floatx80_internal_sig0 >> 32; - *wrd3 = (uae_u32) floatx80_internal_sig0; - *grs = floatx80_internal_sig1 >> 61; - *grs |= (floatx80_internal_sig1 & 0x3fffffffffffffffULL) ? 1 : 0; + fpd->fpx = getFloatInternalRoundedAll(); } - -static void fp_get_internal_unmodified(uae_u32 *grs, fpdata *fpd) +static void fp_get_internal_round(fpdata *fpd) { - uint64_t roundbits; - - fpd->fpx.high = ((uint16_t)floatx80_internal_exp) & 0x7fff; - fpd->fpx.high |= ((uint16_t)floatx80_internal_sign) << 15; - fpd->fpx.low = floatx80_internal_sig0; - - shift64RightJamming(floatx80_internal_sig1, 61, &roundbits); - *grs = (uae_u32)roundbits; + fpd->fpx = getFloatInternalRoundedSome(); +} +static void fp_get_internal_round_exten(fpdata *fpd) +{ + fpd->fpx = getFloatInternalFloatx80(); } - static void fp_get_internal(fpdata *fpd) { - - fpd->fpx.high = ((int16_t)floatx80_internal_exp) & 0x7fff; - fpd->fpx.high |= ((int16_t)floatx80_internal_sign) << 15; - fpd->fpx.low = floatx80_internal_sig; + fpd->fpx = getFloatInternalUnrounded(); +} +static uae_u32 fp_get_internal_grs(void) +{ + return (uae_u32)getFloatInternalGRS(); } /* Functions for rounding */ @@ -435,6 +412,21 @@ static void fp_round_double(fpdata *fpd) fpd->fpx = floatx80_round_to_float64(fpd->fpx, &fs); } +// round to selected precision +static void fp_round(fpdata *a) +{ + switch(fs.floatx80_rounding_precision) { + case 32: + a->fpx = floatx80_round_to_float32(a->fpx, &fs); + break; + case 64: + a->fpx = floatx80_round_to_float64(a->fpx, &fs); + break; + default: + break; + } +} + /* Arithmetic functions */ static void fp_int(fpdata *a, fpdata *b) @@ -454,7 +446,7 @@ static void fp_lognp1(fpdata *a, fpdata *b) if (e) return; to_native(&fpa, b); - fpa = log(a->fp + 1.0); + fpa = logl(a->fp + 1.0); from_native(fpa, a); } static void fp_sin(fpdata *a, fpdata *b) @@ -465,7 +457,7 @@ static void fp_sin(fpdata *a, fpdata *b) if (e) return; to_native(&fpa, b); - fpa = sin(fpa); + fpa = sinl(fpa); from_native(fpa, a); } static void fp_tan(fpdata *a, fpdata *b) @@ -476,7 +468,7 @@ static void fp_tan(fpdata *a, fpdata *b) if (e) return; to_native(&fpa, b); - fpa = tan(fpa); + fpa = tanl(fpa); from_native(fpa, a); } static void fp_logn(fpdata *a, fpdata *b) @@ -487,7 +479,7 @@ static void fp_logn(fpdata *a, fpdata *b) if (e) return; to_native(&fpa, b); - fpa = log(fpa); + fpa = logl(fpa); from_native(fpa, a); } static void fp_log10(fpdata *a, fpdata *b) @@ -498,7 +490,7 @@ static void fp_log10(fpdata *a, fpdata *b) if (e) return; to_native(&fpa, b); - fpa = log10(fpa); + fpa = log10l(fpa); from_native(fpa, a); } static void fp_log2(fpdata *a, fpdata *b) @@ -509,7 +501,7 @@ static void fp_log2(fpdata *a, fpdata *b) if (e) return; to_native(&fpa, b); - fpa = log2(fpa); + fpa = log2l(fpa); from_native(fpa, a); } @@ -521,7 +513,7 @@ static void fp_cos(fpdata *a, fpdata *b) if (e) return; to_native(&fpa, b); - fpa = cos(fpa); + fpa = cosl(fpa); from_native(fpa, a); } static void fp_getexp(fpdata *a, fpdata *b) @@ -634,6 +626,7 @@ static void fp_sinh(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = sinhl(fpa); from_native(fpa, a); + fp_round(a); } static void fp_etoxm1(fpdata *a, fpdata *b) { @@ -645,6 +638,7 @@ static void fp_etoxm1(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = expl(fpa) - 1.0; from_native(fpa, a); + fp_round(a); } static void fp_tanh(fpdata *a, fpdata *b) { @@ -656,6 +650,7 @@ static void fp_tanh(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = tanhl(fpa); from_native(fpa, a); + fp_round(a); } static void fp_atan(fpdata *a, fpdata *b) { @@ -667,6 +662,7 @@ static void fp_atan(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = atanl(fpa); from_native(fpa, a); + fp_round(a); } static void fp_asin(fpdata *a, fpdata *b) { @@ -678,6 +674,7 @@ static void fp_asin(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = asinl(fpa); from_native(fpa, a); + fp_round(a); } static void fp_atanh(fpdata *a, fpdata *b) { @@ -689,6 +686,7 @@ static void fp_atanh(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = atanhl(fpa); from_native(fpa, a); + fp_round(a); } static void fp_etox(fpdata *a, fpdata *b) { @@ -700,6 +698,7 @@ static void fp_etox(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = expl(fpa); from_native(fpa, a); + fp_round(a); } static void fp_twotox(fpdata *a, fpdata *b) { @@ -711,6 +710,7 @@ static void fp_twotox(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = powl(2.0, fpa); from_native(fpa, a); + fp_round(a); } static void fp_tentox(fpdata *a, fpdata *b) { @@ -722,6 +722,7 @@ static void fp_tentox(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = powl(10.0, fpa); from_native(fpa, a); + fp_round(a); } static void fp_cosh(fpdata *a, fpdata *b) { @@ -733,6 +734,7 @@ static void fp_cosh(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = coshl(fpa); from_native(fpa, a); + fp_round(a); } static void fp_acos(fpdata *a, fpdata *b) { @@ -744,6 +746,7 @@ static void fp_acos(fpdata *a, fpdata *b) to_native(&fpa, b); fpa = acosl(fpa); from_native(fpa, a); + fp_round(a); } static void fp_normalize(fpdata *a) @@ -751,11 +754,165 @@ static void fp_normalize(fpdata *a) a->fpx = floatx80_normalize(a->fpx); } +static float_status fsp; + +void to_pack_softfloat (fpdata *fp, uae_u32 *wrd) +{ + uae_s32 exp = 0; + uae_s64 mant = 0; + + if (((wrd[0] >> 16) & 0x7fff) == 0x7fff) { + // infinity has extended exponent and all 0 packed fraction + // nans are copies bit by bit + fpp_to_exten(fp, wrd[0], wrd[1], wrd[2]); + return; + } + if (!(wrd[0] & 0xf) && !wrd[1] && !wrd[2]) { + // exponent is not cared about, if mantissa is zero + wrd[0] &= 0x80000000; + fpp_to_exten(fp, wrd[0], wrd[1], wrd[2]); + return; + } + + + int i; + int zerocount; + uae_s64 multiplier; + + uae_u32 pack_exp = (wrd[0] >> 16) & 0xFFF; // packed exponent + uae_u32 pack_int = wrd[0] & 0xF; // packed integer part + uae_u64 pack_frac = ((uae_u64)wrd[1] << 32) | wrd[2]; // packed fraction + uae_u32 pack_se = (wrd[0] >> 30) & 1; // sign of packed exponent + uae_u32 pack_sm = (wrd[0] >> 31) & 1; // sign of packed significand + + + for (i = 0; i < 3; i++) { + exp *= 10; + exp += (pack_exp >> (8 - i * 4)) & 0xF; + } + + + if (pack_se) { + exp = -exp; + } + + + exp -= 16; + + + if (exp < 0) { + exp = -exp; + pack_se = 1; + } + + + mant = pack_int; + + + for (i = 0; i < 16; i++) { + mant *= 10; + mant += (pack_frac >> (60 - i * 4)) & 0xF; + } + + + if (pack_sm) { + mant = -mant; + } + + + zerocount = 0; + multiplier = 10; + if (exp >= 27) { + if (pack_se) { + for (i = 0; i < 16; i++) { + if ((pack_frac >> (i * 4)) & 0xF) { + break; + } + zerocount++; + } + + + exp -= zerocount; + + while (zerocount) { + if (zerocount & 1) { + mant /= multiplier; + } + multiplier *= multiplier; + zerocount >>= 1; + } + } else { + if (pack_int == 0) { + zerocount++; + for (i = 0; i < 16; i++) { + if ((pack_frac >> (60 - i * 4)) & 0xF) { + break; + } + zerocount++; + } + } + + + exp -= zerocount; + + while (zerocount) { + if (zerocount & 1) { + mant *= multiplier; + } + multiplier *= multiplier; + zerocount >>= 1; + } + } + } + + + /* TODO: calculate rounding mode */ + floatx80 z = int64_to_floatx80(mant); + floatx80 m = int32_to_floatx80(10); + floatx80 a = int32_to_floatx80(1); + + + while (exp) { + if (exp & 1) { + a = floatx80_mul(a, m, &fsp); + } + m = floatx80_mul(m, m, &fsp); + exp >>= 1; + } + + + if (pack_se) { + z = floatx80_div(z, a, &fsp); + } else { + z = floatx80_mul(z, a, &fsp); + } + + + write_log(_T("z = %s\n"), fp_printx80(&z, 0)); + write_log(_T("m = %s\n"), fp_printx80(&m, 0)); + write_log(_T("a = %s\n"), fp_printx80(&a, 0)); + + + write_log(_T("zerocount = %i\n"), zerocount); + write_log(_T("multiplier = %llu\n"), multiplier); + + fp->fpx = z; + if (!currprefs.fpu_softfloat) { + to_native(&fp->fp, fp); + } + + /* TODO: set inex1 and restore rounding mode */ + // if mul/div caused inex2 --> set inex1 + +} + void fp_init_softfloat(void) { float_status fsx = { 0 }; set_floatx80_rounding_precision(80, &fsx); set_float_rounding_mode(float_round_to_zero, &fsx); + set_floatx80_rounding_precision(80, &fsp); + set_float_rounding_mode(float_round_to_zero, &fsp); fpp_print = fp_print; fpp_is_snan = fp_is_snan; @@ -794,7 +951,11 @@ void fp_init_softfloat(void) fpp_normalize = fp_normalize; fpp_get_internal_overflow = fp_get_internal_overflow; fpp_get_internal_underflow = fp_get_internal_underflow; - fpp_get_exceptional_operand_grs = fp_get_exceptional_operand_grs; + fpp_get_internal_round_all = fp_get_internal_round_all; + fpp_get_internal_round = fp_get_internal_round; + fpp_get_internal_round_exten = fp_get_internal_round_exten; + fpp_get_internal = fp_get_internal; + fpp_get_internal_grs = fp_get_internal_grs; fpp_int = fp_int; fpp_sinh = fp_sinh; diff --git a/gfxboard.cpp b/gfxboard.cpp index 8063e05c..60ddf714 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -2712,6 +2712,7 @@ uae_u32 gfxboard_get_romtype(struct rtgboardconfig *rbc) static void gfxboard_init (struct autoconfig_info *aci, struct rtggfxboard *gb) { struct uae_prefs *p = aci->prefs; + gb->rtg_index = aci->devnum; if (!gb->automemory) gb->automemory = xmalloc (uae_u8, GFXBOARD_AUTOCONFIG_SIZE); memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE); diff --git a/include/fpp.h b/include/fpp.h index 81d62e43..6b8a9f4e 100644 --- a/include/fpp.h +++ b/include/fpp.h @@ -46,6 +46,7 @@ typedef void (*FPP_PACK)(uae_u32*, uae_u32*, uae_u32*); typedef void (*FPP_PACKG)(uae_u32*, uae_u32*, uae_u32*, uae_u32*); typedef const TCHAR* (*FPP_PRINT)(fpdata*,int); +typedef uae_u32 (*FPP_GET32)(void); extern FPP_PRINT fpp_print; @@ -85,7 +86,11 @@ extern FPP_A fpp_round64; extern FPP_A fpp_normalize; extern FPP_A fpp_get_internal_overflow; extern FPP_A fpp_get_internal_underflow; -extern FPP_PACKG fpp_get_exceptional_operand_grs; +extern FPP_A fpp_get_internal_round_all; +extern FPP_A fpp_get_internal_round; +extern FPP_A fpp_get_internal_round_exten; +extern FPP_A fpp_get_internal; +extern FPP_GET32 fpp_get_internal_grs; extern FPP_AB fpp_int; extern FPP_AB fpp_sinh; diff --git a/include/inputdevice.h b/include/inputdevice.h index 52efc323..26382c08 100644 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -226,6 +226,7 @@ extern uae_u8 handle_joystick_buttons (uae_u8, uae_u8); extern int magicmouse_alive (void); extern int is_tablet (void); +extern int is_touch_lightpen (void); extern int inputdevice_is_tablet (void); extern int input_mousehack_status(TrapContext *ctx, int mode, uaecptr diminfo, uaecptr dispinfo, uaecptr vp, uae_u32 moffset); extern void input_mousehack_mouseoffset (uaecptr pointerprefs); @@ -249,6 +250,7 @@ extern void inputdevice_devicechange (struct uae_prefs *prefs); #define INTERNALEVENT_CPURESET 0 #define INTERNALEVENT_KBRESET 1 +#define INTERNALEVENT_TOUCHLIGHTPEN 2 extern void send_internalevent (int eventid); @@ -312,9 +314,11 @@ extern void inputdevice_handle_inputcode (void); extern void inputdevice_tablet (int x, int y, int z, int pressure, uae_u32 buttonbits, int inproximity, - int ax, int ay, int az); + int ax, int ay, int az, int devid); extern void inputdevice_tablet_info (int maxx, int maxy, int maxz, int maxax, int maxay, int maxaz, int xres, int yres); extern void inputdevice_tablet_strobe (void); +extern void tablet_lightpen(int x, int y, int maxx, int maxy, int touch, int buttonmask, bool touchmode, int devid); + extern uae_u64 input_getqualifiers (void); diff --git a/slirp/debug.h b/slirp/debug.h index e8dc3ea0..9513c170 100644 --- a/slirp/debug.h +++ b/slirp/debug.h @@ -5,6 +5,8 @@ * terms and conditions of the copyright. */ +#define SLIRP_DEBUG 1 + #define PRN_STDERR 1 #define PRN_SPRINTF 2 @@ -18,14 +20,14 @@ extern int slirp_debug; #define DBG_ERROR 0x4 #define DEBUG_DEFAULT DBG_CALL|DBG_MISC|DBG_ERROR -#ifdef DEBUG +#if SLIRP_DEBUG + #define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { write_log(x); } #define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { write_log(" "); write_log(x, y); write_log("\n"); } #define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { write_log x ;} #define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { write_log x ;} #define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {write_log x; } - #else #define DEBUG_CALL(x) @@ -36,15 +38,15 @@ extern int slirp_debug; #endif -void debug_init _P((char *, int)); -//void ttystats _P((struct ttys *)); -void allttystats _P((void)); -void ipstats _P((void)); -void vjstats _P((void)); -void tcpstats _P((void)); -void udpstats _P((void)); -void icmpstats _P((void)); -void mbufstats _P((void)); -void sockstats _P((void)); -void slirp_exit _P((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_exi(int); diff --git a/slirp/icmp_var.h b/slirp/icmp_var.h index 9fe6d628..a50fd65c 100644 --- a/slirp/icmp_var.h +++ b/slirp/icmp_var.h @@ -61,7 +61,8 @@ struct icmpstat { } extern struct icmpstat icmpstat; +#if 0 extern struct socket icmp; extern struct socket *icmp_last_so; - +#endif #endif diff --git a/slirp/if.cpp b/slirp/if.cpp index 2bae5185..d8fea47c 100644 --- a/slirp/if.cpp +++ b/slirp/if.cpp @@ -7,11 +7,11 @@ #include "slirp.h" -int if_mtu, if_mru; +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 +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) */ @@ -111,7 +111,8 @@ if_input(ttyp) 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); diff --git a/slirp/if.h b/slirp/if.h index 5d96a903..a2564ab1 100644 --- a/slirp/if.h +++ b/slirp/if.h @@ -15,8 +15,8 @@ /* Needed for FreeBSD */ #undef if_mtu -extern int if_mtu; -extern int if_mru; /* MTU and MRU */ +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 */ diff --git a/slirp/ip_icmp.cpp b/slirp/ip_icmp.cpp index f82648c8..4259ea69 100644 --- a/slirp/ip_icmp.cpp +++ b/slirp/ip_icmp.cpp @@ -64,6 +64,8 @@ static int icmp_flush[19] = { /* ADDR MASK REPLY (18) */ 0 }; +#if SLIRP_ICMP + void icmp_init(void) { icmp.so_next = icmp.so_prev = &icmp; @@ -117,19 +119,21 @@ void icmp_detach(struct socket *so) sofree(so); } +#endif + /* * Process a received ICMP message. */ void icmp_input(struct mbuf *m, int hlen) { - register struct icmp *icp; - register struct ip *ip=mtod(m, struct ip *); + struct icmp *icp; + struct ip *ip=mtod(m, struct ip *); int icmplen=ip->ip_len; /* int code; */ DEBUG_CALL("icmp_input"); DEBUG_ARG("m = %p", m); - DEBUG_ARG("m_len = %d", m->m_len); + DEBUG_ARG("m_len = %zu", m->m_len); icmpstat.icps_received++; @@ -168,9 +172,11 @@ void icmp_input(struct mbuf *m, int hlen) struct socket *so; struct sockaddr_in addr; if ((so = socreate()) == NULL) goto freeit; - if (icmp_send(so, m, hlen) == 0) +#if SLIRP_ICMP + if (icmp_send(so, m, hlen) == 0) return; - if(udp_attach(so) == -1) { +#endif + if(udp_attach(so) == -1) { DEBUG_MISC(("icmp_input udp_attach errno = %d-%s\n", errno,strerror(errno))); sofree(so); @@ -257,13 +263,13 @@ end_error: void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, const char *message) { unsigned hlen, shlen, s_ip_len; - register struct ip *ip; - register struct icmp *icp; - register struct mbuf *m; + struct ip *ip; + struct icmp *icp; + struct mbuf *m; DEBUG_CALL("icmp_error"); DEBUG_ARG("msrc = %p", 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; @@ -271,9 +277,9 @@ void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, const 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)); + { 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((" %.16s to %.16s\n", bufa, bufb)); } #endif @@ -292,7 +298,7 @@ void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, const /* 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); } @@ -347,7 +353,7 @@ void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, const /* 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 */ @@ -370,10 +376,10 @@ end_error: */ void icmp_reflect(struct mbuf *m) { - register struct ip *ip = mtod(m, struct ip *); + struct ip *ip = mtod(m, struct ip *); int hlen = ip->ip_hl << 2; int optlen = hlen - sizeof(struct ip ); - register struct icmp *icp; + struct icmp *icp; /* * Send an icmp packet back to the ip level, @@ -416,6 +422,8 @@ void icmp_reflect(struct mbuf *m) icmpstat.icps_reflect++; } +#if SLIRP_ICMP + void icmp_receive(struct socket *so) { struct mbuf *m = so->so_m; @@ -451,3 +459,5 @@ void icmp_receive(struct socket *so) } icmp_detach(so); } + +#endif diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h index e49d2d2e..f827de15 100644 --- a/slirp/ip_icmp.h +++ b/slirp/ip_icmp.h @@ -155,12 +155,17 @@ struct icmp { (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) +void icmp_input(struct mbuf *, int); +void icmp_error(struct mbuf *, u_char, u_char, int, const char *); +void icmp_reflect(struct mbuf *); + +#if SLIRP_ICMP + void icmp_init(void); void icmp_cleanup(void); -void icmp_input _P((struct mbuf *, int)); -void icmp_error _P((struct mbuf *, u_char, u_char, int, const char *)); -void icmp_reflect _P((struct mbuf *)); void icmp_receive(struct socket *so); void icmp_detach(struct socket *so); #endif + +#endif diff --git a/slirp/ip_input.cpp b/slirp/ip_input.cpp index 9a70a3a6..9705c7e7 100644 --- a/slirp/ip_input.cpp +++ b/slirp/ip_input.cpp @@ -55,7 +55,9 @@ void ip_init(void) ip_id = tt.tv_sec & 0xffff; udp_init(); tcp_init(); +#if SLIRP_ICMP icmp_init(); +#endif ip_defttl = IPDEFTTL; } @@ -63,7 +65,9 @@ void ip_cleanup(void) { udp_cleanup(); tcp_cleanup(); +#if SLIRP_ICMP icmp_cleanup(); +#endif } /* @@ -73,7 +77,7 @@ void ip_cleanup(void) void ip_input(struct mbuf *m) { struct ip *ip; - int hlen; + u_int hlen; DEBUG_CALL("ip_input"); DEBUG_ARG("m = %p", m); diff --git a/slirp/ip_output.cpp b/slirp/ip_output.cpp index 146922e6..776313a9 100644 --- a/slirp/ip_output.cpp +++ b/slirp/ip_output.cpp @@ -52,8 +52,9 @@ int ip_output(struct socket *so, struct mbuf *m0) { struct ip *ip; struct mbuf *m = m0; - int hlen = sizeof(struct ip ); - int len, off, error = 0; + u_int hlen = sizeof(struct ip); + u_int len, off; + int error = 0; DEBUG_CALL("ip_output"); DEBUG_ARG("so = %p", so); @@ -125,8 +126,8 @@ int ip_output(struct socket *so, struct mbuf *m0) */ m0 = m; mhlen = sizeof (struct ip); - for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) { - register struct ip *mhip; + for (off = hlen + len; off < ip->ip_len; off += len) { + struct ip *mhip; m = m_get(); if (m == 0) { error = -1; @@ -170,7 +171,7 @@ int ip_output(struct socket *so, struct mbuf *m0) * 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; diff --git a/slirp/mbuf.cpp b/slirp/mbuf.cpp index e2b00851..e9dfc8cf 100644 --- a/slirp/mbuf.cpp +++ b/slirp/mbuf.cpp @@ -24,7 +24,7 @@ int mbuf_alloced = 0; struct mbuf m_freelist, m_usedlist; int mbuf_thresh = 30; int mbuf_max = 0; -int msize; +size_t msize; void m_init(void) { diff --git a/slirp/mbuf.h b/slirp/mbuf.h index e1a9bcda..94003d1a 100644 --- a/slirp/mbuf.h +++ b/slirp/mbuf.h @@ -63,11 +63,11 @@ 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 */ }; /* @@ -130,15 +130,15 @@ extern int mbuf_alloced; extern struct mbuf m_freelist, m_usedlist; extern int mbuf_max; -void m_init _P((void)); -void m_cleanup _P((void)); -void msize_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 m_cleanup(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 *, int); +void m_adj(struct mbuf *, int); +int m_copy(struct mbuf *, struct mbuf *, int, int); +struct mbuf * dtom(void *); #endif diff --git a/slirp/misc.cpp b/slirp/misc.cpp index cc51cdac..6e249010 100644 --- a/slirp/misc.cpp +++ b/slirp/misc.cpp @@ -17,10 +17,7 @@ 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"); @@ -40,12 +37,7 @@ 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; @@ -69,32 +61,34 @@ redir_x(inaddr, start_port, display, screen) #endif #ifndef HAVE_INET_ATON -int -inet_aton(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) +void getouraddr(void) { 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; + } @@ -103,11 +97,10 @@ struct quehead { struct quehead *qh_rlink; }; -void -insque(void *a, void *b) +void insque(void *a, void *b) { - register struct quehead *element = (struct quehead *) a; - register struct quehead *head = (struct quehead *) b; + struct quehead *element = (struct quehead *) a; + struct quehead *head = (struct quehead *) b; element->qh_link = head->qh_link; head->qh_link = (struct quehead *)element; element->qh_rlink = (struct quehead *)head; @@ -115,10 +108,9 @@ insque(void *a, void *b) = (struct quehead *)element; } -void -remque(void *a) +void remque(void *a) { - register struct quehead *element = (struct quehead *) a; + struct quehead *element = (struct quehead *) a; ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link; element->qh_rlink = NULL; @@ -128,8 +120,7 @@ remque(void *a) /* #endif */ -int -add_exec(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; @@ -158,9 +149,7 @@ add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int 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]; @@ -173,8 +162,7 @@ strerror(error) #ifdef _WIN32 -int -fork_exec(struct socket *so, char *ex, int do_pty) +int fork_exec(struct socket *so, char *ex, int do_pty) { /* not implemented */ return 0; @@ -182,8 +170,7 @@ fork_exec(struct socket *so, char *ex, int do_pty) #else -int -slirp_openpty(int *amaster, int *aslave) +int slirp_openpty(int *amaster, int *aslave) { register int master, slave; @@ -257,8 +244,7 @@ slirp_openpty(int *amaster, int *aslave) * do_pty = 1 Fork/exec using slirp.telnetd * do_ptr = 2 Fork/exec using pty */ -int -fork_exec(struct socket *so, char *ex, int do_pty) +int fork_exec(struct socket *so, char *ex, int do_pty) { int s; struct sockaddr_in addr; @@ -414,9 +400,7 @@ fork_exec(struct socket *so, char *ex, int do_pty) #endif #ifndef HAVE_STRDUP -char * -strdup(str) - const char *str; +char *strdup(const char *str) { char *bptr; @@ -428,9 +412,7 @@ strdup(str) #endif #if 0 -void -snooze_hup(num) - int num; +void snooze_hup(int num) { int s, ret; #ifndef NO_UNIX_SOCKETS @@ -470,8 +452,7 @@ snooze_hup(num) } -void -snooze() +void snooze(void) { sigset_t s; int i; @@ -495,9 +476,7 @@ snooze() exit(255); } -void -relay(s) - int s; +void relay(int s) { char buf[8192]; int n; @@ -557,25 +536,14 @@ relay(s) } #endif -int (*lprint_print) _P((void *, const char *, va_list)); +int (*lprint_print)(void *, const char *, va_list); char *lprint_ptr, *lprint_ptr2, **lprint_arg; -void -#if defined(__STDC__) || defined(_MSC_VER) -lprint(const char *format, ...) -#else -lprint(va_alist) va_dcl -#endif +void lprint(const char *format, ...) { va_list args; -#if defined(__STDC__) || defined(_MSC_VER) va_start(args, format); -#else - char *format; - va_start(args); - format = va_arg(args, char *); -#endif #if 0 /* If we're printing to an sbuf, make sure there's enough room */ /* XXX +100? */ @@ -624,8 +592,7 @@ lprint(va_alist) va_dcl va_end(args); } -void -add_emu(char *buff) +void add_emu(char *buff) { u_int lport, fport; u_int8_t tos = 0, emu = 0; @@ -717,41 +684,18 @@ add_emu(char *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; -{ - 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(int usec) +void u_sleep(int usec) { struct timeval t; fd_set fdset; @@ -768,8 +712,7 @@ u_sleep(int usec) * Set fd blocking and non-blocking */ -void -fd_nonblock(SLIRP_SOCKET fd) +void fd_nonblock(SLIRP_SOCKET fd) { #if defined USE_FIONBIO && defined FIONBIO ioctlsockopt_t opt = 1; @@ -784,8 +727,7 @@ fd_nonblock(SLIRP_SOCKET fd) #endif } -void -fd_block(SLIRP_SOCKET fd) +void fd_block(SLIRP_SOCKET fd) { #if defined USE_FIONBIO && defined FIONBIO ioctlsockopt_t opt = 0; @@ -805,13 +747,8 @@ fd_block(SLIRP_SOCKET 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]; diff --git a/slirp/misc.h b/slirp/misc.h index d383f475..ae0d60d5 100644 --- a/slirp/misc.h +++ b/slirp/misc.h @@ -19,15 +19,15 @@ struct ex_list { extern struct ex_list *exec_list; 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 @@ -67,21 +67,21 @@ extern struct emu_t *tcpemu; 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)); -void slirp_insque _P((void *, void *)); -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 _P((struct socket *, char *, int)); -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((SLIRP_SOCKET)); -void fd_block _P((SLIRP_SOCKET)); -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(SLIRP_SOCKET); +void fd_block(SLIRP_SOCKET); +int rsh_exec(struct socket *, struct socket *, char *, char *, char *); #endif diff --git a/slirp/sbuf.cpp b/slirp/sbuf.cpp index fe0392d1..05f1fe62 100644 --- a/slirp/sbuf.cpp +++ b/slirp/sbuf.cpp @@ -71,7 +71,7 @@ void sbappend(struct socket *so, struct mbuf *m) DEBUG_CALL("sbappend"); DEBUG_ARG("so = %p", so); DEBUG_ARG("m = %p", 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) { diff --git a/slirp/sbuf.h b/slirp/sbuf.h index 161e0bb7..25efd804 100644 --- a/slirp/sbuf.h +++ b/slirp/sbuf.h @@ -8,6 +8,8 @@ #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,11 +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 sbappendsb _P((struct sbuf *, struct mbuf *)); -void sbcopy _P((struct sbuf *, int, int, char *)); +void sbfree(struct sbuf *); +void sbdrop(struct sbuf *, int); +void sbreserve(struct sbuf *, int); +void sbappend(struct socket *, struct mbuf *); +void sbappendsb(struct sbuf *, struct mbuf *); +void sbcopy(struct sbuf *, int, int, char *); #endif diff --git a/slirp/slirp.cpp b/slirp/slirp.cpp index cfc69fbe..55059b35 100644 --- a/slirp/slirp.cpp +++ b/slirp/slirp.cpp @@ -222,20 +222,20 @@ int slirp_select_fill(int *pnfds, * 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 */ if (so->so_state & SS_FACCEPTCONN) { - FD_SET(so->s, readfds); + FD_SET(so->s, readfds); UPD_NFDS(so->s); continue; } @@ -302,6 +302,7 @@ int slirp_select_fill(int *pnfds, } } +#if 0 /* * ICMP sockets */ @@ -325,7 +326,7 @@ int slirp_select_fill(int *pnfds, UPD_NFDS(so->s); } } - +#endif } @@ -374,16 +375,16 @@ int slirp_select_fill(int *pnfds, 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(); - + /* * See if anything has timed out */ @@ -398,7 +399,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) last_slowtimo = curtime; } } - + /* * Check sockets */ @@ -408,25 +409,25 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) */ for (so = tcb.so_next; so != &tcb; so = so_next) { so_next = so->so_next; - + /* * FD_ISSET is meaningless on these sockets * (and they can crash the program) */ if (so->so_state & SS_NOFDREF || so->s == -1) - continue; - + continue; + /* * Check for URG data * This will soread as well, so no need to * test for readfds below if this succeeds */ - if (FD_ISSET(so->s, xfds)) - sorecvoob(so); + if (FD_ISSET(so->s, xfds)) { + sorecvoob(so); /* * Check sockets for reading */ - else if (FD_ISSET(so->s, readfds)) { + } else if (FD_ISSET(so->s, readfds)) { /* * Check for incoming connections */ @@ -435,82 +436,86 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) continue; } /* else */ ret = soread(so); - + /* 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; - - ret = send(so->s, (const char*)&ret, 0, 0); - if (ret < 0) { - /* XXXXX Must fix, zero bytes is a NOP */ - if (errno == EAGAIN || errno == EWOULDBLOCK || - errno == EINPROGRESS || errno == ENOTCONN) - continue; + /* + * Check for non-blocking, still-connecting sockets + */ + if (so->so_state & SS_ISFCONNECTING) { + /* Connected */ + so->so_state &= ~SS_ISFCONNECTING; + + ret = send(so->s, (const 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; */ - - /* - * 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 - */ + /* 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 + */ } - + /* * 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 */ - - /* 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((struct mbuf *)NULL, sizeof(struct ip),so); + if (ret < 0) { + /* XXX */ + int error = WSAGetLastError(); + if (error == EAGAIN || error == EWOULDBLOCK || + error == WSAEINPROGRESS || error == WSAENOTCONN) + continue; /* Still connecting, continue */ + + /* 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 */ + int error = WSAGetLastError(); + if (error == EAGAIN || error == EWOULDBLOCK || + 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 */ #endif } @@ -522,12 +527,13 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) */ for (so = udb.so_next; so != &udb; so = so_next) { so_next = so->so_next; - + if (so->s != -1 && FD_ISSET(so->s, readfds)) { sorecvfrom(so); } } +#if 0 /* * Check incoming ICMP relies. */ @@ -538,23 +544,23 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) icmp_receive(so); } } - +#endif } /* * 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 diff --git a/slirp/slirp.h b/slirp/slirp.h index e8439059..945e0d7a 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -11,6 +11,8 @@ #include "sysconfig.h" #include "slirp_config.h" +#define SLIRP_ICMP 0 + #ifdef _WIN32 #include @@ -23,21 +25,23 @@ typedef u_int8_t uint8; typedef u_int16_t uint16; typedef u_int32_t uint32; +typedef char *caddr_t; +typedef int socklen_t; +typedef unsigned long ioctlsockopt_t; + +/* Should be UINT_PTR but SLIRP code has <= 0 tests */ +#define SLIRP_SOCKET INT_PTR + #ifdef _MSC_VER #define container_of(address, type, field) ((type *)( \ (PCHAR)(address) - \ (ULONG_PTR)(&((type *)0)->field))) #endif -typedef char *caddr_t; -typedef int socklen_t; -typedef unsigned long ioctlsockopt_t; - -# include -# include -# include -# include - +#include +#include +#include +#include # define USE_FIONBIO 1 @@ -133,17 +137,6 @@ typedef u_int32_t uint32; #ifndef _WIN32 #include -#endif - -#ifndef _P -#ifndef NO_PROTOTYPES -# define _P(x) x -#else -# define _P(x) () -#endif -#endif - -#ifndef _WIN32 #include #include #endif @@ -154,17 +147,17 @@ typedef u_int32_t uint32; /* 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 @@ -216,25 +209,6 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #include #endif -#ifdef _WIN32 -#undef EWOULDBLOCK -#undef EINPROGRESS -#undef ENOTCONN -#undef EHOSTUNREACH -#undef ENETUNREACH -#undef ECONNREFUSED - -# define EWOULDBLOCK WSAEWOULDBLOCK -# define EINPROGRESS WSAEINPROGRESS -# define ENOTCONN WSAENOTCONN -# define EHOSTUNREACH WSAEHOSTUNREACH -# define ENETUNREACH WSAENETUNREACH -# define ECONNREFUSED WSAECONNREFUSED - -/* Should be UINT_PTR but SLIRP code has <= 0 tests */ -#define SLIRP_SOCKET INT_PTR -#endif - #include "debug.h" #if defined __GNUC__ @@ -280,38 +254,38 @@ 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 *, ...); #ifndef _WIN32 #include @@ -323,49 +297,49 @@ void lprint _P((const char *, ...)); 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_cleanup _P((void)); -void ip_input _P((struct mbuf *)); -struct ip * ip_reass _P((struct ip *, struct ipq *)); -void ip_freef _P((struct ipq *)); -void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *)); -void ip_deq _P((register struct ipasfrag *)); -void ip_slowtimo _P((void)); -void ip_stripoptions _P((register struct mbuf *, struct mbuf *)); +void ip_init(void); +void ip_cleanup(void); +void ip_input(struct mbuf *); +struct ip * ip_reass(struct ip *, struct ipq *); +void ip_freef(struct ipq *); +void ip_enq(struct ipasfrag *, struct ipasfrag *); +void ip_deq(struct ipasfrag *); +void ip_slowtimo(void); +void ip_stripoptions(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 */ -int tcp_reass _P((register struct tcpcb *, register struct tcpiphdr *, struct mbuf *)); -void tcp_input _P((register struct mbuf *, int, struct socket *)); -void tcp_dooptions _P((struct tcpcb *, u_char *, int, struct tcpiphdr *)); -void tcp_xmit_timer _P((register struct tcpcb *, int)); -int tcp_mss _P((register struct tcpcb *, u_int)); +int tcp_reass(struct tcpcb *, struct tcpiphdr *, struct mbuf *); +void tcp_input(struct mbuf *, int, struct socket *); +void tcp_dooptions(struct tcpcb *, u_char *, int, struct tcpiphdr *); +void tcp_xmit_timer(struct tcpcb *, int); +u_int tcp_mss(struct tcpcb *, u_int); /* tcp_output.c */ -int tcp_output _P((register struct tcpcb *)); -void tcp_setpersist _P((register struct tcpcb *)); +int tcp_output(struct tcpcb *); +void tcp_setpersist(struct tcpcb *); /* tcp_subr.c */ -void tcp_init _P((void)); -void tcp_cleanup _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_drain _P((void)); -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_cleanup(void); +void tcp_template(struct tcpcb *); +void tcp_respond(struct tcpcb *, struct tcpiphdr *, struct mbuf *, tcp_seq, tcp_seq, int); +struct tcpcb * tcp_newtcpcb(struct socket *); +struct tcpcb * tcp_close(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 @@ -381,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/slirp/slirp_config.h b/slirp/slirp_config.h index 0ec4a457..0fed9bc6 100644 --- a/slirp/slirp_config.h +++ b/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 @@ -77,9 +72,6 @@ /* Define if you have sys/stropts.h */ #undef HAVE_SYS_STROPTS_H -/* 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__ diff --git a/slirp/socket.cpp b/slirp/socket.cpp index 5a77241c..88c9b6f9 100644 --- a/slirp/socket.cpp +++ b/slirp/socket.cpp @@ -14,8 +14,13 @@ #include #endif -void -so_init() +#ifdef _WIN32 +#define IS_EAGAIN(e) ((e) == WSAEINTR || (e) == EAGAIN) +#else +#define IS_EAGAIN(e) ((e) == EAGAIN) +#endif + +void so_init() { /* Nothing yet */ } @@ -86,11 +91,12 @@ void sofree(struct socket *so) */ int soread(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 = %p", so); @@ -148,10 +154,11 @@ int soread(struct socket *so) nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); #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((" --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); + DEBUG_MISC((" --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, error,strerror(error))); sofcantrcvmore(so); tcp_sockclosed(sototcpcb(so)); return -1; @@ -280,7 +287,7 @@ int sowrite(struct socket *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"); @@ -327,9 +334,12 @@ int sowrite(struct socket *so) 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((" --- sowrite disconnected, so->so_state = %x, errno = %d\n", so->so_state, errno)); @@ -386,12 +396,13 @@ void sorecvfrom(struct socket *so) 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((" udp icmp rx errno = %d-%s\n", - errno,strerror(errno))); - icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); + error,strerror(error))); + icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(error)); } else { icmp_reflect(so->so_m); so->so_m = 0; /* Don't m_free() it again! */ @@ -423,16 +434,17 @@ void sorecvfrom(struct socket *so) m->m_len = recvfrom(so->s, m->m_data, len, 0, (struct sockaddr *)&addr, &addrlen); - DEBUG_MISC((" did recvfrom %d, errno = %d-%s\n", + DEBUG_MISC((" did recvfrom %zu, errno = %d-%s\n", m->m_len, errno,strerror(errno))); if(m->m_len<0) { u_char code=ICMP_UNREACH_PORT; + int error = WSAGetLastError(); - if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; - else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; + if(error == WSAEHOSTUNREACH) code=ICMP_UNREACH_HOST; + else if(error == WSAENETUNREACH) code=ICMP_UNREACH_NET; DEBUG_MISC((" rx error, tx icmp ICMP_UNREACH:%i\n", code)); - icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); + icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(error )); m_free(m); } else { /* @@ -491,7 +503,9 @@ int sosendto(struct socket *so, struct mbuf *m) addr.sin_addr = so->so_faddr; addr.sin_port = so->so_fport; - DEBUG_MISC((" 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((" 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, @@ -557,16 +571,12 @@ struct socket *solisten(u_int port, u_int32_t laddr, u_int lport, int flags) (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 */ closesocket(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)); diff --git a/slirp/socket.h b/slirp/socket.h index f0945960..012cd311 100644 --- a/slirp/socket.h +++ b/slirp/socket.h @@ -81,24 +81,24 @@ struct iovec { }; #endif -void so_init _P((void)); -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 sorwakeup _P((struct socket *)); -void sowwakeup _P((struct socket *)); -void soisfconnecting _P((register struct socket *)); -void soisfconnected _P((register struct socket *)); -void sofcantrcvmore _P((struct socket *)); -void sofcantsendmore _P((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(struct socket *); +void soisfconnected(struct socket *); +void sofcantrcvmore(struct socket *); +void sofcantsendmore(struct socket *); +void soisfdisconnected(struct socket *); +void sofwdrain(struct socket *); #endif /* _SOCKET_H_ */ diff --git a/slirp/tcp.h b/slirp/tcp.h index 372ae3b9..4ecaa250 100644 --- a/slirp/tcp.h +++ b/slirp/tcp.h @@ -38,8 +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 int tcp_rcvspace; -extern int tcp_sndspace; +extern size_t tcp_rcvspace; +extern size_t tcp_sndspace; extern struct socket *tcp_last_so; #define TCP_SNDSPACE 8192 diff --git a/slirp/tcp_input.cpp b/slirp/tcp_input.cpp index 71d94a18..ae5331bb 100644 --- a/slirp/tcp_input.cpp +++ b/slirp/tcp_input.cpp @@ -110,8 +110,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ } #endif -int -tcp_reass(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m) +int tcp_reass(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m) { struct tcpiphdr *q; struct socket *so = tp->t_socket; @@ -170,7 +169,7 @@ tcp_reass(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m) * if they are completely covered, dequeue them. */ while (!tcpfrag_list_end(q, tp)) { - register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; + int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; if (i <= 0) break; if (i < q->ti_len) { @@ -228,31 +227,33 @@ present: */ void tcp_input(struct mbuf *m, int iphlen, struct socket *inso) { - struct ip save_ip, *ip; - register struct tcpiphdr *ti; + struct ip save_ip, *ip; + struct tcpiphdr *ti; caddr_t optp = NULL; int optlen = 0; int len, tlen, off; - register struct tcpcb *tp = 0; - register int tiflags; + struct tcpcb *tp = 0; + 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((" m = %p iphlen = %2d inso = %p\n", - m, iphlen, inso )); - + DEBUG_ARGS((" m = %8lx iphlen = %2d inso = %lx\n", + (long)m, iphlen, (long)inso)); + /* * If called with m == 0, then we're continuing the connect */ if (m == NULL) { so = inso; - + /* Re-set a few variables */ tp = sototcpcb(so); m = so->so_m; @@ -260,11 +261,11 @@ void tcp_input(struct mbuf *m, int iphlen, struct socket *inso) ti = so->so_ti; tiwin = ti->ti_win; tiflags = ti->ti_flags; - + goto cont_conn; } - - + + tcpstat.tcps_rcvtotal++; /* * Get IP and TCP header together in first mbuf. @@ -272,19 +273,19 @@ void tcp_input(struct mbuf *m, int iphlen, struct socket *inso) */ ti = mtod(m, struct tcpiphdr *); if (iphlen > sizeof(struct ip )) { - ip_stripoptions(m, (struct mbuf *)0); - iphlen=sizeof(struct ip ); + ip_stripoptions(m, (struct mbuf *)0); + iphlen=sizeof(struct ip ); } /* XXX Check if too short */ - + /* * 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 *); - save_ip = *ip; - save_ip.ip_len+= iphlen; + ip = mtod(m, struct ip *); + save_ip = *ip; + save_ip.ip_len += iphlen; /* * Checksum extended TCP header and data. @@ -294,13 +295,13 @@ void tcp_input(struct mbuf *m, int iphlen, struct socket *inso) 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); + * ti->ti_sum = cksum(m, len); * if (ti->ti_sum) { */ - if(cksum(m, len)) { - tcpstat.tcps_rcvbadsum++; - goto drop; + if (cksum(m, len)) { + tcpstat.tcps_rcvbadsum++; + goto drop; } /* @@ -308,37 +309,37 @@ void tcp_input(struct mbuf *m, int iphlen, struct socket *inso) * pull out TCP options and adjust length. XXX */ off = ti->ti_off << 2; - if (off < sizeof (struct tcphdr) || off > tlen) { - 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 * prediction?"). If timestamp is the only option and it's * formatted as recommended in RFC 1323 appendix A, we * 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; - + /* * Convert TCP protocol specific fields to host format. */ @@ -350,8 +351,8 @@ void tcp_input(struct mbuf *m, int iphlen, struct socket *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. @@ -359,11 +360,11 @@ void tcp_input(struct mbuf *m, int iphlen, struct socket *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; ++tcpstat.tcps_socachemiss; @@ -376,63 +377,63 @@ findso: * but should either do a listen or a connect soon. * * state == CLOSED means we've done socreate() but haven't - * attached it to a protocol yet... - * + * attached it to a protocol yet... + * * XXX If a TCB does not exist, and the TH_SYN flag is * the only flag set, then create a session, mark it * 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 + + /* + * 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 (so->so_state & SS_ISFCONNECTING) + goto drop; tp = sototcpcb(so); - + /* XXX Should never fail */ if (tp == 0) goto dropwithreset; if (tp->t_state == TCPS_CLOSED) goto drop; - + /* Unscale the window into a 32-bit value. */ /* if ((tiflags & TH_SYN) == 0) * tiwin = ti->ti_win << tp->snd_scale; * else */ - tiwin = ti->ti_win; + tiwin = ti->ti_win; /* * Segment received on connection. @@ -440,9 +441,9 @@ findso: */ tp->t_idle = 0; if (so_options) - tp->t_timer[TCPT_KEEP] = tcp_keepintvl; + tp->t_timer[TCPT_KEEP] = tcp_keepintvl; else - tp->t_timer[TCPT_KEEP] = tcp_keepidle; + tp->t_timer[TCPT_KEEP] = tcp_keepidle; /* * Process options if not in LISTEN state, @@ -450,10 +451,10 @@ 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 @@ -472,34 +473,34 @@ findso: * 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) { - /* - * If last ACK falls within this segment's sequence numbers, - * record the timestamp. + (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. */ ++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)) + /* 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; tcpstat.tcps_rcvackpack++; @@ -526,10 +527,10 @@ 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); - */ - /* + /* 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??? @@ -556,24 +557,25 @@ findso: */ if (so->so_emu) { if (tcp_emu(so,m)) sbappend(so, m); - } else + } else { sbappend(so, m); + } /* * XXX This is called when data arrives. Later, check * 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. - */ + */ tp->t_flags |= TF_ACKNOW; tcp_output(tp); return; @@ -585,11 +587,12 @@ findso: * Receive window is amount of space in rcv queue, * 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)); + { + int win; + 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) { @@ -609,119 +612,119 @@ findso: */ 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)) { - int err2 = errno; - u_char code=ICMP_UNREACH_NET; - DEBUG_MISC((" 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((" tcp fconnect errno = %d-%s\n", + error, strerror(error))); + 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(error)); + } + 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; - 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 */ - + /* * If the state is SYN_SENT: * if seg contains an ACK, but not for our SYN, drop the input. @@ -736,13 +739,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; } @@ -762,7 +765,7 @@ findso: tcpstat.tcps_connects++; soisfconnected(so); tp->t_state = TCPS_ESTABLISHED; - + /* Do window scaling on this connection? */ /* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == * (TF_RCVD_SCALE|TF_REQ_SCALE)) { @@ -770,7 +773,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, @@ -778,10 +781,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, @@ -803,45 +807,45 @@ trimthenstep6: /* * States other than LISTEN or SYN_SENT. * First check timestamp, if present. - * Then check that at least some bytes of segment are within + * Then check that at least some bytes of segment are within * receive window. If segment begins before rcv_nxt, * drop leading data (and SYN); if nothing left, just ack. - * + * * 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) { if (tiflags & TH_SYN) { tiflags &= ~TH_SYN; ti->ti_seq++; - if (ti->ti_urp > 1) + if (ti->ti_urp > 1) ti->ti_urp--; else tiflags &= ~TH_URG; @@ -851,14 +855,14 @@ 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 * of sequence; drop it. */ tiflags &= ~TH_FIN; - + /* * Send an ACK to resynchronize and drop any data. * But keep on processing for RST or ACK. @@ -874,9 +878,9 @@ trimthenstep6: m_adj(m, todrop); ti->ti_seq += todrop; ti->ti_len -= todrop; - if (ti->ti_urp > todrop) + if (ti->ti_urp > todrop) { ti->ti_urp -= todrop; - else { + } else { tiflags &= ~TH_URG; ti->ti_urp = 0; } @@ -886,7 +890,7 @@ 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); tcpstat.tcps_rcvafterclose++; goto dropwithreset; @@ -896,7 +900,7 @@ 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) { tcpstat.tcps_rcvpackafterwin++; if (todrop >= ti->ti_len) { @@ -908,8 +912,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; @@ -924,26 +928,28 @@ trimthenstep6: if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { tp->t_flags |= TF_ACKNOW; tcpstat.tcps_rcvwinprobe++; - } else + } else { goto dropafterack; - } else + } + } 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: @@ -958,14 +964,14 @@ trimthenstep6: 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; */ + /* so->so_error = ECONNRESET; */ close: tp->t_state = TCPS_CLOSED; tcpstat.tcps_drops++; @@ -984,7 +990,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; } @@ -1005,7 +1011,7 @@ trimthenstep6: 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; tcpstat.tcps_connects++; tp->t_state = TCPS_ESTABLISHED; @@ -1016,23 +1022,23 @@ 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; - } + /* 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); + soisfconnected(so); } - + /* Do window scaling? */ /* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == * (TF_RCVD_SCALE|TF_REQ_SCALE)) { @@ -1040,7 +1046,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; @@ -1064,9 +1070,9 @@ trimthenstep6: if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { - tcpstat.tcps_rcvdupack++; - DEBUG_MISC((" dup ack m = %p so = %p \n", - m, so)); + tcpstat.tcps_rcvdupack++; + DEBUG_MISC((" dup ack m = %p so = %p \n", + (long)m, (long)so)); /* * If we have outstanding data (other than * a window probe), this is a completely @@ -1086,18 +1092,18 @@ trimthenstep6: * the new ssthresh). * * Dup acks mean that packets have left the - * network (they're now cached at the receiver) + * network (they're now cached at the receiver) * so bump cwnd by the amount in the receiver * to keep a constant cwnd packets in the * 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) { 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) @@ -1107,19 +1113,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) { tp->snd_cwnd += tp->t_maxseg; - (void) tcp_output(tp); + (void)tcp_output(tp); goto drop; } - } else + } else { tp->t_dupacks = 0; + } break; } synrx_to_est: @@ -1128,7 +1135,7 @@ trimthenstep6: * for the other side's cached packets, retract it. */ if (tp->t_dupacks > tcprexmtthresh && - tp->snd_cwnd > tp->snd_ssthresh) + 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)) { @@ -1148,10 +1155,10 @@ 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 (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); @@ -1164,8 +1171,9 @@ 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. * If the window gives us less than ssthresh packets @@ -1174,16 +1182,16 @@ trimthenstep6: * (maxseg^2 / cwnd per packet). */ { - register u_int cw = tp->snd_cwnd; - register u_int incr = tp->t_maxseg; + u_int cw = tp->snd_cwnd; + 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 { sbdrop(&so->so_snd, acked); @@ -1194,9 +1202,9 @@ 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; @@ -1225,7 +1233,7 @@ trimthenstep6: } 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 @@ -1270,12 +1278,12 @@ 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) + tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) tcpstat.tcps_rcvwinupd++; tp->snd_wnd = tiwin; tp->snd_wl1 = ti->ti_seq; @@ -1289,7 +1297,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 @@ -1305,24 +1313,24 @@ step6: * If this segment advances the known urgent pointer, * then mark the data stream. This should not happen * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since - * a FIN has been received from the remote side. + * a FIN has been received from the remote side. * In these states we ignore the URG. * * According to RFC961 (Assigned Protocols), * the urgent pointer points to the last octet * of urgent data. We continue, however, * to consider it to indicate the first octet - * of data past the urgent section as the original + * 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 @@ -1330,6 +1338,7 @@ step6: */ if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) tp->rcv_up = tp->rcv_nxt; + } dodata: /* @@ -1341,7 +1350,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 @@ -1363,33 +1372,33 @@ 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; tp->rcv_nxt++; } switch (tp->t_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; + 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. */ @@ -1397,7 +1406,7 @@ dodata: 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. @@ -1422,18 +1431,18 @@ dodata: * If this is a small packet, then ACK now - with Nagel * congestion avoidance sender won't send more until * he gets an ACK. - * + * * 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; } @@ -1441,7 +1450,7 @@ dodata: * Return any desired output. */ if (needoutput || (tp->t_flags & TF_ACKNOW)) { - (void) tcp_output(tp); + (void)tcp_output(tp); } return; @@ -1454,7 +1463,7 @@ dropafterack: goto drop; m_freem(m); tp->t_flags |= TF_ACKNOW; - (void) tcp_output(tp); + (void)tcp_output(tp); return; dropwithreset: @@ -1463,8 +1472,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; @@ -1513,7 +1522,7 @@ void 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 */ + (void)tcp_mss(tp, mss); /* sets t_maxseg */ break; /* case TCPOPT_WINDOW: @@ -1559,10 +1568,7 @@ void 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; @@ -1679,10 +1685,10 @@ void tcp_xmit_timer(struct tcpcb *tp, int rtt) * parameters from pre-set or cached values in the routing entry. */ -int tcp_mss(struct tcpcb *tp, u_int offer) +u_int tcp_mss(struct tcpcb *tp, u_int offer) { struct socket *so = tp->t_socket; - int mss; + u_int mss; DEBUG_CALL("tcp_mss"); DEBUG_ARG("tp = %p", tp); diff --git a/slirp/tcp_output.cpp b/slirp/tcp_output.cpp index 47bfc00f..12beac41 100644 --- a/slirp/tcp_output.cpp +++ b/slirp/tcp_output.cpp @@ -124,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 { @@ -199,12 +199,12 @@ again: * 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; } @@ -357,7 +357,7 @@ send: */ /* 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 { @@ -433,12 +433,12 @@ 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)) { @@ -528,7 +528,7 @@ send: { - ((struct ip *)ti)->ip_len = m->m_len; + ((struct ip *)ti)->ip_len = (u_int16_t)m->m_len; ((struct ip *)ti)->ip_ttl = ip_defttl; ((struct ip *)ti)->ip_tos = so->so_iptos; diff --git a/slirp/tcp_subr.cpp b/slirp/tcp_subr.cpp index f17eea2e..45a9d9ca 100644 --- a/slirp/tcp_subr.cpp +++ b/slirp/tcp_subr.cpp @@ -44,10 +44,10 @@ /* patchable/settable parameters for tcp */ int tcp_mssdflt = TCP_MSS; -int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ; -int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */ -int tcp_rcvspace; /* You may want to change this */ -int tcp_sndspace; /* Keep small if you have an error prone link */ +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 @@ -314,10 +314,7 @@ tcp_drain() #ifdef notdef -void -tcp_quench(i, errno) - - int errno; +void tcp_quench(int i, int errno) { struct tcpcb *tp = intotcpcb(inp); @@ -417,8 +414,10 @@ int tcp_fconnect(struct socket *so) addr.sin_addr = so->so_faddr; addr.sin_port = so->so_fport; + char addrstr[INET_ADDRSTRLEN]; DEBUG_MISC((" connect()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", - ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); + 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)); /* @@ -476,7 +475,7 @@ void tcp_connect(struct socket *inso) so->so_lport = inso->so_lport; } - (void) tcp_mss(sototcpcb(so), 0); + (void)tcp_mss(sototcpcb(so), 0); if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { tcp_close(sototcpcb(so)); /* This will sofree() as well */ @@ -816,7 +815,7 @@ int tcp_emu(struct socket *so, struct mbuf *m) ns->so_laddr=so->so_laddr; ns->so_lport=htons(port); - (void) tcp_mss(sototcpcb(ns), 0); + (void)tcp_mss(sototcpcb(ns), 0); ns->so_faddr=so->so_faddr; ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */ @@ -1043,7 +1042,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; diff --git a/slirp/tcp_timer.h b/slirp/tcp_timer.h index 0bc438c7..73fe2089 100644 --- a/slirp/tcp_timer.h +++ b/slirp/tcp_timer.h @@ -130,9 +130,9 @@ extern int tcp_backoff[]; struct tcpcb; -void tcp_fasttimo _P((void)); -void tcp_slowtimo _P((void)); -void tcp_canceltimers _P((struct tcpcb *)); -struct tcpcb * tcp_timers _P((register struct tcpcb *, int)); +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/slirp/tftp.cpp b/slirp/tftp.cpp index 16e08bb3..73b43d25 100644 --- a/slirp/tftp.cpp +++ b/slirp/tftp.cpp @@ -130,7 +130,6 @@ static int tftp_send_error(struct tftp_session *spt, struct sockaddr_in saddr, daddr; struct mbuf *m; struct tftp_t *tp; - int nobytes; m = m_get(); @@ -155,8 +154,6 @@ 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) - sizeof(struct ip) - sizeof(struct udphdr); diff --git a/slirp/udp.cpp b/slirp/udp.cpp index 19a08f18..fc30fb95 100644 --- a/slirp/udp.cpp +++ b/slirp/udp.cpp @@ -278,7 +278,7 @@ int udp_output2(struct socket *so, struct mbuf *m, 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; @@ -294,7 +294,7 @@ int udp_output2(struct socket *so, struct mbuf *m, 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 = ip_defttl; ((struct ip *)ui)->ip_tos = iptos; @@ -326,34 +326,30 @@ int udp_output(struct socket *so, struct mbuf *m, SLIRP_SOCKET udp_attach(struct socket *so) { - struct sockaddr_in addr; + 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; - closesocket(so->s); - so->s=-1; -#ifdef _WIN32 - WSASetLastError(lasterrno); -#else - errno=lasterrno; -#endif - } else { - /* success, insert in queue */ - so->so_expire = curtime + SO_EXPIRE; - insque(so,&udb); - } - } - return(so->s); + 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 error = WSAGetLastError(); + closesocket(so->s); + so->s =- 1; + WSASetLastError(error); + } else { + /* success, insert in queue */ + so->so_expire = curtime + SO_EXPIRE; + insque(so,&udb); + } + } + return(so->s); } void udp_detach(struct socket *so) diff --git a/slirp/udp.h b/slirp/udp.h index 1b445059..592e3a34 100644 --- a/slirp/udp.h +++ b/slirp/udp.h @@ -93,15 +93,15 @@ extern struct udpstat udpstat; extern struct socket udb; struct mbuf; -void udp_init _P((void)); -void udp_cleanup _P((void)); -void udp_input _P((register struct mbuf *, int)); -int udp_output _P((struct socket *, struct mbuf *, struct sockaddr_in *)); -SLIRP_SOCKET udp_attach _P((struct socket *)); -void udp_detach _P((struct socket *)); -u_int8_t udp_tos _P((struct socket *)); -void udp_emu _P((struct socket *, struct mbuf *)); -struct socket * udp_listen _P((u_int, u_int32_t, u_int, int)); +void udp_init(void); +void udp_cleanup(void); +void udp_input(struct mbuf *, int); +int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *); +SLIRP_SOCKET 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); diff --git a/slirp_uae.cpp b/slirp_uae.cpp index b6ce86cc..68f444a8 100644 --- a/slirp_uae.cpp +++ b/slirp_uae.cpp @@ -1,3 +1,4 @@ + #include "sysconfig.h" #ifdef _WIN32 #include "Winsock2.h" -- 2.47.3