Changing the IP Address and MAC address during Runtime

Hi folks,

Am new to this forum, Am working on Renesas RA6M5 controller… i have implemented ethernet … Assigned the IP Address using FreeRTOS_IPInit API… But i dont know how to change the IP address during runtime… I have tried using FreeRTOS_SetAddressConfiguration … by passing only the IP address and sending NULL on other parameters… here is the code for reference

#include "new_thread0.h"
#include "FreeRTOS_IP.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkInterface.h"
#include "FreeRTOS_DHCP.h"

#define USR_TEST_PING_IP "192.168.1.123"  //"172.217.160.174"

volatile bool network_up = false;

uint8_t ucIPAddress[4] = {192,168,1,125};
uint8_t ucMACAddress[6] = {0x00,0x11,0x22,0x33,0x44,0x55};  
const uint8_t ucNetMask[4] = {255,255,255,0};
const uint8_t ucGatewayAddress[4] = {192,168,1,1}; 
const uint8_t ucDNSServerAddress[4] = {8,8,8,8}; 

uint8_t change_ip_address_value[4] = {192,168,1,21};

uint8_t ping_data_received = 0;
uint8_t ping_data_lost = 0;

uint8_t  *gp_remote_ip_address = (uint8_t *)USR_TEST_PING_IP;

BaseType_t vSendPing( const char *pcIPAddress);

bool change_ip_address();

uint32_t convert_ip_address(uint8_t ip_address[4]);

static bool is_ping_successful = false;

void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
    if(eNetworkEvent == eNetworkUp)
    {
        network_up = true;
    }

}

void new_thread0_entry(void *pvParameters)
{

    FSP_PARAMETER_NOT_USED (pvParameters);
    BaseType_t status;
    status = FreeRTOS_IPInit(ucIPAddress, ucNetMask,ucGatewayAddress,ucDNSServerAddress,ucMACAddress);
    if( status == pdFALSE)
    {
        __BKPT(0);
    }
    while (false == network_up)
    {
        ;
    }

    while (true)
    {
        if(is_ping_successful){
            break;
        }
        status =  vSendPing((char *)gp_remote_ip_address);
        vTaskDelay (10);
    }

    // Now Change the IP Address

    change_ip_address();


    while(true){
        __NOP();
    }

}

BaseType_t vSendPing( const char *pcIPAddress)
{
    uint32_t ulIPAddress = 0;

    ulIPAddress = FreeRTOS_inet_addr(pcIPAddress);

    return(FreeRTOS_SendPingRequest(ulIPAddress, 8, 100 / portTICK_PERIOD_MS));
}

void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier )
{
    (void)  usIdentifier;

    switch( eStatus )
    {
        /* A valid ping reply has been received */
        case eSuccess    :
            ping_data_received++;
            is_ping_successful = true;
            break;
            /* A reply was received but it was not valid. */
        case eInvalidData :
            ping_data_lost++;
            break;
        default:
            ping_data_lost++;
            break;
    }
}

bool change_ip_address(){
    bool return_status = false;
    uint32_t changed_ip_address = 0;
    uint32_t get_ip_address = 0;

    network_up = false;
    changed_ip_address = convert_ip_address(change_ip_address_value);
    taskENTER_CRITICAL();
    FreeRTOS_SetAddressConfiguration(&changed_ip_address,NULL,NULL,NULL);
    taskEXIT_CRITICAL();
    xDefaultAddressing.ulDefaultIPAddress = changed_ip_address; 
    FreeRTOS_NetworkDown( );

    R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);

    while (!network_up) {
        vTaskDelay(pdMS_TO_TICKS(100)); 
    }

    get_ip_address = FreeRTOS_GetIPAddress();
    if(get_ip_address == changed_ip_address){
        __NOP();
    }
    return return_status;
}

uint32_t convert_ip_address(uint8_t ip_address[4]){
    uint32_t value = 0;
    value = (uint32_t)(ip_address[0] << 24 | ip_address[1] << 16 | ip_address[2] << 8 | ip_address[3]);
    return value;
}

Here i am not using DHCP , Am using static IP Address and DHCP configuration parameters are as follows…

#define ipconfigUSE_DHCP                         0
#define ipconfigDHCP_REGISTER_HOSTNAME           0
#define ipconfigDHCP_USES_UNICAST                0
#define ipconfigDHCP_SEND_DISCOVER_AFTER_AUTO_IP 0
#define ipconfigUSE_DHCP_HOOK                    0

Please let me know how to change IP address and MAC address and let me know if you have any queries…

