示例#1
0
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()");
}