int main (void) { #define SIZE 100 int i; printf ("point_t points[] = {\n"); for (i=0; i < 1000; i++) { printf (" {%g,%g},", rand_within (SIZE), rand_within (SIZE)); if (i % 5 == 4) printf ("\n"); } printf ("};\n"); }
/* * Function: return_neigh_adv() * * Description: * This function returns neighbor advertisement message * And this updates the gateway information. * * Argument: * sd : socket to send arp reply message * rcveth_p : pointer to ether frame data * current_eth: current MAC address * gateway_p : pointer to IPv6 gateway information * * Return value: * None */ void return_neigh_adv(int sd, struct eth_frame *rcveth_p, struct ip6_gateway_info *gateway_p) { int retval; struct ip6_datagram *rcvip6_p; /* IPv6 part of receiving frame */ struct neighbor_sol *rcvns_p; /* NS part of receiving frame */ unsigned char new_hd_addr[ETH_ALEN]; /* new MAC address */ struct in6_addr new_nexthop; /* new next hop */ size_t sndeth_size; /* size of sending frame */ struct eth_frame sndeth; /* sending frame */ struct ip6_datagram *sndip6_p; /* IPv6 part of sending frame */ struct pseudo_ip6_datagram p_ip6; /* pseudo IP header */ struct neighbor_adv *sndna_p; /* NA part of sending frame */ rcvip6_p = (struct ip6_datagram *)&(rcveth_p->data); rcvns_p = (struct neighbor_sol *)&(rcvip6_p->payload); /* If NS is DAD NS, do nothing */ if (memcmp (&(rcvip6_p->hdr.ip6_src), &in6addr_any, sizeof(struct in6_addr)) == 0) { if (debug) { fprintf(stderr, "Received NS is a DAD NS\n"); return; } } /* Update the gateway information */ memset(new_hd_addr, '\0', ETH_ALEN); /* MAC address */ for (;;) { new_hd_addr[3] = rand_within(0, 254); new_hd_addr[4] = rand_within(0, 254); new_hd_addr[5] = rand_within(1, 254); if (memcmp(gateway_p->hd_addr, new_hd_addr, ETH_ALEN)) { memcpy(gateway_p->hd_addr, new_hd_addr, ETH_ALEN); break; } } gateway_p->ip_addr = rcvns_p->defs.nd_ns_target; /* IP address */ for (;;) { /* next hop */ memset(&new_nexthop, '\0', sizeof(struct in6_addr)); new_nexthop.s6_addr[0] = 0xfe; new_nexthop.s6_addr[1] = 0x80; new_nexthop.s6_addr[15] = rand_within(1, 254); if (memcmp (&(gateway_p->nexthop), &new_nexthop, sizeof(struct in6_addr))) { gateway_p->nexthop = new_nexthop; break; } } /* Build a frame to send */ sndeth_size = sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + sizeof(struct neighbor_adv); memset(&sndeth, '\0', sizeof(struct eth_frame)); sndip6_p = (struct ip6_datagram *)&(sndeth.data); sndna_p = (struct neighbor_adv *)&(sndip6_p->payload); /* Ether */ memcpy(sndeth.hdr.h_dest, rcvns_p->src_laddr, ETH_ALEN); memcpy(sndeth.hdr.h_source, gateway_p->hd_addr, ETH_ALEN); sndeth.hdr.h_proto = htons(ETH_P_IPV6); /* IPv6 */ sndip6_p->hdr.ip6_vfc = 6 << 4; sndip6_p->hdr.ip6_flow |= 0; sndip6_p->hdr.ip6_plen = htons(sizeof(struct neighbor_adv)); sndip6_p->hdr.ip6_nxt = IPPROTO_ICMPV6; sndip6_p->hdr.ip6_hlim = 255; sndip6_p->hdr.ip6_src = gateway_p->ip_addr; sndip6_p->hdr.ip6_dst = rcvip6_p->hdr.ip6_src; /* Neighbor Advertisement */ sndna_p->defs.nd_na_type = ND_NEIGHBOR_ADVERT; sndna_p->defs.nd_na_code = 0; sndna_p->defs.nd_na_cksum = 0; /* Calculate later */ sndna_p->defs.nd_na_target = gateway_p->ip_addr; sndna_p->defs.nd_na_flags_reserved = ND_NA_FLAG_ROUTER | ND_NA_FLAG_SOLICITED | ND_NA_FLAG_OVERRIDE; sndna_p->tla_opt.nd_opt_type = ND_OPT_TARGET_LINKADDR; sndna_p->tla_opt.nd_opt_len = 1; memcpy(sndna_p->tgt_laddr, &(gateway_p->hd_addr), ETH_ALEN); /* Pseudo IPv6 datagram for checksum calculation */ memset(&p_ip6, '\0', sizeof(struct pseudo_ip6_datagram)); p_ip6.hdr.p_ip6_src = sndip6_p->hdr.ip6_src; p_ip6.hdr.p_ip6_dst = sndip6_p->hdr.ip6_dst; p_ip6.hdr.p_ip6_plen = sndip6_p->hdr.ip6_plen; p_ip6.hdr.p_ip6_zero1 = 0; p_ip6.hdr.p_ip6_zero2 = 0; p_ip6.hdr.p_ip6_nxt = sndip6_p->hdr.ip6_nxt; memcpy(p_ip6.payload, sndna_p, sizeof(struct neighbor_adv)); /* Calculate checksum */ sndna_p->defs.nd_na_cksum = calc_checksum((u_int16_t *) (&p_ip6), sizeof(struct pseudo_ip6_hdr) + sizeof(struct neighbor_adv)); /* Send Neighbor Advertisement reply */ retval = write(sd, &sndeth, sndeth_size); if (retval != sndeth_size) fatal_error("write()"); }
/* * Function: return_arp_reply() * * Description: * This function returns arp reply message to arp request message. * And it updates the IPv4 gateway information. * * Argument: * sd : socket to send arp reply message * rcveth_p : pointer to ether frame data * gateway_p : pointer to IPv4 gateway information * * Return value: * None */ void return_arp_reply(int sd, struct eth_frame *rcveth_p, struct ip4_gateway_info *gateway_p) { int retval; struct arp_datagram *rcvarp_p; /* ARP part of receiving frame */ unsigned char new_hd_addr[ETH_ALEN]; /* New MAC address */ unsigned char new_nexthop[4]; /* New next hop */ size_t sndeth_size; /* Size of sending frame */ struct eth_frame sndeth; /* sending frame */ struct arp_datagram *sndarp_p; /* ARP part of sending frame */ rcvarp_p = (struct arp_datagram *)&(rcveth_p->data); /* If arp message is not arp request, do nothing */ if (debug) fprintf(stderr, "ARP OP code is %02x\n", ntohs(rcvarp_p->hdr.ar_op)); if (rcvarp_p->hdr.ar_op != htons(ARPOP_REQUEST)) return; /* Update the gateway information */ memset(new_hd_addr, '\0', ETH_ALEN); /* MAC address */ for (;;) { new_hd_addr[3] = rand_within(0, 254); new_hd_addr[4] = rand_within(0, 254); new_hd_addr[5] = rand_within(1, 254); if (memcmp(gateway_p->hd_addr, new_hd_addr, ETH_ALEN)) { memcpy(gateway_p->hd_addr, new_hd_addr, ETH_ALEN); break; } } memcpy(gateway_p->ip_addr, rcvarp_p->ar_tip, 4); /* IP address */ for (;;) { /* next hop */ memcpy(new_nexthop, gateway_p->ip_addr, 4); new_nexthop[3] = rand_within(1, 254); if (memcmp(gateway_p->nexthop, new_nexthop, 4)) { memcpy(gateway_p->nexthop, new_nexthop, 4); break; } } /* Build a frame to send */ memset(&sndeth, '\0', sizeof(struct eth_frame)); sndarp_p = (struct arp_datagram *)&(sndeth.data); sndeth_size = sizeof(struct ethhdr) + sizeof(struct arp_datagram); /* Ether */ memcpy(sndeth.hdr.h_dest, rcveth_p->hdr.h_source, ETH_ALEN); memcpy(sndeth.hdr.h_source, gateway_p->hd_addr, ETH_ALEN); sndeth.hdr.h_proto = htons(ETH_P_ARP); /* Arp */ sndarp_p->hdr.ar_hrd = htons(ARPHRD_ETHER); sndarp_p->hdr.ar_pro = htons(ETH_P_IP); sndarp_p->hdr.ar_hln = ETH_ALEN; sndarp_p->hdr.ar_pln = 4; sndarp_p->hdr.ar_op = htons(ARPOP_REPLY); memcpy(sndarp_p->ar_sha, gateway_p->hd_addr, ETH_ALEN); memcpy(sndarp_p->ar_sip, gateway_p->ip_addr, 4); memcpy(sndarp_p->ar_tha, rcvarp_p->ar_sha, ETH_ALEN); memcpy(sndarp_p->ar_tip, rcvarp_p->ar_sip, 4); /* Send ARP reply */ retval = write(sd, &sndeth, sndeth_size); if (retval != sndeth_size) fatal_error("write()"); }