diff --git a/src/main/java/net/onrc/onos/core/packet/IPv4.java b/src/main/java/net/onrc/onos/core/packet/IPv4.java
new file mode 100644
index 0000000..7f9db1a
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/packet/IPv4.java
@@ -0,0 +1,559 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ * 
+ */
+package net.onrc.onos.core.packet;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class IPv4 extends BasePacket {
+	public static final int ADDRESS_LENGTH = 4;
+    public static final byte PROTOCOL_ICMP = 0x1;
+    public static final byte PROTOCOL_TCP = 0x6;
+    public static final byte PROTOCOL_UDP = 0x11;
+    public static Map<Byte, Class<? extends IPacket>> protocolClassMap;
+
+    static {
+        protocolClassMap = new HashMap<Byte, Class<? extends IPacket>>();
+        protocolClassMap.put(PROTOCOL_ICMP, ICMP.class);
+        protocolClassMap.put(PROTOCOL_TCP, TCP.class);
+        protocolClassMap.put(PROTOCOL_UDP, UDP.class);
+    }
+
+    protected byte version;
+    protected byte headerLength;
+    protected byte diffServ;
+    protected short totalLength;
+    protected short identification;
+    protected byte flags;
+    protected short fragmentOffset;
+    protected byte ttl;
+    protected byte protocol;
+    protected short checksum;
+    protected int sourceAddress;
+    protected int destinationAddress;
+    protected byte[] options;
+
+    protected boolean isTruncated;
+
+    /**
+     * Default constructor that sets the version to 4.
+     */
+    public IPv4() {
+        super();
+        this.version = 4;
+        isTruncated = false;
+    }
+
+    /**
+     * @return the version
+     */
+    public byte getVersion() {
+        return version;
+    }
+
+    /**
+     * @param version the version to set
+     */
+    public IPv4 setVersion(byte version) {
+        this.version = version;
+        return this;
+    }
+
+    /**
+     * @return the headerLength
+     */
+    public byte getHeaderLength() {
+        return headerLength;
+    }
+
+    /**
+     * @return the diffServ
+     */
+    public byte getDiffServ() {
+        return diffServ;
+    }
+
+    /**
+     * @param diffServ the diffServ to set
+     */
+    public IPv4 setDiffServ(byte diffServ) {
+        this.diffServ = diffServ;
+        return this;
+    }
+
+    /**
+     * @return the totalLength
+     */
+    public short getTotalLength() {
+        return totalLength;
+    }
+
+    /**
+     * @return the identification
+     */
+    public short getIdentification() {
+        return identification;
+    }
+
+    public boolean isTruncated() {
+        return isTruncated;
+    }
+
+    public void setTruncated(boolean isTruncated) {
+        this.isTruncated = isTruncated;
+    }
+
+    /**
+     * @param identification the identification to set
+     */
+    public IPv4 setIdentification(short identification) {
+        this.identification = identification;
+        return this;
+    }
+
+    /**
+     * @return the flags
+     */
+    public byte getFlags() {
+        return flags;
+    }
+
+    /**
+     * @param flags the flags to set
+     */
+    public IPv4 setFlags(byte flags) {
+        this.flags = flags;
+        return this;
+    }
+
+    /**
+     * @return the fragmentOffset
+     */
+    public short getFragmentOffset() {
+        return fragmentOffset;
+    }
+
+    /**
+     * @param fragmentOffset the fragmentOffset to set
+     */
+    public IPv4 setFragmentOffset(short fragmentOffset) {
+        this.fragmentOffset = fragmentOffset;
+        return this;
+    }
+
+    /**
+     * @return the ttl
+     */
+    public byte getTtl() {
+        return ttl;
+    }
+
+    /**
+     * @param ttl the ttl to set
+     */
+    public IPv4 setTtl(byte ttl) {
+        this.ttl = ttl;
+        return this;
+    }
+
+    /**
+     * @return the protocol
+     */
+    public byte getProtocol() {
+        return protocol;
+    }
+
+    /**
+     * @param protocol the protocol to set
+     */
+    public IPv4 setProtocol(byte protocol) {
+        this.protocol = protocol;
+        return this;
+    }
+
+    /**
+     * @return the checksum
+     */
+    public short getChecksum() {
+        return checksum;
+    }
+
+    /**
+     * @param checksum the checksum to set
+     */
+    public IPv4 setChecksum(short checksum) {
+        this.checksum = checksum;
+        return this;
+    }
+    @Override
+    public void resetChecksum() {
+        this.checksum = 0;
+        super.resetChecksum();
+    }
+
+    /**
+     * @return the sourceAddress
+     */
+    public int getSourceAddress() {
+        return sourceAddress;
+    }
+
+    /**
+     * @param sourceAddress the sourceAddress to set
+     */
+    public IPv4 setSourceAddress(int sourceAddress) {
+        this.sourceAddress = sourceAddress;
+        return this;
+    }
+
+    /**
+     * @param sourceAddress the sourceAddress to set
+     */
+    public IPv4 setSourceAddress(String sourceAddress) {
+        this.sourceAddress = IPv4.toIPv4Address(sourceAddress);
+        return this;
+    }
+
+    /**
+     * @return the destinationAddress
+     */
+    public int getDestinationAddress() {
+        return destinationAddress;
+    }
+
+    /**
+     * @param destinationAddress the destinationAddress to set
+     */
+    public IPv4 setDestinationAddress(int destinationAddress) {
+        this.destinationAddress = destinationAddress;
+        return this;
+    }
+
+    /**
+     * @param destinationAddress the destinationAddress to set
+     */
+    public IPv4 setDestinationAddress(String destinationAddress) {
+        this.destinationAddress = IPv4.toIPv4Address(destinationAddress);
+        return this;
+    }
+
+    /**
+     * @return the options
+     */
+    public byte[] getOptions() {
+        return options;
+    }
+
+    /**
+     * @param options the options to set
+     */
+    public IPv4 setOptions(byte[] options) {
+        if (options != null && (options.length % 4) > 0)
+            throw new IllegalArgumentException(
+                    "Options length must be a multiple of 4");
+        this.options = options;
+        return this;
+    }
+
+    /**
+     * Serializes the packet. Will compute and set the following fields if they
+     * are set to specific values at the time serialize is called:
+     *      -checksum : 0
+     *      -headerLength : 0
+     *      -totalLength : 0
+     */
+    public byte[] serialize() {
+        byte[] payloadData = null;
+        if (payload != null) {
+            payload.setParent(this);
+            payloadData = payload.serialize();
+        }
+
+        int optionsLength = 0;
+        if (this.options != null)
+            optionsLength = this.options.length / 4;
+        this.headerLength = (byte) (5 + optionsLength);
+
+        this.totalLength = (short) (this.headerLength * 4 + ((payloadData == null) ? 0
+                : payloadData.length));
+
+        byte[] data = new byte[this.totalLength];
+        ByteBuffer bb = ByteBuffer.wrap(data);
+
+        bb.put((byte) (((this.version & 0xf) << 4) | (this.headerLength & 0xf)));
+        bb.put(this.diffServ);
+        bb.putShort(this.totalLength);
+        bb.putShort(this.identification);
+        bb.putShort((short) (((this.flags & 0x7) << 13) | (this.fragmentOffset & 0x1fff)));
+        bb.put(this.ttl);
+        bb.put(this.protocol);
+        bb.putShort(this.checksum);
+        bb.putInt(this.sourceAddress);
+        bb.putInt(this.destinationAddress);
+        if (this.options != null)
+            bb.put(this.options);
+        if (payloadData != null)
+            bb.put(payloadData);
+
+        // compute checksum if needed
+        if (this.checksum == 0) {
+            bb.rewind();
+            int accumulation = 0;
+            for (int i = 0; i < this.headerLength * 2; ++i) {
+                accumulation += 0xffff & bb.getShort();
+            }
+            accumulation = ((accumulation >> 16) & 0xffff)
+                    + (accumulation & 0xffff);
+            this.checksum = (short) (~accumulation & 0xffff);
+            bb.putShort(10, this.checksum);
+        }
+        return data;
+    }
+
+    @Override
+    public IPacket deserialize(byte[] data, int offset, int length) {
+        ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
+        short sscratch;
+
+        this.version = bb.get();
+        this.headerLength = (byte) (this.version & 0xf);
+        this.version = (byte) ((this.version >> 4) & 0xf);
+        this.diffServ = bb.get();
+        this.totalLength = bb.getShort();
+        this.identification = bb.getShort();
+        sscratch = bb.getShort();
+        this.flags = (byte) ((sscratch >> 13) & 0x7);
+        this.fragmentOffset = (short) (sscratch & 0x1fff);
+        this.ttl = bb.get();
+        this.protocol = bb.get();
+        this.checksum = bb.getShort();
+        this.sourceAddress = bb.getInt();
+        this.destinationAddress = bb.getInt();
+
+        if (this.headerLength > 5) {
+            int optionsLength = (this.headerLength - 5) * 4;
+            this.options = new byte[optionsLength];
+            bb.get(this.options);
+        }
+
+        IPacket payload;
+        if (IPv4.protocolClassMap.containsKey(this.protocol)) {
+            Class<? extends IPacket> clazz = IPv4.protocolClassMap.get(this.protocol);
+            try {
+                payload = clazz.newInstance();
+            } catch (Exception e) {
+                throw new RuntimeException("Error parsing payload for IPv4 packet", e);
+            }
+        } else {
+            payload = new Data();
+        }
+        this.payload = payload.deserialize(data, bb.position(), bb.limit()-bb.position());
+        this.payload.setParent(this);
+
+        if (this.totalLength != length)
+            this.isTruncated = true;
+        else
+            this.isTruncated = false;
+
+        return this;
+    }
+
+    /**
+     * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
+     * returns the corresponding 32 bit integer.
+     * @param ipAddress
+     * @return
+     */
+    public static int toIPv4Address(String ipAddress) {
+        if (ipAddress == null)
+            throw new IllegalArgumentException("Specified IPv4 address must" +
+                "contain 4 sets of numerical digits separated by periods");
+        String[] octets = ipAddress.split("\\.");
+        if (octets.length != 4) 
+            throw new IllegalArgumentException("Specified IPv4 address must" +
+                "contain 4 sets of numerical digits separated by periods");
+
+        int result = 0;
+        for (int i = 0; i < 4; ++i) {
+            result |= Integer.valueOf(octets[i]) << ((3-i)*8);
+        }
+        return result;
+    }
+
+    /**
+     * Accepts an IPv4 address in a byte array and returns the corresponding
+     * 32-bit integer value.
+     * @param ipAddress
+     * @return
+     */
+    public static int toIPv4Address(byte[] ipAddress) {
+        int ip = 0;
+        for (int i = 0; i < 4; i++) {
+          int t = (ipAddress[i] & 0xff) << ((3-i)*8);
+          ip |= t;
+        }
+        return ip;
+    }
+
+    /**
+     * Accepts an IPv4 address and returns of string of the form xxx.xxx.xxx.xxx
+     * ie 192.168.0.1
+     * 
+     * @param ipAddress
+     * @return
+     */
+    public static String fromIPv4Address(int ipAddress) {
+        StringBuffer sb = new StringBuffer();
+        int result = 0;
+        for (int i = 0; i < 4; ++i) {
+            result = (ipAddress >> ((3-i)*8)) & 0xff;
+            sb.append(Integer.valueOf(result).toString());
+            if (i != 3)
+                sb.append(".");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Accepts a collection of IPv4 addresses as integers and returns a single
+     * String useful in toString method's containing collections of IP
+     * addresses.
+     * 
+     * @param ipAddresses collection
+     * @return
+     */
+    public static String fromIPv4AddressCollection(Collection<Integer> ipAddresses) {
+        if (ipAddresses == null)
+            return "null";
+        StringBuffer sb = new StringBuffer();
+        sb.append("[");
+        for (Integer ip : ipAddresses) {
+            sb.append(fromIPv4Address(ip));
+            sb.append(",");
+        }
+        sb.replace(sb.length()-1, sb.length(), "]");
+        return sb.toString();
+    }
+
+    /**
+     * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
+     * returns the corresponding byte array.
+     * @param ipAddress The IP address in the form xx.xxx.xxx.xxx.
+     * @return The IP address separated into bytes
+     */
+    public static byte[] toIPv4AddressBytes(String ipAddress) {
+        String[] octets = ipAddress.split("\\.");
+        if (octets.length != 4) 
+            throw new IllegalArgumentException("Specified IPv4 address must" +
+                "contain 4 sets of numerical digits separated by periods");
+
+        byte[] result = new byte[4];
+        for (int i = 0; i < 4; ++i) {
+            result[i] = Integer.valueOf(octets[i]).byteValue();
+        }
+        return result;
+    }
+    
+    /**
+     * Accepts an IPv4 address in the form of an integer and
+     * returns the corresponding byte array.
+     * @param ipAddress The IP address as an integer.
+     * @return The IP address separated into bytes.
+     */
+    public static byte[] toIPv4AddressBytes(int ipAddress) {
+    	return new byte[] {
+                (byte)(ipAddress >>> 24),
+                (byte)(ipAddress >>> 16),
+                (byte)(ipAddress >>> 8),
+                (byte)ipAddress};
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 2521;
+        int result = super.hashCode();
+        result = prime * result + checksum;
+        result = prime * result + destinationAddress;
+        result = prime * result + diffServ;
+        result = prime * result + flags;
+        result = prime * result + fragmentOffset;
+        result = prime * result + headerLength;
+        result = prime * result + identification;
+        result = prime * result + Arrays.hashCode(options);
+        result = prime * result + protocol;
+        result = prime * result + sourceAddress;
+        result = prime * result + totalLength;
+        result = prime * result + ttl;
+        result = prime * result + version;
+        return result;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (!(obj instanceof IPv4))
+            return false;
+        IPv4 other = (IPv4) obj;
+        if (checksum != other.checksum)
+            return false;
+        if (destinationAddress != other.destinationAddress)
+            return false;
+        if (diffServ != other.diffServ)
+            return false;
+        if (flags != other.flags)
+            return false;
+        if (fragmentOffset != other.fragmentOffset)
+            return false;
+        if (headerLength != other.headerLength)
+            return false;
+        if (identification != other.identification)
+            return false;
+        if (!Arrays.equals(options, other.options))
+            return false;
+        if (protocol != other.protocol)
+            return false;
+        if (sourceAddress != other.sourceAddress)
+            return false;
+        if (totalLength != other.totalLength)
+            return false;
+        if (ttl != other.ttl)
+            return false;
+        if (version != other.version)
+            return false;
+        return true;
+    }
+}
