Ejemplo n.º 1
0
/*
 * Zero off the host bits in an address, leaving
 * only the network bits, using the netbits member of
 * struct mroute_addr as the controlling parameter.
 *
 * TODO: this is called for route-lookup for every yet-unhashed
 * destination address, so for lots of active net-iroutes, this
 * might benefit from some "zeroize 32 bit at a time" improvements
 */
void
mroute_addr_mask_host_bits (struct mroute_addr *ma)
{
  in_addr_t addr = ntohl(*(in_addr_t*)ma->addr);
  if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
    {
      addr &= netbits_to_netmask (ma->netbits);
      *(in_addr_t*)ma->addr = htonl (addr);
    }
  else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
    {
      int byte = ma->len-1;		/* rightmost byte in address */
      int bits_to_clear = 128 - ma->netbits;

      while( byte >= 0 && bits_to_clear > 0 )
        {
	  if ( bits_to_clear >= 8 )
	    { ma->addr[byte--] = 0; bits_to_clear -= 8; }
	  else
	    { ma->addr[byte--] &= (~0 << bits_to_clear); bits_to_clear = 0; }
        }
      ASSERT( bits_to_clear == 0 );
    }
  else
      ASSERT(0);
}
Ejemplo n.º 2
0
/*
 * Zero off the host bits in an address, leaving
 * only the network bits, using the netbits member of
 * struct mroute_addr as the controlling parameter.
 *
 * TODO: this is called for route-lookup for every yet-unhashed
 * destination address, so for lots of active net-iroutes, this
 * might benefit from some "zeroize 32 bit at a time" improvements
 */
void
mroute_addr_mask_host_bits(struct mroute_addr *ma)
{
    if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
    {
        in_addr_t addr = ntohl(ma->v4.addr);
        addr &= netbits_to_netmask(ma->netbits);
        ma->v4.addr = htonl(addr);
    }
    else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
    {
        int byte = sizeof(ma->v6.addr) - 1;     /* rightmost byte in address */
        int bits_to_clear = 128 - ma->netbits;

        while (byte >= 0 && bits_to_clear > 0)
        {
            if (bits_to_clear >= 8)
            {
                ma->v6.addr.s6_addr[byte--] = 0;
                bits_to_clear -= 8;
            }
            else
            {
                ma->v6.addr.s6_addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear);
                bits_to_clear = 0;
            }
        }
        ASSERT( bits_to_clear == 0 );
    }
    else
    {
        ASSERT(0);
    }
}
Ejemplo n.º 3
0
const char *
mroute_addr_print_ex (const struct mroute_addr *ma,
		      const unsigned int flags,
		      struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (64, gc);
  if (ma)
    {
      struct mroute_addr maddr = *ma;

      switch (maddr.type & MR_ADDR_MASK)
	{
	case MR_ADDR_ETHER:
	  buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc)); 
	  break;
	case MR_ADDR_IPV4:
	  {
	    struct buffer buf;
	    in_addr_t addr;
	    int port;
	    bool status;
	    buf_set_read (&buf, maddr.addr, maddr.len);
	    addr = buf_read_u32 (&buf, &status);
	    if (status)
	      {
		if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
		  buf_printf (&out, "ARP/");
		buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
		if (maddr.type & MR_WITH_NETBITS)
		  {
		    if (flags & MAPF_SUBNET)
		      {
			const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
			buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
		      }
		    else
		      buf_printf (&out, "/%d", maddr.netbits);
		  }
	      }
	    if (maddr.type & MR_WITH_PORT)
	      {
		port = buf_read_u16 (&buf);
		if (port >= 0)
		  buf_printf (&out, ":%d", port);
	      }
	  }
	  break;
	case MR_ADDR_IPV6:
	  buf_printf (&out, "IPV6"); 
	  break;
	default:
	  buf_printf (&out, "UNKNOWN"); 
	  break;
	}
      return BSTR (&out);
    }
  else
    return "[NULL]";
}
Ejemplo n.º 4
0
/*
 * Zero off the host bits in an address, leaving
 * only the network bits, using the netbits member of
 * struct mroute_addr as the controlling parameter.
 */
void
mroute_addr_mask_host_bits (struct mroute_addr *ma)
{
  in_addr_t addr = ntohl(*(in_addr_t*)ma->addr);
  ASSERT ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4);
  addr &= netbits_to_netmask (ma->netbits);
  *(in_addr_t*)ma->addr = htonl (addr);
}
Ejemplo n.º 5
0
/*
 * Remove iroutes from the push_list.
 */
