DMDFrame::DMDFrame(const DMDFrame &source) : width(source.width), height(source.height), row_width_bytes(source.row_width_bytes), height_in_panels(source.height_in_panels), font(source.font) { bitmap = (uint8_t *)malloc(bitmap_bytes()); memcpy((void *)bitmap, (void *)source.bitmap, bitmap_bytes()); }
DMDFrame::DMDFrame(byte pixelsWide, byte pixelsHigh) : width(pixelsWide), height(pixelsHigh), font(0) { row_width_bytes = (pixelsWide + 7)/8; // on full panels pixelsWide is a multiple of 8, but for sub-regions may not be height_in_panels = (pixelsHigh + PANEL_HEIGHT-1) / PANEL_HEIGHT; bitmap = (uint8_t *)malloc(bitmap_bytes()); memset((void *)bitmap, 0xFF, bitmap_bytes()); }
static inline int __ipmap_create(const struct ip_set_req_ipmap_create *req, struct ip_set_ipmap *map) { map->netmask = req->netmask; if (req->netmask == 0xFFFFFFFF) { map->hosts = 1; map->sizeid = map->last_ip - map->first_ip + 1; } else { unsigned int mask_bits, netmask_bits; ip_set_ip_t mask; map->first_ip &= map->netmask; /* Should we better bark? */ mask = range_to_mask(map->first_ip, map->last_ip, &mask_bits); netmask_bits = mask_to_bits(map->netmask); if ((!mask && (map->first_ip || map->last_ip != 0xFFFFFFFF)) || netmask_bits <= mask_bits) return -ENOEXEC; DP("mask_bits %u, netmask_bits %u", mask_bits, netmask_bits); map->hosts = 2 << (32 - netmask_bits - 1); map->sizeid = 2 << (netmask_bits - mask_bits - 1); } if (map->sizeid > MAX_RANGE + 1) { ip_set_printk("range too big, %d elements (max %d)", map->sizeid, MAX_RANGE+1); return -ENOEXEC; } DP("hosts %u, sizeid %u", map->hosts, map->sizeid); return bitmap_bytes(0, map->sizeid - 1); }
static void list_members(const struct ip_set *set, void *data) { struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; int bytes = bitmap_bytes(0, map->sizeid - 1); memcpy(data, map->members, bytes); }
static int bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags) { struct bitmap_port *map; u16 first_port, last_port; if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) return -IPSET_ERR_PROTOCOL; first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]); last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); if (first_port > last_port) { u16 tmp = first_port; first_port = last_port; last_port = tmp; } map = kzalloc(sizeof(*map), GFP_KERNEL); if (!map) return -ENOMEM; if (tb[IPSET_ATTR_TIMEOUT]) { map->memsize = (last_port - first_port + 1) * sizeof(unsigned long); if (!init_map_port(set, map, first_port, last_port)) { kfree(map); return -ENOMEM; } map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); set->variant = &bitmap_tport; bitmap_port_gc_init(set); } else { map->memsize = bitmap_bytes(0, last_port - first_port); pr_debug("memsize: %zu\n", map->memsize); if (!init_map_port(set, map, first_port, last_port)) { kfree(map); return -ENOMEM; } set->variant = &bitmap_port; } return 0; }
// Set the entire screen void DMDFrame::fillScreen(bool on) { memset((void *)bitmap, on ? 0 : 0xFF, bitmap_bytes()); }
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; }
static int bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) { struct bitmap_ip *map; u32 first_ip, last_ip, hosts, elements; u8 netmask = 32; int ret; if (unlikely(!tb[IPSET_ATTR_IP] || !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 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) { u32 tmp = first_ip; first_ip = last_ip; last_ip = tmp; } } else if (tb[IPSET_ATTR_CIDR]) { u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); if (cidr >= 32) return -IPSET_ERR_INVALID_CIDR; last_ip = first_ip | ~ip_set_hostmask(cidr); } else return -IPSET_ERR_PROTOCOL; if (tb[IPSET_ATTR_NETMASK]) { netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]); if (netmask > 32) return -IPSET_ERR_INVALID_NETMASK; first_ip &= ip_set_hostmask(netmask); last_ip |= ~ip_set_hostmask(netmask); } if (netmask == 32) { hosts = 1; elements = last_ip - first_ip + 1; } else { u8 mask_bits; u32 mask; mask = range_to_mask(first_ip, last_ip, &mask_bits); if ((!mask && (first_ip || last_ip != 0xFFFFFFFF)) || netmask <= mask_bits) return -IPSET_ERR_BITMAP_RANGE; pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask); hosts = 2 << (32 - netmask - 1); elements = 2 << (netmask - mask_bits - 1); } if (elements > IPSET_BITMAP_MAX_RANGE + 1) return -IPSET_ERR_BITMAP_RANGE_SIZE; pr_debug("hosts %u, elements %u\n", hosts, elements); map = kzalloc(sizeof(*map), GFP_KERNEL); if (!map) return -ENOMEM; if (tb[IPSET_ATTR_TIMEOUT]) { map->memsize = elements * sizeof(unsigned long); if (!init_map_ip(set, map, first_ip, last_ip, elements, hosts, netmask)) { kfree(map); return -ENOMEM; } map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); set->variant = &bitmap_tip; bitmap_ip_gc_init(set); } else { map->memsize = bitmap_bytes(0, elements - 1); if (!init_map_ip(set, map, first_ip, last_ip, elements, hosts, netmask)) { kfree(map); return -ENOMEM; } set->variant = &bitmap_ip; } return 0; }
static int list_members_size(const struct ip_set *set) { struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; return bitmap_bytes(0, map->sizeid - 1); }
static void flush(struct ip_set *set) { struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; memset(map->members, 0, bitmap_bytes(0, map->sizeid - 1)); }
static int create(struct ip_set *set, const void *data, size_t size) { int newbytes; struct ip_set_req_ipmap_create *req = (struct ip_set_req_ipmap_create *) data; struct ip_set_ipmap *map; if (size != sizeof(struct ip_set_req_ipmap_create)) { ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_ipmap_create), size); return -EINVAL; } DP("from %u.%u.%u.%u to %u.%u.%u.%u", HIPQUAD(req->from), HIPQUAD(req->to)); if (req->from > req->to) { DP("bad ip range"); return -ENOEXEC; } map = kmalloc(sizeof(struct ip_set_ipmap), GFP_KERNEL); if (!map) { DP("out of memory for %d bytes", sizeof(struct ip_set_ipmap)); return -ENOMEM; } map->first_ip = req->from; map->last_ip = req->to; map->netmask = req->netmask; if (req->netmask == 0xFFFFFFFF) { map->hosts = 1; map->sizeid = map->last_ip - map->first_ip + 1; } else { unsigned int mask_bits, netmask_bits; ip_set_ip_t mask; map->first_ip &= map->netmask; /* Should we better bark? */ mask = range_to_mask(map->first_ip, map->last_ip, &mask_bits); netmask_bits = mask_to_bits(map->netmask); if ((!mask && (map->first_ip || map->last_ip != 0xFFFFFFFF)) || netmask_bits <= mask_bits) return -ENOEXEC; DP("mask_bits %u, netmask_bits %u", mask_bits, netmask_bits); map->hosts = 2 << (32 - netmask_bits - 1); map->sizeid = 2 << (netmask_bits - mask_bits - 1); } if (map->sizeid > MAX_RANGE + 1) { ip_set_printk("range too big (max %d addresses)", MAX_RANGE+1); kfree(map); return -ENOEXEC; } DP("hosts %u, sizeid %u", map->hosts, map->sizeid); newbytes = bitmap_bytes(0, map->sizeid - 1); map->members = kmalloc(newbytes, GFP_KERNEL); if (!map->members) { DP("out of memory for %d bytes", newbytes); kfree(map); return -ENOMEM; } memset(map->members, 0, newbytes); set->data = map; return 0; }
static inline int poolbytes(ip_pool_t index) { struct ip_pool *pool = lookup(index); return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0; }
static int getpool( struct sock *sk, int optval, void *user, int *len ) { struct ip_pool_request req; struct ip_pool *pool; ip_pool_t i; int newbytes; void *newmembers; int res; DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user); if (!capable(CAP_NET_ADMIN)) return -EINVAL; if (optval != SO_IP_POOL) return -EINVAL; if (*len != sizeof(req)) { return -EFAULT; } if (copy_from_user(&req, user, sizeof(req)) != 0) return -EFAULT; DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index); if (req.op < IP_POOL_BAD001) { printk("obsolete op - upgrade your ippool(8) utility.\n"); return -EFAULT; } switch(req.op) { case IP_POOL_HIGH_NR: DP("ip_pool HIGH_NR\n"); req.index = IP_POOL_NONE; for (i=0; i<nr_pool; i++) if (POOL[i].members) req.index = i; return copy_to_user(user, &req, sizeof(req)); case IP_POOL_LOOKUP: DP("ip_pool LOOKUP\n"); pool = lookup(req.index); if (!pool) return -EINVAL; if (!pool->members) return -EBADF; req.addr = htonl(pool->first_ip); req.addr2 = htonl(pool->last_ip); return copy_to_user(user, &req, sizeof(req)); case IP_POOL_USAGE: DP("ip_pool USE\n"); pool = lookup(req.index); if (!pool) return -EINVAL; if (!pool->members) return -EBADF; req.addr = pool->nr_use; req.addr2 = pool->nr_match; return copy_to_user(user, &req, sizeof(req)); case IP_POOL_TEST_ADDR: DP("ip_pool TEST 0x%08x\n", req.addr); pool = lookup(req.index); if (!pool) return -EINVAL; res = 0; read_lock_bh(&pool->lock); if (!pool->members) { DP("ip_pool TEST_ADDR no members in pool\n"); res = -EBADF; goto unlock_and_return_res; } req.addr = ntohl(req.addr); if (req.addr < pool->first_ip) { DP("ip_pool TEST_ADDR address < pool bounds\n"); res = -ERANGE; goto unlock_and_return_res; } if (req.addr > pool->last_ip) { DP("ip_pool TEST_ADDR address > pool bounds\n"); res = -ERANGE; goto unlock_and_return_res; } req.addr = (0 != test_bit((req.addr - pool->first_ip), pool->members)); read_unlock_bh(&pool->lock); return copy_to_user(user, &req, sizeof(req)); case IP_POOL_FLUSH: DP("ip_pool FLUSH not yet implemented.\n"); return -EBUSY; case IP_POOL_DESTROY: DP("ip_pool DESTROY not yet implemented.\n"); return -EBUSY; case IP_POOL_INIT: DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2); pool = lookup(req.index); if (!pool) return -EINVAL; req.addr = ntohl(req.addr); req.addr2 = ntohl(req.addr2); if (req.addr > req.addr2) { DP("ip_pool INIT bad ip range\n"); return -EINVAL; } newbytes = bitmap_bytes(req.addr, req.addr2); newmembers = kmalloc(newbytes, GFP_KERNEL); if (!newmembers) { DP("ip_pool INIT out of mem for %d bytes\n", newbytes); return -ENOMEM; } memset(newmembers, 0, newbytes); write_lock_bh(&pool->lock); if (pool->members) { DP("ip_pool INIT pool %d exists\n", req.index); kfree(newmembers); res = -EBUSY; goto unlock_and_return_res; } pool->first_ip = req.addr; pool->last_ip = req.addr2; pool->nr_use = 0; pool->nr_match = 0; pool->members = newmembers; write_unlock_bh(&pool->lock); return 0; case IP_POOL_ADD_ADDR: DP("ip_pool ADD_ADDR 0x%08x\n", req.addr); req.addr = pool_change(req.index, ntohl(req.addr), 0); return copy_to_user(user, &req, sizeof(req)); case IP_POOL_DEL_ADDR: DP("ip_pool DEL_ADDR 0x%08x\n", req.addr); req.addr = pool_change(req.index, ntohl(req.addr), 1); return copy_to_user(user, &req, sizeof(req)); default: DP("ip_pool:getpool bad op %d\n", req.op); return -EINVAL; } return -EINVAL; unlock_and_return_res: if (pool) read_unlock_bh(&pool->lock); return res; }