static unsigned int mroute_extract_addr_arp (struct mroute_addr *src, struct mroute_addr *dest, const struct buffer *buf) { unsigned int ret = 0; if (BLEN (buf) >= (int) sizeof (struct openvpn_arp)) { const struct openvpn_arp *arp = (const struct openvpn_arp *) BPTR (buf); if (arp->mac_addr_type == htons(0x0001) && arp->proto_addr_type == htons(0x0800) && arp->mac_addr_size == 0x06 && arp->proto_addr_size == 0x04) { mroute_get_in_addr_t (src, arp->ip_src, MR_ARP); mroute_get_in_addr_t (dest, arp->ip_dest, MR_ARP); /* multicast packet? */ if (mroute_is_mcast (arp->ip_dest)) ret |= MROUTE_EXTRACT_MCAST; ret |= MROUTE_EXTRACT_SUCCEEDED; } } return ret; }
unsigned int mroute_extract_addr_ipv4 (struct mroute_addr *src, struct mroute_addr *dest, const struct buffer *buf) { unsigned int ret = 0; if (BLEN (buf) >= 1) { switch (OPENVPN_IPH_GET_VER (*BPTR(buf))) { case 4: if (BLEN (buf) >= (int) sizeof (struct openvpn_iphdr)) { const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR (buf); mroute_get_in_addr_t (src, ip->saddr, 0); mroute_get_in_addr_t (dest, ip->daddr, 0); /* multicast packet? */ if (mroute_is_mcast (ip->daddr)) ret |= MROUTE_EXTRACT_MCAST; /* IGMP message? */ if (ip->protocol == OPENVPN_IPPROTO_IGMP) ret |= MROUTE_EXTRACT_IGMP; ret |= MROUTE_EXTRACT_SUCCEEDED; } break; case 6: if (BLEN (buf) >= (int) sizeof (struct openvpn_ipv6hdr)) { const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR (buf); #if 0 /* very basic debug */ struct gc_arena gc = gc_new (); msg( M_INFO, "IPv6 packet! src=%s, dst=%s", print_in6_addr( ipv6->saddr, 0, &gc ), print_in6_addr( ipv6->daddr, 0, &gc )); gc_free (&gc); #endif mroute_get_in6_addr (src, ipv6->saddr, 0); mroute_get_in6_addr (dest, ipv6->daddr, 0); if (mroute_is_mcast_ipv6 (ipv6->daddr)) ret |= MROUTE_EXTRACT_MCAST; ret |= MROUTE_EXTRACT_SUCCEEDED; } break; default: msg (M_WARN, "IP packet with unknown IP version=%d seen", OPENVPN_IPH_GET_VER (*BPTR(buf))); } } return ret; }
unsigned int mroute_extract_addr_ipv4 (struct mroute_addr *src, struct mroute_addr *dest, const struct buffer *buf) { unsigned int ret = 0; static bool ipv6warned = false; if (BLEN (buf) >= 1) { switch (OPENVPN_IPH_GET_VER (*BPTR(buf))) { case 4: if (BLEN (buf) >= (int) sizeof (struct openvpn_iphdr)) { const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR (buf); mroute_get_in_addr_t (src, ip->saddr, 0); mroute_get_in_addr_t (dest, ip->daddr, 0); /* multicast packet? */ if (mroute_is_mcast (ip->daddr)) ret |= MROUTE_EXTRACT_MCAST; /* IGMP message? */ if (ip->protocol == OPENVPN_IPPROTO_IGMP) ret |= MROUTE_EXTRACT_IGMP; ret |= MROUTE_EXTRACT_SUCCEEDED; } break; case 6: { if( !ipv6warned ) { msg (M_WARN, "IPv6 in tun mode is not supported in OpenVPN 2.2"); ipv6warned = true; } break; } } } return ret; }
unsigned int mroute_extract_addr_ipv4 (struct mroute_addr *src, struct mroute_addr *dest, const struct buffer *buf) { unsigned int ret = 0; if (BLEN (buf) >= 1) { switch (OPENVPN_IPH_GET_VER (*BPTR(buf))) { case 4: if (BLEN (buf) >= (int) sizeof (struct openvpn_iphdr)) { const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR (buf); mroute_get_in_addr_t (src, ip->saddr, 0); mroute_get_in_addr_t (dest, ip->daddr, 0); /* multicast packet? */ if (mroute_is_mcast (ip->daddr)) ret |= MROUTE_EXTRACT_MCAST; /* IGMP message? */ if (ip->protocol == OPENVPN_IPPROTO_IGMP) ret |= MROUTE_EXTRACT_IGMP; ret |= MROUTE_EXTRACT_SUCCEEDED; } break; case 6: { msg (M_WARN, "Need IPv6 code in mroute_extract_addr_from_packet"); break; } } } return ret; }