/* Returns the protocol to connect to in case of timeout; * if not found, return the first protocol specified */ struct proto* timeout_protocol(void) { struct proto* p = get_first_protocol(); for (; p && strcmp(p->description, on_timeout); p = p->next); if (p) return p; return get_first_protocol(); }
void init_cnx(struct connection *cnx) { memset(cnx, 0, sizeof(*cnx)); cnx->q[0].fd = -1; cnx->q[1].fd = -1; cnx->proto = get_first_protocol(); }
probe_t * probe_wrap_packet(packet_t * packet) { probe_t * probe; size_t segment_size, remaining_size; layer_t * layer; uint8_t * segment; const protocol_t * protocol; if (!(probe = probe_create())) { goto ERR_PROBE_CREATE; } // Clear the probe packet_free(probe->packet); probe->packet = packet; probe_layers_clear(probe); // Prepare iteration segment = packet_get_bytes(probe->packet); remaining_size = packet_get_size(probe->packet); // Push layers for (protocol = get_first_protocol(packet); protocol; protocol = protocol->get_next_protocol(layer)) { if (remaining_size < protocol->write_default_header(NULL)) { // Not enough bytes left for the header, packet is truncated segment_size = remaining_size; } else { segment_size = protocol->get_header_size(segment); } if (!(layer = layer_create_from_segment(protocol, segment, segment_size))) { goto ERR_CREATE_LAYER; } if (!probe_push_layer(probe, layer)) { goto ERR_PUSH_LAYER; } segment += segment_size; remaining_size -= segment_size; if (remaining_size < 0) { fprintf(stderr, "probe_wrap_packet: Truncated packet\n"); goto ERR_TRUNCATED_PACKET; } if (!protocol->get_next_protocol) { break; } continue; ERR_TRUNCATED_PACKET: ERR_PUSH_LAYER: layer_free(layer); ERR_CREATE_LAYER: goto ERR_LAYER_DISCOVER_LAYER; } // Rq: Some packets (e.g ICMP type 3) do not have payload. // In this case we push an empty payload probe_push_payload(probe, remaining_size); return probe; ERR_LAYER_DISCOVER_LAYER: probe_free(probe); ERR_PROBE_CREATE: return NULL; }