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; }
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; }