hello every body,

I am a new prog.in C.My final yr project based on incrementing ipv6 address by 1.The address format is - fe80:0000:0000:0000:0204:61ff:fe9d:ffff
So the result will be - fe80:0000:0000:0000:0204:61ff:fe9e:0000
User enter the valid ipv6 address and final result will be +1 incremented.Its a incrementation of hex.value.

It also support address like - fe80::0204:61ff:fe9d:ffff
Can any body help me for solving the code using C language.

Recommended Answers

All 11 Replies

You will likely want to break the problem down into two distinct parts: parsing input and managing the increment.
If you parse the input properly then the increment should be trivial with the exception of propagation of the carry.

Can any body help me for solving the code using C language.

Start by ignoring the requirement to handle the "::" shorthand. That's the only part of the problem that makes it even remotely difficult.

You will likely want to break the problem down into two distinct parts: parsing input and managing the increment.

Depending on how you choose to handle the increment, reformatting the IP address may be necessary. I think the best approach would be to normalize the input string, break it down into an array of 16-bit integers, handle the increment, and then convert the array back to a string.

Since it's a surprisingly amusing exercise, I did it on my end. The only somewhat tricky part is handling the consecutive zeros shorthand. Here's my output for one test:

Source:     'fe80::0204:61ff:fe9d:ffff'
Normalized: 'fe80:0000:0000:0000:0204:61ff:fe9d:ffff'
IPv6 Parts:
        1: FE80
        2: 0
        3: 0
        4: 0
        5: 204
        6: 61FF
        7: FE9D
        8: FFFF
IPv6 Parts (after increment):
        1: FE80
        2: 0
        3: 0
        4: 0
        5: 204
        6: 61FF
        7: FE9E
        8: 0
Reformatted (normalized): 'fe80:0000:0000:0000:0204:61ff:fe9e:0000'
Reformatted (shorthand):  'fe80::204:61ff:fe9e:0'

It's about 130 lines of code, and that's a first draft, so that should be a taste of what it takes to do the job in C.

Thanks for your reply,

But I cant written the code in C.I understand the logic.Can any body help me to solve the problem?

Start by ignoring the requirement to handle the "::" shorthand. That's the only part of the problem that makes it even remotely difficult.


Depending on how you choose to handle the increment, reformatting the IP address may be necessary. I think the best approach would be to normalize the input string, break it down into an array of 16-bit integers, handle the increment, and then convert the array back to a string.

Since it's a surprisingly amusing exercise, I did it on my end. The only somewhat tricky part is handling the consecutive zeros shorthand. Here's my output for one test:

Source:     'fe80::0204:61ff:fe9d:ffff'
Normalized: 'fe80:0000:0000:0000:0204:61ff:fe9d:ffff'
IPv6 Parts:
        1: FE80
        2: 0
        3: 0
        4: 0
        5: 204
        6: 61FF
        7: FE9D
        8: FFFF
IPv6 Parts (after increment):
        1: FE80
        2: 0
        3: 0
        4: 0
        5: 204
        6: 61FF
        7: FE9E
        8: 0
Reformatted (normalized): 'fe80:0000:0000:0000:0204:61ff:fe9e:0000'
Reformatted (shorthand):  'fe80::204:61ff:fe9e:0'

It's about 130 lines of code, and that's a first draft, so that should be a taste of what it takes to do the job in C.

I just write down one part of the code.next part increase the address by 1.I already pick up the 8 parts(assuming my ipv6 format is - abcd:1432:fabe:1243:bb12:7263:0987:34ff)
The code is -

#include "stdafx.h"
#include "conio.h"
#include "stdio.h"
#include "string.h"


int _tmain(int argc, _TCHAR* argv[])
{
   //char line[] = "abcd:1432:fabe:1243:bb12:7263:0987:34ff";
	char address[50];
	printf("Enter the valis IPv6 address :");
	gets(address);
   char a[10], b[10], c[10],d[10],e[10],f[10],g[10],h[10];
   if(sscanf(address, "%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]", a, b, c,d,e,f,g,h) == 8)
   {
      printf("1st   = %s\n", a);
      printf("2nd   = %s\n", b);
      printf("3rd   = %s\n", c);
      printf("4th   = %s\n", d);
      printf("5th   = %s\n", e);
      printf("6th   = %s\n", f);
      printf("7th   = %s\n", g);
      printf("8th   = %s\n", h);
   }
   getch();
   return 0;
   
}

Output -

1st = abcd
2nd = 1432
3rd = fabe
4th = 1243
5th = bb12
6th = 7263
7th = 0987
8th = 34ff

But I dont know how to increment the hex value.

Waiting for your reply.

Jinna

Start by ignoring the requirement to handle the "::" shorthand. That's the only part of the problem that makes it even remotely difficult.


