Home/Support/Support Forum/Getting Local Ip Address
Welcome to Digi Forum, where you can ask questions and receive answers from other members of the community.

Getting Local Ip Address

0 votes
Hello,

How Can we know the local (own) ip of th Digi Connect Me 9210 with NET+OS? We have tried with the function getSocketName but We allways get 0.0.0.0

We are using Digi Net+OS 7.4. Any Ideas?

Thank you!
asked Jun 17, 2013 in NET+OS by ingsoft New to the Community (2 points)

Please log in or register to answer this question.

3 Answers

0 votes
Digi generally recommends using IAM APIs for internet related tasks such as this one. These are described in the API reference guide. Specifically look at customizeIamGetIfAddress. Please be sure you read the description as ultimately this returns a sockaddr_storage structure which needs specifc handling in order to retrieve the address.

Additionally, the API reference for getsockname states the use of a sockaddr structure BUT the write-up for the sockaddr_storage struct mentions that getsockname returns a sockaddr_storage struct. This change is because a sock_addr struct can not hold an IPv6 address.

Side note starting with NET+OS V7.0 NET+OS switched to an IP stack that supports both IPV4 and IPV6. This required an updated structure that can handle both.

A place where many customer get hung up on is handling a sockadd_storage struct. You MUST check the family of the returned struct and access the union based on the family. The sockadd_storage struct is described in the API reference manual also.
answered Jun 17, 2013 by dakotas_dad Veteran of the Digi Community (694 points)
0 votes
Hello

I did a little checking on the internet. getsockname returning 0.0.0.0 is quite common as follows:

http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr2/zockname.htm

http://stackoverflow.com/questions/5759031/getsockname-always-returning-0-0-0-0

Yes, if you bind it to a LOOPBACK , u have to specify INADDR_LOOPBACK. Otherwise it attaches itself to 0.0.0.0 which represents all the network interfaces available. I was facing the same problem, while issuing getnameinfo() call.

