static int _net_flow_src_ip_handler(flow_t * flow, flow_field_map_t * map, void * ctx) { flow_stats_t * stats= (flow_stats_t *) ctx; ip_trace_t * trace= NULL; net_error_t result; ip_opt_t opts; net_node_t * src_node= network_find_node(network_get_default(), flow->src_addr); if (src_node == NULL) { printf("Source node not found\n"); return -1; } ip_options_init(&opts); if (flow_field_map_isset(map, FLOW_FIELD_DST_MASK)) { ip_pfx_t pfx= { .network=flow->dst_addr, .mask=flow->dst_mask, }; ip_options_alt_dest(&opts, pfx); } result= node_load_flow(src_node, NET_ADDR_ANY, flow->dst_addr, flow->bytes, stats, &trace, &opts); if (result < 0) return 0; if (trace != NULL) { stream_printf(gdsout, "TRACE=["); ip_trace_dump(gdsout, trace, 0); stream_printf(gdsout, "]\n"); ip_trace_destroy(&trace); } return 0; } static int _net_flow_src_asn_handler(flow_t * flow, flow_field_map_t * map, void * ctx) { // Find source based on source ASN as_level_topo_t * topo= aslevel_get_topo(); if (topo == NULL) { printf("no AS-level topology loaded\n"); return -1; } flow->src_addr= topo->addr_mapper(flow->src_asn); return _net_flow_src_ip_handler(flow, map, ctx); }
void group_and_source_specific_query(int sockfd, struct in_addr saddr, struct in_addr daddr, struct in_addr group, struct in_addr *sources, int num_sources, int max_resp_time) { int len = sizeof(struct iphdr) + sizeof(struct ipopts) + sizeof(struct igmpv3_query) + num_sources*sizeof(__be32); unsigned char *buffer = malloc(len); if (buffer == NULL) { perror("malloc()"); exit(EXIT_FAILURE); } struct iphdr *ip_header = (struct iphdr *) buffer; struct ipopts *ip_options = (struct ipopts *)(buffer + sizeof(struct iphdr)); struct igmpv3_query *igmp_header; igmp_header = (struct igmpv3_query *) (buffer + sizeof(struct iphdr) + sizeof(struct ipopts)); ip_header_init(ip_header, saddr, daddr); ip_options_init(ip_options); igmp_header->type = IGMP_HOST_MEMBERSHIP_QUERY; igmp_header->code = max_resp_time; igmp_header->group = group.s_addr; int i; for (i = 0; i < num_sources; i++) igmp_header->srcs[i] = sources[i].s_addr; igmp_header->csum = 0; igmp_header->csum = checksum((unsigned short *) igmp_header, sizeof(struct igmpv3_query) + num_sources*sizeof(__be32)); send_ip_frame(sockfd, daddr, buffer, len); free(buffer); }
void general_query(int sockfd, struct in_addr saddr) { int len = sizeof(struct iphdr) + sizeof(struct ipopts) + sizeof(struct igmphdr); unsigned char *buffer = malloc(len); if (buffer == NULL) { perror("malloc()"); exit(EXIT_FAILURE); } struct iphdr *ip_header = (struct iphdr *) buffer; struct ipopts *ip_options = (struct ipopts *)(buffer + sizeof(struct iphdr)); struct igmphdr *igmp_header; igmp_header = (struct igmphdr *) (buffer + sizeof(struct iphdr) + sizeof(struct ipopts)); struct in_addr daddr; inet_aton("224.0.0.1", &daddr); ip_header_init(ip_header, saddr, daddr); ip_options_init(ip_options); igmp_header->type = IGMP_HOST_MEMBERSHIP_QUERY; igmp_header->code = 0; /* IGMPv1 general query */ igmp_header->group = 0; igmp_header->csum = 0; igmp_header->csum = checksum((unsigned short *) igmp_header, sizeof(struct igmphdr)); send_ip_frame(sockfd, daddr, buffer, len); free(buffer); }