int compare_route_entries(const void *a, const void *b) { const struct route_table_entry *entry_a = (const struct route_table_entry *)a; const struct route_table_entry *entry_b = (const struct route_table_entry *)b; if (entry_a->prefix == entry_b->prefix) { if (entry_a->mask == entry_b->mask) { return 0; } else { if (entry_a->mask > entry_b->mask) return 1; else return -1; } } else { if (entry_a->prefix > entry_b->prefix) return 1; else return -1; } } struct route_table_entry *best_route(struct route_table_entry *route_table, int rt_len, uint32_t ip) { int left = 0, right = rt_len - 1; struct route_table_entry *best = NULL; while (left <= right) { int mid = left + (right - left) / 2; struct route_table_entry *rt = &route;_table[mid]; if ((rt->mask & ip) == (rt->mask & rt->prefix)) { if (best == NULL || rt->mask > best->mask) { best = rt; } left = mid + 1; } else { right = mid - 1; } } return best; }