public void parse(Parcel parcel){
	
		try{
			// Extract CRC from packet header
			parcel.rewind();
			this.hdr_hdr_chk = parcel.getInt(Packet.HEADER_LENGTH + DataPacket.DATA_HDR_SIZE - 4);
			
			// Set CRC field to 0
			parcel.add(Packet.HEADER_LENGTH + DataPacket.DATA_HDR_SIZE - 4, (int)0);
			
			// Extract data to do CRC check for
			byte[] data = new byte[Packet.HEADER_LENGTH+DataPacket.DATA_HDR_SIZE+DataPacket.DATA_XHDR_SIZE];		
			parcel.rewind();
			parcel.get(data, 0, Packet.HEADER_LENGTH+DataPacket.DATA_HDR_SIZE+DataPacket.DATA_XHDR_SIZE);
			
			// Calculate CRC checksum for extracted data
			CRC32 crc32Checker = new CRC32();
			crc32Checker.update(data);
			
			// Check computed checksum against checksum extracted from header
			if(((int)crc32Checker.getValue()) != this.hdr_hdr_chk){
				throw new PacketException("CRC check for data packet did not pass.");
			}
			
		}catch(BufferUnderflowException ex){
			throw new PacketException("Packet is too short - cannot parse.");
		}
		
		super.parse(parcel);
		
		Parcel contents = getContents();
			
		if(contents == null){
			throw new PacketException("Malformed data packet. Missing contents.");
		}
		
		// HDR-DST-ID (8)
		this.hdr_dst = new Peer(new PeerAddress(contents));
		
		// HDR-DST-LOC (24)
		this.hdr_dst.setLocation(new GeoLocation(contents));
		
		// HDR-FWD-DST-ID (8)
		this.hdr_fwd_dst_id = new PeerAddress(contents);
		this.fwd_dst_set = true;
		
		// HDR-FWD-MODE (1)
		byte fwd_mode = contents.getByte();
		if(fwd_mode == ForwardMode.GREEDY.getFlag())
		    this.hdr_fwd_mode = ForwardMode.GREEDY;
		else
		    this.hdr_fwd_mode = ForwardMode.PERIMETER;
		
		// HDR-DATA-LEN (2)
		short payloadLength = contents.getShort();
		
		// HDR-QOS (1)
		byte qos = contents.getByte();
		if(qos == QualityOfService.CONTROL.getFlag())
		    this.hdr_qos = QualityOfService.CONTROL;
		else if(qos == QualityOfService.COMMUNICATION.getFlag())
		    this.hdr_qos = QualityOfService.COMMUNICATION;
		else if(qos == QualityOfService.REGULAR.getFlag())
		    this.hdr_qos = QualityOfService.REGULAR;
		else
			this.hdr_qos = null;
		
		// HDR-HDR-CHK (4)
		contents.getInt();
		
		// XHDR (96)
		if(this.hdr_fwd_mode == ForwardMode.PERIMETER){
			this.xhdr_entered_loc = new GeoLocation(contents);
			this.xhdr_face_entered_loc = new GeoLocation(contents);
			this.xhdr_face_first_edge_src = new GeoLocation(contents);
			this.xhdr_face_first_edge_dst = new GeoLocation(contents);
		}
		else{
			for(int i=0; i<DataPacket.DATA_XHDR_SIZE; i++)
				contents.getByte();
		}
		
		// Extract payload
		this.payload = new byte[payloadLength];
		contents.getByteArray(this.payload);
		
	}