Example #1
0
int ars_seems_ip(struct ars_iphdr *ip, size_t size)
{
	if (ip->version == 4 &&
	    ip->ihl >= 5 &&
	    (ip->ihl << 2) <= size &&
	    ars_check_ip_cksum(ip) == 1)
		return 1;
	return 0;
}
Example #2
0
int ars_split_ip(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len)
{
	struct ars_iphdr *ip = packet, *newip;
	int flags = 0;
	int ipsize = ip->ihl << 2;

	/* Check for bad header size and checksum */
	if (size < ipsize) {
		flags |= ARS_SPLIT_FTRUNC;
		ipsize = size;
	}
	else if (ars_check_ip_cksum(ip) == 0)
		flags |= ARS_SPLIT_FBADCKSUM;
	ipsize = MIN(ipsize, 20);

	if ((newip = ars_add_iphdr(pkt, 0)) == NULL)
		return -ARS_NOMEM;
	memcpy(newip, ip, ipsize);
	ars_set_flags(pkt, ARS_LAST_LAYER, flags);

	*len = ipsize;

	if (flags & ARS_SPLIT_FTRUNC) {
		*state = ARS_SPLIT_GET_DATA;
		return -ARS_OK;
	}

	if (ip->ihl > 5) { /* IP options */
		*state = ARS_SPLIT_GET_IPOPT;
		pkt->aux = (ip->ihl - 5) << 2;
		return -ARS_OK;
	}

	switch(ip->protocol) {
	case ARS_IPPROTO_IPIP:
		*state = ARS_SPLIT_GET_IP;
		break;
	case ARS_IPPROTO_ICMP:
		*state = ARS_SPLIT_GET_ICMP;
		break;
	case ARS_IPPROTO_TCP:
		*state = ARS_SPLIT_GET_TCP;
		break;
	case ARS_IPPROTO_UDP:
		*state = ARS_SPLIT_GET_UDP;
		break;
	default:
		*state = ARS_SPLIT_GET_DATA;
		break;
	}
	return -ARS_OK;
}
Example #3
0
int ars_split_ip(struct ars_packet *pkt, void *packet, size_t size, int *state, int *len)
{
	struct ars_iphdr *ip = packet, *newip;
	int flags = 0;
	int ipsize;
	

	/* Check for bad header size and checksum */
	if (size < sizeof(struct ars_iphdr)) {
		flags |= ARS_SPLIT_FTRUNC;
		ipsize = size;
	} else {
		ipsize = ip->ihl << 2;
		if (size < ipsize) {
			flags |= ARS_SPLIT_FTRUNC;
			ipsize = size;
		}
		else if (ip->ihl < 4 || ars_check_ip_cksum(ip) == 0)
			flags |= ARS_SPLIT_FBADCKSUM;
		ipsize = MIN(ipsize, 20);
	}
	if ((newip = ars_add_iphdr(pkt, 0)) == NULL)
		return -ARS_NOMEM;

	memcpy(newip, ip, ipsize);
	ars_set_flags(pkt, ARS_LAST_LAYER, flags);
	*len = ipsize;

	if (flags & ARS_SPLIT_FTRUNC) {
		*state = ARS_SPLIT_GET_DATA;
		return -ARS_OK;
	}

	if (ip->ihl > 5) { /* IP options */
		/* IP protocol saved so after the IP option
		 * processing we can start with the right status */
		pkt->aux_ipproto = ip->protocol;
		*state = ARS_SPLIT_GET_IPOPT;
		pkt->aux = (ip->ihl - 5) << 2;
		return -ARS_OK;
	}
	ars_ip_next_state(ip->protocol, state);
	return -ARS_OK;
}