Example #1
0
icmp_time_exceeded* IcmpLayer::setTimeExceededData(uint8_t code, IPv4Layer* ipHeader, Layer* l4Header)
{
	if (code > 1)
	{
		LOG_ERROR("Unknown code %d for ICMP time exceeded data", (int)code);
		return NULL;
	}

	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_time_exceeded) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_TIME_EXCEEDED;

	icmp_time_exceeded* header = getTimeExceededData();
	header->code = code;
	header->unused = 0;

	if (!setIpAndL4Layers(ipHeader, l4Header))
		return NULL;

	return header;
}
Example #2
0
bool IcmpLayer::setEchoData(IcmpMessageType echoType, uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data, size_t dataLen)
{
	if (!cleanIcmpLayer())
		return false;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_echo_hdr) - sizeof(icmphdr) + dataLen))
		return false;

	getIcmpHeader()->type = (uint8_t)echoType;

	icmp_echo_request* header = NULL;
	if (echoType == ICMP_ECHO_REQUEST)
		header = getEchoRequestData();
	else if (echoType == ICMP_ECHO_REPLY)
		header = (icmp_echo_request*)getEchoReplyData();
	else
		return false;

	header->header->code = 0;
	header->header->checksum = 0;
	header->header->id = htons(id);
	header->header->sequence = htons(sequence);
	header->header->timestamp = timestamp;
	if (data != NULL && dataLen > 0)
		memcpy(header->data, data, dataLen);

	return true;
}
Example #3
0
icmp_param_problem* IcmpLayer::setParamProblemData(uint8_t code, uint8_t errorOctetPointer, IPv4Layer* ipHeader, Layer* l4Header)
{
	if (code > 2)
	{
		LOG_ERROR("Unknown code %d for ICMP parameter problem data", (int)code);
		return NULL;
	}

	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_param_problem) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_PARAM_PROBLEM;

	icmp_param_problem* header = getParamProblemData();
	header->code = code;
	header->unused1 = 0;
	header->unused2 = 0;
	header->pointer = errorOctetPointer;

	if (!setIpAndL4Layers(ipHeader, l4Header))
		return NULL;

	return header;
}
Example #4
0
icmp_router_advertisement* IcmpLayer::setRouterAdvertisementData(uint8_t code, uint16_t lifetimeInSeconds, const std::vector<icmp_router_address_structure>& routerAddresses)
{
	if (code != 0 && code != 16)
	{
		LOG_ERROR("Unknown code %d for ICMP router advertisement data (only codes 0 and 16 are legal)", (int)code);
		return NULL;
	}

	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_router_advertisement_hdr) + (routerAddresses.size()*sizeof(icmp_router_address_structure)) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_ROUTER_ADV;

	icmp_router_advertisement* header = getRouterAdvertisementData();
	header->header->code = code;
	header->header->lifetime = htons(lifetimeInSeconds);
	header->header->advertisementCount = (uint8_t)routerAddresses.size();
	header->header->addressEntrySize = 2;

	icmp_router_address_structure* curPos = (icmp_router_address_structure*)((uint8_t*)header->header + sizeof(icmp_router_advertisement_hdr));
	for (std::vector<icmp_router_address_structure>::const_iterator iter = routerAddresses.begin(); iter != routerAddresses.end(); iter++)
	{
		curPos->routerAddress = iter->routerAddress;
		curPos->preferenceLevel = iter->preferenceLevel;
		curPos += 1;
	}

	return header;
}
Example #5
0
icmp_redirect* IcmpLayer::setRedirectData(uint8_t code, IPv4Address gatewayAddress, IPv4Layer* ipHeader, Layer* l4Header)
{
	if (code > 3)
	{
		LOG_ERROR("Unknown code %d for ICMP redirect data", (int)code);
		return NULL;
	}

	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_redirect) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_REDIRECT;

	icmp_redirect* header = getRedirectData();
	header->code = code;
	header->gatewayAddress = gatewayAddress.toInt();

	if (!setIpAndL4Layers(ipHeader, l4Header))
		return NULL;

	return header;
}
Example #6
0
IcmpMessageType IcmpLayer::getMessageType()
{
	uint8_t type = getIcmpHeader()->type;
	if (type > 18)
		return ICMP_UNSUPPORTED;

	return (IcmpMessageType)type;
}
Example #7
0
void IcmpLayer::computeCalculateFields()
{
	// calculate checksum
	getIcmpHeader()->checksum = 0;

	size_t icmpLen = 0;
	Layer* curLayer = this;
	while (curLayer != NULL)
	{
		icmpLen += curLayer->getHeaderLen();
		curLayer = curLayer->getNextLayer();
	}

	ScalarBuffer<uint16_t> buffer;
	buffer.buffer = (uint16_t*)getIcmpHeader();
	buffer.len = icmpLen;
	size_t checksum = compute_checksum(&buffer, 1);

	getIcmpHeader()->checksum = htons(checksum);
}
Example #8
0
icmp_router_solicitation* IcmpLayer::setRouterSolicitationData()
{
	if (!cleanIcmpLayer())
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_ROUTER_SOL;

	icmp_router_solicitation* header = getRouterSolicitationData();
	header->code = 0;

	return header;
}
Example #9
0
icmp_info_reply* IcmpLayer::setInfoReplyData(uint16_t id, uint16_t sequence)
{
	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_info_reply) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_INFO_REPLY;

	icmp_info_reply* header = getInfoReplyData();
	header->code = 0;
	header->id = htons(id);
	header->sequence = htons(sequence);

	return header;
}
Example #10
0
icmp_address_mask_reply* IcmpLayer::setAddressMaskReplyData(uint16_t id, uint16_t sequence, IPv4Address mask)
{
	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_address_mask_reply) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_ADDRESS_MASK_REPLY;

	icmp_address_mask_reply* header = getAddressMaskReplyData();
	header->code = 0;
	header->id = htons(id);
	header->sequence = htons(sequence);
	header->addressMask = htonl(mask.toInt());

	return header;
}
Example #11
0
icmp_source_quench* IcmpLayer::setSourceQuenchdata(IPv4Layer* ipHeader, Layer* l4Header)
{
	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_source_quench) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_SOURCE_QUENCH;

	icmp_source_quench* header = getSourceQuenchdata();
	header->unused = 0;

	if (!setIpAndL4Layers(ipHeader, l4Header))
		return NULL;

	return header;
}
Example #12
0
icmp_destination_unreachable* IcmpLayer::setDestUnreachableData(IcmpDestUnreachableCodes code, uint16_t nextHopMTU, IPv4Layer* ipHeader, Layer* l4Header)
{
	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_destination_unreachable) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_DEST_UNREACHABLE;

	icmp_destination_unreachable* header = getDestUnreachableData();
	header->code = code;
	header->nextHopMTU = htons(nextHopMTU);
	header->unused = 0;

	if (!setIpAndL4Layers(ipHeader, l4Header))
		return NULL;

	return header;
}
Example #13
0
icmp_timestamp_request* IcmpLayer::setTimestampRequestData(uint16_t id, uint16_t sequence, timeval originateTimestamp)
{
	if (!cleanIcmpLayer())
		return NULL;

	if (!this->extendLayer(m_DataLen, sizeof(icmp_timestamp_request) - sizeof(icmphdr)))
		return NULL;

	getIcmpHeader()->type = (uint8_t)ICMP_TIMESTAMP_REQUEST;

	icmp_timestamp_request* header = getTimestampRequestData();
	header->code = 0;
	header->id = htons(id);
	header->sequence = htons(sequence);
	header->originateTimestamp = htonl(originateTimestamp.tv_sec*1000 + originateTimestamp.tv_usec/1000);
	header->receiveTimestamp = 0;
	header->transmitTimestamp = 0;

	return header;
}
Example #14
0
std::string IcmpLayer::toString()
{
	std::string messageTypeAsString;
	IcmpMessageType type = getMessageType();
	switch (type)
	{
	case ICMP_ECHO_REPLY:
		messageTypeAsString = "Echo (ping) reply";
		break;
	case ICMP_DEST_UNREACHABLE:
		messageTypeAsString = "Destination unreachable";
		break;
	case ICMP_SOURCE_QUENCH:
		messageTypeAsString = "Source quench (flow control)";
		break;
	case ICMP_REDIRECT:
		messageTypeAsString = "Redirect";
		break;
	case ICMP_ECHO_REQUEST:
		messageTypeAsString = "Echo (ping) request";
		break;
	case ICMP_ROUTER_ADV:
		messageTypeAsString = "Router advertisement";
		break;
	case ICMP_ROUTER_SOL:
		messageTypeAsString = "Router solicitation";
		break;
	case ICMP_TIME_EXCEEDED:
		messageTypeAsString = "Time-to-live exceeded";
		break;
	case ICMP_PARAM_PROBLEM:
		messageTypeAsString = "Parameter problem: bad IP header";
		break;
	case ICMP_TIMESTAMP_REQUEST:
		messageTypeAsString = "Timestamp request";
		break;
	case ICMP_TIMESTAMP_REPLY:
		messageTypeAsString = "Timestamp reply";
		break;
	case ICMP_INFO_REQUEST:
		messageTypeAsString = "Information request";
		break;
	case ICMP_INFO_REPLY:
		messageTypeAsString = "Information reply";
		break;
	case ICMP_ADDRESS_MASK_REQUEST:
		messageTypeAsString = "Address mask request";
		break;
	case ICMP_ADDRESS_MASK_REPLY:
		messageTypeAsString = "Address mask reply";
		break;
	default:
		messageTypeAsString = "Unknown";
		break;
	}

	std::ostringstream typeStream;
	typeStream << (int)getIcmpHeader()->type;

	return "ICMP Layer, " + messageTypeAsString + " (type: " + typeStream.str() + ")";
}
Example #15
0
int processPacket (struct pcap_pkthdr *h,	/* Captured stuff */
		u_char *pp,			/* packet pointer */
		nfs_pkt_t *record
		)
{
	struct	ip	*ip_b		= NULL;
	struct	tcphdr	*tcp_b		= NULL;
	struct	udphdr	*udp_b		= NULL;
	u_int32_t	tot_len		= h->caplen;
	u_int32_t	consumed	= 0;
	u_int32_t	src_port	= 0;
	u_int32_t	dst_port	= 0;
	u_int16_t	id;
	int	e_len, i_len, h_len;
	u_int32_t	rpc_len;
	unsigned int	length;
	u_int32_t srcHost, dstHost;
	unsigned int proto;

	if (OutFile == NULL) {
		OutFile = stdout;
	}

	/*
	 * It doesn't make any sense to run this program with a small
	 * caplen (aka snap length) because the important stuff will
	 * get lost.
	 *
	 * Too-short packets *should* never happen, since the min
	 * packet length is longer than this, but it's always better
	 * to be safe than to be sucker-punched by a bug elsewhere...
	 */

	if (tot_len <= (MIN_ETHER_HDR_LEN + MIN_IP_HDR_LEN + MIN_UDP_HDR_LEN)) {
		return (0);
	}

	e_len = getEtherHeader (tot_len, pp, &proto, &length);
	if (e_len <= 0) {
		return (-1);
	}
	consumed += e_len;

	/*
	 * If the type of the packet isn't IP, then we're not
	 * interested in it-- chuck it now.
	 *
	 * Note-- ordinarily by the time we get here, we've already
	 * filtered out the packets using a pattern in the pcap
	 * library, so this shouldn't happen (unless we are running
	 * off a capture of the entire traffic on the wire).
	 */

	if (proto != 0x0800) {
		return (0);
	}

	ip_b = (struct ip *) (pp + e_len);

	i_len = getIpHeader (ip_b, &proto, &id, &length, &srcHost, &dstHost);
	if (i_len <= 0) {
		return (-2);
	}

	record->ipLen = length;
	record->ipIdentifier = id;

	consumed += i_len;

	/*
	 * Truncated packet-- what's up with that?  At this point,
	 * this can only happen if the packet is very short and the IP
	 * options are very long.  Still, must be cautious...
	 */

	if (consumed >= tot_len) {
		return (0);
	}

	if (proto == IPPROTO_TCP) {
		if (consumed + MIN_TCP_HDR_LEN >= tot_len) {
/* 			fprintf (OutFile, "XX 1: TCP pkt too short.\n"); */
			return (0);
		}

		tcp_b = (struct tcphdr *) (pp + consumed);
		h_len = getTcpHeader (tcp_b);
		if (h_len <= 0) {
/* 			fprintf (OutFile, "XX 2: TCP header error\n"); */
			return (-3);
		}

		consumed += h_len;
		if (consumed >= tot_len) {
/* 			fprintf (OutFile, */
/* 			"XX 3: Dropped (consumed = %d, tot_len = %d)\n", */
/* 					consumed, tot_len); */
			return (0);
		}

		h_len += sizeof (u_int32_t);

		src_port = ntohs (tcp_b->th_sport);
		dst_port = ntohs (tcp_b->th_dport);
		record->ipProto = 'T';

	}
	else if (proto == IPPROTO_UDP) {
		if (consumed + MIN_UDP_HDR_LEN >= tot_len) {
			return (0);
		}

		udp_b = (struct udphdr *) (pp + consumed);
		h_len = getUdpHeader (udp_b);
		if (h_len <= 0) {
			return (-4);
		}

		consumed += h_len;
		if (consumed >= tot_len) {
			return (0);
		}

		src_port = ntohs (udp_b->uh_sport);
		dst_port = ntohs (udp_b->uh_dport);

		rpc_len = tot_len - consumed;
		record->ipProto = 'U';

	}
	else if (proto == IPPROTO_ICMP) {
		struct icmp *icmp_b;

		if (consumed + sizeof(struct icmp) >= tot_len) {
			return (0);
		}

		icmp_b = (struct icmp *) (pp + consumed);
		h_len = getIcmpHeader (icmp_b);
		record->ipProto = 'C';
		record->icmpType = icmp_b->icmp_type;

		if (icmp_b->icmp_type == ICMP_ECHO) {
			memmove(record->icmpPayload,
				(pp + consumed + sizeof(struct icmp)), 16);
		}
	}
	else {

		/* 
		 * If it's not TCP, UPD, or ICMP, then no matter what
		 * it is, we don't care about it, so just ignore it.
		 */

/* 		fprintf (OutFile, "XX 5: Not TCP or UDP.\n"); */
		return (0);
	}

	/*
	 * If we get to this point, there's a good chance this packet
	 * contains something interesting, so we start filling in the
	 * fields of the record immediately.
	 */

	record->secs	= h->ts.tv_sec;
	record->usecs	= h->ts.tv_usec;
	record->srcHost	= srcHost;
	record->dstHost	= dstHost;
	record->srcPort	= src_port;
	record->dstPort	= dst_port;
	record->ipLen   = length;

	printPacketHeader(record, stdout);

	return 0;

}