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

UDP send always fails with -1

Altera_Forum
Honored Contributor II
1,541 Views

Hi, 

 

We have a simple setup running on Altera development board where we are attempting to send a UDP packet out to a PC for collcetion. Starting with the net example files, I was able to build a cut down version of udp_lo_test.c that only sends UDP rather than both send and recieve. A Linux machine running Ethereal has been configured to pick up the outgoing UDP packets. 

 

The problem is that when we go to send the UDP packet we get a -1 return from the sendto() method. Looking into the documentation has prooved fruitless as it seems that sendto() responds with -1 on every possible error it produces. This is odd, as an ARP request has been intercepted by the Linux box, possibly indicating that the Altera has attempted to resolve the Linux machines MAC. The NIOS II debugger IDE has not yielded any answers either, all it seems to do is display erratic (yet consistant) behaviour once entering the ECOS library. 

 

We are certain that ECOS is set up correctly as we are able to access the ECOS status web bage from the target. 

 

Can anyone shed any light on to what we are doing wrong? 

 

Our application is included below. 

 

//========================================================================== // //      tests/udp_lo_test.c // //      Simple UDP throughput test // //========================================================================== //####BSDCOPYRIGHTBEGIN#### // // ------------------------------------------- // // Portions of this software may have been derived from OpenBSD or other sources // and are covered by the appropriate copyright disclaimers included herein. // // ------------------------------------------- // //####BSDCOPYRIGHTEND#### //========================================================================== //#####DESCRIPTIONBEGIN#### // // Author(s):    sorin@netappi.com // Contributors: gthomas,sorin@netappi.com, hmt // Date:         2000-05-24 // Mofified:     steve.mann@<stuff>.co.nz // replace stuff with tait // Date:         2005-03-12 // Network throughput test code # include <network.h> # include <cyg/infra/testcase.h> # define SOURCE_PORT 9990 # define MAX_BUF 1000 static unsigned char data_buf_write="Client UDP is alive. You may continue ...."; # define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x10000) static char stack_client; static cyg_thread client_thread_data; static cyg_handle_t client_thread_handle;   # define MAIN_THREAD_PRIORITY     CYGPKG_NET_THREAD_PRIORITY-4 /* This looks to be a tidier exit routine than the defailt one. */ void pexit(char *s) {    CYG_TEST_FAIL_FINISH( s ); } void client(void) {  /* Our local stuff.   */    int s_source; // Socket handle    struct sockaddr_in local; // Address structure    int len; // Seems to hold the return value of the packet send.  Quite possibly a lenght indicator.    printf("client:started\n");        /* In most operating systems, network connections are handled much like file streams.     * We request a handle that we can configure and use, and when we are done we can     * call the close method on the handle.     */    s_source = socket(AF_INET, SOCK_DGRAM, 0);        /* Nothing like a little sanity test on the socket.     * Here, a negative number appears to be an error report.     */    if (s_source < 0) {        pexit("stream socket");    }        /* This appears to be a structure zeroing procedure.     * I imagine there are other fields in this structure that are not considered by     * this routine and are zeroed to set them to a known default.     */    memset(&local, 0, sizeof(local));        /* Here, the connection is defined.     */    local.sin_family = AF_INET;    local.sin_len = sizeof(local);    local.sin_port = htons(SOURCE_PORT);        /* Target address - it is an IP in hex.     * In this particular case, 172.25.110.17 ges to AC.19.6E.11     */    local.sin_addr.s_addr = htonl(0xAC196E11);    //local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);        //printf("%d \n",connect(s_source, (struct sockaddr *)&local, sizeof(local)));        /* This portion of code appears to be the send routine for the client/     */    if ( (len= sendto(s_source,data_buf_write,sizeof(data_buf_write),                      0,(struct sockaddr *)&local,sizeof(local))) < 0 ) {        printf("%d\n", len);        CYG_TEST_FAIL_FINISH("Error writing buffer");    }        /* When we are done, it is good karma to deal woith our allcoated socket.     */    close(s_source); } void udp_client(cyg_addrword_t param) {    printf("Start UDP client - test\n"); # if NLOOP > 0    client(); # endif } void cyg_start(void) {    CYG_TEST_INIT();    printf("UDP blit test - How much data can we pull?\n");    while(1)        client(); }
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
857 Views

You might want to check the value of errno after the call to sendto() fails. This should contain the reason for the error, and may shed more light on what&#39;s going wrong.

0 Kudos
Altera_Forum
Honored Contributor II
857 Views

Thanks for that, I now know the error is 331 which is... 

 

EADDRNOTAVAIL 331 /* Can&#39;t assign requested address */ 

 

I assume this is referring to the IP address of the target I&#39;m trying to send to, but have checked this and it is correct.  

 

I was wondering if the setting in &#39;Basic networking framework&#39; in the config tool for eth0 could affest this. I&#39;ve unselected &#39;Use full DHCP instead of BOOTP&#39; and have entered specific addresses for eth0. 

 

Any suggestions would be appreciated.
0 Kudos
Altera_Forum
Honored Contributor II
857 Views

Given that you can access the web page, it sounds like the problem really is something to do with the address that you are using. Is the ARP you are seeing for the correct address? and is the machine you are trying to send to the same one as you are running your web browser on? 

 

Also, while it&#39;s probably nothing to do with your problem, I would have used: 

 

local.sin_addr.s_addr = inet_addr ("172.25.110.17"); 

 

rather than: 

 

local.sin_addr.s_addr = htonl(0xAC196E11); 

 

