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++
12745 Discussions

problem with re-building TCP/IP connection on Nios

Altera_Forum
Honored Contributor II
2,102 Views

Dear all, 

 

Currently in my design I want to make a function to change the Nios' ip address. It is almost completed, but there is still a problem.  

 

So here are the progress : 

1. I can change the Nios ip address successfully. It has been proven by ping function from other devices / PC to the Nios' new ip address. 

2. The Nios can initialize a new socket using its new ip address. There is no error in TCP/IP socket initiation (create socket, bind, listen). In the new TCP/IP connection, I have to make Nios use different port, otherwise it will be error (I'm not sure what the reason is). 

 

The problem is.. when I try to establish a TCP/IP connection from my PC, somehow the Nios can't accept any request from other devices. It just keep listening and my pc seems that it couldn't find the Nios socket with its new ip address. 

 

Here is my code : 

 

void SocketComTask() { int fd_listen, max_socket, new_fd_listen; struct sockaddr_in addr; static SCConn conn; fd_set readfds; AccData acc; NetInfo ip_data; while(1) { if(ip_data.ip_chg==1) { change_ip(ip_data); // function to change ip address } // socket creation // ------------------------------------------------ if((fd_listen = socket(AF_INET, SOCK_STREAM, 0)) < 0) // socket function returns a descriptor referencing the new socket { alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE," Socket creation failed"); } // bind // ------------------------------------------------ addr.sin_family = AF_INET; if(ip_data.ip_chg == 0) addr.sin_port = htons(SC_PORT); else addr.sin_port = htons(SC_PORT2); addr.sin_addr.s_addr = INADDR_ANY; if ((bind(fd_listen,(struct sockaddr *)&addr,sizeof(addr)))<0) { alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE," Bind failed"); } // listen // ------------------------------------------------ if((listen(fd_listen,1))<0) { alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE," Listen failed"); } sc_reset_conn(&conn); if(ip_data.ip_chg == 0) printf(" Socket Com listening on port %d\n", SC_PORT); else { printf(" Socket Com listening on port %d\n", SC_PORT2); ip_data.ip_chg = 0; } while(1) { FD_ZERO(&readfds); // FD_ZERO(*set) : initializes the set to the null set FD_SET (fd_listen, &readfds); // FD_SET(s,*set) : add descriptor s to set max_socket = fd_listen+1; if (conn.fd != 1) { FD_SET(conn.fd, &readfds); if(max_socket <= conn.fd) { max_socket = conn.fd+1; } } select(max_socket, &readfds, NULL, NULL, NULL); if(FD_ISSET(fd_listen, &readfds)) // FD_ISSET(s,*set) : nonzero if s is a member of the set, otherwise zero { acc = sc_handle_accept(fd_listen, &conn); } else { if((conn.fd != -1) && FD_ISSET(conn.fd, &readfds) && acc.index==0) { sc_handle_receive(&conn); } else if((conn.fd != -1) && FD_ISSET(conn.fd, &readfds) && acc.index==1) { ip_data = sc_handle_receive_ctrl(&fd_listen, &conn, acc.client_ip); if(ip_data.ip_chg==1) // check indicator whether there is ip change command or not { conn.close = 1; close(conn.fd); close(fd_listen); break; } } } } } } int change_ip (NetInfo new_ip) { NET p_net; ip_addr ipaddr, netmask, gw; int iface = 0; 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(new_ip.dhcp_actv) { p_net -> n_flags |= NF_DHCPC; dhc_state_init(iface, FALSE); // put DHCP client in INIT reboot printf(" DHCP IP has been assigned\n"); } else { p_net -> n_flags &= ~NF_DHCPC; dhc_set_state(iface, 0); // put DHCP client 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; printf(" Static IP has been assigned\n"); } int e = dhc_second(); if(e) printf("DHCP returned error %i.\n", e); return 0; }  

 

 

Does anyone know what's wrong with my program? Anybody know how to completely close socket and flush its configuration? I'm wondering that the problem is related with select function, somehow Nios maybe can't find its socket that is ready for reading/writing...:confused: 

 

Or if you have any suggestion for my problem, please kindly to tell me :(
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
1,065 Views

If you mean you can ping and connect with other clients but not with the PC which previously established the connection with the old address, the problem is simple: 

The TCP/IP stack has a address table (named ARP table) which stores IP addresses along with the associated MAC address. This avoids the stack to issue a ARP request every time a connection to a known IP is requested: if the IP has already been used, the system already knows where it can be found. 

The table is updated continuously when new IP are discovered, but each entry is cleared only after a few minutes (I mean 5 to 10 minutes) the IP address is not used. 

Then, if you change the IP address of one of these devices, the ARP table entry is not updated and it would contain mismatched IP and MAC. 

If you use Windows you can verify it with the arp -a command which displays the current ARP entries. 

Solutions: 

- wait the time required for ARP table to be cleared when you change the IP before trying a new connection 

- manually clear the ARP table entry at the old IP address: arp -d <old_ip> 

 

I hope this helps you 

 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
1,065 Views

Hi Cris, thank you for your reply :) 

 

I have tried your advice, and it almost solve my problem. The PC which previously established with the old ip address still couldn't connect to the Nios (even though I have cleared the Nios' old ip address from PC's ARP table and waited for several minutes). But when I try to connect from another PC (from different ip address of course), I can connect to the Nios (Horray!! :) ). 

 

So is there a mechanism 'client-list' in Nios (sorry, I don't know how to call it) that stores any ip address which ever connected to the Nios? If there is, how to clear that 'list'? :confused: Or maybe you notice another problem in this case. 

 

Looking forward your reply, Thanks!
0 Kudos
Altera_Forum
Honored Contributor II
1,065 Views

Update : 

I just tried once again (assigned the Nios a new ip address, cleared ARP table in PC side, and waited for several minutes), and it works. :D 

Ah! sorry, you are right I have to wait for several minutes :p (even though I connect from different PC). So clearing the ARP table manually didn't guarantee that the same client (PC) can connect to Nios soon. I think it is because the router's ARP table is still being updated, am I correct? Or is it possibly caused by 'client-list' that I asked in my previous post (if such mechanism exist :confused:) 

 

The important thing now is I know that my code is correct and I can connect to Nios' new ip address...fiuuh. I've spent weeks desperately to figure out what the actual problem is.  

Thanks! ;)
0 Kudos
Altera_Forum
Honored Contributor II
1,065 Views

Probably you need to clear the Nios ARP entry, too; otherwise you have to wait a long timeout, like on PC side. 

You can try this function: 

int clear_arp_entries(ip_addr dest_ip, NET ifp) 

 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
1,065 Views

Good point, I didn't think of the ARP cache before. 

 

How are your devices connected? 

Do you have a sophisticated switch between them?  

Those are known for keeping an ARP-Cache, too. 

 

*just guessing* 

Does it help to disconnect and reconnect the Ethernet cable? 

Maybe it's enough to restart autoconfiguration on the Phy then?
0 Kudos
Altera_Forum
Honored Contributor II
1,065 Views

The external switches will only be remembering the MAC address. 

Reconnecting the cable really ought to have no effect at all. 

(Microsoft Windows is broken here - it should not disconnect TCP connections when the cable is disconnected.)
0 Kudos
Reply