summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2011-10-24 18:00:01 +0000
committerGerrit <chrome-bot@google.com>2011-11-17 14:51:33 -0800
commit804fb2fd41bfbbc95206537c0f673e73938b4497 (patch)
tree1243f8be0611c6225171aa4b594a05ff2d98409c /net
parent32c71f6b9f2b4f26636f093e167f2267522cb672 (diff)
UPSTREAM: net: tftpput: Add support for receiving ICMP packets
ICMP packets can tell you when there is no server at the other end. It is useful for tftp to figure this out, so that a quick error can be displayed, rather than pointlessly retrying. This adds an ICMP packet handler to the net interface. Signed-off-by: Simon Glass <sjg@chromium.org> (cherry picked from commit 4793ee6522f10a3d108de7e47adbcf5f15eb3f46) Change-Id: I02bbd41b3852b92b06210db160a06c62f5bf414f Reviewed-on: https://gerrit.chromium.org/gerrit/11795 Commit-Ready: Simon Glass <sjg@chromium.org> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'net')
-rw-r--r--net/net.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/net/net.c b/net/net.c
index 759cb8d2948..5eaf5333550 100644
--- a/net/net.c
+++ b/net/net.c
@@ -217,6 +217,7 @@ volatile uchar *NetRxPackets[PKTBUFSRX];
/* Current RX packet handler */
static rxhand_f *packetHandler;
+static rxhand_icmp_f *packet_icmp_handler; /* Current ICMP rx handler */
/* Current timeout handler */
static thand_f *timeHandler;
/* Time base value */
@@ -346,6 +347,7 @@ int
NetLoop(proto_t protocol)
{
bd_t *bd = gd->bd;
+ int ret = -1;
#ifdef CONFIG_NET_MULTI
NetRestarted = 0;
@@ -527,7 +529,7 @@ restart:
if (ctrlc()) {
eth_halt();
puts("\nAbort\n");
- return -1;
+ goto done;
}
ArpTimeoutCheck();
@@ -581,12 +583,19 @@ restart:
setenv("fileaddr", buf);
}
eth_halt();
- return NetBootFileXferSize;
+ ret = NetBootFileXferSize;
+ goto done;
case NETLOOP_FAIL:
- return -1;
+ goto done;
}
}
+
+done:
+ /* Clear out the handlers */
+ NetSetHandler(NULL);
+ net_set_icmp_handler(NULL);
+ return ret;
}
/**********************************************************************/
@@ -665,6 +674,10 @@ NetSetHandler(rxhand_f *f)
packetHandler = f;
}
+void net_set_icmp_handler(rxhand_icmp_f *f)
+{
+ packet_icmp_handler = f;
+}
void
NetSetTimeout(ulong iv, thand_f *f)
@@ -1409,6 +1422,10 @@ static void receive_icmp(IP_t *ip, int len, IPaddr_t src_ip, Ethernet_t *et)
break;
#endif
default:
+ if (packet_icmp_handler)
+ packet_icmp_handler(icmph->type, icmph->code,
+ ntohs(ip->udp_dst), src_ip, ntohs(ip->udp_src),
+ icmph->un.data, ntohs(ip->udp_len));
break;
}
}
@@ -1697,6 +1714,10 @@ NetReceive(volatile uchar *inpkt, int len)
* subnet. So this is probably a warning that your
* configuration might be wrong. But I'm not really
* sure if there aren't any other situations.
+ *
+ * Simon Glass <sjg@chromium.org>: We get an ICMP when
+ * we send a tftp packet to a dead connection, or when
+ * there is no server at the other end.
*/
if (ip->ip_p == IPPROTO_ICMP) {
receive_icmp(ip, len, src_ip, et);