Depending on how you choose to handle the increment, reformatting the IP address may be necessary. I think the best approach would be to normalize the input string, break it down into an array of 16-bit integers, handle the increment, and then convert the array back to a string.

Since it's a surprisingly amusing exercise, I did it on my end. The only somewhat tricky part is handling the consecutive zeros shorthand. Here's my output for one test:

Source:     'fe80::0204:61ff:fe9d:ffff'
Normalized: 'fe80:0000:0000:0000:0204:61ff:fe9d:ffff'
IPv6 Parts:
        1: FE80
        2: 0
        3: 0
        4: 0
        5: 204
        6: 61FF
        7: FE9D
        8: FFFF
IPv6 Parts (after increment):
        1: FE80
        2: 0
        3: 0
        4: 0
        5: 204
        6: 61FF
        7: FE9E
        8: 0
Reformatted (normalized): 'fe80:0000:0000:0000:0204:61ff:fe9e:0000'
Reformatted (shorthand):  'fe80::204:61ff:fe9e:0'

It's about 130 lines of code, and that's a first draft, so that should be a taste of what it takes to do the job in C.

Don't store each hex value as a string, store it as a short. Then the increment is trivial. Here's my driver for the program without the increment step:

int main(void)
{
    const char *ip_src = "fe80::0204:61ff:fe9d:ffff";
    char *s = ipv6_normalize(ip_src);
    uint16_t parts[8];
    size_t k = 0;
    
    printf("Source:     '%s'\nNormalized: '%s'\n", ip_src, s);
    
    for (char *tok = strtok(s, ":"); tok != NULL; tok = strtok(NULL, ":"))
        sscanf(tok, "%hx", &parts[k++]);
    
    free(s);
    puts("IPv6 Parts:");
    
    for (size_t i = 0; i < k; i++)
        printf("\t%d: %hX\n", i + 1, parts[i]);
    
    // Increment from right to left until the result isn't 0 (unsigned wrap)
    
    puts("IPv6 Parts (after increment):");
    
    for (size_t i = 0; i < k; i++)
        printf("\t%d: %hX\n", i + 1, parts[i]);
        
    s = ipv6_tostring(parts, false);
    printf("Reformatted (normalized): '%s'\n", s);
    free(s);
    
    s = ipv6_tostring(parts, true);
    printf("Reformatted (shorthand):  '%s'\n", s);
    free(s);
        
    return 0;
}

The increment step is a simple loop, but I didn't want to do all of the work for you.

Thnx for your reply.
But this code is not running or not compiling.I am using visual studio 2005.What kind of editor you are using?Is there any problem for my editor?

My total code is -

// string_p.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "conio.h"
#include "stdio.h"
#include "string.h"
#include "malloc.h"


int _tmain(int argc, _TCHAR* argv[])
{
	 
    const char *ip_src = "fe80::0204:61ff:fe9d:ffff";
    char *s = ipv6_normalize(ip_src);
    uint16_t parts[8];
    size_t k =0;
     
    printf("Source: '%s'\nNormalized: '%s'\n", ip_src, s);
     
    for (char *tok = strtok(s, ":"); tok != NULL; tok = strtok(NULL, ":"))
    sscanf(tok, "%hx", &parts[k++]);
     
    free(s);
    puts("IPv6 Parts:");
     
    for (size_t i = 0; i < k; i++)
    printf("\t%d: %hX\n", i + 1, parts[i]);
     
    // Increment from right to left until the result isn't 0 (unsigned wrap)
     
    puts("IPv6 Parts (after increment):");
     
    for (size_t i = 0; i < k; i++)
    printf("\t%d: %hX\n", i + 1, parts[i]);
     
    s = ipv6_tostring(parts, false);
    printf("Reformatted (normalized): '%s'\n", s);
    free(s);
     
    s = ipv6_tostring(parts, true);
    printf("Reformatted (shorthand): '%s'\n", s);
    free(s);
     
    getch();
    return 0;
   
}

Output is -

1>c:\documents and settings\polaris\my documents\visual studio 2005\projects\string_t\string_t\string_t.cpp(15) : error C3861: 'ipv6_normalize': identifier not found
1>c:\documents and settings\polaris\my documents\visual studio 2005\projects\string_t\string_t\string_t.cpp(16) : error C2065: 'uint16_t' : undeclared identifier
1>c:\documents and settings\polaris\my documents\visual studio 2005\projects\string_t\string_t\string_t.cpp(16) : error C2146: syntax error : missing ';' before identifier 'parts'
1>c:\documents and settings\polaris\my documents\visual studio 2005\projects\string_t\string_t\string_t.cpp(16) : error C2065: 'parts' : undeclared identifier
1>c:\documents and settings\polaris\my documents\visual studio 2005\projects\string_t\string_t\string_t.cpp(37) : error C3861: 'ipv6_tostring': identifier not found
1>c:\documents and settings\polaris\my documents\visual studio 2005\projects\string_t\string_t\string_t.cpp(41) : error C3861: 'ipv6_tostring': identifier not found

