But when it comes to ICMP redirct, things changed. If the Default gateway tells the K60 to contact the end device directly then regardless the netmask, K60 should setup a ROUTING rule for it to reach.
Here is what I did as a work around (add a indirect routing rule):
in icmp.c for case ICMPTYPE_REDIRECT in ICMP_service() I add the detection for redirect for a host and call RTCSCMD_internal(parms, IPIF_gate_add_redirect_other) instead - IPIF_gate_add_redirect_other is the function I added in ipif_add.c (see below ) - note that I add two more parameters in IP_route_add_indirect(). Also in IP_route_test() I check for RTF_REDIRECT_HOST flag and return the correct info if match.
I might miss some source code - but you should get the idea.
-----------------
icmp.c
------------------
@@ -99,7 +99,7 @@
_ip_address source, dest;
uint_32 error;
uint_16 chksum;
- uchar type;
+ uchar type, code;
ICMP_cfg_ptr = RTCS_getcfg(ICMP);
@@ -109,6 +109,7 @@
source = IP_source(pcb);
dest = IP_dest(pcb);
type = ntohc(packet->TYPE);
+ code = ntohc(packet->CODE);
/*
** Make sure that
@@ -170,6 +171,14 @@
parms.network = origdest;
parms.netmask = 0xFFFFFFFFL;
parms.locmask = 0;
+#define ICMP_REDIRECT_FIX 1
+#if ICMP_REDIRECT_FIX //WMQ
+ parms.ihandle = pcb->IFSRC;
+ if(code == ICMPCODE_RD_HOST){
+ parms.address = dest;
+ RTCSCMD_internal(parms, IPIF_gate_add_redirect_other);
+ } else
+#endif
RTCSCMD_internal(parms, IPIF_gate_add_redirect);
} else {
IF_ICMP_STATS_ENABLED(ICMP_cfg_ptr->STATS.COMMON.ST_RX_DISCARDED++);
---------------------------------------
rtcs/source/tcpip/ipif_add.c
-----------------------------------------
+/* for ICMP redirect when gateway is the destination */
+void IPIF_gate_add_redirect_other
+ (
+ IPIF_PARM_PTR parms
+ )
+{ /* Body */
+
+#if RTCSCFG_ENABLE_IP4
+
+ _ip_address netmask = parms->netmask;
+ uint_32 error;
+
+ /*
+ ** Make sure the netmask is valid. We use the fact that
+ ** (x & x+1) == 0 <=> x = 2^n-1.
+ */
+ if (~netmask & (~netmask + 1)) {
+ RTCSCMD_complete(parms, RTCSERR_IP_BIND_MASK);
+ return;
+ } /* Endif */
+
+ /* Start CR 1133 */
+ //error = IP_route_add_direct(parms->address, parms->netmask, (IP_IF_PTR)parms->ihandle, (IP_IF_PTR)parms->ihandle); /* this one causes memory leak*/
+ error = IP_route_add_indirect(parms->network, netmask, parms->network, RTF_REDIRECT | RTF_REDIRECT_HOST, parms->locmask, (IP_IF_PTR)parms->ihandle,parms->address);
+
+ RTCSCMD_complete(parms, error);
+#else
+
+ RTCSCMD_complete(parms, RTCSERR_IP_IS_DISABLED);
+
+#endif /* RTCSCFG_ENABLE_IP4 */
+
+} /* Endbody */
--------------------------------------------
rtcs/source/tcpip/iproute.c
--------------------------------------------
uint_32 IP_route_add_indirect
(
_ip_address address, /* Gateway address */
@@ -373,7 +373,9 @@
_ip_address netmask, /* Network mask */
_ip_address network, /* Network address */
uint_32 flag, /* [IN] RTF_* */
- uint_16 metric /* [IN] the route metric [0,65535] */
+ uint_16 metric, /* [IN] the route metric [0,65535] */
+ IP_IF_PTR destif, /* WMQ:Interface for outgoing packets */
+ _ip_address source /* WMQ: source address to send */
)
{ /* Body */
IP_CFG_STRUCT_PTR IP_cfg_ptr = RTCS_getcfg(IP);
@@ -390,6 +392,8 @@
route->FLAGS = flag | RTF_UP;
route->IS_DIRECT = NULL;
route->METRIC = metric;
+ route->DESTIF = destif; //WMQ
+ route->ADDRESS = source; //WMQ
-------------------------------------------
static boolean IP_route_test
(
pointer node_data,
pointer data
)
{ /* Body */
.....
if (indirect && testdata->check_gateway) {
do {
if (indirect->FLAGS & RTF_UP) {
testdata->hopdest = indirect->GATEWAY;
#if 1
if(indirect->FLAGS & RTF_REDIRECT_HOST){
testdata->sendit = TRUE;
testdata->ifdest = indirect->DESTIF;
testdata->retval = RTCS_OK;
if (!testdata->hopsrcislocal) {
testdata->hopsrc = indirect->ADDRESS;
} /* Endif */
}
#endif
/* Notify calling function that a gateway was found */
testdata->check_gateway = FALSE;
return TRUE;
} /* Endif */
indirect = indirect->NEXT;
} while(indirect != route->INDIRECT);
---------------------------------------------
rtcs/source/include/ip_prv.h
---------------------------------------------
| #define RTF_REDIRECT_HOST | 0x0008 | /* created for a ICMP redirect for a host*/ |