Skip to content

Commit 1d0f879

Browse files
ArnaudArnaud
authored andcommitted
[ICMP] replace ICMP offsets by struct IcmpHeader
1 parent ae8fa71 commit 1d0f879

File tree

3 files changed

+51
-31
lines changed

3 files changed

+51
-31
lines changed

src/EtherUtil.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,14 @@ inline uint8_t *udp_payload()
5050
return (uint8_t *)&udp_header() + sizeof(UdpHeader);
5151
}
5252

53+
inline IcmpHeader &icmp_header()
54+
{
55+
return *(IcmpHeader *)ip_payload();
56+
}
57+
58+
inline uint8_t *icmp_payload()
59+
{
60+
return (uint8_t *)&icmp_header() + sizeof(IcmpHeader);
61+
}
62+
5363
#endif /* ETHERUTIL_H */

src/net.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,22 @@ struct ArpHeader
189189
// ******* ICMP *******
190190
#define ICMP_TYPE_ECHOREPLY_V 0
191191
#define ICMP_TYPE_ECHOREQUEST_V 8
192-
//
193-
#define ICMP_TYPE_P 0x22
194-
#define ICMP_CHECKSUM_P 0x24
195-
#define ICMP_CHECKSUM_H_P 0x24
196-
#define ICMP_CHECKSUM_L_P 0x25
197-
#define ICMP_IDENT_H_P 0x26
198-
#define ICMP_IDENT_L_P 0x27
199-
#define ICMP_DATA_P 0x2a
192+
193+
struct IcmpHeader
194+
{
195+
uint8_t type;
196+
uint8_t code;
197+
uint16_t checksum;
198+
union
199+
{
200+
uint32_t rest;
201+
struct
202+
{
203+
uint16_t identifier;
204+
uint16_t sequence;
205+
} ping;
206+
};
207+
};
200208

201209
// ******* UDP *******
202210
struct UdpHeader

src/tcpip.cpp

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
#include "EtherUtil.h"
1717
#undef word // arduino nonsense
1818

19-
#define PINGPATTERN 0x42
19+
#define ICMP_PING_PAYLOAD_PATTERN 0x42
20+
#define ICMP_PING_PAYLOAD_SIZE 56
2021

2122
// Avoid spurious pgmspace warnings - http://forum.jeelabs.net/node/327
2223
// See also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
@@ -247,10 +248,9 @@ static void make_arp_answer_from_request() {
247248

248249
static void make_echo_reply_from_request(uint16_t len) {
249250
make_eth_ip_reply();
250-
gPB[ICMP_TYPE_P] = ICMP_TYPE_ECHOREPLY_V;
251-
if (gPB[ICMP_CHECKSUM_P] > (0xFF-0x08))
252-
gPB[ICMP_CHECKSUM_P+1]++;
253-
gPB[ICMP_CHECKSUM_P] += 0x08;
251+
IcmpHeader &ih = icmp_header();
252+
ih.type = ICMP_TYPE_ECHOREPLY_V;
253+
ih.checksum = ih.checksum + 0x08;
254254
EtherCard::packetSend(len);
255255
}
256256

@@ -370,17 +370,15 @@ void EtherCard::clientIcmpRequest(const uint8_t *destip) {
370370
IpHeader &iph = init_ip_frame(destip, IP_PROTO_ICMP_V);
371371
iph.totalLen = HTONS(0x54);
372372
fill_ip_hdr_checksum(iph);
373-
gPB[ICMP_TYPE_P] = ICMP_TYPE_ECHOREQUEST_V;
374-
gPB[ICMP_TYPE_P+1] = 0; // code
375-
gPB[ICMP_CHECKSUM_H_P] = 0;
376-
gPB[ICMP_CHECKSUM_L_P] = 0;
377-
gPB[ICMP_IDENT_H_P] = 5; // some number
378-
gPB[ICMP_IDENT_L_P] = EtherCard::myip[3]; // last byte of my IP
379-
gPB[ICMP_IDENT_L_P+1] = 0; // seq number, high byte
380-
gPB[ICMP_IDENT_L_P+2] = 1; // seq number, low byte, we send only 1 ping at a time
381-
memset(gPB + ICMP_DATA_P, PINGPATTERN, 56);
382-
fill_checksum(ICMP_CHECKSUM_H_P, ICMP_TYPE_P, 56+8,0);
383-
packetSend(98);
373+
IcmpHeader &ih = icmp_header();
374+
ih.type = ICMP_TYPE_ECHOREQUEST_V;
375+
ih.code = 0;
376+
ih.checksum = 0;
377+
ih.ping.identifier = HTONS(0x0500 | EtherCard::myip[3]);
378+
ih.ping.sequence = HTONS(1);
379+
memset(icmp_payload(), ICMP_PING_PAYLOAD_PATTERN, ICMP_PING_PAYLOAD_SIZE);
380+
fill_checksum(ih.checksum, (const uint8_t *)&ih, sizeof(IcmpHeader) + ICMP_PING_PAYLOAD_SIZE, 0);
381+
packetSend(icmp_payload() - gPB + ICMP_PING_PAYLOAD_SIZE);
384382
}
385383

386384
void EtherCard::ntpRequest (uint8_t *ntpip, uint8_t srcport) {
@@ -654,8 +652,8 @@ void EtherCard::registerPingCallback (const IcmpCallback callback) {
654652
uint8_t EtherCard::packetLoopIcmpCheckReply (const uint8_t *ip_monitoredhost) {
655653
const IpHeader &iph = ip_header();
656654
return iph.protocol == IP_PROTO_ICMP_V &&
657-
gPB[ICMP_TYPE_P]==ICMP_TYPE_ECHOREPLY_V &&
658-
gPB[ICMP_DATA_P]== PINGPATTERN &&
655+
icmp_header().type == ICMP_TYPE_ECHOREPLY_V &&
656+
icmp_payload()[0] == ICMP_PING_PAYLOAD_PATTERN &&
659657
check_ip_message_is_from(iph, ip_monitoredhost);
660658
}
661659

@@ -790,11 +788,15 @@ uint16_t EtherCard::packetLoop (uint16_t plen) {
790788
arpStoreSet(is_lan(myip, iph.spaddr) ? iph.spaddr : gwip, eh.shaddr);
791789

792790
#if ETHERCARD_ICMP
793-
if (iph.protocol == IP_PROTO_ICMP_V && gPB[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
794-
{ //Service ICMP echo request (ping)
795-
if (icmp_cb)
796-
(*icmp_cb)(iph.spaddr);
797-
make_echo_reply_from_request(plen);
791+
if (iph.protocol == IP_PROTO_ICMP_V)
792+
{
793+
const IcmpHeader &ih = icmp_header();
794+
if (ih.type == ICMP_TYPE_ECHOREQUEST_V)
795+
{ //Service ICMP echo request (ping)
796+
if (icmp_cb)
797+
(*icmp_cb)(iph.spaddr);
798+
make_echo_reply_from_request(plen);
799+
}
798800
return 0;
799801
}
800802
#endif

0 commit comments

Comments
 (0)