Waiting for your reply

Don't store each hex value as a string, store it as a short. Then the increment is trivial. Here's my driver for the program without the increment step:

int main(void)
{
    const char *ip_src = "fe80::0204:61ff:fe9d:ffff";
    char *s = ipv6_normalize(ip_src);
    uint16_t parts[8];
    size_t k = 0;
    
    printf("Source:     '%s'\nNormalized: '%s'\n", ip_src, s);
    
    for (char *tok = strtok(s, ":"); tok != NULL; tok = strtok(NULL, ":"))
        sscanf(tok, "%hx", &parts[k++]);
    
    free(s);
    puts("IPv6 Parts:");
    
    for (size_t i = 0; i < k; i++)
        printf("\t%d: %hX\n", i + 1, parts[i]);
    
    // Increment from right to left until the result isn't 0 (unsigned wrap)
    
    puts("IPv6 Parts (after increment):");
    
    for (size_t i = 0; i < k; i++)
        printf("\t%d: %hX\n", i + 1, parts[i]);
        
    s = ipv6_tostring(parts, false);
    printf("Reformatted (normalized): '%s'\n", s);
    free(s);
    
    s = ipv6_tostring(parts, true);
    printf("Reformatted (shorthand):  '%s'\n", s);
    free(s);
        
    return 0;
}

The increment step is a simple loop, but I didn't want to do all of the work for you.

But this code is not running or not compiling.

No shit. I'm not going to do your work for you, and as such, I didn't give you all of the code from my program. The definitions for ipv6_normalize() and ipv6_tostring() are key examples, those functions are the meat of the program in that they do the heavy lifting of preparing the IPv6 string for conversion to parts and for display.

I also didn't include headers, which should be the first flag that the code is a snippet and not compilable as-is.

Hi Narue,

Thnx for you help.I already done the code with your help.My code is given below -

#include "stdafx.h"
#include "conio.h"
#include "stdio.h"


int _tmain(int argc, _TCHAR* argv[])
{
	 
    unsigned int addr[8];
	char *argument = "aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa";
	

    if (sscanf(argument, "%x:%x:%x:%x:%x:%x:%x:%x",
        addr + 0,
        addr + 1,
        addr + 2,
        addr + 3,
        addr + 4,
        addr + 5,
        addr + 6,
		addr + 7) < 8) {
		fputs("argument is of wrong format\n", stderr);
        return 1;
    }

    unsigned int carry = 1, i = 8;
    while (carry && i)
    {
        addr[i-1] += carry;
        if (addr[i-1] > 0xffff || !addr[i-1])
        {
            carry = 1;
            addr[i-1] &= 0xffff;
        } else carry = 0;
        i--;
    }
    printf("Original address:\n%s\n"
           "New address:\n%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
           argument,
           addr[0],
           addr[1],
           addr[2],
           addr[3],
           addr[4],
           addr[5],
           addr[6],
           addr[7]);
    if (carry) puts("also, an overflow occured"); 
    getch();
    return 0;
   
}

But the problem is that when the string is abcf:6252::ffff
My output will be abcf:6252::0001:0000

Can you help me in this matter?


No shit. I'm not going to do your work for you, and as such, I didn't give you all of the code from my program. The definitions for ipv6_normalize() and ipv6_tostring() are key examples, those functions are the meat of the program in that they do the heavy lifting of preparing the IPv6 string for conversion to parts and for display.

I also didn't include headers, which should be the first flag that the code is a snippet and not compilable as-is.

But the problem is that when the string is abcf:6252::ffff
My output will be abcf:6252::0001:0000

Can you help me in this matter?

What's wrong with that output? It looks fine to me:

Original:    "abcf:6252::ffff"
Expanded:    "abcf:6252:0000:0000:0000:0000:0000:ffff"
Incremented: "abcf:6252:0000:0000:0000:0000:0001:0000"
Compacted:   "abcf:6252::0001:0000"

Hi Narue,

Thank you very much for your reply.My code is working only when the address is abcf:6252:0000:0000:0000:0000:0000:ffff or in this full IPv6 format.
But if I enter abcf:6252::ffff its not work.
This is the main problem.
So,can you help me in this matter?

What's wrong with that output? It looks fine to me:

Original:    "abcf:6252::ffff"
Expanded:    "abcf:6252:0000:0000:0000:0000:0000:ffff"
Incremented: "abcf:6252:0000:0000:0000:0000:0001:0000"
Compacted:   "abcf:6252::0001:0000"

But if I enter abcf:6252::ffff its not work.

That's understandable. scanf() doesn't know what IPv6 is, you need to figure out how to turn "abcf:6252::ffff" into "abcf:6252:0000:0000:0000:0000:0000:ffff" and write code to do it. That means counting how many fields are missing and filling them in with zeros.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.