Ejemplo n.º 1
0
static uint8_t *
tcpeek_disassemble_ip(const uint8_t *packet, uint16_t plen, int datalink, struct tcpeek_segment_ip *dst) {
	struct ip *ip;
	uint16_t hlen, sum;

	ip = (struct ip *)tcpeek_disassemble_datalink(packet, plen, datalink, &dst->datalink);
	if(!ip) {
		return NULL;
	}
	plen -= (caddr_t)ip - (caddr_t)packet;
	if(plen < sizeof(struct ip)) {
		return NULL;
	}
	hlen = ip->ip_hl << 2;
	if(plen < hlen || plen < ntohs(ip->ip_len)) {
		return NULL;
	}
	if(g.option.checksum & TCPEEK_CKSUM_IP) {
		sum = cksum16((uint16_t *)ip, hlen, 0);
		if(sum != 0) {
			lprintf(LOG_WARNING, "%s [warning] IP checksum error. %04X (%04X)", __func__, sum, ip->ip_sum);
			return NULL;
		}
	}
	if(ip->ip_p != IPPROTO_TCP && (g.option.icmp ? ip->ip_p != IPPROTO_ICMP : 1)) {
		return NULL;
	}
	memcpy(&dst->hdr, ip, sizeof(struct ip));
	return (uint8_t *)((caddr_t)ip + hlen);
}
Ejemplo n.º 2
0
void IPv4Checksum::update_(Packet *pkt) const {
  char buffer[60];
  PHV *phv = pkt->get_phv();
  Header &ipv4_hdr = phv->get_header(header_id);
  if (!ipv4_hdr.is_valid()) return;
  Field &ipv4_cksum = ipv4_hdr[field_offset];
  ipv4_hdr.deparse(buffer);
  buffer[IPV4_CKSUM_OFFSET] = 0; buffer[IPV4_CKSUM_OFFSET + 1] = 0;
  uint16_t cksum = cksum16(buffer, ipv4_hdr.get_nbytes_packet());
  // cksum is in network byte order
  ipv4_cksum.set_bytes(reinterpret_cast<char *>(&cksum), 2);
}
Ejemplo n.º 3
0
bool
IPv4Checksum::verify_(const Packet &pkt) const {
  char buffer[60];
  const PHV &phv = *(pkt.get_phv());
  const Header &ipv4_hdr = phv.get_header(header_id);
  if (!ipv4_hdr.is_valid()) return true;  // return true if no header... TODO ?
  const Field &ipv4_cksum = ipv4_hdr[field_offset];
  ipv4_hdr.deparse(buffer);
  buffer[IPV4_CKSUM_OFFSET] = 0; buffer[IPV4_CKSUM_OFFSET + 1] = 0;
  uint16_t cksum = cksum16(buffer, ipv4_hdr.get_nbytes_packet());
  // TODO(antonin): improve this?
  return !memcmp(reinterpret_cast<char *>(&cksum),
                 ipv4_cksum.get_bytes().data(), 2);
}
Ejemplo n.º 4
0
static uint8_t *
tcpeek_disassemble_tcp(const uint8_t *packet, uint16_t plen, int datalink, struct tcpeek_segment_tcp *dst) {
	uint8_t *payload;
	struct tcphdr *tcphdr;
	uint16_t hlen, tcplen, sum;
	struct ip *ip;
	uint32_t pseudo = 0;

	payload = tcpeek_disassemble_ip(packet, plen, datalink, &dst->ip);
	if(!payload) {
		return NULL;
	}
	if(dst->ip.hdr.ip_p == IPPROTO_ICMP) {
		return payload;
	}
	tcphdr = (struct tcphdr *)payload;
	if(!tcphdr) {
		return NULL;
	}
	plen -= (caddr_t)tcphdr - (caddr_t)packet;
	if(plen < sizeof(struct tcphdr)) {
		return NULL;
	}
	hlen = tcphdr->th_off << 2;
	if(plen < hlen) {
		return NULL;
	}
	ip = &dst->ip.hdr;
	tcplen = ntohs(ip->ip_len) - (ip->ip_hl << 2);
	if(g.option.checksum & TCPEEK_CKSUM_TCP) {
		pseudo += ip->ip_src.s_addr >> 16;
		pseudo += ip->ip_src.s_addr & 0xffff;
		pseudo += ip->ip_dst.s_addr >> 16;
		pseudo += ip->ip_dst.s_addr & 0xffff;
		pseudo += htons(IPPROTO_TCP);
		pseudo += htons(tcplen);
		sum = cksum16((uint16_t *)tcphdr, tcplen, pseudo);
		if(sum != 0) {
			lprintf(LOG_WARNING, "%s [warning] TCP checksum error. %04X (%04X)", __func__, sum, tcphdr->th_sum);
			return NULL;
		}
	}