Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12606 Discussions

How do Nios-II handle IP address change during the TCP/IP connection?

Altera_Forum
Honored Contributor II
3,733 Views

Dear all, 

 

I have problem with changing IP address in the FPGA board.  

 

Here is my case, let say I have a FPGA board which is connected to PC. The PC sends a command to the FPGA that asks the FPGA to change its IP address to a new given IP address. 

 

Here is my idea to handle this task : 

  1. After receiving IP changes command from PC, both FPGA and PC terminate their TCP/IP connection by close their socket. 

  2. The FPGA does the IP changes mechanism 

  3. Both FPGA and PC initiate a new TCP/IP connection like usual 

  4. The FPGA sends acknowledgement to the PC to tell that it already changes its IP address successfully. 

 

 

Up to here, what do you think guys? Is my idea correct? :confused:  

 

Now I'm facing problem with step no.2 above. To change the FPGA's IP address, what I'm thinking is in the FPGA I have to do these steps : 

  1. Terminate the previous TCP/IP connection (close the exist socket) 

  2. Assign new IP address to the FPGA (I have made a new function called 'change_ip' which is basically same as get_ip_addr function provided by altera) 

  3. Initiate new TCP/IP connection (create, bind, listen socket) 

 

 

But the result is error, I got this following error message : 

: See STDERR for expanded diagnosis translation. : Bind failed : ERRNO: : : See STDERR (FAULT_LEVEL is SYSTEM). : FAULT_LEVEL is SYSTEM. : FATAL Error, Restart required. : Locking scheduler - endless loop. 

 

I also tried to kill the previous "inet main" and "clock tick" tasks, but in the end it also ends up with the same error message. 

 

Anybody know how is the correct procedure to change FPGA's IP address? :confused: :confused:  

 

Thanks for any comments or suggestions!
0 Kudos
27 Replies
Altera_Forum
Honored Contributor II
1,036 Views

Take a look at the function "set_ipaddr()" inside the following file: 

 

C:\altera\91\nios2eds\components\altera_iniche\UCOSII\src\misclib\nrmenus.c 

 

This will indicate how the InterNiche stack performs a ip address change. See if that helps. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Hi jakobjones, thanks for your reply. Finally I got a clue.  

I will check the function you mentioned and tell you the result later! ;)  

 

If anybody have other suggestions, feel free to share it :)
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Hi Jakobjones! 

 

I've checked the "set_ipaddr()" function and "alt_iniche_dev.c", then I made my own function to change the ip address. Here is the code : 

