/// Write-only accessor to _destAddress. /// @param newVal A stirng containing a numerical IPv4 or IPv6 address. /// @throw InvalidIPv4Address If the IP address was not in numerical 0.0.0.0 format. virtual void setDestAddress(const std::string& newVal) { if (newVal.empty() || checkValidAddress(_destAddress)) _destAddress = newVal; else throw InvalidIPv4Address("Improper IPv4 address given to devUdp4::setAddress"); _dest_addr.sin_addr.s_addr = IPv4Addr(newVal).get(); }
void IPv4::DemuxThreadFunc(void) { union PacketUnion { MaxPacket m_bytes; unsigned int m_words[5]; IPv4Header m_header; } *pInBE = new PacketUnion; ASSERT(pInBE); union { unsigned int m_words[5]; IPv4Header m_header; } in; while (1) { m_rRecvRing.Pop(pInBE->m_bytes); ASSERT(pInBE->m_bytes.m_startOffset == 0); for (int count = 0; count < 5; count++) in.m_words[count] = __builtin_bswap32(pInBE->m_words[count]); PacketError err; //check ipv4 if (in.m_header.m_version != 4) continue; //check header size int header_size = in.m_header.m_ihl * 4; if (header_size < 20 || header_size > 60) continue; //check all the sizes sum up if (in.m_header.m_totalLength != pInBE->m_bytes.m_size) continue; //check checksum pInBE->m_bytes.x[10] = 0; pInBE->m_bytes.x[11] = 0; unsigned short checksum = ip_checksum(&pInBE->m_header, header_size); if (checksum != in.m_header.m_headerChecksum) continue; //check the destination; we have no routing bool found = false; for (auto it = m_localAddrs.begin(); it != m_localAddrs.end(); it++) if (*it == in.m_header.m_destIpAddr) { found = true; break; } if (!found) continue; //find a decoder for the protocol auto it = m_protocols.find(in.m_header.m_protocol); if (it == m_protocols.end()) continue; Protocol *pProt = it->second; ASSERT(pProt); pInBE->m_bytes.m_startOffset = header_size; err = pProt->DecodeAndDispatch(IPv4Addr(in.m_header.m_sourceIpAddr), pInBE->m_bytes, in.m_header.m_totalLength - header_size); if (err == kErrorOk) continue; //no problem it = m_protocols.find(1); if (it == m_protocols.end()) continue; //uh-oh, no icmp switch (err) { case kDestPortUnreachable: ((ICMP *)it->second)->EnqueueErrorPacket(*this, IPv4Addr(in.m_header.m_sourceIpAddr), err, &pInBE->m_bytes.x[0], pInBE->m_bytes.m_size); break; default: break; } } }