/** * Check if ip-source is a (directed) broadcast address. * Some hacker may try to create a broadcast storm. * Also check for null source address (0.0.0.0). * Broadcast destination is already filtered out by icmp_handler(). */ static BOOL icmp_check (const in_Header *ip, int type) { DWORD src, dst; BOOL bcast; src = intel (ip->source); dst = intel (ip->destination); bcast = (~src & ~sin_mask) == 0; if (bcast) { icmp_bogus (ip, type, _LANG(" (broadcast)")); return (FALSE); } if (ip->source == 0UL) { icmp_bogus (ip, type, _LANG(" (network)")); return (FALSE); } if (IN_MULTICAST(dst)) { icmp_bogus (ip, type, _LANG(" (multicast)")); return (FALSE); } if (IN_EXPERIMENTAL(dst)) { icmp_bogus (ip, type, _LANG(" (experimental)")); return (FALSE); } return (TRUE); }
static void do_dial (const char *value) { int rc = slip_dial (value); if (rc == -1) outsnl (_LANG("Modem not responding\7")); if (rc == -2) outsnl (_LANG("Connect failed")); }
/** * Print info about bogus and possibly dangerous ICMP messages. * e.g. "ICMP: (144.133.122.111) Bogus Redirect; GW = 111.110.109.108" */ static void icmp_bogus (const in_Header *ip, int type, const char *msg) { char buf[100]; strcpy (buf, _LANG("Bogus ")); strcat (buf, _LANG(icmp_type_str[type])); if (msg) strcat (buf, msg); icmp_print (1, buf, ip->source); }
/* * Check if ip-source is a (directed) broadcast address. * Some hacker may try to create a broadcast storm. * Also check for null source address (0.0.0.0). * Broadcast destination is already filtered out by icmp_handler(). */ static int icmp_chk_src (const in_Header *ip, int type) { BOOL bcast = (~intel(ip->source) & ~sin_mask) == 0; if (bcast) { icmp_bogus (ip, type, _LANG(" (broadcast)")); return (0); } if (ip->source == 0UL) { icmp_bogus (ip, type, _LANG(" (network)")); return (0); } return (1); }
void ReadHostFile (const char *fname) { if (!fname || !*fname) return; hostFname = strdup (fname); if (!hostFname) return; sethostent (1); if (!hostFile) return; while (1) { struct _hostent h; if (!_gethostent(&h)) break; if (!tree_insert(&host_root, (void*)&h, sizeof(h), (CmpFunc)host_cmp_name)) { outsnl (_LANG("Hostfile too big!\7")); break; } } atexit (endhostent); }
static int icmp_echo_reply (const in_Header *ip, const union ICMP_PKT *req, unsigned len) { struct _pkt *pkt; union ICMP_PKT *icmp; if (!icmp_check(ip,ICMP_ECHO)) return (0); icmp_print (2, _LANG("PING reply sent"), 0); #if defined(USE_FRAGMENTS) if (len > _mtu - sizeof(*ip)) { icmp = (union ICMP_PKT*) req; /* reuse input for output */ icmp->echo.type = ICMP_ECHOREPLY; icmp->echo.checksum = 0; icmp->echo.checksum = ~CHECKSUM (icmp, len); return _IP4_SEND_FRAGMENTS (NULL, ICMP_PROTO, ip->source, icmp, len); } #endif pkt = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP4_TYPE); icmp = &pkt->icmp; len = min (len, _mtu - sizeof(*ip)); memcpy (icmp, req, len); icmp->echo.type = ICMP_ECHOREPLY; icmp->echo.code = req->echo.code; /* Win uses 0, Unix !0 */ /* Use supplied ip values in case we ever multi-home. * Note that ip values are still in network order. */ return icmp_send (pkt, ip->destination, ip->source, len); }
/** * Send an ICMP destination/protocol unreachable back to 'ip->source'. * Limit the rate of these to 20 per second. Ref. RFC-1812. */ int icmp_send_unreach (const in_Header *ip, int code) { static DWORD next_time = 0UL; struct _pkt *pkt; union ICMP_PKT *unr; unsigned len; if (!icmp_check(ip,ICMP_UNREACH)) return (0); if (next_time && !chk_timeout(next_time)) return (0); next_time = set_timeout (50); pkt = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP4_TYPE); unr = &pkt->icmp; len = intel16 (ip->length) - in_GetHdrLen (ip); len = min (len, sizeof(*ip)+sizeof(unr->unused.spares)); icmp_print (1, _LANG(icmp_unreach_str[code]), ip->destination); memcpy (&unr->unused.ip, ip, len); unr->unused.type = ICMP_UNREACH; unr->unused.code = (BYTE) code; return icmp_send (pkt, ip->destination, ip->source, sizeof(unr->unused)); }
/* * trace2com_init() - Public initialisation */ int trace2com_init (WORD portAddress, DWORD baudRate) { BYTE Lsb, Msb; WORD base; DWORD div; /* Check/get UART address */ if (portAddress < 1 || portAddress > 4) return (0); base = trace2com_stdPorts [portAddress-1]; /* See if the chip is actually there and ready */ if (_inportb (base+IER_REG) == 0xFF) /* Nothing here */ return (0); if ((_inportb (base+IER_REG) & 0x0F) != 0x00) return (0); /* UART is already in use by another program */ _outportb (base+IER_REG, 0); /* disable all interrupts */ if (_inportb (base+IER_REG) != 0) return (0); /* Whatever is here is not an UART */ /* Set up UARTs registers */ div = 115200UL / baudRate; Msb = div >> 8; Lsb = (div << 8) >> 8; _outportb (base+LCR_REG, 0x80); /* Turn address latch on */ _outportb (base+BAUD_LSB_REG, Lsb); _outportb (base+BAUD_MSB_REG, Msb); _outportb (base+LCR_REG, 0x00); /* Turn address latch off (again) */ _outportb (base+IER_REG, 0x00); /* No interrupts, we use polling */ _outportb (base+FIFO_REG, 0x01|0x08); /* Activate FIFO @ MODE 2 */ _outportb (base+LCR_REG , 0x03); /* 8, N, 1 */ _outportb (base+MCR_REG, 0x03); /* DTR + DTS on */ /* Check chip type, gives us the FIFO size */ _outportb (base + FIFO_REG, 0x11); Lsb = _inportb (base + FIFO_REG); /* If we have a 16750 or 16550 the FIFO size is 16, otherwise we assume 1 */ trace2com_fifoSize_1 = ((Lsb & 0x20) != 0x20 || (Lsb & 0xC0) == 0xC0) ? 15 : 0; /* We are now officially open for business */ trace2com_speed = baudRate; trace2com_base = base; SIO_TRACE ((_LANG("Watt-32 COM%d trace started"), portAddress)); return (1); }
/** * Handle incoming PPPoE packets. */ int pppoe_handler (const pppoe_Packet *pkt) { const BYTE *buf; const void *src; const void *dst; WORD proto, len; BOOL bcast, delivered = FALSE; if (pkt->type != 1 || pkt->ver != 1) return (0); src = MAC_SRC (pkt); dst = MAC_DST (pkt); proto = MAC_TYP (pkt); bcast = !memcmp (dst, _eth_brdcast, _eth_mac_len); if (proto == PPPOE_SESS_TYPE && state == StateSession) { if (pkt->code == PPPOE_CODE_SESS && pkt->session == session && !bcast && !memcmp(dst, _eth_addr, _eth_mac_len) && /* to us? */ !memcmp(src, ac_macAddr, _eth_mac_len)) { len = intel16 (pkt->length); buf = &pkt->data[0]; ppp_input (buf, len); /* assume ppp_input() traces it */ delivered = TRUE; } } else if (!bcast && proto == PPPOE_DISC_TYPE && state == StateDiscovery) { if (pkt->code == PPPOE_CODE_PADO) /* Offer (can this be bcast?) */ { got_PADO = TRUE; memcpy (ac_macAddr, src, _eth_mac_len); } else if (pkt->code == PPPOE_CODE_PADT && /* Terminate */ pkt->session == session) { if (cfg.trace) outsnl (_LANG("PPPoE: session terminated")); got_PADT = TRUE; session = 0; } else if (pkt->code == PPPOE_CODE_PADS) /* Session-confirmation */ { got_PADS = TRUE; session = pkt->session; } else if (pkt->code == PPPOE_CODE_PADM) /* Message (what to do?) */ { got_PADM = TRUE; } } if (!delivered) DEBUG_RX (NULL, pkt); return (1); }
int sock_recv_from (udp_Socket *s, DWORD *hisip, WORD *hisport, char *buffer, int len, int peek) { tcp_Socket *t; recv_buf *p; recv_data *r = (recv_data*) s->rdata; int i; if (r->recv_sig != RECV_USED) return (-1); switch (s->ip_type) { case UDP_PROTO: p = (recv_buf*) r->recv_bufs; /* find a used buffer */ for (i = 0; i < r->recv_bufnum; i++, p++) { switch (p->buf_sig) { case RECV_UNUSED: break; case RECV_USED: if (p->buf_len < 0) /* a 0-byte probe packet */ len = -1; else { len = min (p->buf_len, len); memcpy (buffer, p->buf_data, len); } if (hisip) *hisip = p->buf_hisip; if (hisport) *hisport = p->buf_hisport; if (!peek) p->buf_sig = RECV_UNUSED; return (len); default: outsnl (_LANG("ERROR: sock_recv_init data err")); return (0); } } return (0); #if !defined(USE_UDP_ONLY) case TCP_PROTO: t = (tcp_Socket*) s; if (len > t->rdatalen) len = t->rdatalen; if (len) memcpy (buffer, r->recv_bufs, len); return (len); #endif } return (0); }
int sock_recv (udp_Socket *s, char *buffer, int len) { recv_buf *p; recv_data *r = (recv_data*) s->rdata; int i; if (r->recv_sig != RECV_USED) return (-1); switch (s->ip_type) { case UDP_PROTO: p = (recv_buf*) r->recv_bufs; /* find a used buffer */ for (i = 0; i < r->recv_bufnum; i++, p++) { switch (p->buf_sig) { case RECV_UNUSED: break; case RECV_USED: if (len > p->buf_len) len = p->buf_len; if (len > 0) memcpy (buffer, p->buf_data, len); p->buf_sig = RECV_UNUSED; return (len); default: outsnl (_LANG("ERROR: sock_recv_init data err")); return (0); } } return (0); #if !defined(USE_UDP_ONLY) case TCP_PROTO : { tcp_Socket *t = (tcp_Socket*) s; if (len > t->rdatalen) len = t->rdatalen; if (len) memcpy (buffer, r->recv_bufs, len); return (len); } #endif } return (0); }
static void icmp_print (int dbg_lvl, const char *msg, DWORD src) { if (debug_on < dbg_lvl) return; outs ("\nICMP: "); if (src) { outs ("("); outs (_inet_ntoa(NULL,intel(src))); outs ("): "); } outsnl (_LANG(msg)); }
/* * Do a reverse lookup on `my_ip_addr'. If successfull, replace * `hostname' and `def_domain' with returned result. */ int reverse_lookup_myip (void) { char myname [MAX_HOSTLEN]; if (!resolve_ip(htonl(my_ip_addr),myname)) return (0); if (debug_on >= 1) { outs (_LANG("My FQDN: ")); outsnl (myname); } if (sethostname(myname,sizeof(myname)) < 0) return (0); return (1); }
/* * _dorarp - Checks global variable _rarptimeout * returns 1 on success and sets ip address */ int _dorarp (void) { DWORD rarptimeout = set_timeout (1000 * _rarptimeout); WORD magictimeout = Random (7000, 14000); outs (_LANG("Configuring through RARP...")); while (1) { DWORD sendtimeout; if (!_rarp_request()) break; sendtimeout = set_timeout (magictimeout); magictimeout += Random (1000, 7000); while (!chk_timeout(sendtimeout)) { const struct rarp_Header *rarp; WORD eth_type; BOOL bcast; if (chk_timeout(rarptimeout)) return (0); WATT_YIELD(); rarp = (rarp_Header*) _eth_arrived (ð_type, &bcast); if (!rarp) continue; DEBUG_RX (NULL, rarp); if (eth_type == RARP_TYPE && !bcast && rarp->opcode == RARP_REPLY && rarp->protType == IP4_TYPE && !memcmp(rarp->dstEthAddr,_eth_addr,sizeof(mac_address))) { my_ip_addr = intel (rarp->dstIPAddr); _eth_free (rarp); return (1); } _eth_free (rarp); } } return (0); }
static int slip_dial (const char *str) { char dial_str[80]; WORD mcr = slip_base_reg + 4; WORD lcr = slip_base_reg + 3; _outportb (lcr, _inportb(lcr) & 0x43); /* 8N1 */ _outportb (mcr, _inportb(mcr) | 1); /* raise DTR */ if (!modem_command("ATZ\r","OK",5)) return (0); strcpy (dial_str, str); strcat (dial_str, "\r"); outs (_LANG("SLIP dialing..")); if (!modem_command(dial_str,"OK",2)) return (-1); if (!modem_command(NULL,"CONNECT",slip_timeout)) return (-2); return (0); }
void backgroundon (void) { outsnl (_LANG("Use wintr_init() / wintr_enable() instead")); exit (3); }
/* * Unhook signal-handlers and optionally chain to previous handlers * if we caught signals. */ void _sock_sig_restore (void) { if (signal_depth == 0) return; if (--signal_depth > 0) return; _sock_stop_timer(); watcbroke = 0; wathndlcbrk = wat_brkmode; #if defined(SIGALRM) && TRAP_SIGALRM signal (SIGALRM, old_sigalrm); unblock_sigalrm(); #if 0 /* don't do this since a socket function might be called from an * alarm handler. This could cause serious recursion and stack fault. */ if (sigalrm_caught && old_sigalrm != SIG_IGN && old_sigalrm != SIG_DFL) { sigalrm_caught = 0; (*old_sigalrm) (SIGALRM); } #endif #endif #if defined(SIGBREAK) signal (SIGBREAK, old_sigbrk); if (sigbrk_caught && old_sigbrk != SIG_IGN && old_sigbrk != SIG_DFL) { sigbrk_caught = 0; (*old_sigbrk) (SIGBREAK); } #endif #if defined(SIGPIPE) signal (SIGPIPE, old_sigpipe); if (sigpipe_caught) { if (old_sigpipe != SIG_IGN && old_sigpipe != SIG_DFL) { sigpipe_caught = 0; (*old_sigpipe) (SIGPIPE); } else { outsnl (_LANG("Terminating on SIGPIPE")); exit (-1); } } #endif #if defined(SIGQUIT) signal (SIGQUIT, old_sigquit); if (sigquit_caught) { if (old_sigquit != SIG_IGN && old_sigquit != SIG_DFL) { sigquit_caught = 0; (*old_sigquit) (SIGQUIT); } else { SOCK_DEBUGF ((NULL, "\nExiting stuck program")); exit (-1); } } #endif signal (SIGINT, old_sigint); if (sigint_caught && old_sigint != SIG_IGN && old_sigint != SIG_DFL) { sigint_caught = 0; (*old_sigint) (SIGINT); } sigalrm_caught = sigbrk_caught = 0; sigint_caught = sigquit_caught = 0; sigpipe_caught = 0; }
/** * Initialise WinPcap and return our MAC address. */ int pkt_eth_init (mac_address *mac_addr) { struct { PACKET_OID_DATA oidData; char descr[512]; } oid; const ADAPTER *adapter = NULL; DWORD thread_id; BOOL is_up; if (_watt_is_win9x) /**< \todo Support Win-9x too */ { (*_printf) (_LANG("Win-NT or later reqired.\n")); _pkt_errno = PDERR_GEN_FAIL; return (WERR_ILL_DOSX); } if (!_watt_no_config || _watt_user_config_fn) parse_config_pass_1(); _pkt_inf = calloc (sizeof(*_pkt_inf), 1); if (!_pkt_inf) { (*_printf) (_LANG("Failed to allocate WinPcap DRIVER data.\n")); _pkt_errno = PDERR_GEN_FAIL; return (WERR_NO_MEM); } if (debug_on >= 2 && dump_fname[0]) dump_file = fopen_excl (ExpandVarStr(dump_fname), "w+t"); if (!PacketInitModule(TRUE, dump_file)) { (*_printf) (_LANG("Failed to initialise WinPcap.\n")); pkt_release(); _pkt_errno = PDERR_NO_DRIVER; return (WERR_PKT_ERROR); } if (!_pktdrvrname[0] && !find_adapter(_pktdrvrname,sizeof(_pktdrvrname))) { (*_printf) (_LANG("No WinPcap driver found.\n")); _pkt_errno = PDERR_NO_DRIVER; return (WERR_NO_DRIVER); } TCP_CONSOLE_MSG (2, ("device %s\n", _pktdrvrname)); adapter = PacketOpenAdapter (_pktdrvrname); if (!adapter) { if (debug_on > 0) (*_printf) (_LANG("PacketOpenAdapter (\"%s\") failed; %s\n"), _pktdrvrname, win_strerror(GetLastError())); pkt_release(); return (WERR_NO_DRIVER); } _pkt_inf->adapter = adapter; #if defined(USE_DYN_PACKET) _pkt_inf->adapter_info = NULL; #else _pkt_inf->adapter_info = PacketFindAdInfo (_pktdrvrname); #endif /* Query the NIC driver for the adapter description */ memset (&oid, 0, sizeof(oid)); oid.oidData.Oid = OID_GEN_VENDOR_DESCRIPTION; oid.oidData.Length = sizeof(oid.descr); if (PacketRequest (adapter, FALSE, &oid.oidData)) StrLcpy (_pktdrvr_descr, (char*)oid.oidData.Data, sizeof(_pktdrvr_descr)); else { (*_printf) (_LANG("PacketRequest() failed; %s\n"), win_strerror(GetLastError())); pkt_release(); return (WERR_PKT_ERROR); } if (!get_interface_type(&_pktdevclass)) { pkt_release(); return (WERR_PKT_ERROR); } if (get_connected_status(&is_up) && !is_up) (*_printf) (_LANG("Warning: the adapter %s is down\n"), _pktdrvrname); switch (_pktdevclass) { case PDCLASS_TOKEN: _pkt_ip_ofs = sizeof(tok_Header); break; case PDCLASS_ETHER: _pkt_ip_ofs = sizeof(eth_Header); break; case PDCLASS_FDDI: _pkt_ip_ofs = sizeof(fddi_Header); break; case PDCLASS_ARCNET: _pkt_ip_ofs = ARC_HDRLEN; break; default: pkt_release(); (*_printf) (_LANG("WinPcap-ERROR: Unsupported driver class %dh\n"), _pktdevclass); _pkt_errno = PDERR_NO_CLASS; return (WERR_PKT_ERROR); } if (!pkt_get_addr(mac_addr)) /* get our MAC address */ { pkt_release(); return (WERR_PKT_ERROR); } pktq_init (&_pkt_inf->pkt_queue, sizeof(_pkt_inf->rx_buf[0]), /* RX_SIZE */ DIM(_pkt_inf->rx_buf), /* RX_BUFS */ (char*)&_pkt_inf->rx_buf); _pkt_inf->npf_buf_size = RX_SIZE * pkt_num_rx_bufs; _pkt_inf->npf_buf = malloc (_pkt_inf->npf_buf_size); if (!_pkt_inf->npf_buf) { (*_printf) (_LANG("Failed to allocate %d byte Rx buffer.\n"), _pkt_inf->npf_buf_size); pkt_release(); _pkt_errno = PDERR_GEN_FAIL; return (WERR_NO_MEM); } PacketSetMode (adapter, PACKET_MODE_CAPT); PacketSetBuff (adapter, _pkt_inf->npf_buf_size); PacketSetMinToCopy (adapter, ETH_MIN); /* PacketReceivePacket() blocks until something is received */ PacketSetReadTimeout ((ADAPTER*)adapter, 0); /* Set Rx-mode forced via config. */ if (_pkt_forced_rxmode != -1) { _pkt_forced_rxmode &= 0xFFFF; /* clear bits not set via ARG_ATOX_W */ if (_pkt_forced_rxmode == 0 || /* check illegal bit-values */ (_pkt_forced_rxmode & 0x10) || (_pkt_forced_rxmode & 0x40) || (_pkt_forced_rxmode > 0x80)) { TCP_CONSOLE_MSG (0, ("Illegal Rx-mode (0x%02X) specified\n", _pkt_forced_rxmode)); _pkt_forced_rxmode = -1; } } if (pkt_get_rcv_mode()) _pkt_rxmode0 = _pkt_rxmode; if (_pkt_forced_rxmode != -1) pkt_set_rcv_mode (_pkt_forced_rxmode); else pkt_set_rcv_mode (RXMODE_DEFAULT); #if 1 _pkt_inf->recv_thread = CreateThread (NULL, 2048, pkt_recv_thread, NULL, 0, &thread_id); #else _pkt_inf->recv_thread = _beginthreadex (NULL, 2048, pkt_recv_thread, NULL, 0, &thread_id); #endif if (!_pkt_inf->recv_thread) { (*_printf) (_LANG("Failed to create receiver thread; %s\n"), win_strerror(GetLastError())); pkt_release(); _pkt_errno = PDERR_GEN_FAIL; return (WERR_PKT_ERROR); } if (thr_realtime) SetThreadPriority (_pkt_inf->recv_thread, THREAD_PRIORITY_TIME_CRITICAL); TCP_CONSOLE_MSG (2, ("capture thread-id %lu\n", thread_id)); #if defined(USE_DEBUG) if (debug_on >= 2) { (*_printf) ("link-details:\n"); show_link_details(); } #endif return (0); }
/** * Handler for incoming ICMP packets. */ void icmp_handler (const in_Header *ip, BOOL broadcast) { union ICMP_PKT *icmp; const in_Header *orig_ip; int type, code; unsigned len; DWORD delta_time; BOOL for_me, i_orig; /* is it for me, did I originate it */ const char *msg; DEBUG_RX (NULL, ip); if (block_icmp) /* application is handling ICMP; not needed */ return; len = in_GetHdrLen (ip); icmp = (union ICMP_PKT*) ((BYTE*)ip + len); len = intel16 (ip->length) - len; for_me = _ip4_is_multihome_addr (intel(ip->destination)); if (!for_me || broadcast) /* drop broadcast pings.. */ return; if (len < sizeof(icmp->info)) { STAT (icmpstats.icps_tooshort++); return; } if (CHECKSUM(icmp,len) != 0xFFFF) { STAT (icmpstats.icps_checksum++); icmp_print (1, _LANG("bad checksum"), ip->source); return; } type = icmp->unused.type; code = icmp->unused.code; orig_ip = &icmp->ip.ip; i_orig = _ip4_is_local_addr (intel(orig_ip->source)); if (type == ICMP_MASKREPLY) { if (!_do_mask_req) return; i_orig = TRUE; } /* !! this needs work */ if (!i_orig && (type != ICMP_ECHOREPLY && type != ICMP_ECHO && type != ICMP_IREQREPLY && type != ICMP_TSTAMP)) { icmp_bogus (ip, type, NULL); return; } switch (type) { case ICMP_ECHOREPLY: /* check if we were waiting for it */ delta_time = set_timeout(0) - icmp->echo.identifier; add_ping (intel(ip->source), delta_time, icmp->echo.index); return; case ICMP_UNREACH: if (code < DIM(icmp_unreach_str)) { UINT len_needed = 8 + in_GetHdrLen (orig_ip); WORD next_mtu = 0; msg = _LANG (icmp_unreach_str[code]); icmp_print (1, msg, ip->source); if (orig_ip->proto == TCP_PROTO || orig_ip->proto == UDP_PROTO) len_needed += 4; /* Need the src/dest port numbers */ if (len >= len_needed) { if (code == ICMP_UNREACH_NEEDFRAG) next_mtu = intel16 (icmp->needfrag.next_mtu); #if !defined(USE_UDP_ONLY) if (orig_ip->proto == TCP_PROTO) _tcp_cancel (orig_ip, ICMP_UNREACH, code, msg, &next_mtu); else #endif if (orig_ip->proto == UDP_PROTO) _udp_cancel (orig_ip, ICMP_UNREACH, code, msg, &next_mtu); /** \todo Handle cancelling raw sockets */ #if defined(USE_BSD_API) && 0 else _raw_cancel (orig_ip, ICMP_UNREACH, code, msg); #endif } else STAT (icmpstats.icps_tooshort++); } else STAT (icmpstats.icps_badcode++); return; case ICMP_SOURCEQUENCH: #if !defined(USE_UDP_ONLY) if (orig_ip->proto == TCP_PROTO) { msg = _LANG (icmp_type_str[type]); icmp_print (1, msg, ip->source); _tcp_cancel (orig_ip, ICMP_SOURCEQUENCH, code, msg, NULL); } #endif return; case ICMP_REDIRECT: if (code < DIM(icmp_redirect_str)) icmp_redirect (icmp, ip, orig_ip, code); else STAT (icmpstats.icps_badcode++); return; case ICMP_ECHO: icmp_print (2, _LANG("PING requested of us"), ip->source); icmp_echo_reply (ip, icmp, len); return; case ICMP_TIMXCEED: if (code >= DIM(icmp_exceed_str)) { STAT (icmpstats.icps_badcode++); return; } if (code == 0) /* "TTL exceeded in transit" */ switch (orig_ip->proto) { #if !defined(USE_UDP_ONLY) case TCP_PROTO: msg = _LANG (icmp_exceed_str[0]); icmp_print (1, msg, ip->source); _tcp_cancel (orig_ip, ICMP_TIMXCEED, code, msg, NULL); break; #endif case UDP_PROTO: msg = _LANG (icmp_exceed_str[0]); icmp_print (1, msg, ip->source); _udp_cancel (orig_ip, ICMP_TIMXCEED, code, msg, NULL); break; } return; case ICMP_PARAMPROB: msg = _LANG (icmp_type_str[ICMP_PARAMPROB]); switch (orig_ip->proto) { #if !defined(USE_UDP_ONLY) case TCP_PROTO: icmp_print (0, msg, ip->source); _tcp_cancel (orig_ip, ICMP_PARAMPROB, code, msg, NULL); break; #endif case UDP_PROTO: icmp_print (0, msg, ip->source); _udp_cancel (orig_ip, ICMP_PARAMPROB, code, msg, NULL); break; } return; case ICMP_ROUTERADVERT: /* todo !! */ msg = _LANG (icmp_type_str[ICMP_ROUTERADVERT]); icmp_print (1, msg, ip->source); return; case ICMP_ROUTERSOLICIT: /* todo !! */ msg = _LANG (icmp_type_str[ICMP_ROUTERSOLICIT]); icmp_print (1, msg, ip->source); return; case ICMP_TSTAMP: msg = _LANG (icmp_type_str[ICMP_TSTAMP]); icmp_print (1, msg, ip->source); /**< \todo send reply? */ return; case ICMP_TSTAMPREPLY: msg = _LANG (icmp_type_str[ICMP_TSTAMPREPLY]); icmp_print (1, msg, ip->source); /**< \todo should store */ return; case ICMP_IREQ: msg = _LANG (icmp_type_str[ICMP_IREQ]); icmp_print (1, msg, ip->source); /**< \todo send reply */ return; case ICMP_IREQREPLY: msg = _LANG (icmp_type_str[ICMP_IREQREPLY]); icmp_print (1, msg, ip->source); /**< \todo send reply upwards */ return; case ICMP_MASKREQ: /* might be sent by us, never answer */ break; case ICMP_MASKREPLY: msg = _LANG (icmp_type_str[ICMP_MASKREPLY]); icmp_print (0, msg, ip->source); if ((icmp->mask.identifier == addr_mask_id) && (icmp->mask.sequence == addr_mask_seq-1) && sin_mask != intel(icmp->mask.mask)) outsnl ("Conflicting net-mask from \"ICMP Addr Mask Reply\"\7"); addr_mask_id = 0; return; } }
/* * Open a TFTP connection on a random local port (our transaction ID). * Send the request, wait for first data block and send the first ACK. */ static int tftp_open (DWORD server, const char *fname) { int retry; WORD port = 69; #if defined(USE_BSD_API) struct servent *sp = getservbyname ("tftp", "udp"); if (sp) port = intel16 ((WORD)sp->s_port); #endif currblock = 0UL; blocksize = 0; for (retry = 0; retry < tftp_retry; retry++) { WORD our_tid; /* our transaction ID (local port) */ if (tftp_lport && tftp_lport < TFTP_PORT_LOW) outsnl (_LANG("tftp: Illegal local port.")); if (tftp_lport >= TFTP_PORT_LOW) our_tid = tftp_lport; else our_tid = Random (TFTP_PORT_LOW, TFTP_PORT_HIGH); /* Try to open a TFTP connection to the server */ if (!udp_open(&sock->udp, our_tid, server, port, NULL)) { TRACE (("tftp: %s\n", sockerr(sock))); return (0); } sock->udp.locflags |= LF_NOCLOSE; /* don't close socket on timeout */ /* Send the file request block, and then wait for the first data * block. If there is no response to the query, retry it with * another transaction ID (local port), so that all old packets get * discarded automatically. */ send_req (RRQ, fname); /* This hack makes it work because the response is sent back on * a source-port different from port 69; i.e. the server TID * uses a random port. Force the response packet to match a passive * socket in udp_handler(). */ sock->udp.hisaddr = 0; ibuflen = recv_packet (1); if (ibuflen >= 0) { blocksize = ibuflen; isopen = TRUE; send_ack (1); return (1); } /* If an error (except timeout) occurred, retries are useless */ if (tftp_errno == ERR_ERR || tftp_errno == ERR_UNKNOWN) break; } return (0); }
/* * Load the BOOT-file from TFTP server */ int tftp_boot_load (void) { int rc = 0; /* Allocate socket and buffers */ sock = (sock_type*) malloc (sizeof(sock->udp)); inbuf = (struct tftphdr*) malloc (TFTP_HEADSIZE+SEGSIZE); outbuf = (struct tftphdr*) malloc (TFTP_HEADSIZE+SEGSIZE); if (!sock || !inbuf || !outbuf) { outsnl (_LANG("No memory for TFTP boot.")); return (0); } if (!tftp_boot_remote_file) { outsnl (_LANG("No remote TFTP boot filename defined.")); return (0); } if (tftp_server_name[0] && !tftp_server) tftp_server = resolve (tftp_server_name); if (!tftp_server) { outsnl (_LANG("Cannot resolve TFTP-server ")); return (0); } if (debug_on) outs (_LANG("Doing TFTP boot load...")); /* Open connection and request file */ if (!tftp_open (tftp_server, tftp_boot_remote_file)) { tftp_close(); return (0); } while (1) { const char *buf; int size = tftp_get_block (&buf); if (size < 0) /* error in transfer */ { rc = 0; break; } if (size > 0 && (*tftp_writer)(buf,size) < 0) { rc = -1; /* writer failed, errno set */ break; } if (size < blocksize) /* got last block */ { rc = 1; break; } } tftp_close(); return (rc); }
/* * _recvdaemon - gets upcalled when data arrives */ static int _recvdaemon (udp_Socket *s, BYTE *data, int len, tcp_PseudoHeader *ph, udp_Header *udp) { recv_data *r; recv_buf *p; int i; switch (s->ip_type) { case UDP_PROTO: r = (recv_data*)s->rdata; p = (recv_buf*) r->recv_bufs; if (r->recv_sig != RECV_USED) { outsnl (_LANG("ERROR: udp recv data conflict")); return (0); } /* find an unused buffer */ for (i = 0; i < r->recv_bufnum; i++, p++) switch (p->buf_sig) { case RECV_USED: break; case RECV_UNUSED: /* take this one */ p->buf_sig = RECV_USED; p->buf_hisip = ph->src; p->buf_hisport = udp->srcPort; len = min (len, sizeof(p->buf_data)); if (len > 0) { memcpy (p->buf_data, data, len); p->buf_len = len; } else p->buf_len = -1; /* a 0-byte probe */ return (0); default: outsnl (_LANG("ERROR: sock_recv_daemon data err")); return (0); } return (0); #if !defined(USE_UDP_ONLY) case TCP_PROTO: { tcp_Socket *t = (tcp_Socket*) s; r = (recv_data*) t->rdata; if (len > t->max_seg) return (0); if (r->recv_sig != RECV_USED) { outsnl (_LANG("ERROR: tcp recv data conflict")); return (0); } /* stick it on the end if you can */ i = t->maxrdatalen - t->rdatalen; if (i > 1) { /* we can accept some of this */ if (len > i) len = i; if (len > 0) memcpy (&r->recv_bufs[s->rdatalen], data, len); s->rdatalen += len; return (len); } return (0); /* didn't take none */ } #endif } return (0); }
/** * Initialize the network driver interface. * \return 0 okay. * \return error-code otherwise. */ int _eth_init (void) { int rc; SIO_TRACE (("_eth_init")); if (_eth_is_init) return (0); rc = pkt_eth_init (&_eth_addr); if (rc) return (rc); /* error message already printed */ /* Save our MAC-address incase we change it. Change back at exit. */ memcpy (_eth_real_addr, _eth_addr, sizeof(_eth_real_addr)); switch (_pktdevclass) { case PDCLASS_ETHER: mac_tx_format = eth_mac_format; mac_transmit = eth_mac_xmit; break; case PDCLASS_TOKEN: case PDCLASS_TOKEN_RIF: mac_tx_format = tok_mac_format; mac_transmit = tok_mac_xmit; break; case PDCLASS_FDDI: mac_tx_format = fddi_mac_format; mac_transmit = fddi_mac_xmit; break; case PDCLASS_ARCNET: mac_tx_format = arcnet_mac_format; mac_transmit = arcnet_mac_xmit; break; case PDCLASS_SLIP: case PDCLASS_PPP: case PDCLASS_AX25: /* !! for now */ mac_tx_format = null_mac_format; mac_transmit = null_mac_xmit; break; default: outsnl (_LANG("No supported driver class found")); return (WERR_NO_DRIVER); } memset (TX_BUF(), 0, sizeof(union link_Packet)); memset (&_eth_brdcast, 0xFF, sizeof(_eth_brdcast)); _eth_loop_addr[0] = 0xCF; pkt_buf_wipe(); if (!_eth_get_hwtype(NULL, &_eth_mac_len)) _eth_mac_len = sizeof(eth_address); if (!strcmp(_pktdrvrname,"NDIS3PKT")) _eth_ndis3pkt = TRUE; else if (!strcmp(_pktdrvrname,"SwsVpkt")) _eth_SwsVpkt = TRUE; _eth_is_init = TRUE; RUNDOWN_ADD (_eth_release, 10); return (0); /* everything okay */ }
void ReadNetworksFile (const char *fname) { static BOOL been_here = FALSE; if (!fname || !*fname) return; if (been_here) /* loading multiple network files */ { free (networkFname); fclose (networkFile); networkFile = NULL; } networkFname = strdup (fname); if (!networkFname) return; setnetent (1); if (!networkFile) return; been_here = TRUE; while (1) { struct netent *n = getnetent(); struct _netent *n2; int i; if (!n) break; n2 = (struct _netent*) calloc (sizeof(*n2), 1); if (!n2) { outs (networkFname); outsnl (_LANG(" too big!")); break; } for (i = 0; n->n_aliases[i]; i++) n2->n_aliases[i] = strdup (n->n_aliases[i]); n2->n_net = n->n_net; n2->n_addrtype = n->n_addrtype; n2->n_name = strdup (n->n_name); if (!n2->n_name) break; n2->n_next = network0; network0 = n2; } rewind (networkFile); RUNDOWN_ADD (endnetent, 251); #if 0 /* test */ { struct _netent *n; printf ("\n%s entries:\n", networkFname); for (n = network0; n; n = n->n_next) { int i; printf ("net %-15.15s name %-10.10s Aliases:", inet_ntoa(inet_makeaddr(n->n_net,0)), n->n_name); for (i = 0; n->n_aliases[i]; i++) printf (" %s,", n->n_aliases[i]); puts (""); } fflush (stdout); } #endif }
/* * Handler for incoming ICMP packets */ void icmp_handler (const in_Header *ip, BOOL broadcast) { union icmp_pkt *icmp; in_Header *orig_ip; int len, type, code; BOOL for_me, i_orig; /* is it for me, did I originate it */ const char *msg; DEBUG_RX (NULL, ip); if (block_icmp) /* application is handling ICMP; not needed */ return; len = in_GetHdrLen (ip); icmp = (union icmp_pkt*) ((BYTE*)ip + len); len = intel16 (ip->length) - len; for_me = (DWORD) (intel(ip->destination) - my_ip_addr) <= multihomes; if (!for_me || broadcast) /* drop broadcast pings.. */ return; if (len < sizeof(icmp->info)) { STAT (icmpstats.icps_tooshort++); return; } if (checksum(icmp,len) != 0xFFFF) { STAT (icmpstats.icps_checksum++); icmp_print (1, _LANG("bad checksum"), ip->source); return; } type = icmp->unused.type; code = icmp->unused.code; orig_ip = &icmp->ip.ip; i_orig = is_local_addr (intel(orig_ip->source)); if (type == ICMP_MASKREPLY) { if (!_domask_req) return; i_orig = TRUE; } /* !! this needs work */ if (!i_orig && (type != ICMP_ECHOREPLY && type != ICMP_ECHO && type != ICMP_IREQREPLY && type != ICMP_TSTAMP)) { icmp_bogus (ip, type, NULL); return; } switch (type) { case ICMP_ECHOREPLY: /* check if we were waiting for it */ STAT (icmpstats.icps_inhist[ICMP_ECHOREPLY]++); ping_hcache = intel (ip->source); ping_tcache = set_timeout (1000) - *(DWORD*)&icmp->echo.identifier; if (ping_tcache > 0x7FFFFFFFL) ping_tcache += 0x1800B0L; ping_number = *(DWORD*)(((BYTE*)&icmp->echo.identifier) + 4); return; case ICMP_UNREACH: STAT (icmpstats.icps_inhist[ICMP_UNREACH]++); if (code < DIM(icmp_unreach_str)) { icmp_print (1, msg = icmp_unreach_str[code], ip->source); #if !defined(USE_UDP_ONLY) if (orig_ip->proto == TCP_PROTO) _tcp_cancel (orig_ip, type, msg, 0); else #endif if (orig_ip->proto == UDP_PROTO) _udp_cancel (orig_ip, type, msg, 0); } else STAT (icmpstats.icps_badcode++); return; case ICMP_SOURCEQUENCH: STAT (icmpstats.icps_inhist[ICMP_SOURCEQUENCH]++); #if !defined(USE_UDP_ONLY) if (orig_ip->proto == TCP_PROTO) { icmp_print (1, _LANG("Source Quench"), ip->source); _tcp_cancel (orig_ip, type, NULL, 0); } #endif return; case ICMP_REDIRECT: STAT (icmpstats.icps_inhist[ICMP_REDIRECT]++); if (code < 4) { DWORD new_gw = intel (icmp->ip.ipaddr); /* Check if new gateway is on our subnet */ if ((new_gw ^ my_ip_addr) & sin_mask) { char buf[100], adr[20]; strcpy (buf, ", GW = "); strcat (buf, _inet_ntoa(adr,new_gw)); icmp_bogus (ip, type, buf); return; } icmp_print (1, msg = icmp_redirect_str[code], ip->source); switch (orig_ip->proto) { #if !defined(USE_UDP_ONLY) case TCP_PROTO: if (do_redirect.tcp) /* do it to some socket */ _tcp_cancel (orig_ip, type, msg, new_gw); break; #endif case UDP_PROTO: if (do_redirect.udp) _udp_cancel (orig_ip, type, msg, new_gw); break; case ICMP_PROTO: if (do_redirect.icmp) { _ip_recursion = 1; _arp_register (new_gw, intel(orig_ip->destination), 0); _ip_recursion = 0; } break; case IGMP_PROTO: if (do_redirect.igmp) { _ip_recursion = 1; _arp_register (new_gw, intel(orig_ip->destination), 0); _ip_recursion = 0; } break; } } else STAT (icmpstats.icps_badcode++); return; case ICMP_ECHO: STAT (icmpstats.icps_inhist[ICMP_ECHO]++); icmp_print (2, _LANG("PING requested of us"), ip->source); { /* Extract eth-address and create Echo reply packet. */ struct _pkt *pkt; union icmp_pkt *newicmp; if (!icmp_chk_src(ip,ICMP_ECHO)) return; pkt = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP_TYPE); newicmp = &pkt->icmp; /* Don't let a huge reassembled ICMP-packet kill us. */ len = min (len, mtu - sizeof(*ip)); memcpy (newicmp, icmp, len); newicmp->echo.type = ICMP_ECHOREPLY; newicmp->echo.code = code; /* Use supplied ip values in case we ever multi-home. * Note that ip values are still in network order. */ icmp_send (pkt, ip->destination, ip->source, len); icmp_print (2, _LANG("PING reply sent"), 0); } return; case ICMP_TIMXCEED: if (code >= DIM(icmp_exceed_str)) { STAT (icmpstats.icps_badcode++); return; } STAT (icmpstats.icps_inhist[ICMP_TIMXCEED]++); if (code != 1) switch (orig_ip->proto) { #if !defined(USE_UDP_ONLY) case TCP_PROTO: icmp_print (1, icmp_exceed_str[code], ip->source); _tcp_cancel (orig_ip, ICMP_TIMXCEED, NULL, 0); break; #endif case UDP_PROTO: icmp_print (1, icmp_exceed_str[code], ip->source); _udp_cancel (orig_ip, ICMP_TIMXCEED, NULL, 0); break; } return; case ICMP_PARAMPROB: STAT (icmpstats.icps_inhist[ICMP_PARAMPROB]++); switch (orig_ip->proto) { #if !defined(USE_UDP_ONLY) case TCP_PROTO: icmp_print (0, _LANG(icmp_type_str[type]), ip->source); _tcp_cancel (orig_ip, type, NULL, 0); break; #endif case UDP_PROTO: icmp_print (0, _LANG(icmp_type_str[type]), ip->source); _udp_cancel (orig_ip, type, NULL, 0); break; } return; case ICMP_ROUTERADVERT: /* todo !! */ STAT (icmpstats.icps_inhist[ICMP_ROUTERADVERT]++); icmp_print (1, _LANG(icmp_type_str[type]), ip->source); return; case ICMP_ROUTERSOLICIT: /* todo !! */ STAT (icmpstats.icps_inhist[ICMP_ROUTERSOLICIT]++); icmp_print (1, _LANG(icmp_type_str[type]), ip->source); return; case ICMP_TSTAMP: STAT (icmpstats.icps_inhist[ICMP_TSTAMP]++); icmp_print (1, _LANG(icmp_type_str[type]), ip->source); /* todo!!, send reply? */ return; case ICMP_TSTAMPREPLY: STAT (icmpstats.icps_inhist[ICMP_TSTAMPREPLY]++); icmp_print (1, _LANG(icmp_type_str[type]), ip->source); /* todo!!, should store */ return; case ICMP_IREQ: STAT (icmpstats.icps_inhist[ICMP_IREQ]++); icmp_print (1, _LANG(icmp_type_str[type]), ip->source); /* todo!!, send reply */ return; case ICMP_IREQREPLY: STAT (icmpstats.icps_inhist[ICMP_IREQREPLY]++); icmp_print (1, _LANG(icmp_type_str[type]), ip->source); /* todo!!, send reply upwards */ return; case ICMP_MASKREQ: STAT (icmpstats.icps_inhist[ICMP_MASKREQ]++); break; case ICMP_MASKREPLY: STAT (icmpstats.icps_inhist[ICMP_MASKREPLY]++); icmp_print (0, _LANG(icmp_type_str[type]), ip->source); if ((icmp->mask.identifier == addr_mask_id) && (icmp->mask.sequence == addr_mask_seq-1) && sin_mask != intel(icmp->mask.mask)) outsnl ("Conflicting net-mask from \"ICMP Addr Mask Reply\"\7"); addr_mask_id = 0; return; } }
/* * Gets upcalled when data arrives. * We MUST set 'p->buf_len = -1' to signal a 0-byte UDP packet * not 0 */ static int sock_recvdaemon (sock_type *s, const void *data, unsigned len, const tcp_PseudoHeader *ph, const udp_Header *udp) { recv_data *r; recv_buf *p; unsigned i; switch (s->udp.ip_type) { case UDP_PROTO: r = (recv_data*) s->udp.rx_data; p = (recv_buf*) r->recv_bufs; if (r->recv_sig != RECV_USED) { outsnl (_LANG("ERROR: udp recv data conflict")); return (0); } /* find an unused buffer */ for (i = 0; i < r->recv_bufnum; i++, p++) switch (p->buf_sig) { case RECV_USED: break; case RECV_UNUSED: /* take this one */ p->buf_sig = RECV_USED; p->buf_hisport = udp->srcPort; p->buf_seqnum = seq_num++; #if defined(USE_IPV6) if (s->udp.is_ip6) memcpy (&p->buf_hisip6, &((tcp_PseudoHeader6*)ph)->src, sizeof(p->buf_hisip6)); else #endif p->buf_hisip = ph->src; len = min (len, sizeof(p->buf_data)); if (len > 0) { memcpy (p->buf_data, data, len); p->buf_len = (short) len; } else p->buf_len = -1; /* a 0-byte probe */ #if 0 SOCK_DEBUGF (("\nsock_recvdaemon(): buffer %d, " "seq-num %ld, len %d", i, seq_num-1, p->buf_len)); #endif return (0); default: outsnl (_LANG("ERROR: sock_recv_daemon data err")); return (0); } return (0); #if !defined(USE_UDP_ONLY) case TCP_PROTO: { _tcp_Socket *t = &s->tcp; r = (recv_data*) t->rx_data; if (r->recv_sig != RECV_USED) { outsnl (_LANG("ERROR: tcp recv data conflict")); return (0); } /* stick it on the end if you can */ i = t->max_rx_data - t->rx_datalen; if (i > 1) { /* we can accept some of this */ if (len > i) len = i; if (len > 0) memcpy (r->recv_bufs + t->rx_datalen, data, len); t->rx_datalen += len; return (len); } return (0); /* didn't take none */ } #endif } return (0); }
int sock_recv_from (sock_type *s, void *hisip, WORD *hisport, void *buffer, unsigned len, int peek) { #if !defined(USE_UDP_ONLY) _tcp_Socket *t; #endif recv_buf *p, *oldest = NULL; recv_data *r = (recv_data*) s->udp.rx_data; long seqnum = LONG_MAX; int i; if (r->recv_sig != RECV_USED) { SOCK_ERRNO (EBADF); /* To differentiate an error from 0-byte probe (also -1) */ return (-1); } switch (s->udp.ip_type) { case UDP_PROTO: p = (recv_buf*) r->recv_bufs; /* find the oldest used UDP buffer. */ for (i = 0; i < r->recv_bufnum; i++, p++) { switch (p->buf_sig) { case RECV_UNUSED: break; case RECV_USED: /* Drop looped packets sent by us (running * under Win32 DOS box using NDIS3PKT or SwsVpkt). */ if ((_eth_ndis3pkt || _eth_SwsVpkt) && !s->tcp.is_ip6 && p->buf_hisip == intel(my_ip_addr)) { p->buf_sig = RECV_UNUSED; continue; } if (p->buf_seqnum < seqnum) /* ignore wraps */ { seqnum = p->buf_seqnum; oldest = p; #if 0 SOCK_DEBUGF (("\nsock_recv_from(): buffer %d, " "seq-num %ld, len %d", i, seqnum, p->buf_len)); #endif } break; default: outsnl (_LANG("ERROR: sock_recv_init data err")); return (0); } } break; #if !defined(USE_UDP_ONLY) case TCP_PROTO: t = &s->tcp; len = min (len, (unsigned)t->rx_datalen); if (len) memcpy (buffer, r->recv_bufs, len); return (len); #endif } if (!oldest) return (0); /* found the oldest UDP packet */ p = oldest; if (p->buf_len < 0) /* a 0-byte probe packet */ len = -1; else { len = min ((unsigned)p->buf_len, len); memcpy (buffer, p->buf_data, len); } #if defined(USE_IPV6) if (s->tcp.is_ip6) { if (hisip) memcpy (hisip, &p->buf_hisip6, sizeof(ip6_address)); } else #endif if (hisip) *(DWORD*)hisip = p->buf_hisip; if (hisport) *hisport = p->buf_hisport; if (!peek) p->buf_sig = RECV_UNUSED; return (len); }
void ReadHostsFile (const char *fname) { static BOOL been_here = FALSE; if (!fname || !*fname) return; if (been_here) /* loading multiple hosts files */ { free (hostFname); fclose (hostFile); hostFile = NULL; } hostFname = strdup (fname); if (!hostFname) return; sethostent (1); if (!hostFile) return; been_here = TRUE; while (1) { struct hostent *h = gethostent(); struct _hostent *h2; int i; if (!h) break; h2 = (struct _hostent*) calloc (sizeof(*h2), 1); if (!h2) { outs (hostFname); outsnl (_LANG(" too big!")); break; } for (i = 0; h->h_aliases[i]; i++) h2->h_aliases[i] = strdup (h->h_aliases[i]); h2->h_name = strdup (h->h_name); h2->h_address[0] = *(DWORD*) h->h_addr_list[0]; h2->h_num_addr = 1; if (!h2->h_name) break; h2->h_next = host0; host0 = h2; } #if 0 /* test !! */ { const struct _hostent *h; int i; printf ("\n%s entries:\n", hostFname); for (h = host0; h; h = h->h_next) { printf ("address = %-17.17s name = %-30.30s Aliases:", inet_ntoa(*(struct in_addr*)&h->h_address[0]), h->h_name); for (i = 0; h->h_aliases[i]; i++) printf (" %s,", h->h_aliases[i]); puts (""); } fflush (stdout); } #endif rewind (hostFile); RUNDOWN_ADD (endhostent, 254); }
/* * ___trace2com() - Strings passed here are dumped to the set-up serial * "com" port. If the string is < 16 chars long, it will fit into the * 16550 UARTs FIFO and will not cause any significant delay. * No interrupts are used, so this will not interfere with anything * else that might be happening. */ int MS_CDECL __trace2com (const char *fmt, ...) { int fifoLeft = 0; /* Assume TX FIFO is full on first round -> force check */ char buf [256]; int len, i; va_list args; if (trace2com_base <= 0) /* Not yet initialized */ return (0); va_start (args, fmt); #if defined(VSNPRINTF) len = VSNPRINTF (buf, sizeof(buf)-1, fmt, args); if (len < 0 || len >= SIZEOF(buf)-1) { outsnl (_LANG("ERROR: __trace2com() overrun")); len = sizeof(buf)-1; buf [len] = '\0'; } #else len = vsprintf (buf, fmt, args); if (len > SIZEOF(buf)) /* harm already done, but better than no test */ { outsnl (_LANG("ERROR: __trace2com() overrun")); return (0); } #endif for (i = 0; i < len; i++) { DWORD to = set_timeout (400000/trace2com_speed); /* 10ms at 38kB/s */ if (--fifoLeft < 0) /* Is the TX FIFO full? */ { /* Wait until THRE or TX FIFO empty */ while (!(_inportb (trace2com_base+LSR_REG) & LSR_THRE)) { if (chk_timeout(to)) return (i); } fifoLeft = trace2com_fifoSize_1; /* Now we can fill it up again */ } _outportb (trace2com_base+TXRX_REG, buf[i]); } if (--fifoLeft < 0) { DWORD to = set_timeout (400000/trace2com_speed); /* Wait until THRE or TX FIFO empty */ while (!(_inportb (trace2com_base+LSR_REG) & LSR_THRE)) { if (chk_timeout(to)) return (len); } } _outportb (trace2com_base+TXRX_REG, '\r'); _outportb (trace2com_base+TXRX_REG, '\n'); return (len+2); }
int getopt (int argc, char **argv, const char *opt_str) { char c, *q; int i, j; if (optind == 0) { optind = 1; done = 0; next_opt = empty; if (optmode == GETOPT_ANY) { options = malloc (argc * sizeof(char*)); non_options = malloc (argc * sizeof(char*)); if (!options || !non_options) { printf (_LANG("out of memory (getopt)\n")); exit (255); } options_count = 0; non_options_count = 0; } } if (done) return (EOF); restart: optarg = NULL; if (*next_opt == 0) { if (optind >= argc) { if (optmode == GETOPT_ANY) { j = 1; for (i = 0; i < options_count; ++i) argv[j++] = options[i]; for (i = 0; i < non_options_count; ++i) argv[j++] = non_options[i]; optind = options_count+1; free (options); free (non_options); } done = 1; return (EOF); } else if (!strchr (optswchar, argv[optind][0]) || argv[optind][1] == 0) { if (optmode == GETOPT_UNIX) { done = 1; return (EOF); } PUT (non_options); optarg = argv[optind++]; if (optmode == GETOPT_ANY) goto restart; /* optmode==GETOPT_KEEP */ return (0); } else if (argv[optind][0] == argv[optind][1] && argv[optind][2] == 0) { if (optmode == GETOPT_ANY) { j = 1; for (i = 0; i < options_count; ++i) argv[j++] = options[i]; argv[j++] = argv[optind]; for (i = 0; i < non_options_count; ++i) argv[j++] = non_options[i]; for (i = optind+1; i < argc; ++i) argv[j++] = argv[i]; optind = options_count+2; free (options); free (non_options); } ++optind; done = 1; return (EOF); } else { PUT (options); sw_char = argv[optind][0]; next_opt = argv[optind]+1; } } c = *next_opt++; if (*next_opt == 0) /* Move to next argument if end of argument reached */ optind++; if (c == ':' || (q = strchr (opt_str, c)) == NULL) { if (opterr) { if (c < ' ' || c >= 127) printf (_LANG("Invalid option; character code=0x%.2x\n"), c); else printf (_LANG("Invalid option `%c%c'\n"), sw_char, c); } optopt = '?'; return ('?'); } if (q[1] == ':') { if (*next_opt != 0) /* Argument given */ { optarg = next_opt; next_opt = empty; ++optind; } else if (q[2] == ':') optarg = NULL; /* Optional argument missing */ else if (optind >= argc) { /* Required argument missing */ if (opterr) printf (_LANG("No argument for `%c%c' option\n"), sw_char, c); c = '?'; } else { PUT (options); optarg = argv[optind++]; } } optopt = c; return (c); }