void DoPing( uint8_t pingslot ) { unsigned short ppl; uint16_t seqnum = ++ClientPingEntries[pingslot].last_send_seqnum; uint16_t checksum = (seqnum + pingslot + 0x0800) ; int8_t arpslot = RequestARP( ClientPingEntries[pingslot].ip ); if( arpslot < 0 ) return; //must set macfrom to be the IP address of the target. memcpy( macfrom, ClientArpTable[arpslot].mac, 6 ); enc424j600_startsend( NetGetScratch() ); send_etherlink_header( 0x0800 ); send_ip_header( 32, ClientPingEntries[pingslot].ip, 0x01 ); PUSH16( 0x0800 ); //ping request + 0 for code PUSH16( ~checksum ); //Checksum PUSH16( pingslot ); //Idneitifer PUSH16( seqnum ); //Sequence number PUSH16( 0x0000 ); //Payload PUSH16( 0x0000 ); enc424j600_start_checksum( 8, 20 ); ppl = enc424j600_get_checksum(); enc424j600_alter_word( 18, ppl ); enc424j600_endsend(); }
/*----------------------------------------------------------------------------*/ uint8_t * IPOutput(struct mtcp_manager *mtcp, tcp_stream *stream, uint16_t tcplen) { struct iphdr *iph; int nif; unsigned char *haddr; if (stream->sndvar->nif_out >= 0) { nif = stream->sndvar->nif_out; } else { nif = GetOutputInterface(stream->daddr); stream->sndvar->nif_out = nif; } haddr = GetDestinationHWaddr(stream->daddr); if (!haddr) { #if 0 uint8_t *da = (uint8_t *)&stream->daddr; TRACE_INFO("[WARNING] The destination IP %u.%u.%u.%u " "is not in ARP table!\n", da[0], da[1], da[2], da[3]); #endif /* if not found in the arp table, send arp request and return NULL */ /* tcp will retry sending the packet later */ RequestARP(mtcp, stream->daddr, stream->sndvar->nif_out, mtcp->cur_ts); return NULL; } iph = (struct iphdr *)EthernetOutput(mtcp, ETH_P_IP, stream->sndvar->nif_out, haddr, tcplen + IP_HEADER_LEN); if (!iph) { return NULL; } iph->ihl = IP_HEADER_LEN >> 2; iph->version = 4; iph->tos = 0; iph->tot_len = htons(IP_HEADER_LEN + tcplen); iph->id = htons(stream->sndvar->ip_id++); iph->frag_off = htons(0x4000); // no fragmentation iph->ttl = 64; iph->protocol = IPPROTO_TCP; iph->saddr = stream->saddr; iph->daddr = stream->daddr; iph->check = 0; iph->check = ip_fast_csum(iph, iph->ihl); return (uint8_t *)(iph + 1); }
/*----------------------------------------------------------------------------*/ uint8_t * IPOutputStandalone(struct mtcp_manager *mtcp, uint16_t ip_id, uint32_t saddr, uint32_t daddr, uint16_t tcplen) { struct iphdr *iph; int nif; unsigned char * haddr; nif = GetOutputInterface(daddr); if (nif < 0) return NULL; haddr = GetDestinationHWaddr(daddr); if (!haddr) { #if 0 uint8_t *da = (uint8_t *)&daddr; TRACE_INFO("[WARNING] The destination IP %u.%u.%u.%u " "is not in ARP table!\n", da[0], da[1], da[2], da[3]); #endif RequestARP(mtcp, daddr, nif, mtcp->cur_ts); return NULL; } iph = (struct iphdr *)EthernetOutput(mtcp, ETH_P_IP, nif, haddr, tcplen + IP_HEADER_LEN); if (!iph) { return NULL; } iph->ihl = IP_HEADER_LEN >> 2; iph->version = 4; iph->tos = 0; iph->tot_len = htons(IP_HEADER_LEN + tcplen); iph->id = htons(ip_id); iph->frag_off = htons(0x4000); // no fragmentation iph->ttl = 64; iph->protocol = IPPROTO_TCP; iph->saddr = saddr; iph->daddr = daddr; iph->check = 0; iph->check = ip_fast_csum(iph, iph->ihl); return (uint8_t *)(iph + 1); }