-3

I'm getting the error Segmentation Fault: 11, when I'm trying to compile my C code using gcc. The code is implementing multibit trie algorithm for ip lookup and is as follows:

Sometimes the code does run, however most of the times it's ending up in the segmentation error problem.

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <math.h>

/* nodes is an array 8 elements. Each element is a pointer to its child node.*/
/* stride has been taken as 3. therefore 2^3 = 8, the elements in a node */
struct Mt_Node{
    struct Mt_Node* nodes[8];
    int verdict;
};

typedef struct Mt_Node node;

/* Initialize the multibit trie node */
Mt_Node* init_mtnode(){
    node *ret;
        int size;
        ret = static_cast<node *>(malloc(sizeof(node)));
        if (ret == NULL) /* check for NULL */
            return NULL;
        size = 2 << 3;
        if (size >= 8)
            size = 7; /* maximum possible value */
        for (int i = 0 ; i < size ; ++i)
               ret->nodes[i] = NULL;
        ret->verdict = -1;
        return ret;
}

/* Clean up Multibit Trie */
void free_mt(struct Mt_Node *root){
    for( int i=0; i<8; i++){
        if(root->nodes[i]){
        free_mt(root->nodes[i]);
    }

    }
    free(root);
}

/* Insert a Rule */
void insert_rule(struct Mt_Node *root, uint32_t prefix, int prelen, int portnum){

    static int n_rules = 0;
    n_rules ++;

    /* default rule: if packet matches none of the rules, 
     * it will match this default rule, i.e. 0.0.0.0/0 */
    if( prelen == 0 ){
        root->verdict = portnum;
        return;
    }    

    uint32_t    temp_prefix = prefix;
    int curr_bits, curr_bits1;
    Mt_Node     *curr_node = root;

    if(prelen % 3 == 0){
        /* if the condition is 0, then this node will be used, 
        otherwise we will have to move to next node */

        for(int j=0; j<(prelen/3); j++){
            curr_bits = temp_prefix & 0xE0000000;
            temp_prefix = curr_bits >> 29;
            int index = (int) temp_prefix;


            if(curr_node->nodes[index] == NULL){
                curr_node->nodes[index] = init_mtnode();
            }

            curr_node = curr_node->nodes[index];
            temp_prefix=temp_prefix<<3;
        }

        curr_node->verdict = portnum;

    }

    else if(prelen % 3 == 1){

        int b = prelen/3;
        int c = 1;
        for (int i=0; i<b; i++){

            curr_bits = temp_prefix & 0xE0000000;
            temp_prefix = curr_bits >> 29;
            int index = (int) temp_prefix;


            if(curr_node->nodes[index] == NULL){
                curr_node->nodes[index] = init_mtnode();
            }

            curr_node = curr_node->nodes[index];
            temp_prefix=temp_prefix<<3;

        }

        curr_bits = (temp_prefix & 0x80000000)? 1 : 0;
        if(curr_bits == 0){
            for(int z=0; z<4;z++){
                if(curr_node->nodes[z] == NULL){
                curr_node->nodes[z] = init_mtnode();
                (curr_node->nodes[z])->verdict = portnum;
                }
            }
        }

        else {

            for(int z=4; z<8;z++){
                if(curr_node->nodes[z] == NULL){
                curr_node->nodes[z] = init_mtnode();
                (curr_node->nodes[z])->verdict = portnum;
                }
            }
        }

    }

    else if(prelen % 3 == 2){

        int b = prelen/3;
        int c = 0;
        for (int i=0; i<b; i++){

            curr_bits = temp_prefix & 0xE0000000;
            temp_prefix = curr_bits >> 29;
            int index = (int) temp_prefix;


            if(curr_node->nodes[index] == NULL){
                curr_node->nodes[index] = init_mtnode();
            }

            curr_node = curr_node->nodes[index];
            temp_prefix=temp_prefix<<3;

        }

        curr_bits = temp_prefix & 0xc0000000;
        curr_bits = curr_bits>>30;
        int curr_bits1 = (int) curr_bits;

        if(curr_bits1 == 0){
            for(int z=0; z<2;z++){
                if(curr_node->nodes[z] == NULL){
                curr_node->nodes[z] = init_mtnode();
                (curr_node->nodes[z])->verdict = portnum;
            }

        }

    }

        else if(curr_bits1 == 1){
            for(int z=2; z<4;z++){
                if(curr_node->nodes[z] == NULL){
                curr_node->nodes[z] = init_mtnode();
                (curr_node->nodes[z])->verdict = portnum;
            }


        }

    }

        else if(curr_bits1 == 2){
            for(int z=4; z<6;z++){
                if(curr_node->nodes[z] == NULL){
                curr_node->nodes[z] = init_mtnode();
                (curr_node->nodes[z])->verdict = portnum;
            }

        }

    }

        else {

            for(int z=6; z<8;z++){
                if(curr_node->nodes[z] == NULL){
                curr_node->nodes[z] = init_mtnode();
                (curr_node->nodes[z])->verdict = portnum;
            }

        }


    }

}

}

int lookup_ip(Mt_Node *root, uint32_t ip)
{
    uint32_t    temp_prefix = ip;
    Mt_Node      *curr_node = root;
    int         curr_verdict = root->verdict;
    int         curr_bit = 0;
    int         curr_3bits = 0;
    int         curr_bits1 = 0;
    int b =0;

    temp_prefix = temp_prefix & 0xE0000000;
    temp_prefix = temp_prefix >> 29;
    int index = (int) temp_prefix;

        if(curr_node->nodes[index] == NULL){
            return curr_verdict;
        }

        while(curr_node->nodes[index] != NULL){

        curr_verdict = (curr_node->verdict == -1) ? curr_verdict : curr_node->verdict;
        curr_node = curr_node->nodes[index];


        b += 3;

        temp_prefix = (ip << b);
        temp_prefix = temp_prefix & 0xE0000000;
        temp_prefix = temp_prefix >> 29;
        index = (int) temp_prefix;

        }


curr_verdict = (curr_node->verdict == -1) ? curr_verdict : curr_node->verdict;
return curr_verdict ;



}
Arjun Sehgal
  • 59
  • 1
  • 8
  • The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should \[edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Dec 02 '16 at 05:44
  • 1
    Is this a C or C++ question? Pick one tag or the other. – 1201ProgramAlarm Dec 02 '16 at 06:01
  • You should look into [proper C formatting](//prohackr112.tk/r/proper-c-formatting). Or learn how to [thoroughly obfuscate your code](//prohackr112.tk/r/proper-c-obfuscation). – MD XF Dec 02 '16 at 06:08

1 Answers1

1

Your nodes array in node has space for 8 elements, but in your code you have the maximum possible value of 7. As a result, nodes[7] is not given a value, and will have random garbage in it when you free the node with free_mt (and other places where you reference that element).

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56