- /* Check if it is for our own subnet */
-
- if(subnet->owner == myself)
- return; /* silently ignore */
-
- /* Create neighbor advertation reply */
-
- memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */
- packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
-
- memcpy(&hdr->ip6_dst, &hdr->ip6_src, 16); /* swap destination and source protocol address */
- memcpy(&hdr->ip6_src, &ns->nd_ns_target, 16); /* ... */
-
- memcpy((char *) opt + sizeof(*opt), packet->data + ETHER_ADDR_LEN, 6); /* add fake source hard addr */
-
- ns->nd_ns_hdr.icmp6_cksum = 0;
- ns->nd_ns_hdr.icmp6_type = ND_NEIGHBOR_ADVERT;
- ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[0] = 0x40; /* Set solicited flag */
- ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[1] =
- ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[2] =
- ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[3] = 0;
- opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
-
- /* Create pseudo header */
-
- memcpy(&pseudo.ip6_src, &hdr->ip6_src, 16);
- memcpy(&pseudo.ip6_dst, &hdr->ip6_dst, 16);
- pseudo.length = htonl(sizeof(*ns) + sizeof(*opt) + 6);
- pseudo.junk[0] = pseudo.junk[1] = pseudo.junk[2] = 0;
- pseudo.junk[3] = IPPROTO_ICMPV6;
-
- /* Generate checksum */
-
- checksum = inet_checksum((uint16_t *) & pseudo, sizeof(pseudo) / 2, ~0);
- checksum = inet_checksum((uint16_t *) ns, sizeof(*ns) / 2 + 4, checksum);
-
- ns->nd_ns_hdr.icmp6_cksum = htons(checksum);
-
- write_packet(packet);
-}
-
-void route_arp(vpn_packet_t * packet)
-{
- struct ether_arp *arp;
- subnet_t *subnet;
- uint8_t ipbuf[4];
-
- cp();
-
- /* First, snatch the source address from the ARP packet */
-
- memcpy(mymac.net.mac.address.x, packet->data + 6, 6);
-
- /* This routine generates replies to ARP requests.
- You don't need to set NOARP flag on the interface anymore (which is broken on FreeBSD).
- Most of the code here is taken from choparp.c by Takamichi Tateoka (tree@mma.club.uec.ac.jp)
- */
-
- arp = (struct ether_arp *) (packet->data + 14);
-
- /* Check if this is a valid ARP request */
-
- if(ntohs(arp->arp_hrd) != ARPHRD_ETHER || ntohs(arp->arp_pro) != ETHERTYPE_IP ||
- arp->arp_hln != ETHER_ADDR_LEN || arp->arp_pln != 4 || ntohs(arp->arp_op) != ARPOP_REQUEST) {
- if(debug_lvl > DEBUG_TRAFFIC) {
- syslog(LOG_WARNING, _("Cannot route packet: received unknown type ARP request"));
- }