just for readability.
0 Kudos
Altera_Forum
Honored Contributor II
857 Views

Hi, 

 

I&#39;ve made progress today, I&#39;ve managed to get things so that sendto does not fail. To do this I added init_all_network_interfaces() into CYG_START, and that seemed to cure things.  

 

I&#39;m using a hub to connect to the PC (to avoid any probs the network may cause), and all that results is that one ARP goes across to the PC, which acknowledges it and sends it out (Ethereal readout looks fine). You can see the green LED on the NIOS-eval_board flash each time, and there after there is no activity. Even though the client is run multiple times and reports its sent the entire data_buffer.  

 

I&#39;ve included the code I&#39;m currently using and the console readout below. I guess I need to figure out why things go dead after the ARP, but don&#39;t know where to start (really am a novice at all this)! 

 

//========================================================================== // //      tests/udp_lo_test.c // //      Simple UDP throughput test // //========================================================================== //####BSDCOPYRIGHTBEGIN#### // // ------------------------------------------- // // Portions of this software may have been derived from OpenBSD or other sources // and are covered by the appropriate copyright disclaimers included herein. // // ------------------------------------------- // //####BSDCOPYRIGHTEND#### //========================================================================== //#####DESCRIPTIONBEGIN#### // // Author(s):    sorin@netappi.com // Contributors: gthomas,sorin@netappi.com, hmt // Date:         2000-05-24 // Network throughput test code # include <network.h># include <errno.h> # include <cyg/infra/testcase.h> # define SOURCE_PORT 9990# define SINK_PORT   9991 # define NUM_BUF 1024# define MAX_BUF 8192 static unsigned char data_buf; static unsigned char data_buf_write="Client UDP is alive. You may continue ...."; # define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x10000) static char stack_server; static cyg_thread server_thread_data; static cyg_handle_t server_thread_handle; static char stack_client; static cyg_thread client_thread_data; static cyg_handle_t client_thread_handle;   # define MAIN_THREAD_PRIORITY     CYGPKG_NET_THREAD_PRIORITY-4 void pexit(char *s) {    CYG_TEST_FAIL_FINISH( s ); } void client(void) {    int s_source;    struct sockaddr_in local;    int len;    printf("client:started\n");        s_source = socket(AF_INET, SOCK_DGRAM, 0);    if (s_source < 0) {        pexit("stream socket");    }    memset(&local, 0, sizeof(local));    local.sin_family = AF_INET;    local.sin_len = sizeof(local);    local.sin_port = htons(SOURCE_PORT);    local.sin_addr.s_addr = inet_addr ("172.25.110.17"); //    local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);    if ( (len= sendto(s_source,data_buf_write,sizeof(data_buf_write),                      0,(struct sockaddr *)&local,sizeof(local))) < 0 ) {        diag_printf("error = %d\n",errno);        CYG_TEST_FAIL_FINISH("Error writing buffer");            }    printf("Length Sent %d\n",len);        close(s_source); } void udp_server(cyg_addrword_t param) {    init_all_network_interfaces();    diag_printf("Start UDP server - test\n");    cyg_thread_resume(client_thread_handle);    // Start the other one# if NLOOP > 0    server();    CYG_TEST_PASS_FINISH("Server returned OK");# endif    CYG_TEST_NA( "No loopback devs" ); } void udp_client(cyg_addrword_t param) {    diag_printf("Start UDP client - test\n");# if NLOOP > 0    client(); # endif } void cyg_start(void) {    //CYG_TEST_INIT();        init_all_network_interfaces();    while(1)     client(); } 

 

Console ... 

 

[cyg_net_init] Init: mbinit(0x00000000) 

[cyg_net_init] Init: cyg_net_init_devs(0x00000000) 

Init device &#39;lan91c111_eth0&#39; 

[cyg_net_init] Init: loopattach(0x00000000) 

[cyg_net_init] Init: ifinit(0x00000000) 

[cyg_net_init] Init: domaininit(0x00000000) 

[cyg_net_init] Init: cyg_net_add_domain(0x0105e55c) 

New domain internet at 0x00000000 

[cyg_net_init] Init: cyg_net_add_domain(0x0105deb0) 

New domain route at 0x00000000 

[cyg_net_init] Init: call_route_init(0x00000000) 

[cyg_net_init] Done 

BOOTP[eth0] op: REPLY 

htype: Ethernet 

hlen: 6 

hops: 0 

xid: 0x0 

secs: 0 

flags: 0x0 

hw_addr: 00:07:ed:0b:05:26 

client IP: 172.25.106.77 

my IP: 172.25.106.77 

server IP: 172.25.112.64 

gateway IP: 172.25.2.251 

options: 

subnet mask: 255.255.0.0 

IP broadcast: 172.25.2.251 

gateway: 172.25.2.251 

[eth_drv_ioctl] Warning: Driver can&#39;t set multi-cast mode 

[eth_drv_ioctl] Warning: Driver can&#39;t set multi-cast mode 

[eth_drv_ioctl] Warning: Driver can&#39;t set multi-cast mode 

client:started 

Length Sent 8192 

client:started 

Length Sent 8192 

client:started
0 Kudos
Altera_Forum
Honored Contributor II
857 Views

I&#39;ve taken a different approach, and tried the ping test in the net packages. That worked. So I added the client() function from above into the ping code just after the ping call. The UDP send works now.  

 

So I conclude that the origianl UDP code is missing a crucial piece of its initialization, and that is causing things to fall over. Can anyone confirm this hypothesis, and tell me what was missing? 

 

Thanks
0 Kudos
Reply