Skip to content

Commit 2cfd4eb

Browse files
committed
Support packet larger than MTU
1 parent 53702eb commit 2cfd4eb

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/gateway.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,36 @@ void Gateway::run() {
248248
tcpLayer->getTcpHeader()->portDst = htobe16(data->realPort);
249249
tcpLayer->calculateChecksum(true);
250250
ipv4Layer->computeCalculateFields();
251-
self->dev->sendPacket(&newPacket);
251+
if (newEthLayer.getLayerPayloadSize() < self->dev->getMtu()) {
252+
self->dev->sendPacket(&newPacket);
253+
} else {
254+
uint64_t fragmentSize = self->dev->getMtu();
255+
uint64_t offset{};
256+
while (offset < ipv4Layer->getLayerPayloadSize()) {
257+
pcpp::Packet packetSlice;
258+
259+
pcpp::EthLayer ether(newEthLayer);
260+
packetSlice.addLayer(&ether);
261+
262+
pcpp::IPv4Layer ipLayerSlice(*ipv4Layer);
263+
ipLayerSlice.getIPv4Header()->fragmentOffset = htobe16(offset / 8) | htobe16(0x2000);
264+
packetSlice.addLayer(&ipLayerSlice);
265+
266+
uint8_t *payload = ipv4Layer->getLayerPayload() + offset;
267+
uint64_t payloadSize = fragmentSize - ipLayerSlice.getHeaderLen();
268+
269+
// last fragment
270+
if (offset + fragmentSize >= ipv4Layer->getLayerPayloadSize()) {
271+
ipLayerSlice.getIPv4Header()->fragmentOffset = htobe16(offset / 8) & htobe16(0x1FFF);
272+
payloadSize = ipv4Layer->getLayerPayloadSize() - offset;
273+
}
274+
pcpp::PayloadLayer payloadLayerSlice(payload, payloadSize, false);
275+
packetSlice.addLayer(&payloadLayerSlice);
276+
packetSlice.computeCalculateFields();
277+
offset += payloadSize;
278+
self->dev->sendPacket(&packetSlice);
279+
}
280+
}
252281

253282
if (tcpLayer->getTcpHeader()->finFlag) {
254283
self->portMap.removeMapping(tcpLayer->getDstPort());

0 commit comments

Comments
 (0)