static int
bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
		  const struct xt_action_param *par,
		  enum ipset_adt adt, const struct ip_set_adt_opt *opt)
{
	struct bitmap_ipmac *map = set->data;
	ipset_adtfn adtfn = set->variant->adt[adt];
	struct ipmac data;

	/* MAC can be src only */
	if (!(opt->flags & IPSET_DIM_TWO_SRC))
		return 0;

	data.id = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
	if (data.id < map->first_ip || data.id > map->last_ip)
		return -IPSET_ERR_BITMAP_RANGE;

	/* Backward compatibility: we don't check the second flag */
	if (skb_mac_header(skb) < skb->head ||
	    (skb_mac_header(skb) + ETH_HLEN) > skb->data)
		return -EINVAL;

	data.id -= map->first_ip;
	data.ether = eth_hdr(skb)->h_source;

	return adtfn(set, &data, opt_timeout(opt, map), opt->cmdflags);
}
Esempio n. 2
0
SSDP::SSDP( int nServicePort ) :
    m_procReqLineExp("[ \r\n][ \r\n]*"),
    m_nPort(SSDP_PORT),
    m_nSearchPort(SSDP_SEARCHPORT),
    m_nServicePort(nServicePort),
    m_pNotifyTask(NULL),
    m_bTermRequested(false),
    m_lock(QMutex::NonRecursive)
{
    m_nPort =
        UPnp::g_pConfig->GetValue( "UPnP/SSDP/Port"      , SSDP_PORT       );
    m_nSearchPort =
        UPnp::g_pConfig->GetValue( "UPnP/SSDP/SearchPort", SSDP_SEARCHPORT );

    m_Sockets[ SocketIdx_Search    ] =
        new MSocketDevice( MSocketDevice::Datagram );
    m_Sockets[ SocketIdx_Multicast ] =
        new QMulticastSocket( SSDP_GROUP, m_nPort );
    m_Sockets[ SocketIdx_Broadcast ] =
        new QBroadcastSocket( "255.255.255.255", m_nPort );

    m_Sockets[ SocketIdx_Search    ]->setBlocking( false );
    m_Sockets[ SocketIdx_Multicast ]->setBlocking( false );
    m_Sockets[ SocketIdx_Broadcast ]->setBlocking( false );

    // Setup SearchSocket
    QHostAddress ip4addr( QHostAddress::Any );
    m_Sockets[ SocketIdx_Search ]->bind( ip4addr, m_nSearchPort ); 

    m_Sockets[ SocketIdx_Search ]->bind( QHostAddress::Any, m_nSearchPort );

}
Esempio n. 3
0
int parse_a_txt(char *str, const char **rrp, const char *def_rr,
                struct dsctx *dsc) {
  char *rr;
  static char rrbuf[4+256];	/*XXX static buffer */
  if (*str == ':') {
    ip4addr_t a;
    int bits = ip4addr(str + 1, &a, &str);
    if (!a || bits <= 0) {
      dswarn(dsc, "invalid A RR");
      return 0;
    }
    if (bits == 8)
      a |= IP4A_LOOPBACK; /* only last digit in 127.0.0.x */
    SKIPSPACE(str);
    if (*str == ':') {	/* A+TXT */
      ++str;
      SKIPSPACE(str);
      rr = str - 4;
      PACK32(rr, a);
    }
    else if (*str) {
      dswarn(dsc, "unrecognized value for an entry");
      return 0;
    }
    else {	/* only A - take TXT from default entry */
      unsigned tlen = strlen(def_rr+4);	/* tlen is <= 255 */
      rr = rrbuf;
      PACK32(rr, a);
      memcpy(rr+4, def_rr+4, tlen+1);
      *rrp = rr;
      return tlen + 5;
    }
  }
  else {
    rr = str - 4;
    memcpy(rr, def_rr, 4);
  }
  if (*str) {
    unsigned len = strlen(str);
    if (len > 255) {
      dswarn(dsc, "TXT RR truncated to 255 bytes");
      str += 255;
    }
    else
      str += len;
    *str = '\0';
  }
  *rrp = rr;
  return 1 + (str - rr);
}
static int
bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
	       enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
{
	struct bitmap_ip *map = set->data;
	ipset_adtfn adtfn = set->variant->adt[adt];
	u32 ip;

	ip = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
	if (ip < map->first_ip || ip > map->last_ip)
		return -IPSET_ERR_BITMAP_RANGE;

	ip = ip_to_id(map, ip);

	return adtfn(set, &ip, map->timeout);
}
Esempio n. 5
0
SSDP::SSDP() :
    MThread                ("SSDP" ),
    m_procReqLineExp       ("[ \r\n][ \r\n]*"),
    m_nPort                ( SSDP_PORT ),
    m_nSearchPort          ( SSDP_SEARCHPORT ),
    m_nServicePort         ( 0 ),
    m_pNotifyTask          ( NULL ),
    m_bAnnouncementsEnabled( false ),
    m_bTermRequested       ( false ),
    m_lock                 ( QMutex::NonRecursive )
{
    LOG(VB_UPNP, LOG_NOTICE, "Starting up SSDP Thread..." );

    Configuration *pConfig = UPnp::GetConfiguration();

    m_nPort       = pConfig->GetValue("UPnP/SSDP/Port"      , SSDP_PORT      );
    m_nSearchPort = pConfig->GetValue("UPnP/SSDP/SearchPort", SSDP_SEARCHPORT);

    m_Sockets[ SocketIdx_Search    ] =
        new MMulticastSocketDevice();
    m_Sockets[ SocketIdx_Multicast ] =
        new MMulticastSocketDevice(SSDP_GROUP, m_nPort);
    m_Sockets[ SocketIdx_Broadcast ] =
        new MBroadcastSocketDevice("255.255.255.255", m_nPort);

    m_Sockets[ SocketIdx_Search    ]->setBlocking( false );
    m_Sockets[ SocketIdx_Multicast ]->setBlocking( false );
    m_Sockets[ SocketIdx_Broadcast ]->setBlocking( false );

    // Setup SearchSocket
    QHostAddress ip4addr( QHostAddress::Any );

    m_Sockets[ SocketIdx_Search ]->bind( ip4addr          , m_nSearchPort );
    m_Sockets[ SocketIdx_Search ]->bind( QHostAddress::Any, m_nSearchPort );

    // ----------------------------------------------------------------------
    // Create the SSDP (Upnp Discovery) Thread.
    // ----------------------------------------------------------------------

    start();

    LOG(VB_UPNP, LOG_INFO, "SSDP Thread Starting soon" );
}
static int
bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
	       const struct xt_action_param *par,
	       enum ipset_adt adt, struct ip_set_adt_opt *opt)
{
	struct bitmap_ip *map = set->data;
	ipset_adtfn adtfn = set->variant->adt[adt];
	struct bitmap_ip_adt_elem e = { };
	struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
	u32 ip;

	ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
	if (ip < map->first_ip || ip > map->last_ip)
		return -IPSET_ERR_BITMAP_RANGE;

