Example #1
0
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;
}
Example #2
0
/*
 * If raw tunnel packet is IPv4, return true and increment
 * buffer offset to start of IP header.
 */
bool
is_ipv4 (int tunnel_type, struct buffer *buf)
{
  int offset;
  const struct openvpn_iphdr *ih;

  verify_align_4 (buf);
  if (tunnel_type == DEV_TYPE_TUN)
    {
      if (BLEN (buf) < (int) sizeof (struct openvpn_iphdr))
	return false;
      offset = 0;
    }
  else if (tunnel_type == DEV_TYPE_TAP)
    {
      const struct openvpn_ethhdr *eh;
      if (BLEN (buf) < (int)(sizeof (struct openvpn_ethhdr)
	  + sizeof (struct openvpn_iphdr)))
	return false;
      eh = (const struct openvpn_ethhdr *) BPTR (buf);
      if (ntohs (eh->proto) != OPENVPN_ETH_P_IPV4)
	return false;
      offset = sizeof (struct openvpn_ethhdr);
    }
  else
    return false;

  ih = (const struct openvpn_iphdr *) (BPTR (buf) + offset);

  if (OPENVPN_IPH_GET_VER (ih->version_len) == 4)
    return buf_advance (buf, offset);
  else
    return false;
}
Example #3
0
/*
 * If raw tunnel packet is IPv<X>, return true and increment
 * buffer offset to start of IP header.
 */
static
bool
is_ipv_X( int tunnel_type, struct buffer *buf, int ip_ver )
{
    int offset;
    const struct openvpn_iphdr *ih;

    verify_align_4(buf);
    if (tunnel_type == DEV_TYPE_TUN)
    {
    	//tun类型,不包含以太头
        if (BLEN(buf) < (int) sizeof(struct openvpn_iphdr))
        {
            return false;
        }
        offset = 0;
    }
    else if (tunnel_type == DEV_TYPE_TAP)
    {
    	//tap类型,包含以太头
        const struct openvpn_ethhdr *eh;
        if (BLEN(buf) < (int)(sizeof(struct openvpn_ethhdr)
                              + sizeof(struct openvpn_iphdr)))
        {
            return false;
        }
        eh = (const struct openvpn_ethhdr *) BPTR(buf);
        if (ntohs(eh->proto) != (ip_ver == 6 ? OPENVPN_ETH_P_IPV6 : OPENVPN_ETH_P_IPV4))
        {
        	//非指定协议,返回false
            return false;
        }
        offset = sizeof(struct openvpn_ethhdr);
    }
    else
    {
        return false;
    }

    //指向ip头部
    ih = (const struct openvpn_iphdr *) (BPTR(buf) + offset);

    /* IP version is stored in the same bits for IPv4 or IPv6 header */
    if (OPENVPN_IPH_GET_VER(ih->version_len) == ip_ver)
    {
    	//为对应ip协议,使buf指向对应的ip头部
        return buf_advance(buf, offset);
    }
    else
    {
    	//非对应的ip协议,返回false
        return false;
    }
}
Example #4
0
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;
}
Example #5
0
File: proto.c Project: jmadhav/lib
/*
 * If raw tunnel packet is IPv4, return true and increment
 * buffer offset to start of IP header.
 */
bool
is_ipv4 (int tunnel_type, struct buffer *buf)
{
  int offset;
  const struct openvpn_iphdr *ih;

  verify_align_4 (buf);
  if (tunnel_type == DEV_TYPE_TUN)
    {
      if (BLEN (buf) < (int) sizeof (struct openvpn_iphdr))
	return false;
      offset = 0;
    }
  else if (tunnel_type == DEV_TYPE_TAP)
    {
      const struct openvpn_ethhdr *eh;
      if (BLEN (buf) < (int)(sizeof (struct openvpn_ethhdr)
	  + sizeof (struct openvpn_iphdr)))
	return false;
      eh = (const struct openvpn_ethhdr *) BPTR (buf);
      if (ntohs (eh->proto) != OPENVPN_ETH_P_IPV4)
	return false;
      offset = sizeof (struct openvpn_ethhdr);
    }
  else
    return false;

  ih = (const struct openvpn_iphdr *) (BPTR (buf) + offset);

  if (OPENVPN_IPH_GET_VER (ih->version_len) == 4)
  {	
	 /* struct	in_addr x,y;
	  x.s_addr = ih->saddr;
	  y.s_addr = ih->daddr;
	  
    printf("\n src=%s,dest=%s", inet_ntoa(x),inet_ntoa(y));*/
	  return buf_advance (buf, offset);
  }  
  else
    return false;
}
Example #6
0
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;
}