void
remove_iroutes_from_push_route_list(struct options *o)
{
    if (o && o->push_list.head && o->iroutes)
    {
        struct gc_arena gc = gc_new();
        struct push_entry *e = o->push_list.head;

        /* cycle through the push list */
        while (e)
        {
            char *p[MAX_PARMS];
            bool enable = true;

            /* parse the push item */
            CLEAR(p);
            if (e->enable
                && parse_line(e->option, p, SIZE(p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
            {
                /* is the push item a route directive? */
                if (p[0] && !strcmp(p[0], "route") && !p[3])
                {
                    /* get route parameters */
                    bool status1, status2;
                    const in_addr_t network = getaddr(GETADDR_HOST_ORDER, p[1], 0, &status1, NULL);
                    const in_addr_t netmask = getaddr(GETADDR_HOST_ORDER, p[2] ? p[2] : "255.255.255.255", 0, &status2, NULL);

                    /* did route parameters parse correctly? */
                    if (status1 && status2)
                    {
                        const struct iroute *ir;

                        /* does route match an iroute? */
                        for (ir = o->iroutes; ir != NULL; ir = ir->next)
                        {
                            if (network == ir->network && netmask == netbits_to_netmask(ir->netbits >= 0 ? ir->netbits : 32))
                            {
                                enable = false;
                                break;
                            }
                        }
                    }
                }

                /* should we copy the push item? */
                e->enable = enable;
                if (!enable)
                {
                    msg(D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option);
                }
            }

            e = e->next;
        }

        gc_free(&gc);
    }
}
Ejemplo n.º 6
0
Archivo: pf.c Proyecto: benjdag/openvpn
static bool
add_subnet(const char *line, const char *prefix, const int line_num, struct pf_subnet ***next, const bool exclude)
{
    struct in_addr network;
    in_addr_t netmask = 0;

    if (strcmp(line, "unknown"))
    {
        int netbits = 32;
        char *div = strchr(line, '/');

        if (div)
        {
            *div++ = '\0';
            if (sscanf(div, "%d", &netbits) != 1)
            {
                msg(D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: '%s'", prefix, line_num, div);
                return false;
            }
            if (netbits < 0 || netbits > 32)
            {
                msg(D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: must be between 0 and 32: '%s'", prefix, line_num, div);
                return false;
            }
        }

        if (openvpn_inet_aton(line, &network) != OIA_IP)
        {
            msg(D_PF_INFO, "PF: %s/%d: bad network address: '%s'", prefix, line_num, line);
            return false;
        }
        netmask = netbits_to_netmask(netbits);
        if ((network.s_addr & htonl(netmask)) != network.s_addr)
        {
            network.s_addr &= htonl(netmask);
            msg(M_WARN, "WARNING: PF: %s/%d: incorrect subnet %s/%d changed to %s/%d", prefix, line_num, line, netbits, inet_ntoa(network), netbits);
        }
    }
    else
    {
        /* match special "unknown" tag for addresses unrecognized by mroute */
        network.s_addr = htonl(0);
        netmask = IPV4_NETMASK_HOST;
    }

    {
        struct pf_subnet *e;
        ALLOC_OBJ_CLEAR(e, struct pf_subnet);
        e->rule.exclude = exclude;
        e->rule.network = ntohl(network.s_addr);
        e->rule.netmask = netmask;
        **next = e;
        *next = &e->next;
        return true;
    }
}
Ejemplo n.º 7
0
static const char *
print_netmask (int netbits, struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (128, gc);
  const in_addr_t netmask = netbits_to_netmask (netbits);

  buf_printf (&out, "%s (/%d)", print_in_addr_t (netmask, 0, gc), netbits);

  return BSTR (&out);
}
Ejemplo n.º 8
0
const char *
mroute_addr_print_ex (const struct mroute_addr *ma,
		      const unsigned int flags,
		      struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (64, gc);
  if (ma)
    {
      struct mroute_addr maddr = *ma;

      switch (maddr.type & MR_ADDR_MASK)
	{
	case MR_ADDR_ETHER:
	  buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc)); 
	  break;
	case MR_ADDR_IPV4:
	  {
	    struct buffer buf;
	    in_addr_t addr;
	    int port;
	    bool status;
	    buf_set_read (&buf, maddr.addr, maddr.len);
	    addr = buf_read_u32 (&buf, &status);
	    if (status)
	      {
		if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
		  buf_printf (&out, "ARP/");
		buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
		if (maddr.type & MR_WITH_NETBITS)
		  {
		    if (flags & MAPF_SUBNET)
		      {
			const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
			buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
		      }
		    else
		      buf_printf (&out, "/%d", maddr.netbits);
		  }
	      }
	    if (maddr.type & MR_WITH_PORT)
	      {
		port = buf_read_u16 (&buf);
		if (port >= 0)
		  buf_printf (&out, ":%d", port);
	      }
	  }
	  break;
	case MR_ADDR_IPV6:
#ifdef USE_PF_INET6
          {
	    struct buffer buf;
	    struct sockaddr_in6 sin6;
	    int port;
	    char buf6[INET6_ADDRSTRLEN] = "";
	    CLEAR(sin6);
	    sin6.sin6_family = AF_INET6;
	    buf_set_read (&buf, maddr.addr, maddr.len);
            if (buf_read(&buf, &sin6.sin6_addr, sizeof (sin6.sin6_addr)))
            {
              if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6),
                                      buf6, sizeof (buf6), NULL, 0, NI_NUMERICHOST) != 0)
                {
                  buf_printf (&out, "MR_ADDR_IPV6 getnameinfo() err");
                  break;
		}
              buf_puts (&out, buf6);
	      if (maddr.type & MR_WITH_NETBITS)
	        buf_printf (&out, "/%d", maddr.netbits);
              if (maddr.type & MR_WITH_PORT)
                {
                  port = buf_read_u16 (&buf);
                  if (port >= 0)
                    buf_printf (&out, ":%d", port);
                }
	    }
          }
#else /* old, pre USE_PF_INET6 code */
	  buf_printf (&out, "IPV6"); 
#endif
	  break;
	default:
	  buf_printf (&out, "UNKNOWN"); 
	  break;
	}
      return BSTR (&out);
    }
  else
    return "[NULL]";
}
Ejemplo n.º 9
0
const char *
mroute_addr_print_ex(const struct mroute_addr *ma,
                     const unsigned int flags,
                     struct gc_arena *gc)
{
    struct buffer out = alloc_buf_gc(64, gc);
    if (ma)
    {
        struct mroute_addr maddr = *ma;

        switch (maddr.type & MR_ADDR_MASK)
        {
            case MR_ADDR_ETHER:
                buf_printf(&out, "%s", format_hex_ex(ma->eth_addr,
                                                     sizeof(ma->eth_addr), 0, 1, ":", gc));
                break;

            case MR_ADDR_IPV4:
            {
                if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
                {
                    buf_printf(&out, "ARP/");
                }
                buf_printf(&out, "%s", print_in_addr_t(ntohl(maddr.v4.addr),
                                                       (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
                if (maddr.type & MR_WITH_NETBITS)
                {
                    if (flags & MAPF_SUBNET)
                    {
                        const in_addr_t netmask = netbits_to_netmask(maddr.netbits);
                        buf_printf(&out, "/%s", print_in_addr_t(netmask, 0, gc));
                    }
                    else
                    {
                        buf_printf(&out, "/%d", maddr.netbits);
                    }
                }
                if (maddr.type & MR_WITH_PORT)
                {
                    buf_printf(&out, ":%d", ntohs(maddr.v4.port));
                }
            }
            break;

            case MR_ADDR_IPV6:
            {
                if (IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
                {
                    buf_printf(&out, "%s", print_in_addr_t(maddr.v4mappedv6.addr,
                                                           IA_NET_ORDER, gc));
                    /* we only print port numbers for v4mapped v6 as of
                     * today, because "v6addr:port" is too ambiguous
                     */
                    if (maddr.type & MR_WITH_PORT)
                    {
                        buf_printf(&out, ":%d", ntohs(maddr.v6.port));
                    }
                }
                else
                {
                    buf_printf(&out, "%s", print_in6_addr(maddr.v6.addr, 0, gc));
                }
                if (maddr.type & MR_WITH_NETBITS)
                {
                    buf_printf(&out, "/%d", maddr.netbits);
                }
            }
            break;

            default:
                buf_printf(&out, "UNKNOWN");
                break;
        }
        return BSTR(&out);
    }
    else
    {
        return "[NULL]";
    }
}