Example #1
0
int garden_patricia_check(patricia_tree_t *ptree,
			  pass_through *ptlist, uint32_t *ptcnt,
			  struct pkt_ipphdr_t *ipph, int dst) {
  int found = 0;
  prefix_t *prefix;
  patricia_node_t *pfx;
  struct in_addr sin;

  sin.s_addr = dst ? ipph->daddr : ipph->saddr;
  prefix = patricia_prefix_new (AF_INET, &sin, 32);

  pfx = patricia_search_best(ptree, prefix);
  if (pfx) {
    struct node_pass_through_list *
        nd = PATRICIA_DATA_GET(pfx, struct node_pass_through_list);

    if (nd) {
      pass_through *pt=0;
      switch (garden_check(nd->ptlist, &nd->ptcnt,
			   &pt, ipph, dst, ptree)) {
        case 1:
          found = 1;
          break;
        case -1:
          if (pt)
            pass_through_rem(ptlist, ptcnt, pt, ptree);
          break;
      }
    }
  }

  patricia_prefix_deref (prefix);
  return found;
}
Example #2
0
int garden_patricia_add(pass_through * pt, patricia_tree_t * ptree)
{
	uint32_t mask;
	unsigned char count;
	prefix_t *prefix;
	patricia_node_t *pfx;
	struct in_addr sin;

	for (count = 0, mask = 0x80000000; mask != 0; mask >>= 1) {
		if (pt->mask.s_addr & mask)
			count++;
	}

	sin.s_addr = pt->host.s_addr;
	prefix = patricia_prefix_new(AF_INET, &sin, count);

	pfx = patricia_lookup(ptree, prefix);

	if (pfx != NULL) {
		struct node_pass_through_list *nd =
		    PATRICIA_DATA_GET(pfx, struct node_pass_through_list);

		if (nd == NULL) {
			nd = (struct node_pass_through_list *)
			    malloc(sizeof(struct node_pass_through_list) +
				   sizeof(pass_through));
			if (nd) {
				nd->ptcnt = 1;
				memcpy(nd->ptlist, pt, sizeof(*pt));
			}
		} else {
			int i;
			for (i = 0; i < nd->ptcnt; i++) {
				if (pt_equal(&nd->ptlist[i], pt)) {
					log_dbg
					    ("Uamallowed already exists #%d:%d: proto=%d host=%s port=%d",
					     i, nd->ptcnt, pt->proto,
					     inet_ntoa(pt->host), pt->port);
					break;
				}
			}
			if (i == nd->ptcnt) {
				nd->ptcnt++;
				nd = realloc(nd,
					     sizeof(struct
						    node_pass_through_list) +
					     (sizeof(pass_through) *
					      nd->ptcnt));
				memcpy(&nd->ptlist[nd->ptcnt - 1], pt,
				       sizeof(*pt));
			}
		}

		PATRICIA_DATA_SET(pfx, nd);
	}

	patricia_prefix_deref(prefix);
	return 0;
}
Example #3
0
int garden_patricia_rem(pass_through *pt, patricia_tree_t *ptree) {
  uint32_t mask;
  unsigned char count;
  prefix_t *prefix;
  patricia_node_t *pfx;
  struct in_addr sin;

  for (count = 0, mask = 0x80000000; mask != 0; mask >>= 1) {
    if (pt->mask.s_addr & mask)
      count++;
  }

  sin.s_addr = pt->host.s_addr;
  prefix = patricia_prefix_new (AF_INET, &sin, count);

  pfx = patricia_search_exact (ptree, prefix);
  if (pfx != NULL) {
    struct node_pass_through_list *
        nd = PATRICIA_DATA_GET(pfx, struct node_pass_through_list);

    if (nd != NULL) {
      int i;

      for (i=0; i < nd->ptcnt; i++) {
	if (pt_equal(&nd->ptlist[i], pt)) {
          if (_options.debug) {
            syslog(LOG_DEBUG, "(Patricia)Uamallowed removing #%d:%d: proto=%d host=%s port=%d",
                   i, nd->ptcnt, pt->proto, inet_ntoa(pt->host), pt->port);
            syslog(LOG_DEBUG, "Shifting uamallowed list %d to %d", i, nd->ptcnt);
          }

	  for (; i < nd->ptcnt-1; i++)
	    memcpy(&nd->ptlist[i], &nd->ptlist[i+1], sizeof(pass_through));

	  nd->ptcnt--;

	  if (nd->ptcnt > 0) {

	    nd = realloc(nd,
			 sizeof(struct node_pass_through_list)+
			 (sizeof(pass_through)*nd->ptcnt));

	    PATRICIA_DATA_SET(pfx, nd);

	  } else {
	    free(nd);
	    patricia_remove (ptree, pfx);
	  }

	  break;
	}
      }
    }
  }

  patricia_prefix_deref (prefix);
  return 0;
}