void set_grid_direction_1(Graph *graph, Vertex *v, int *marks) { int i; Vertex *next_v; Arc *via; // this procedure marks the link arc from v to its adjacencies. // these marks serve to retain all non-visited arcs for further // orientation step(s) for (i = 0; i < v->nb_adjacencies; i++) { // next adjacency via = graph->arcs[v->adjacent_arcs[i]]; next_v = via->source == v->id ? graph->vertices[via->target] : graph->vertices[via->source]; if (!marks[via->id]) { marks[via->id] = 1; // direction father->son // the vertex `v` should be the source of via if (via->source != v->id) { reverse_direction(via); } set_grid_direction_1(graph, next_v, marks); } } }
static string origin_direction(string direction) { switch (direction) { case "up": return "below"; case "down": return "above"; default: return "the " + reverse_direction(direction); } }
void patch_multiarcs(Graph *graph, float percentage, int nb_lanes_max) { int i; int random_id; int new_arc_id; Arc *random_arc; int nb_arcs_to_add; int arcs_cnt = 0; int *lanes_cnt = (int *)malloc(sizeof(int) * graph->nb_arcs); for (i = 0; i < graph->nb_arcs; i++) { lanes_cnt[i] = 0; } // percentage cannot be greater than 1 if (percentage > 1) percentage = 1; nb_arcs_to_add = (int)ceil(graph->nb_arcs * percentage); // extend the memory allocation of arcs set graph->arcs = (Arc **)realloc(graph->arcs, sizeof(Arc *) * (graph->nb_arcs + nb_arcs_to_add)); for (i = graph->nb_arcs; i < graph->nb_arcs + nb_arcs_to_add; i++) { graph->arcs[i] = (Arc *)malloc(sizeof(Arc)); } while (arcs_cnt < nb_arcs_to_add) { random_id = rand_ij(&g_default_seed, 0, graph->nb_arcs); if (lanes_cnt[random_id] >= nb_lanes_max -1) { continue; } random_arc = graph->arcs[random_id]; new_arc_id = graph->nb_arcs + arcs_cnt; // first duplicate the arc // then decide whether to reverse the direction or not set_arc_attr(graph, new_arc_id, random_arc->source, random_arc->target, random_arc->cost); if (1 == rand_ij(&g_default_seed, 0, 2)) { reverse_direction(graph->arcs[new_arc_id]); } lanes_cnt[random_id]++; arcs_cnt++; } graph->nb_arcs += nb_arcs_to_add; graph->per_multiarcs = (int) (percentage * 100); free(lanes_cnt); }
void set_grid_direction_2(Graph *graph, int *marks) { int i; Arc *arc; for (i = 0; i < graph->nb_arcs; i++) { if (!marks[i]) { arc = graph->arcs[i]; // set direction descendant->ancestor reverse_direction(arc); } } }
struct packet *new_icmp_packet(int address_family, enum direction_t direction, const char *type_string, const char *code_string, int protocol, u32 tcp_start_sequence, u32 payload_bytes, s64 mtu, char **error) { s32 type = -1; /* bad type; means "unknown so far" */ s32 code = -1; /* bad code; means "unknown so far" */ struct packet *packet = NULL; /* the newly-allocated result packet */ /* Calculate lengths in bytes of all sections of the packet. * For now we only support the most common ICMP message * format, which includes at the end the original outgoing IP * header and the first 8 bytes after that (which will * typically have the port info needed to demux the message). */ const int ip_fixed_bytes = ip_header_len(address_family); const int ip_option_bytes = 0; const int ip_header_bytes = ip_fixed_bytes + ip_option_bytes; const int echoed_bytes = ip_fixed_bytes + ICMP_ECHO_BYTES; const int icmp_bytes = icmp_header_len(address_family) + echoed_bytes; const int ip_bytes = ip_header_bytes + icmp_bytes; /* Sanity-check all the various lengths */ if (ip_option_bytes & 0x3) { asprintf(error, "IP options are not padded correctly " "to ensure IP header is a multiple of 4 bytes: " "%d excess bytes", ip_option_bytes & 0x3); goto error_out; } assert((ip_header_bytes & 0x3) == 0); /* Parse the ICMP type and code */ if (parse_icmp_type_and_code(address_family, type_string, code_string, &type, &code, error)) goto error_out; assert(is_valid_u8(type)); assert(is_valid_u8(code)); /* Allocate and zero out a packet object of the desired size */ packet = packet_new(ip_bytes); memset(packet->buffer, 0, ip_bytes); packet->ip_bytes = ip_bytes; packet->direction = direction; packet->flags = 0; packet->ecn = 0; /* Set IP header fields */ const enum ip_ecn_t ecn = ECN_NONE; set_packet_ip_header(packet, address_family, ip_bytes, direction, ecn, icmp_protocol(address_family)); /* Find the start of the ICMP header and then populate common fields. */ void *icmp_header = packet_start(packet) + ip_header_bytes; if (set_packet_icmp_header(packet, icmp_header, address_family, type, code, mtu, error)) goto error_out; /* All ICMP message types currently supported by this tool * include a copy of the outbound IP header and the first few * bytes inside. To ensure that the inbound ICMP message gets * demuxed to the correct socket in the kernel, here we * construct enough of a basic IP header and during test * execution we fill in the port numbers and (if specified) * TCP sequence number in the TCP header. */ u8 *echoed_ip = packet_echoed_ip_header(packet); const int echoed_ip_bytes = (ip_fixed_bytes + layer4_header_len(protocol) + payload_bytes); set_ip_header(echoed_ip, address_family, echoed_ip_bytes, reverse_direction(direction), ecn, protocol); if (protocol == IPPROTO_TCP) { u32 *seq = packet_echoed_tcp_seq(packet); *seq = htonl(tcp_start_sequence); } return packet; error_out: if (packet != NULL) packet_free(packet); return NULL; }