	e.id = ip_to_id(map, ip);

	return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
}
static int
bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
		  enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
{
	struct bitmap_ipmac *map = set->data;
	ipset_adtfn adtfn = set->variant->adt[adt];
	struct ipmac data;

	data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
	if (data.id < map->first_ip || data.id > map->last_ip)
		return -IPSET_ERR_BITMAP_RANGE;

	/* Backward compatibility: we don't check the second flag */
	if (skb_mac_header(skb) < skb->head ||
	    (skb_mac_header(skb) + ETH_HLEN) > skb->data)
		return -EINVAL;

	data.id -= map->first_ip;
	data.ether = eth_hdr(skb)->h_source;

	return adtfn(set, &data, map->timeout);
}
Esempio n. 8
0
static int
bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
		  const struct xt_action_param *par,
		  enum ipset_adt adt, struct ip_set_adt_opt *opt)
{
	struct bitmap_ipmac *map = set->data;
	ipset_adtfn adtfn = set->variant->adt[adt];
	struct bitmap_ipmac_adt_elem e = { .id = 0, .add_mac = 1 };
	struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
	u32 ip;

	ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
	if (ip < map->first_ip || ip > map->last_ip)
		return -IPSET_ERR_BITMAP_RANGE;

	/* Backward compatibility: we don't check the second flag */
	if (skb_mac_header(skb) < skb->head ||
	    (skb_mac_header(skb) + ETH_HLEN) > skb->data)
		return -EINVAL;

	e.id = ip_to_id(map, ip);

	if (opt->flags & IPSET_DIM_ONE_SRC)
		ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
	else
		ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);

	if (is_zero_ether_addr(e.ether))
		return -EINVAL;

	return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
}

static int
bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
		  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
{
	const struct bitmap_ipmac *map = set->data;
	ipset_adtfn adtfn = set->variant->adt[adt];
	struct bitmap_ipmac_adt_elem e = { .id = 0 };
	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
	u32 ip = 0;
	int ret = 0;

	if (tb[IPSET_ATTR_LINENO])
		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);

	if (unlikely(!tb[IPSET_ATTR_IP]))
		return -IPSET_ERR_PROTOCOL;

	ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
	if (ret)
		return ret;

	ret = ip_set_get_extensions(set, tb, &ext);
	if (ret)
		return ret;

	if (ip < map->first_ip || ip > map->last_ip)
		return -IPSET_ERR_BITMAP_RANGE;

	e.id = ip_to_id(map, ip);
	if (tb[IPSET_ATTR_ETHER]) {
		if (nla_len(tb[IPSET_ATTR_ETHER]) != ETH_ALEN)
			return -IPSET_ERR_PROTOCOL;
		memcpy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]), ETH_ALEN);
		e.add_mac = 1;
	}
	ret = adtfn(set, &e, &ext, &ext, flags);

	return ip_set_eexist(ret, flags) ? 0 : ret;
}

static bool
bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b)
{
	const struct bitmap_ipmac *x = a->data;
	const struct bitmap_ipmac *y = b->data;

	return x->first_ip == y->first_ip &&
	       x->last_ip == y->last_ip &&
	       a->timeout == b->timeout &&
	       a->extensions == b->extensions;
}

