struct proto_process_stack *core_stack_backup(struct proto_process_stack *stack, struct packet* old_pkt, struct packet *new_pkt) { struct proto_process_stack *new_stack = malloc(sizeof(struct proto_process_stack) * (CORE_PROTO_STACK_MAX + 2)); if (!new_stack) { pom_oom(sizeof(struct proto_process_stack) * (CORE_PROTO_STACK_MAX + 2)); return NULL; } memcpy(new_stack, stack, sizeof(struct proto_process_stack) * (CORE_PROTO_STACK_MAX + 2)); int i; for (i = 0; i < CORE_PROTO_STACK_MAX + 2; i++) { // Clone pkt_info if (stack[i].proto && stack[i].pkt_info) { new_stack[i].pkt_info = packet_info_pool_clone(stack[i].proto, stack[i].pkt_info); if (!new_stack[i].pkt_info) { for (; i; i--) { if (new_stack[i].pkt_info) packet_info_pool_release(new_stack[i].pkt_info, stack[i].proto->id); } free(new_stack); return NULL; } } // Adjust pload pointer if (stack[i].pload && old_pkt->buff != new_pkt->buff) new_stack[i].pload = new_pkt->buff + (stack[i].pload - old_pkt->buff); } return new_stack; }
void core_stack_release(struct proto_process_stack *stack) { int i; for (i = 1; i < CORE_PROTO_STACK_MAX && stack[i].proto; i++) packet_info_pool_release(stack[i].pkt_info, stack[i].proto->id); free(stack); }
static void packet_stream_free_packet(struct packet_stream_pkt *p) { int i; for (i = 1; i < CORE_PROTO_STACK_MAX && p->stack[i].proto; i++) packet_info_pool_release(&p->stack[i].proto->pkt_info_pool, p->stack[i].pkt_info); free(p->stack); packet_pool_release(p->pkt); free(p); }
int core_process_packet_stack(struct proto_process_stack *stack, unsigned int stack_index, struct packet *p) { unsigned int i; int res = PROTO_OK; for (i = stack_index; i < CORE_PROTO_STACK_MAX - CORE_PROTO_STACK_START; i++) { proto_process_pload_listeners(p, stack, i - 1); struct proto_process_stack *s = &stack[i]; if (!s->proto) break; if (s->proto->info->pkt_fields) { if (s->pkt_info) pomlog(POMLOG_WARN "Packet info already allocated !"); s->pkt_info = packet_info_pool_get(s->proto); } res = proto_process(p, stack, i); if (res == PROTO_ERR) pomlog(POMLOG_ERR "Error while processing packet for proto %s", s->proto->info->name); if (res < 0) break; struct proto_process_stack *s_next = &stack[i + 1]; if (!s_next->pload || !s_next->plen) break; } for (; i >= stack_index; i--) { if (!stack[i].proto) continue; if (res >= 0) { if (proto_post_process(p, stack, i) == POM_ERR) { pomlog(POMLOG_ERR "Error while post processing packet for proto %s", stack[stack_index].proto->info->name); res = PROTO_ERR; } } if (stack[i].ce) conntrack_refcount_dec(stack[i].ce); packet_info_pool_release(stack[i].pkt_info, stack[i].proto->id); } return res; }
struct packet_info *packet_info_pool_clone(struct proto *p, struct packet_info *info) { struct packet_info *new_info = packet_info_pool_get(p); if (!new_info) return NULL; struct proto_pkt_field *fields = p->info->pkt_fields; int i; for (i = 0; fields[i].name; i++) { if (ptype_copy(new_info->fields_value[i], info->fields_value[i]) != POM_OK) { packet_info_pool_release(new_info, p->id); return NULL; } } return new_info; }