int pass_through_rem(pass_through *ptlist, uint32_t *ptcnt, pass_through *pt #ifdef HAVE_PATRICIA , patricia_tree_t *ptree #endif ) { uint32_t cnt = *ptcnt; int i; for (i=0; i < cnt; i++) { if (pt_equal(&ptlist[i], pt)) { if (_options.debug) { syslog(LOG_DEBUG, "Uamallowed removing #%d: proto=%d host=%s port=%d", i, pt->proto, inet_ntoa(pt->host), pt->port); syslog(LOG_DEBUG, "Shifting uamallowed list %d to %d", i, cnt); } for (; i < cnt-1; i++) memcpy(&ptlist[i], &ptlist[i+1], sizeof(pass_through)); *ptcnt = *ptcnt - 1; break; } } #ifdef HAVE_PATRICIA if (ptree) garden_patricia_rem(pt, ptree); #endif return 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; }
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; }
int pass_through_add(pass_through *ptlist, uint32_t ptlen, uint32_t *ptcnt, pass_through *pt, char is_dyn #ifdef HAVE_PATRICIA , patricia_tree_t *ptree #endif ) { uint32_t cnt = *ptcnt; int i; for (i=0; i < cnt; i++) { if (pt_equal(&ptlist[i], pt)) { if (_options.debug) syslog(LOG_DEBUG, "Uamallowed already exists #%d:%d: proto=%d host=%s port=%d", i, ptlen, pt->proto, inet_ntoa(pt->host), pt->port); if (is_dyn) { if (_options.debug) syslog(LOG_DEBUG, "Shifting uamallowed list %d to %d", i, cnt); for (; i<cnt-1; i++) memcpy(&ptlist[i], &ptlist[i+1], sizeof(pass_through)); cnt = *ptcnt = *ptcnt - 1; break; } else { return 0; } } } if (cnt == ptlen) { if (!is_dyn) { if (_options.debug) syslog(LOG_DEBUG, "No more room for walled garden entries"); return -1; } if (_options.debug) syslog(LOG_DEBUG, "Shifting uamallowed list %d to %d", i, ptlen); for (i=0; i<ptlen-1; i++) memcpy(&ptlist[i], &ptlist[i+1], sizeof(pass_through)); cnt = *ptcnt = *ptcnt - 1; } if (_options.debug) syslog(LOG_DEBUG, "Uamallowed IP address #%d:%d: proto=%d host=%s port=%d", cnt, ptlen, pt->proto, inet_ntoa(pt->host), pt->port); memcpy(&ptlist[cnt], pt, sizeof(pass_through)); *ptcnt = cnt + 1; #ifdef HAVE_PATRICIA if (ptree) garden_patricia_add(pt, ptree); #endif return 0; }