int change_ip (int dhcp_actv) { alt_iniche_dev *p_dev; NET p_net; ip_addr ipaddr, netmask, gw; NetInfo new_ip; new_ip.ipaddr_in = 192; new_ip.ipaddr_in = 168; new_ip.ipaddr_in = 1; new_ip.ipaddr_in = 3; new_ip.netmask_in = 255; new_ip.netmask_in = 255; new_ip.netmask_in = 255; new_ip.netmask_in = 0; new_ip.gw_in = 192; new_ip.gw_in = 168; new_ip.gw_in = 1; new_ip.gw_in = 1; p_dev -> p_net = nets; // Get the new ip address printf(" Get the new ip address\n"); if(dhcp_actv) p_net -> n_flags |= NF_DHCPC; else { IP4_ADDR( ipaddr, new_ip.ipaddr_in, new_ip.ipaddr_in, new_ip.ipaddr_in, new_ip.ipaddr_in ); IP4_ADDR( netmask, new_ip.netmask_in, new_ip.netmask_in, new_ip.netmask_in, new_ip.netmask_in ); IP4_ADDR( gw, new_ip.gw_in, new_ip.gw_in, new_ip.gw_in, new_ip.gw_in ); p_net -> n_ipaddr = ipaddr; p_net -> snmask = netmask; p_net -> n_defgw = gw; } return 0; }  

 

There was no error either during the compilation or after the program execution, but the Nios' IP address didn't change (I've checked it by ping the Nios from my pc). It still used the old IP address. 

Do you know what's wrong with my code? I'm thinking that I need to reset the NicheStack or force the NicheStack to read the new assigned IP address. But I don't know how to do that. Hopefully you can help me..  

Thanks before.
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Ah.. I got it! I found the mistake in my code. 

 

The mistake is here : 

p_dev -> p_net = nets[0]; 

 

It should be  

p_net = nets[0]; 

 

Thank you all!
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Sorry to re-open this thread, but I had the same problem. 

Your code worked for me, except for DHCP. 

 

This one does: 

 

if(dhcp_actv) { p_net -> n_flags |= NF_DHCPC; // dhc_setup(); // fails, because port is in use? dhc_state_init(0, FALSE); /* Put DHCPClient in INIT-REBOOT state */ int e = dhc_second(); /* To send the DISCOVER/REQUEST pkt */ if (e) printf("DHCP returned error %i.\n", e); } In dhc_setup(), calling dhc_first() fails , probably because the port is already in use. So I just called dhc_second, is it's done in dhc_setup(). 

Works for me.
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

@ Jakobjones 

 

I have created this following function to change the ethernet's IP address during the TCP/IP connection  

 

int change_ip (int dhcp_actv, NetInfo new_ip) { NET p_net; ip_addr ipaddr, netmask, gw; p_net = nets; // for multi network interface, check file alt_iniche_dev.c // Get the new ip address printf(" Get the new ip address\n"); if(dhcp_actv) p_net -> n_flags |= NF_DHCPC; else { IP4_ADDR( ipaddr, new_ip.ipaddr_in, new_ip.ipaddr_in, new_ip.ipaddr_in, new_ip.ipaddr_in ); IP4_ADDR( netmask, new_ip.netmask_in, new_ip.netmask_in, new_ip.netmask_in, new_ip.netmask_in ); IP4_ADDR( gw, new_ip.gw_in, new_ip.gw_in, new_ip.gw_in, new_ip.gw_in ); p_net -> n_ipaddr = ipaddr; p_net -> snmask = netmask; p_net -> n_defgw = gw; } netmain_init(); iniche_net_ready = TRUE; return 0; }Then after executing the above code, I re-initialize the TCP/IP connection (socket creation, bind, listen, select). 

 

The above code could work correctly. However, it only could change the IP address for two times in sequence. In the third times, it would be error. The error message said that the program couldn't find any ethernet card anymore.  

 

From debugging my code, I noticed that whenever I assigned a new IP address to my ethernet, the Nios-II thought that as IP address for another ethernet card. Since in the default niche configuration Nios-II only supports for two ethernet cards, in the third times of new IP address assignment, Nios-II will generate error notification. 

 

Do you know how to solve this problem? Is there any function to flush the ethernet configuration, such that whenever I assign a new ip address, the Nios will notice it as for the same ethernet card? :( 

 

And another question is about the DHCP connection. Since in this current project I want to provide on-fly DHCP / manual IP address assignment, I disable the 'dhcp client' option in the altera niche. For re-initialize DHCP function do you think it is enough by assigning this single code :  

p_net -> n_flags |= NF_DHCPCOr are there anything else that I need to configure? :confused: 

 

 

Thank you. 

I'm looking forward any help from you or anyone
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

As far as I have seen, there is no need to call netmain_init(). 

Is there a reason why you are executing it? 

 

If you disable DHCP in the BSP, there is no DHCP code in your project. 

It is surrounded by -ifdef everywhere, and won't get included. 

 

It will be better to change get_ip_addr(), and set use_dhcp = 0 there. 

This function is there for customization, so that's the point to start. 

I'm not sure this will do it, maybe one has to disable the NF_DHCPC flag (wherever that gets set; I have seen it already, but can't remember where). 

 

To enable DHCP then, you can use my code as above. 

 

The 3 times problem I have not seen yet, as I have just changed my IP Address 2 times: DHCP->static->DHCP. 

I'll try tomorrow.
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Hi mcr42! Thank you for your reply :)  

 

I thought that we used netmain_init() to apply new IP address that we just assigned. Otherwise, the ethernet card would not notice the new ip address, am I correct?  

 

Well, I will try not to call netmain_init() after assign a new IP address, and see what happen. Maybe netmain_init() is the reason for my three times problems (fyi, on that time I tried to do static --> static --> static ip address assignment). 

 

I just read your DHCP configuration code today, I will also try it and inform you about the results. 

 

Thanks! :)
0 Kudos
Altera_Forum
Honored Contributor II
1,035 Views

I have done a small test, 7 changes static->static, and it seems to be stable. 

Even when doing 4 times DHCP->static->DHCP, there is no problem. 

 

It might be neccessary to wait until DHCP has finished (which is not the case when DHC_second returns). 

Depending on the network the DHCP response takes a moment. 

 

A newly initiated connection might still use the old IP. When the response arrives after the new IP was assigned, it will not be seen, and the connection times out.  

 

Also, reading the code again, dhc_second() does not evalutate the NF_DHCPC flag. Also, there is a note that dhc_second() should be called every once in a while to update leases. 

 

Therefore I think it's neccessany to disable the DHCPClient via the state variable: 

 

if(dhcp_actv) { p_net -> n_flags |= NF_DHCPC; dhc_state_init(iface, FALSE); /* Put DHCPClient in INIT-REBOOT state */ ...... } else { p_net -> n_flags &= ~NF_DHCPC; dhc_set_state(iface, 0); /* set interface state to DHCS_UNUSED */ ...... } So my change_ip() looks like this now: 

typedef struct { alt_u8 ipaddr_in; alt_u8 netmask_in; alt_u8 gw_in; } NetInfo; int change_ip (NetInfo new_ip, int dhcp_actv) { // alt_iniche_dev *p_dev; NET p_net; ip_addr ipaddr, netmask, gw; int iface = 0; // number of interface to use p_net = nets; // Get the new ip address printf(" Get new ip address:\n"); if(dhcp_actv) { p_net -> n_flags |= NF_DHCPC; dhc_state_init(iface, FALSE); /* Put DHCPClient in INIT-REBOOT state */ } else { p_net -> n_flags &= ~NF_DHCPC; dhc_set_state(iface, 0); /* put DHCPClient in DHCS_UNUSED state */ IP4_ADDR( ipaddr, new_ip.ipaddr_in, new_ip.ipaddr_in, new_ip.ipaddr_in, new_ip.ipaddr_in ); IP4_ADDR( netmask, new_ip.netmask_in, new_ip.netmask_in, new_ip.netmask_in, new_ip.netmask_in ); IP4_ADDR( gw, new_ip.gw_in, new_ip.gw_in, new_ip.gw_in, new_ip.gw_in ); p_net -> n_ipaddr = ipaddr; p_net -> snmask = netmask; p_net -> n_defgw = gw; } // dhc_setup(); // fails, because port is in use? int e = dhc_second(); /* To send the DISCOVER/REQUEST pkt */ if (e) printf("DHCP returned error %i.\n", e); return 0; }
0 Kudos
Altera_Forum
Honored Contributor II
1,035 Views

Thanks for sharing your code. It looks great! 

 

Now I'm trying using your code. Somehow, my Nios is always failed when it tries to bind the new socket. Do you have any suggestion about this? 

 

Thank you.
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Can you be a bit more specific? 

What are you trying to do?
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Ah sorry, I didn't tell you before. What I'm trying to do is I want to change my Nios IP address by sending a command from PC. 

 

So here is the step-by-step process that happen in my current system : 

  1. At first Nios obtains its IP address via DHCP 

  2. Nios acts as a server and provides a TCP/IP connection. It does these TCP/IP connection initiation functions : creating socket, binding, listening, and selecting socket 

  3. PC builds TCP/IP connection to Nios 

  4. After the TCP/IP connection has been established, PC sends a command to Nios (via TCP/IP) that tells Nios to change its IP address. In this step, the new IP address that will be assigned to the Nios is determined by PC (the new IP address is also sent with the command). 

  5. After sending the command, PC will close the TCP/IP connection (since Nios will use the new IP address, the previous TCP/IP connection will be broken) 

  6. Nios change its IP address (using 'change_ip' function, static method) 

  7. Nios repeat step no.2 

  8. PC repeat step no.3 (of course, PC will call Nios using its new IP address) 

  9. Nios sends a official notification to PC that it has changed its IP address correctly. 

 

 

That's all. Do you get some idea with this?
0 Kudos
Altera_Forum
Honored Contributor II
1,035 Views

Yes, I get the idea. 

 

I have just been using the webserver example, and there is no need to re-do the socket_create/bind/listen stuff. I just issue change_ip() and the webserver is responding at the new address. 

 

I'm not sure whether the example takes care of it, but I would be surprised if it does. 

 

Where is your problem?  

Are you getting an error in Step 7?  

Are you getting no connection in Step 8?
0 Kudos
Altera_Forum
Honored Contributor II
1,035 Views

Update : 

When PC sends a command to Nios that tells Nios to renew its DHCP IP address, Nios can re-initialize the new TCP/IP connection correctly. 

 

Hmm.... I'm wondering what's wrong with my static ip address assignment case.
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

I am failed at step 7. Since the step 7 is failed of course step 8 is also failed (because PC couldn't find the available socket) 

 

Wow really?? are you sure you don't need to re-do the TCP/IP establishment? How can the previous TCP/IP connection is not broken? 

 

I've tried also without re-initialization of TCP/IP connection, but it was error on step 8. But the strange thing is I can ping the Nios with its new IP address.
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

I assume, server sockets are indepentent of the given IP address. 

Once a client connects, a new socket is created for this connection. 

This new socket might be bound to the ip address. 

 

I have no idea why your server should not be reachable, if ping is working. 

Maybe you can compare the ping code to yours?
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Hi all, 

 

I want to inform you that the bind-socket problem in my design can be overcome by connecting to the Nios via different port. It seems that the previous port is still being used (somehow..I don't know:confused:) 

 

So now I face another problem. I have closed my previous socket (using close() function), changed Nios' IP address with the new IP address, re-initialize TCP/IP connection (create socket, bind, listen) correctly / without error.  

 

But when I tried to access the Nios (which has been assigned with the new ip address) from my PC, my PC always couldn't connect to the Nios :confused:. It looked like that my PC couldn't find the Nios' new socket. :confused: 

 

Meanwhile, the Nios was ready to accept any new connection. The Nios IP address also could be ping from my PC. So do anyone know how to solve this problem?? :( 

 

I'm thinking that the previous socket wasn't closed completely. Does anyone know how to completely destroy the old socket? 

 

Thanks all! Hopefully anyone of you can help me to figure out my problem.
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

@mcr42  

Hi, I want to ask you some questions.  

 

You said that after you changed the Nios' IP address, you didn't need to close the previous connection or re-initialize the TCP/IP connection. When your Nios changed its IP address, was it still connected to any client or not :confused:? I mean, has The Nios accepted a TCP/IP connection request from any client before it changed its IP address?  

 

In my case, before the Nios changed its IP address, it was still connected to a client. And my problem is in maintaining or rebuilding a new TCP/IP connection to the same client. 

 

Would you share a piece of your code? I'm still curious how you can maintain the TCP/IP connection despite of Nios IP changes. If you mind to put it in this public thread, you may send it by private message to me. 

 

Thank you. 

 

p.s. I really appreciate if there are anyone have suggestion to solve my problem. :(
0 Kudos
Altera_Forum
Honored Contributor II
1,036 Views

Hello fightingdreamer, i would like a piece of your code that you used to transfer from fifo->pio->sdram, if you could.. (send me a private msg or e-mail me at aprado@dhw.eng.br :D) 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
908 Views

I did not write any code concerning connections. 

I was just using the web server example, which I checked from the browser on my development machine. 

The NIOS web server responded on one IP address, the IP address was changed, and the NIOS responded on the new IP address. 

 

But HTTP is not a protocoll where connections are kept open for long.  

So I have not changed the IP during an active connection. 

But, I'd assume the TPC stack drops all packets that don't match the IP address (as it probably should). 

The server however starts responding as soon as the new IP address is in place.
0 Kudos
Reply