cycle_t make_cycle(const cyclic_group_t* group, aesrand_t *aes) { cycle_t cycle; cycle.group = group; cycle.generator = find_primroot(group, aes); cycle.offset = (uint32_t) (aesrand_getword(aes) & 0xFFFFFFFF); cycle.offset %= group->prime; return cycle; }
// Return a (random) number coprime with (p - 1) of the group, // which is a generator of the additive group mod (p - 1) static uint32_t find_primroot(const cyclic_group_t *group) { uint32_t candidate = (uint32_t) ((aesrand_getword() & 0xFFFFFFFF) % group->prime); while (check_coprime(candidate, group) != COPRIME) { ++candidate; } uint64_t retv = isomorphism(candidate, group); return retv; }
// Return a (random) number coprime with (p - 1) of the group, // which is a generator of the additive group mod (p - 1) static uint32_t find_primroot(const cyclic_group_t *group, aesrand_t *aes) { uint32_t candidate = (uint32_t) ((aesrand_getword(aes) & 0xFFFFFFFF) % group->prime); if (candidate == 0) { ++candidate; } while (check_coprime(candidate, group) != COPRIME) { ++candidate; //special case where we need to restart check from begin if(candidate >= group->prime) { candidate = 1; } } uint64_t retv = isomorphism(candidate, group); return retv; }
// global sender initialize (not thread specific) iterator_t* send_init(void) { // generate a new primitive root and starting position iterator_t *it; it = iterator_init(zconf.senders, zconf.shard_num, zconf.total_shards); // process the dotted-notation addresses passed to ZMAP and determine // the source addresses from which we'll send packets; srcip_first = inet_addr(zconf.source_ip_first); if (srcip_first == INADDR_NONE) { log_fatal("send", "invalid begin source ip address: `%s'", zconf.source_ip_first); } srcip_last = inet_addr(zconf.source_ip_last); if (srcip_last == INADDR_NONE) { log_fatal("send", "invalid end source ip address: `%s'", zconf.source_ip_last); } log_debug("send", "srcip_first: %u", srcip_first); log_debug("send", "srcip_last: %u", srcip_last); if (srcip_first == srcip_last) { srcip_offset = 0; num_src_addrs = 1; } else { uint32_t ip_first = ntohl(srcip_first); uint32_t ip_last = ntohl(srcip_last); assert(ip_first && ip_last); assert(ip_last > ip_first); uint32_t offset = (uint32_t) (aesrand_getword(zconf.aes) & 0xFFFFFFFF); srcip_offset = offset % (srcip_last - srcip_first); num_src_addrs = ip_last - ip_first + 1; } // process the source port range that ZMap is allowed to use num_src_ports = zconf.source_port_last - zconf.source_port_first + 1; log_debug("send", "will send from %i address%s on %u source ports", num_src_addrs, ((num_src_addrs ==1 ) ? "":"es"), num_src_ports); // global initialization for send module assert(zconf.probe_module); if (zconf.probe_module->global_initialize) { zconf.probe_module->global_initialize(&zconf); } // concert specified bandwidth to packet rate if (zconf.bandwidth > 0) { int pkt_len = zconf.probe_module->packet_length; pkt_len *= 8; pkt_len += 8*24; // 7 byte MAC preamble, 1 byte Start frame, // 4 byte CRC, 12 byte inter-frame gap if (pkt_len < 84*8) { pkt_len = 84*8; } if (zconf.bandwidth / pkt_len > 0xFFFFFFFF) { zconf.rate = 0; } else { zconf.rate = zconf.bandwidth / pkt_len; if (zconf.rate == 0) { log_warn("send", "bandwidth %lu bit/s is slower than 1 pkt/s, " "setting rate to 1 pkt/s", zconf.bandwidth); zconf.rate = 1; } } log_debug("send", "using bandwidth %lu bits/s, rate set to %d pkt/s", zconf.bandwidth, zconf.rate); } // Get the source hardware address, and give it to the probe // module if (!zconf.hw_mac_set) { if (get_iface_hw_addr(zconf.iface, zconf.hw_mac)) { log_fatal("send", "could not retrieve hardware address for " "interface: %s", zconf.iface); return NULL; } log_debug("send", "no source MAC provided. " "automatically detected %02x:%02x:%02x:%02x:%02x:%02x as hw " "interface for %s", zconf.hw_mac[0], zconf.hw_mac[1], zconf.hw_mac[2], zconf.hw_mac[3], zconf.hw_mac[4], zconf.hw_mac[5], zconf.iface); } log_debug("send", "source MAC address %02x:%02x:%02x:%02x:%02x:%02x", zconf.hw_mac[0], zconf.hw_mac[1], zconf.hw_mac[2], zconf.hw_mac[3], zconf.hw_mac[4], zconf.hw_mac[5]); if (zconf.dryrun) { log_info("send", "dryrun mode -- won't actually send packets"); } // initialize random validation key validate_init(); zsend.start = now(); return it; }