示例#1
0
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);
        }
    }
}
示例#2
0
static string origin_direction(string direction)
{
    switch (direction) {
    case "up":   return "below";
    case "down": return "above";
    default:     return "the " + reverse_direction(direction);
    }
}
示例#3
0
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);
}
示例#4
0
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);
        }
    }
}
示例#5
0
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;
}