Note: Kindly concentrate on change_ip_address function.

Thanks & regards,
Vikram

why would you want to change the MAC address?

Hi @Vikram

If you want to update static IP address please refer to this post here.

Note that FreeRTOS_NetworkDown is needed to reinitialise the stack and update the new IP address.
We will document this and share the documentation shortly.

Thanks you

Thanks for the update… The post which you have shared has DHCP configuration Enabled… But am not using DHCP at all…
I request you to just look into the change_ip_address() from my code once… And let me know what further changes are required… Will be awaiting for your response…
Kindly let me know for any further queries…

Thanks & regards,
Vikram.

Ideally the solution mentioned above should work for both DHCP enabled/disabled case. You just need to set bEnableDHCP to pdFALSE to use the static IP address.
But to check your change_ip_address function further can you please let me know which version on FreeRTOS-Plus-TCP are you using?

Please find the version details as you have asked for :

FreeRTOS+TCP : “V2.4.0”
FreeRTOS Kernel Version Number : “V10.4.6”

I couldnt find bEnableDHCP but i found this “ipconfigUSE_DHCP”… Are you referring to “ipconfigUSE_DHCP” configuration variable ?

During changing the IP address, should i again configure ipconfigUSE_DHCP variable to false ?

Just want to remind you that all the configuration variables related to DHCP is false

#define ipconfigUSE_DHCP 0
#define ipconfigDHCP_REGISTER_HOSTNAME 0
#define ipconfigDHCP_USES_UNICAST 0
#define ipconfigDHCP_SEND_DISCOVER_AFTER_AUTO_IP 0
#define ipconfigUSE_DHCP_HOOK 0

Please let me know if any of the above mentioned variables are to be set true…?

Thanks & regards,
Vikram

In this function on V2.4.0 we are only updating ipLOCAL_IP_ADDRESS_POINTER, which seems to be not getting overwritten when we are doing NetworkDown_Event, hence using FreeRTOS_SetAddressConfiguration is not the correct way to update the address here.

Can you please try updating xDefaultAddressing.ulDefaultIPAddress instead of calling FreeRTOS_SetAddressConfiguration.

Also is there any reason to use this very old version of FreeRTOS-PLUS-TCP? There are a lot of new features and bug fixes have been added in the latest release. You can also give it a try.

Thank you.

I had tried this before also … And now i removed the FreeRTOS_SetAddressConfiguration and tried… Its Still the same madam… I could not able to ping the IP address(Changed)…

Btw…
Could you please let me know the latest FreeRTOS+TCP version ?

Thanks & regards,
Vikram.

Latest version is V4.0.0.

Anyway, I will try to move to the older version which you are using, look into the issue and update you.

Thank you for your patience!

Sure madam… Will be awaiting for your response…

Thanks & regards,
Vikram

Madam, I have upgraded TCP to 4.0.0 i.e the latest version… Here my query is previously i.e 2.4.0 the FreeRTOS_NetworkDown API didnt have any importing parameters… Now in 4.0.0 version FreeRTOS_NetworkDown has importing parameters…

void FreeRTOS_NetworkDown( struct xNetworkInterface * pxNetworkInterface )… How to get the data of network interface ?

Thanks & regards,
Vikram.

Hi @Vikram,
Really appreciate your help on updating TCP version!

To obtain the pointer to the xNetworkInterface, you can call the FreeRTOS_FirstNetworkInterface() and FreeRTOS_NextNetworkInterface() functions from the FreeRTOS_Routing.h header file. These functions allow you to iterate through all available network interfaces. Please note that they will return NULL when you reach the end of the interface list. For more detailed information and guidance, kindly refer to the IPv6 and Multiple Interface Functions documentation.

Thank you.

Hi…

Can you please brief me the procedure… Am using Renesas RA6M5 controller… And recently i had upgraded the version of TCP to 4.0.0…What i had done before was

  1. I have used FreeRTOS_IPInit to initialize the IP address and MAC Addresses and then
    if( status == pdFALSE)
    {
    __BKPT(0);
    }
    while (false == network_up)
    {
    ;
    }
  2. Am using void vApplicationIPNetworkEventHook API to know if the Network is up or not…

vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
if(eNetworkEvent == eNetworkUp)
{
network_up = true;
}
}

  1. And from my microcontroller am trying to ping the IP address of my PC… If its successfull… Am tryting to change the IP address of the controller through function change_ip_address

  2. Am using FreeRTOS_SetAddressConfiguration to change the IP address… and after that am calling FreeRTOS_NetworkDown()… In previous version the function FreeRTOS_NetworkDown() did not had any importing parameters… But now its asking for network interface as importing parameter… Please find the whole code below and let me know where should i call this FreeRTOS_FirstNetworkInterface and FreeRTOS_NextNetworkInterface…And what are the other changes are required…

Here my main objective is to change the IP address and MAC Address to desired IP address and MAC address… manually…
Am not using DHCP in this scenario… Is it required to enable DHCP ?

#include “new_thread0.h”
/* New Thread entry function /
/
pvParameters contains TaskHandle_t */

#include “FreeRTOS_IP.h”
#include “FreeRTOS_IP_Private.h”
#include “NetworkInterface.h”
#include “FreeRTOSIPConfig.h”

#include “FreeRTOS_DHCP.h”
#include “FreeRTOS_ARP.h”
#include “FreeRTOS_DNS.h”
#include “FreeRTOS_TCP_IP.h”

#define USR_TEST_PING_IP “192.168.1.123”
volatile bool network_up = false;

uint8_t ucIPAddress[4] = {192,168,1,125};
uint8_t ucMACAddress[6] = {0x00,0x11,0x22,0x33,0x44,0x55};

const uint8_t ucNetMask[4] = {255,255,255,0};
const uint8_t ucGatewayAddress[4] = {192,168,1,1};
const uint8_t ucDNSServerAddress[4] = {8,8,8,8};

uint8_t change_ip_address_value[4] = {192,168,1,21};

uint8_t ping_data_received = 0;
uint8_t ping_data_lost = 0;

uint8_t *gp_remote_ip_address = (uint8_t *)USR_TEST_PING_IP;

BaseType_t vSendPing( const char *pcIPAddress);

bool change_ip_address();

uint32_t convert_ip_address(uint8_t ip_address[4]);

static bool changeIPAddress = false;
static bool is_ping_successful = false;

void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
if(eNetworkEvent == eNetworkUp)
{
network_up = true;
}
}

void new_thread0_entry(void *pvParameters)
{
FSP_PARAMETER_NOT_USED (pvParameters);

/* TODO: add your own code here */
BaseType_t status;
status = FreeRTOS_IPInit(ucIPAddress, ucNetMask,ucGatewayAddress,ucDNSServerAddress,ucMACAddress);
if( status == pdFALSE)
{
    __BKPT(0);
}
while (false == network_up)
{
    ;
}
/* TODO: add your own code here */
while (true)
{
    if(is_ping_successful){
        break;
    }
    status =  vSendPing((char *)gp_remote_ip_address);
    vTaskDelay (10);
}

// Now Change the IP Address

change_ip_address();
changeIPAddress = true;

while (1)
{
    vTaskDelay (1);
}

}

BaseType_t vSendPing( const char *pcIPAddress)
{
uint32_t ulIPAddress = 0;

ulIPAddress = FreeRTOS_inet_addr(pcIPAddress);

return(FreeRTOS_SendPingRequest(ulIPAddress, 8, 100 / portTICK_PERIOD_MS));

}

void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier )
{
(void) usIdentifier;

switch( eStatus )
{
    /* A valid ping reply has been received */
    case eSuccess    :
        ping_data_received++;
        is_ping_successful = true;
        break;
        /* A reply was received but it was not valid. */
    case eInvalidData :
        ping_data_lost++;
        break;
    default:
        ping_data_lost++;
        break;
}

}

bool change_ip_address(){
bool return_status = false;
uint32_t changed_ip_address = 0;
uint32_t get_ip_address = 0;
NetworkInterface_t network_interface_data;
NetworkBufferDescriptor_t * pxNetworkBuffer = NULL;

network_up = false;
changed_ip_address = FreeRTOS_inet_addr(change_ip_address_value);
taskENTER_CRITICAL();
//    FreeRTOS_SetIPAddress(changed_ip_address);
xDefaultAddressing.ulDefaultIPAddress = changed_ip_address;     FreeRTOS_SetAddressConfiguration(&changed_ip_address,NULL,NULL,NULL);
taskEXIT_CRITICAL();
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
__BKPT(0);
FreeRTOS_NetworkDown( );
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
while (!network_up) {
    vTaskDelay(pdMS_TO_TICKS(100)); // Adjust delay as needed
}

get_ip_address = FreeRTOS_GetIPAddress();
if(get_ip_address == changed_ip_address){
    __NOP();
}

return return_status;

}