/* Plain variant */

#include "ip_set_bitmap_gen.h"

/* Create bitmap:ip,mac type of sets */

static bool
init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
	       u32 first_ip, u32 last_ip, u32 elements)
{
	map->members = ip_set_alloc(map->memsize);
	if (!map->members)
		return false;
	map->first_ip = first_ip;
	map->last_ip = last_ip;
	map->elements = elements;
	set->timeout = IPSET_NO_TIMEOUT;

	map->set = set;
	set->data = map;
	set->family = NFPROTO_IPV4;

	return true;
}

static int
bitmap_ipmac_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
		    u32 flags)
{
	u32 first_ip = 0, last_ip = 0;
	u64 elements;
	struct bitmap_ipmac *map;
	int ret;

	if (unlikely(!tb[IPSET_ATTR_IP] ||
		     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
		     !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
		return -IPSET_ERR_PROTOCOL;

	ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
	if (ret)
		return ret;

	if (tb[IPSET_ATTR_IP_TO]) {
		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
		if (ret)
			return ret;
		if (first_ip > last_ip)
			swap(first_ip, last_ip);
	} else if (tb[IPSET_ATTR_CIDR]) {
		u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);

		if (cidr >= HOST_MASK)
			return -IPSET_ERR_INVALID_CIDR;
		ip_set_mask_from_to(first_ip, last_ip, cidr);
	} else {
		return -IPSET_ERR_PROTOCOL;
	}

	elements = (u64)last_ip - first_ip + 1;

	if (elements > IPSET_BITMAP_MAX_RANGE + 1)
		return -IPSET_ERR_BITMAP_RANGE_SIZE;

	set->dsize = ip_set_elem_len(set, tb,
				     sizeof(struct bitmap_ipmac_elem),
				     __alignof__(struct bitmap_ipmac_elem));
	map = ip_set_alloc(sizeof(*map) + elements * set->dsize);
	if (!map)
		return -ENOMEM;

	map->memsize = bitmap_bytes(0, elements - 1);
	set->variant = &bitmap_ipmac;
	if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
		kfree(map);
		return -ENOMEM;
	}
	if (tb[IPSET_ATTR_TIMEOUT]) {
		set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
		bitmap_ipmac_gc_init(set, bitmap_ipmac_gc);
	}
	return 0;
}
Esempio n. 9
0
static void
initsockets(const char *bindaddr[MAXSOCK], int nba, int UNUSED family) {

  int i, x;
  char *host, *serv;
  const char *ba;

#ifdef NO_IPv6

  struct sockaddr_in sin;
  ip4addr_t sinaddr;
  int port;
  struct servent *se;
  struct hostent *he;

  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;

  if (!(se = getservbyname("domain", "udp")))
    port = htons(DNS_PORT);
  else
    port = se->s_port;

#else

  struct addrinfo hints, *aires, *ai;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = family;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_flags = AI_PASSIVE;

#endif

  for (i = 0; i < nba; ++i) {
    ba = bindaddr[i];
    host = estrdup(ba);

    serv = strchr(host, '/');
    if (serv) {
      *serv++ = '\0';
      if (!*host)
        error(0, "missing host part in bind address `%.60s'", ba);
    }

#ifdef NO_IPv6

    if (!serv || !*serv)
      sin.sin_port = port;
    else if ((x = satoi(serv)) > 0 && x <= 0xffff)
      sin.sin_port = htons(x);
    else if (!(se = getservbyname(serv, "udp")))
      error(0, "unknown service in `%.60s'", ba);
    else
      sin.sin_port = se->s_port;

    if (ip4addr(host, &sinaddr, NULL) > 0) {
      sin.sin_addr.s_addr = htonl(sinaddr);
      newsocket(&sin);
    }
    else if (!(he = gethostbyname(host))
             || he->h_addrtype != AF_INET
             || he->h_length != 4
             || !he->h_addr_list[0])
      error(0, "unknown host in `%.60s'", ba);
    else {
      for(x = 0; he->h_addr_list[x]; ++x) {
        memcpy(&sin.sin_addr, he->h_addr_list[x], 4);
        newsocket(&sin);
      }
    }

#else

    if (!serv || !*serv)
      serv = "domain";

    x = getaddrinfo(host, serv, &hints, &aires);
    if (x != 0)
      error(0, "%.60s: %s", ba, gai_strerror(x));
    for(ai = aires, x = 0; ai; ai = ai->ai_next)
      if (newsocket(ai))
        ++x;
    if (!x)
      error(0, "%.60s: no available protocols", ba);
    freeaddrinfo(aires);

#endif

    free(host);
  }
  endservent();
  endhostent();

  for (i = 0; i < numsock; ++i) {
    x = 65536;
    do
      if (setsockopt(sock[i], SOL_SOCKET, SO_RCVBUF, (void*)&x, sizeof x) == 0)
        break;
    while ((x -= (x >> 5)) >= 1024);
  }
}