X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/blobdiff_plain/127afaea3cf716aa9261e5c2cf129a10acbd1688..51f24d14e8c4c52776a98c8e2aaacf95f90ad1f4:/practicas/pipi/src/ipout.cpp diff --git a/practicas/pipi/src/ipout.cpp b/practicas/pipi/src/ipout.cpp index fb60ffd..d673f8d 100644 --- a/practicas/pipi/src/ipout.cpp +++ b/practicas/pipi/src/ipout.cpp @@ -23,10 +23,10 @@ bool IPOut::send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src, bool df, uint8_t ttl, uint16_t id) throw (std::runtime_error) { - // TODO fragmentar - if (IPHeader::header_len() + data.size() > dev.mtu) + // No quieren fragmentar + if (df && (IPHeader::header_len() + data.size() > dev.mtu)) { - drop("Tamaño de paquete más grande que MTU", data); + drop("Tamaño de paquete más grande que MTU y DF=1", data); return false; } if (!src) @@ -35,13 +35,27 @@ bool IPOut::send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src, id = get_id(); IPHeader iph(4, IPHeader::header_len() + data.size(), id, df, 0, 0, ttl, proto, src, dst); - std::string buf((char*) &iph, sizeof(IPHeader)); - buf += data; + // Fragmenta (de ser necesario) + int max_payload = dev.mtu - IPHeader::header_len(); + int cant_frag = data.size() / max_payload; + if (data.size() % max_payload) + ++cant_frag; + for (int i = 0; i < cant_frag; ++i) + { + IPHeader iph2 = iph; + if (i != (cant_frag - 1)) + iph2.mf = 1; + iph2.offset += i * max_payload; + iph2.total_len -= i * max_payload; + iph2.do_checksum(); + std::string buf((char*) &iph2, sizeof(IPHeader)); + buf += data.substr(i * max_payload, max_payload); #ifdef DEBUG - log << "IPOut::send: IPHeader: " << iph << "\n"; - log << "IPOut::send: buf = " << buf << "\n"; + log << "IPOut::send: Fragmento 0 => IPHeader: " << iph2 << "\n"; + log << "\tbuf (" << buf.size() << ") = " << buf << "\n"; #endif - dev.transmit(buf, dst /*TODO rutear */); + dev.transmit(buf, dst); + } return true; }