public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
From: "Thierry Brémard" <bremardt@esiee.fr>
To: ecos-discuss@sources.redhat.com
Subject: [ECOS] re: TCP problem: Accept doesn't accept + No ARP reply of Arcom Viper running with eCos
Date: Sun, 19 Jun 2005 17:38:00 -0000	[thread overview]
Message-ID: <20050619173841.5BDBB3658F4@mail.esiee.fr> (raw)

Hello, 
I am still on my TCP Server,
I managed to specify a static IP address and now I am able to connect
from my arcom viper card to my PC and send to my pc data via TCP
sockets.
However my final issue is to build a server on my viper card.

My function OpenPort return with 1 (succesful) and when I attempt to
connect (whith the correct ip and correct port) with a telnet
<viper_ip>  <port_opened> , I can see SYN request from my PC without
any ack from the viper.
Furthermore, it doesn't reply to arp request (ie for the moment I have
to set a arp -s ip mac to be able to send packets to the viper .. but
the viper announce itself (once)just after the go command )

I built my project with the eCos configuration Tool, selected the
'net' package, checked and filled the 'address setups for eth0' and
unchecked the DNS support (because only work whit ip addresses).

Here is the output of redBoot, lauching my eCos program

----------------------------------------------------------------

RedBoot>
RedBoot> go
[cyg_net_init] Init: mbinit(0x00000000)
[cyg_net_init] Init: cyg_net_init_devs(0x00000000)
Init device 'lan91cxx_eth0'
[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(0x0043d774)
New domain internet at 0x00000000
[cyg_net_init] Init: cyg_net_add_domain(0x0043d1fc)
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:80:66:10:14:ee
     client IP: 147.215.40.77
         my IP: 147.215.40.77
     server IP: 147.215.40.2
    gateway IP: 147.215.40.1
  options:
        subnet mask: 255.255.255.0
       IP broadcast: 147.215.40.255
            gateway: 147.215.40.1
[eth_drv_ioctl] Warning: Driver can't set multi-cast mode
[eth_drv_ioctl] Warning: Driver can't set multi-cast mode
[eth_drv_ioctl] Warning: Driver can't set multi-cast mode
Server Redboot !
Opening port 105..ok

----------------------------------------------------------------

Here is the source code:

----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <network.h>
#include <arpa/inet.h>

#define SOCKET_ERROR -1
#define DESIRED_BACKGROUND_LOAD 50

int OpenPort(unsigned short port)
{
    struct sockaddr_in sin;
    int sock;

    if((sock = socket(AF_INET, SOCK_STREAM, 0))== SOCKET_ERROR)
    {
        printf("error in OpenPort, socket()");
        return 0;
    }

    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = 0;
//    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_family = AF_INET;
    sin.sin_len    = sizeof(sin);
        
    if(SOCKET_ERROR == bind(sock, (struct sockaddr *)&sin,
sizeof(struct sockaddr_in) ))
    {
        printf("error in OpenPort, bind()");
        return 0;
    }

    if(SOCKET_ERROR == listen(sock, SOMAXCONN))
    {
        printf("error in OpenPort, listen()");
        return 0;
    }
 
    return sock;

}




int Connexion(unsigned short port)
{
    struct sockaddr_in sin;
    int sock;

    if((sock = socket(AF_INET, SOCK_STREAM, 0))== SOCKET_ERROR)
    {
        printf("error in OpenPort, socket()\n");
        return 0;
    }

    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = inet_addr("147.215.40.139");
    sin.sin_family = AF_INET;
  
    if(SOCKET_ERROR == connect(sock, (struct sockaddr *)&sin,
sizeof(struct sockaddr_in) ))
    {
        printf("error in Connexion, connect()\n");
        return 0;
    }
    return sock;

}



// envoi les données pointées par data taille = len
// tout est envoyé grace à un appel à recv dans le while
// retourne le nombre d'octets envoyés 
int SendData(int sock, char *data, int len)
{
    int total = 0;
    int ret;
    
    while((ret = send(sock, data, len, 0))>0) // envoi les données
    {
        total += ret;  // octets envoyés au total
        data  += ret;  // pointe plus loin sur les données non
envoyées
        len   -= ret;  // la taille restante diminue
    }
    
    return total;  // nombre d'octets envoyés
}

// envoie la chaine de caractère ascii, terminée par un 0.
// retourne le nombre d'octets envoyés (n'envoie pas le 0)
int SendString(int sock, char *str)
{
   return SendData(sock, str, strlen(str));
}

// recoit des données, les stocke dans buffer
// la réception s'achève oubien quand len octets ont été recus
// ou bien quand \n est recu.
// les caractères \r et \n sont enlevés de la fin du buffer avant de
retourner
// le nombre de caractères mis dans buffer est retourné.
int RecvLine(int sock, char *buffer, int len)
{
    char c;
    int total = 0;
    int ret;
    
    memset(buffer, 0 , len);
    
    while( (total<len) && ((ret = recv(sock, &c, 1, 0))>0) )
    {
        memcpy(&buffer[total], &c, ret ); // buffer[total] = c;
        total += ret; // total++;
        if(buffer[total-1] =='\n')
            break ; // sortie de la boucle si retour chariot recu.
    
    }
    
    len = strlen(buffer);
    while((buffer[len-1] =='\n') || (buffer[len-1] =='\r'))
    {
        buffer[len-1] = 0; // écrase \n ou \r par caractère de fin de
chaine
        len--;
        if(!len)   // si taille nulle
            break; // termine la boucle
    }
    
    return len;
    
}

//void cyg_user_start(void)
int main(void)
{
//int i;
int sock, client;
char buffer[1024];

    init_all_network_interfaces();
//    calibrate_load(DESIRED_BACKGROUND_LOAD);
    printf("Server Redboot !\n");
    
    /*
    if(sock = Connexion(90))
    {
        
        printf("Connected ... ");
        SendString(sock, "Hello Server, I am the Viper !!\r\n");
        SendString(sock, "quit\r\n");
        close(sock);
        printf("Disconnected!\r\n");
        
        
    }*/
        
        
    printf("Opening port 105..");
    if(!(sock = OpenPort(105)))
    {
        printf("error opening port !\n");
        return 0;
    }
    printf("ok\n");
    
    
    if(SOCKET_ERROR == (client = accept(sock, NULL, 0)))
    {
        printf("error of accept!");
        return 0;
    }
    printf("Client connected!");
    strcpy(buffer, "Hello you are on the Viper Server!\r\n");
    SendString(client, buffer);

    while(strncmp(buffer, "quit", 3))
    {
        RecvLine(client, buffer, 1024);
        printf("client sent: %s", buffer);
        SendString(client, "220 ok for");
        SendString(client, buffer);
        SendString(client, "\r\n");
    }    
    
    close(sock);
    close(client);

    puts("Server finished");
    return 0;
  
}
----------------------------------------------------------------



Here is another source provided whith eCos which gives the same
result: opens port but donot ack the syn:

//====================================================================
======
// Network server test code
#include <stdio.h>
#include <stdlib.h>
#include <network.h>

#ifndef CYGPKG_LIBC_STDIO
#define perror(s) diag_printf(#s ": %s\n", strerror(errno))
#endif

#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000)
static char stack[STACK_SIZE];
static cyg_thread thread_data;
static cyg_handle_t thread_handle;

extern void
cyg_test_exit(void);

void
pexit(char *s)
{
    perror(s);
    cyg_test_exit();
}

static void
server_test(struct bootp *bp)
{
    int s, client, client_len;
    struct sockaddr_in client_addr, local;
    char buf[256];
    int one = 1;
    fd_set in_fds;
    int num, len;
    struct timeval tv;

    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s < 0) {
        pexit("stream socket");
    }
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
        pexit("setsockopt SO_REUSEADDR");
    }
    if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one))) {
        pexit("setsockopt SO_REUSEPORT");
    }
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_len = sizeof(local);
    local.sin_port = htons(7734);
    local.sin_addr.s_addr = INADDR_ANY;
    if(bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
        pexit("bind error");
    }
    listen(s, SOMAXCONN);
    printf("server ok .. wainting for client on 7734\n");
    while (true) {
        client_len = sizeof(client_addr);
        if ((client = accept(s, (struct sockaddr *)&client_addr,
&client_len)) < 0) {
            pexit("accept");
        }
        client_len = sizeof(client_addr);
        getpeername(client, (struct sockaddr *)&client_addr,
&client_len);
        diag_printf("connection from %s:%d\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

#ifdef CYGPKG_LIBC_STDIO        
        sprintf(buf, "Hello %s:%d\n", inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));
#else        
        strcpy(buf, "Hello ");
        strcat(buf, inet_ntoa(client_addr.sin_addr));
        strcat(buf,":");
        strcat(buf, atoi(ntohs(client_addr.sin_port)));
        strcat(buf,"\n");
#endif
        
        write(client, buf, strlen(buf));
        tv.tv_sec = 5;
        tv.tv_usec = 0;
        FD_ZERO(&in_fds);
        FD_SET(client, &in_fds);
        num = select(client+1, &in_fds, 0, 0, &tv);
        if (num > 0) {
            len = read(client, buf, sizeof(buf)-1);
            buf[len] = '\0';
            diag_printf("buf = '%s'\n", buf);
        } else if (num == 0) {
            diag_printf("No reply - timed out\n");
        } else {
            perror("select");
        }
        close(client);
    }
    close(s);
}

void
net_test(cyg_addrword_t param)
{
    diag_printf("Start SERVER test\n");
    init_all_network_interfaces();
#ifdef CYGHWR_NET_DRIVER_ETH0
    if (eth0_up) {
        server_test(&eth0_bootp_data);
    }
#endif
    cyg_test_exit();
}

void
cyg_start(void)
{
    // Create a main thread, so we can run the scheduler and have time
'pass'
    cyg_thread_create(10,                // Priority - just a number
                      net_test,          // entry
                      0,                 // entry parameter
                      "Network test",    // Name
                      &stack[0],         // Stack
                      STACK_SIZE,        // Size
                      &thread_handle,    // Handle
                      &thread_data       // Thread data structure
            );
    cyg_thread_resume(thread_handle);  // Start it
    cyg_scheduler_start();
}



Thank you

I am wondering why it doesnt reply to arp request whereas it announces
itself at the startup(whith a packet 'who has me me ?').
And the card is able to make arp queries to connect to my pc....

is there something special to check in the eCos configuration tool ?

Thierry Brémard

--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

                 reply	other threads:[~2005-06-19 17:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050619173841.5BDBB3658F4@mail.esiee.fr \
    --to=bremardt@esiee.fr \
    --cc=ecos-discuss@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).