uint32_t convert_ip_address(uint8_t ip_address[4]){
uint32_t value = 0;
value = (uint32_t)(ip_address[0] << 24 | ip_address[1] << 16 | ip_address[2] << 8 | ip_address[3]);
return value;
}

Awaiting for your response…

Thanks & regards,
Vikram

Assuming that both ipconfigCOMPATIBLE_WITH_SINGLE and ipconfigIPv4_BACKWARD_COMPATIBLE are enabled, please follow these steps:

  1. In the change_ip_address function, you can call FreeRTOS_SetAddressConfiguration(...) to change the IP address.
  2. After updating the IP address, call FreeRTOS_NetworkDown(FreeRTOS_FirstNetworkInterface()) to restart the network stack with the new IP address. Since ipconfigCOMPATIBLE_WITH_SINGLE is enabled, you should have only one network interface.
  3. Wait for the network interface to reinitialize, similar to the process you did in vApplicationIPNetworkEventHook.
  4. Once the network interface is ready, you can test the new IP address by pinging it or establishing a socket connection using the updated address.

If you have any further questions or require additional assistance, please feel free to reach out. I’ll be happy to provide clarification or support.

Thank you.

Thanks for the support,

The problem am facing now is while am using FreeRTOS_SetAddressConfiguration and FreeRTOS_NetworkDown API , And now if am trying to get the IP address using FreeRTOS_GetIPAddress API… The FreeRTOS_GetIPAddress returns me the previous IP address, And Not the updated one…

But when i dont use FreeRTOS_NetworkDown and use only FreeRTOS_SetAddressConfiguration and execute FreeRTOS_GetIPAddress API… Am getting the Updated IP address… But the point is i could not able to ping the updated IP address…

Here is my updated code,

bool change_ip_address(){
bool return_status = false;
uint32_t changed_ip_address = 0;
uint32_t changed_net_mask = 0;
uint32_t changed_gateway_address = 0;
uint32_t changed_dns_address = 0;

uint32_t check_ip_address_network_interface = 0;
uint32_t get_ip_address = 0;
NetworkInterface_t network_interface_data;
NetworkBufferDescriptor_t * pxNetworkBuffer = NULL;

uint32_t previous_ip_address = 0;

struct xNetworkInterface *pxNetworkInterface = NULL;

network_up = false;
changed_ip_address = convert_ip_address(change_ip_address_value);

__BKPT(0);
taskENTER_CRITICAL();
//xDefaultAddressing.ulDefaultIPAddress = FreeRTOS_inet_addr_quick( change_ip_address_value[0],change_ip_address_value[1],change_ip_address_value[2],change_ip_address_value[3]);
FreeRTOS_SetAddressConfiguration(&changed_ip_address,NULL,NULL,NULL);
FreeRTOS_NetworkDown(FreeRTOS_FirstNetworkInterface());
taskEXIT_CRITICAL();

R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);

while (!network_up) {
    vTaskDelay(pdMS_TO_TICKS(100)); // Adjust delay as needed
}

changeIPAddress = true;
vTaskDelay(100);
//xNetworkInterfaceInitialise();
get_ip_address = FreeRTOS_GetIPAddress();
if(get_ip_address == changed_ip_address){
    __NOP();
}
//    }
return return_status;

}

And now i have these variables ipconfigCOMPATIBLE_WITH_SINGLE and ipconfigIPv4_BACKWARD_COMPATIBLE = 1

FYI…
#ifndef ipconfigCOMPATIBLE_WITH_SINGLE
#define ipconfigCOMPATIBLE_WITH_SINGLE ( 1 )
#endif

#ifndef ipconfigIPv4_BACKWARD_COMPATIBLE
#define ipconfigIPv4_BACKWARD_COMPATIBLE ( 1 )
#endif

Hi @Vikram

Can you try pinging the updated ip address through command line once it is up? Is that working?

No Madam… Its Not pinging…

Just asking… Are you guys eligible to connect via Anydesk ?

Thanks & regards,
Vikram.

Hi all,

I could able to ping the changed IP address… The problem was with the conversion of changed_ip_address to uint32_t data type… Thank you guys so much…

Just one last question, Will the change of MAC address is also this way… Or any complications are there ?

Thanks & regards,
Vikram.

1 Like

Again, why would you want to modify the MAC address?

1 Like

Thanks for feedback!

Yes, from the FreeRTOS-Plus-TCP perspective, the MAC address can be updated in the same way. As @RAc asked, could you please share the reason behind your interest in modifying the MAC address?

Thank you.