Dylan halls
Dylan halls

Reputation: 52

Creating list of ip addresses over a specific range in C

I am writing a tool to scan all the nodes on a network but I have ran in to a problem. I'm writing the tool in C but I'm new to the language so I'm not sure how the iterate through the address range.

The user will give the argument 192.168.*.* and it will create every IP address in that range, e.g. 192.168.1.1, 192.168.1.2, 192.168.1.3 and then eventually 192.168.2.1, 192.168.2.2, 192.168.2.3 etc.

My previous code was:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void scanner(int s) 
{
    char addr[20];

    for (int i = 0; i < 255; ++i) 
    {
        sprintf(addr, "192.168.%d.%d", s, i);
        printf("%s\n", addr);
    }
 }

int main() 
{

    for (int i = 0; i < 255; ++i) 
    {
        scanner(i);
    }

    return 0;
}

But I don't know how to run this from the user input.

Upvotes: 0

Views: 733

Answers (2)

nucleon
nucleon

Reputation: 1158

Inspired by (e.g. python-) generators, my solution doesn't perform dynamic memory allocation and and has constant memory consumption. I don't like that I currently rely on a do while loop. Also the explicit check for ig->num_wildcards == 0 is ugly. Anyways:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define IP_OCTETS 4
#define MAX_UCHAR 255

typedef struct {
    int wildcard_pos[IP_OCTETS];
    int num_wildcards;
    int counter[IP_OCTETS];
    int octet[IP_OCTETS];
} ip_generator;

char* mystrsep(char** stringp, const char* delim)
{
    char* start = *stringp;
    char* p;

    p = (start != NULL) ? strpbrk(start, delim) : NULL;

    if (p == NULL)
    {
        *stringp = NULL;
    }
    else
    {
        *p = '\0';
        *stringp = p + 1;
    }

    return start;
}

void init_ip_gen(ip_generator *ig, char* ip_mask)
{
    char *token, *string;
    char* ip_mask_ptr = ip_mask;
    const char delimiters[] = ".";
    int i = 0;

    while ((token = mystrsep(&ip_mask_ptr, delimiters)) != NULL)
    {
        ig->wildcard_pos[i] = -1;
        if (strcmp(token, "*") == 0)
        {
            ig->wildcard_pos[ig->num_wildcards] = i;
            ig->counter[ig->num_wildcards] = 1;
            ig->num_wildcards++;
        }
        else
        {
            ig->octet[i] = atoi(token);
        }
        i++;
    }
}

int ig_next(ip_generator *ig)
{
    int i;
    int carry = 1;

    if (ig->num_wildcards == 0)
    {
        return 0;
    }

    for (i = ig->num_wildcards - 1; i >= 0; i--)
    {
        if (carry == 1)
        {
            if (ig->counter[i] == MAX_UCHAR)
            {
                ig->counter[i] = 1;
            }
            else
            {
                ig->counter[i]++;
                carry = 0;
            }
        }
        if (carry == 0)
        {
            break;
        }
        if (i == 0 && carry == 1)
        {
            return 0;
        }
    }

    return 1;
}

void generate_ip(ip_generator *ig, char *ip)
{
    int i;
    int j = 0;

    int oct[IP_OCTETS];

    for (i = 0; i < IP_OCTETS; i++)
    {
        if (i == ig->wildcard_pos[j])
        {
            oct[i] = ig->counter[j];
            j++;
        }
        else
        {
            oct[i] = ig->octet[i];
        }
    }

    sprintf(ip, "%d.%d.%d.%d", oct[0], oct[1], oct[2], oct[3]);
}

int main()
{
    char ip_mask[] = "192.*.10.*";
    //char ip_mask[] = "192.1.10.123";

    ip_generator ig;
    memset(&ig, 0, sizeof(ig));
    init_ip_gen(&ig, ip_mask);

    char ip[32];
    memset(ip, 0, sizeof(ip));

    do
    {
        generate_ip(&ig, ip);
        printf("%s\n", ip);
    } while (ig_next(&ig));

    return 0;
}

Upvotes: 0

Rahul Behl
Rahul Behl

Reputation: 381

You can take the inputs from the user using the scanf function. I have updated your code to use the same -

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int addr_byte_0;
int addr_byte_1;

void scanner(int s) 
{
    char addr[200];
    int i;
    for (i = 0; i < 255; ++i) 
    {
        sprintf(addr, "%d.%d.%d.%d", addr_byte_0, addr_byte_1, s, i);
        printf("%s\n", addr);
    }
 }

int main() 
{
    int i;
    //printf("Enter the first byte of the address: ");
    scanf ("%d", &addr_byte_0);
    //printf("Enter the second byte of the address: ");
    scanf ("%d", &addr_byte_1);
    for (i = 0; i < 255; ++i) 
    {
        scanner(i);
    }

    return 0;
}

Also, as per C standards you cannot declare a variable inside the for loop. Hence I have moved the declaration out of the for loop. Hope this helps!

Upvotes: 1

Related Questions