Bottom line is that most of the time unless you specifically bound the socket to an interface, getsockname returns 0.0.0.0 meaning all interfaces. I have tried the API I mentioned previously (customizeIamGetIfAddress) and becuase in this API you pass a specific interface (ethernet is eth0 and wireless is wln0 you get an actual IP address. Again this is due to you requesting a specific interface.
answered Jun 17, 2013 by dakotas_dad Veteran of the Digi Community (694 points)
0 votes
Thank you very much for your answer dakotas_dad.

Where can I find the API Reference guide?, I have some guides of NET OS but I don´t find anything about customizeIamGetIfAddress.
answered Jun 18, 2013 by ingsoft New to the Community (2 points)
In the NET+OS installation tree (it is also available in ESP) there is a documentation directory. IN the documentation directory look for the file ApiReference.chm. Double clock on this file. ON the LEFT hand side of the screen  is a list of topics. Click into subject as follows:

Internetworking\Internet Address Manager (IAM)\IAM Parameter  API\Functions\customizeIamGetIfAddress. The API is explained therein.


Below I am including a root.c that demonstrates the concept:

/*
 *  Copyright (c) 1996-2007 Digi International Inc., All Rights Reserved
 *
 *  This software contains proprietary and confidential information of Digi
 *  International Inc.  By accepting transfer of this copy, Recipient agrees
 *  to retain this software in confidence, to prevent disclosure to others,
 *  and to make no use of this software other than that for which it was
 *  delivered.  This is an unpublished copyrighted work of Digi International
 *  Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 *  prohibited.
 *
 *  Restricted Rights Legend
 *
 *  Use, duplication, or disclosure by the Government is subject to
 *  restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 *  Technical Data and Computer Software clause at DFARS 252.227-7031 or
 *  subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 *  Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 *  Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 * Description.
 * =======================================================================
 * applicationStart() is the entry point for user applications.  This
 * This function will be called after the kernel has started and the
 * TCP/IP stack has loaded.  applicationTcpDown() is called periodically
 * after the kernel has started while the system is waiting for the
 * TCP/IP stack to start.  
 *                                                                        
 *                                                                        
 * Edit Date/Ver   Edit Description
 * ==============  ===================================================
 *
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <tx_api.h>
#include "appconf.h"
#include "sockapi.h"
#include "bsp_api.h"
#include "nastatus.h"
#include "iam.hh"




/*
 * Set this to 1 to run the manufacturing burn in tests.
 */
int APP_BURN_IN_TEST = 0;








/*
 *
 *  Function: void applicationTcpDown (void)
 *
 *  Description:
 *
 *      This routine will be called by the NET+OS root thread once every
 *      clock tick while it is waiting for the TCP/IP stack to come up.  
 *      This function can increment a counter everytime it's called to
 *      keep track of how long we've been waiting for the stack to start.
 *      If we've been waiting too long, then this function can do something
 *      to handle the error.  
 *
 *      This function will not be called once the stack has started.
 *
 *  Parameters:
 *
 *      none
 *
 *  Return Values:
 *
 *      none
 *
 */

void applicationTcpDown (void)

{
    static int ticksPassed = 0;

    ticksPassed++;
/*
 * Code to handle error condition if the stack doesn't come up goes here.
 */
}




/*
 *
 *  Function: void applicationStart (void)
 *
 *  Description:
 *
 *      This routine is responsible for starting the user application.  It should
 *      create any threads or other resources the application needs.
 *
 *      ThreadX, the NET+OS device drivers, and the TCP/IP stack will be running
 *      when this function is called.
 *
 *  Parameters:
 *
 *      none
 *
 *  Return Values:
 *
 *      none
 *
 */

#define MAX_IP_BUFFER_SIZE 128
void applicationStart (void)

{
    struct sockaddr_storage theModulesAddress;
    struct sockaddr_storage theBindingAddress;
    int callStatus = 0;
    int mySocket = -1;
    int theStructSize = sizeof(struct sockaddr_storage);
    char theIPAddressBuffer[MAX_IP_BUFFER_SIZE];
    NaStatus myNAStatus = NASTATUS_SUCCESS;
    NaIamStatus_t theIAMStatus = NA_IAM_STATUS_SUCCESS;
    NaIamIfAddress_t theIAMIPAddress;
   
     
/*
 * Code to start the user application goes here.
 */
    printf ("Test getsockname!\n");
    memset(&theModulesAddress, '\0', sizeof (struct sockaddr_storage));
    memset(theIPAddressBuffer, '\0', MAX_IP_BUFFER_SIZE);
    mySocket = socket(AF_INET, SOCK_STREAM, 0);
    memset(&theIAMIPAddress, '\0', sizeof(NaIamIfAddress_t));
    memset(&theBindingAddress, '\0', sizeof (struct sockaddr_storage));
    
    if(mySocket < 0)
    {
        printf("No socket available\n");
        return;
    }
    
    theBindingAddress.addr.ipv4.sin_family = AF_INET;
    theBindingAddress.addr.ipv4.sin_port = htons(1234);
    theBindingAddress.addr.ipv4.sin_addr.s_addr = htonl(INADDR_ANY);   
    callStatus = bind(mySocket, (struct sockaddr *)&theBindingAddress, sizeof(struct sockaddr_storage));
    printf("bind returned %d\n", callStatus);
    callStatus = getsockname(mySocket, (struct sockaddr *)&theModulesAddress, &theStructSize);
    if(callStatus < 0)
    {
        printf("Call to getsockname failed\n");
        return;
    }
    myNAStatus = na_ntop(theModulesAddress.addr.ipv4.sin_family, &theModulesAddress, theIPAddressBuffer, MAX_IP_BUFFER_SIZE);
    if(myNAStatus != NASTATUS_SUCCESS)
    {
        printf("Nothing available\n");
    }
    else
    {
        printf("IP address found was %s\n", theIPAddressBuffer);
    }
    
    // now try using IAM calls
    theIAMStatus = customizeIamGetIfAddress("eth0", AF_INET, &theIAMIPAddress);
    if(theIAMStatus != NA_IAM_STATUS_SUCCESS)
    {
        printf("Unable to retrieve IP address\n");
        return;
    }

    
    myNAStatus = na_ntop(theIAMIPAddress.ipAddress.addr.ipv4.sin_family, &theIAMIPAddress.ipAddress, theIPAddressBuffer, MAX_IP_BUFFER_SIZE);
    if(myNAStatus != NASTATUS_SUCCESS)
    {
        printf("Nothing available\n");
    }
    else
    {
        printf("IP address found was %s\n", theIPAddressBuffer);
    }
    
    tx_thread_suspend(tx_thread_identify());
}
I have it!
Thank you very much for your time and your help.

Greetings!
...