예제 #1
0
파일: ranges.c 프로젝트: aburan28/isowall
void
rangelist_remove_range(struct RangeList *task, unsigned begin, unsigned end)
{
    unsigned i;
    struct Range x;

    x.begin = begin;
    x.end = end;

    /* See if the range overlaps any exist range already in the
     * list */
    for (i = 0; i < task->count; i++) {
        if (!range_is_overlap(task->list[i], x))
            continue;

        /* If the removal-range wholly covers the range, delete
         * it completely */
        if (begin <= task->list[i].begin && end >= task->list[i].end) {
            todo_remove_at(task, i);
            i--;
            continue;
        }

        /* If the removal-range bisects the target-rage, truncate
         * the lower end and add a new high-end */
        if (begin > task->list[i].begin && end < task->list[i].end) {
            struct Range newrange;

            newrange.begin = end+1;
            newrange.end = task->list[i].end;


            task->list[i].end = begin-1;

            rangelist_add_range(task, newrange.begin, newrange.end);
            i--;
            continue;
        }

        /* If overlap on the lower side */
        if (end >= task->list[i].begin && end < task->list[i].end) {
            task->list[i].begin = end+1;
        }

        /* If overlap on the upper side */
        if (begin > task->list[i].begin && begin <= task->list[i].end) {
             task->list[i].end = begin-1;
        }

        //assert(!"impossible");
    }
}
예제 #2
0
파일: ranges.c 프로젝트: aburan28/isowall
/***************************************************************************
 * Add the IPv4 range to our list of ranges.
 ***************************************************************************/
void
rangelist_add_range(struct RangeList *task, unsigned begin, unsigned end)
{
    unsigned i;
    struct Range range;

    range.begin = begin;
    range.end = end;

    /* auto-expand the list if necessary */
    if (task->count + 1 >= task->max) {
        size_t new_max = (size_t)task->max * 2 + 1;
        struct Range *new_list;
        
        if (new_max >= SIZE_MAX/sizeof(*new_list))
            exit(1); /* integer overflow */
        new_list = (struct Range *)malloc(sizeof(*new_list) * new_max);
        if (new_list == NULL)
            exit(1); /* out of memory */
        
        memcpy(new_list, task->list, task->count * sizeof(*new_list));
        if (task->list)
            free(task->list);
        task->list = new_list;
        task->max = (unsigned)new_max;
    }

    /* See if the range overlaps any exist range already in the
     * list */
    for (i = 0; i < task->count; i++) {
        if (range_is_overlap(task->list[i], range)) {
            range_combine(&range, task->list[i]);
            todo_remove_at(task, i);
            rangelist_add_range(task, range.begin, range.end);
            return;
        }
    }

    /* Find a spot to insert in sorted order */
    for (i = 0; i < task->count; i++) {
        if (range.begin < task->list[i].begin) {
            memmove(task->list+i+1, task->list+i, (task->count - i) * sizeof(task->list[0]));
            break;
        }
    }

    /* Add to end of list */
    task->list[i].begin = begin;
    task->list[i].end = end;
    task->count++;
}
예제 #3
0
파일: ranges.c 프로젝트: codercold/masscan
/***************************************************************************
 * Add the IPv4 range to our list of ranges.
 ***************************************************************************/
void
rangelist_add_range(struct RangeList *task, unsigned begin, unsigned end)
{
    int first, middle, last;
    struct Range range;

    range.begin = begin;
    range.end = end;

    /* auto-expand the list if necessary */
    if (task->count + 1 >= task->max) {
        size_t new_max = (size_t)task->max * 2 + 1;
        struct Range *new_list;

        if (new_max >= SIZE_MAX/sizeof(*new_list))
            exit(1); /* integer overflow */
        new_list = (struct Range *)malloc(sizeof(*new_list) * new_max);
        if (new_list == NULL)
            exit(1); /* out of memory */

        memcpy(new_list, task->list, task->count * sizeof(*new_list));
        if (task->list)
            free(task->list);
        task->list = new_list;
        task->max = (unsigned)new_max;
    }

    if (!task->count) {
        task->list[0].begin = begin;
        task->list[0].end = end;
        task->count++;
        return;
    }

    /* Binary search to find where the current IP range belongs by comparing range beginnings */
    first = 0;
    last = task->count - 1;
    middle = (first + last) / 2;

    while (first <= last) {
        if (task->list[middle].begin < range.begin)
            first = middle + 1;
        else if (task->list[middle].begin == range.begin)
            break;
        else
            last = middle - 1;

        middle = (first + last) / 2;
    }

    /* `middle` now points to the IP range numerically smaller than or equal to it. Try to merge it
     *  with the numerically smaller, and then greater ranges. */
    if (range_is_overlap(task->list[middle], range)) {
        range_combine(&range, task->list[middle]);
        todo_remove_at(task, middle);
        rangelist_add_range(task, range.begin, range.end);
        return;
    }
    if (task->count > (middle+1) && range_is_overlap(task->list[middle+1], range)) {
        range_combine(&range, task->list[middle+1]);
        todo_remove_at(task, middle+1);
        rangelist_add_range(task, range.begin, range.end);
        return;
    }

    /* Make space for the current range respecting sorted order by placing it in entry `middle+1` */
    memmove(task->list+middle+2, task->list+middle+1, (task->count - middle - 1) * sizeof(task->list[0]));

    /* Add to the list */
    task->list[middle+1].begin = begin;
    task->list[middle+1].end = end;
    task->count++;
}