Skip to content
Snippets Groups Projects
Commit 0f77b289 authored by Shudong Zhou's avatar Shudong Zhou
Browse files

Handle IP fragments and packet parsing errors

parent a968cbb6
No related branches found
No related tags found
No related merge requests found
......@@ -17,12 +17,16 @@
package net.floodlightcontroller.packet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author David Erickson (daviderickson@cs.stanford.edu)
*/
public abstract class BasePacket implements IPacket {
public static final Logger log = LoggerFactory.getLogger(BasePacket.class);
protected IPacket parent;
protected IPacket payload;
......@@ -113,4 +117,4 @@ public abstract class BasePacket implements IPacket {
pkt.setParent(this.parent);
return pkt;
}
}
\ No newline at end of file
}
......@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import net.floodlightcontroller.core.annotations.LogMessageDoc;
import net.floodlightcontroller.util.MACAddress;
import org.openflow.util.HexString;
......@@ -228,9 +229,15 @@ public class Ethernet extends BasePacket {
return data;
}
@LogMessageDoc(level="INFO",
message="Failed to parse ethernet packet payload",
explanation="Was unable to parse ethernet payload, often caused " +
"by packet truncation. Packet is forwarded as a plain " +
"ethernet packet.",
recommendation=LogMessageDoc.GENERIC_ACTION)
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
if (length <= 0)
if (length <= 16) // Ethernet packet minium should be 60, this is reasonable
return null;
ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
if (this.destinationMACAddress == null)
......@@ -261,13 +268,22 @@ public class Ethernet extends BasePacket {
Class<? extends IPacket> clazz = Ethernet.etherTypeClassMap.get(this.etherType);
try {
payload = clazz.newInstance();
this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
} catch (Exception e) {
throw new RuntimeException("Error parsing payload for Ethernet packet", e);
log.info("Failed to parse ethernet packet {}->{} payload as {}," +
" treat as plain ethernet packet",
new Object[] {this.sourceMACAddress, this.destinationMACAddress,
clazz.getClass().getName()});
if (log.isDebugEnabled()) {
log.debug("Exception from parsing {}", e);
}
payload = new Data();
this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
}
} else {
payload = new Data();
this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
}
this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
this.payload.setParent(this);
return this;
}
......
......@@ -26,6 +26,8 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import net.floodlightcontroller.core.annotations.LogMessageDoc;
/**
* @author David Erickson (daviderickson@cs.stanford.edu)
*
......@@ -334,6 +336,11 @@ public class IPv4 extends BasePacket {
return data;
}
@LogMessageDoc(level="INFO",
message="IP fragment detected",
explanation="Packet in is an IP fragment. Controller forwards " +
"it using IP header only. Transport headers are ignored.",
recommendation=LogMessageDoc.GENERIC_ACTION)
@Override
public IPacket deserialize(byte[] data, int offset, int length) {
ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
......@@ -361,7 +368,8 @@ public class IPv4 extends BasePacket {
}
IPacket payload;
if (IPv4.protocolClassMap.containsKey(this.protocol)) {
boolean is_frag = ((this.flags & 0x1) != 0) || (this.fragmentOffset != 0);
if (!is_frag && IPv4.protocolClassMap.containsKey(this.protocol)) {
Class<? extends IPacket> clazz = IPv4.protocolClassMap.get(this.protocol);
try {
payload = clazz.newInstance();
......@@ -369,6 +377,11 @@ public class IPv4 extends BasePacket {
throw new RuntimeException("Error parsing payload for IPv4 packet", e);
}
} else {
if (is_frag) {
log.info("IPv4 fragment detected {}->{}, forward using IP header only",
fromIPv4Address(this.sourceAddress),
fromIPv4Address(this.destinationAddress));
}
payload = new Data();
}
int payloadLength = this.totalLength - this.headerLength * 4;
......@@ -493,7 +506,7 @@ public class IPv4 extends BasePacket {
* @return The IP address separated into bytes.
*/
public static byte[] toIPv4AddressBytes(int ipAddress) {
return new byte[] {
return new byte[] {
(byte)(ipAddress >>> 24),
(byte)(ipAddress >>> 16),
(byte)(ipAddress >>> 8),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment