static BOOL modem_command (const char *cmd, const char *resp, int timeout) { DWORD timer; int len = cmd ? strlen (cmd) : strlen (resp); if (cmd) rc = pkt_send (cmd, len); /**<\todo Bypass PKTDRVR ? */ if (rc < len || !_eth_is_init) return (FALSE); timer = set_timeout (1000 * timeout); while (!chk_timeout(timer)) { char *pkt = (char*) _eth_arrived (NULL NULL); if (!pkt) continue; outsn (pkt, len); /* print the modem echo */ _eth_free (pkt, type); return (strncmp(pkt,resp,strlen(resp)) == 0); /* got modem response */ } return (FALSE); }
/* * _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); }
/* * Fix the LLC header to look like ordinary Ethernet II * !! not yet. */ static void fix_llc_head (void **mac) { SIO_TRACE (("fix_llc_head")); #if 1 DEBUG_RX (NULL, *mac); _eth_free (*mac); *mac = NULL; #else /** \todo handle IEEE 802.3 encapsulation also. */ #endif }
/** * Poll for arrival of new packets (IP/ARP/RARP/PPPoE protocol). * Sets protocol-type of packet received in 'type'. * * For Ethernet/TokenRing-type drivers: \n * \retval Pointer past the MAC-header to the IP/ARP/RARP * protocol header. Also check for link-layer broadcast. * * For PPP/SLIP-type drivers (no MAC-headers): \n * \retval Pointer to the IP-packet itself. * IP-protocol is assumed. Can never be link-layer broadcast. */ void *_eth_arrived (WORD *type_ptr, BOOL *broadcast) { union link_Packet *pkt; mac_address *dst; void *ret = NULL; BOOL is_bcast = FALSE; WORD type = 0; SIO_TRACE (("_eth_arrived")); if (!_eth_is_init) /* GvB 2002-09, Lets us run without a working driver */ return (NULL); if (_eth_recv_hook) pkt = (union link_Packet*) (*_eth_recv_hook) (&type); else pkt = poll_recv_queue (&type); if (!pkt) return (NULL); if (_eth_recv_peek && !(*_eth_recv_peek)(pkt)) { _eth_free (pkt); return (NULL); } /* Hack: If _ip?_handler() can't be reentered, only accept * non-IP packets. Assume PPPoE session packets carry only IP. */ if (_ip_recursion && (type == IP4_TYPE || type == IP6_TYPE || type == PPPOE_SESS_TYPE)) { /**< \todo push back packet, else it's lost */ STAT (macstats.num_ip_recurse++); _eth_free (pkt); return (NULL); } if (_pktserial) { dst = NULL; ret = (void*) &pkt->ip; } else if (_pktdevclass == PDCLASS_TOKEN || _pktdevclass == PDCLASS_TOKEN_RIF) { dst = &pkt->tok.head.destination; ret = (void*) &pkt->tok.data; } else if (_pktdevclass == PDCLASS_FDDI) { dst = &pkt->fddi.head.destination; ret = (void*) &pkt->fddi.data; } else if (_pktdevclass == PDCLASS_ARCNET) { dst = (mac_address*) &pkt->arc.head.destination; ret = (void*) ((BYTE*)pkt + ARC_HDRLEN); } else /* must be ether */ { dst = &pkt->eth.head.destination; ret = (void*) &pkt->eth.data; } #if defined(NEED_PKT_SPLIT) pkt_split_mac_in (pkt); #endif #if defined(USE_STATISTICS) update_in_stat(); #endif #if defined(NEED_PKT_SPLIT) && defined(USE_DEBUG) && 0 /* test */ pkt_print_split_in(); #endif /* ARCnet should never have LLC fields. So don't test for it */ if (_pktdevclass != PDCLASS_ARCNET) { if (dst && !memcmp(dst, &_eth_brdcast, sizeof(_eth_brdcast))) is_bcast = TRUE; if (intel16(type) < 0x600) /* LLC length field */ fix_llc_head (&ret); } else if (dst && *(BYTE*)dst == 0) /* ARCnet broadcast */ { is_bcast = TRUE; } if (type_ptr) *type_ptr = type; if (broadcast) *broadcast = is_bcast; return (ret); }