Move ICMP parsing code in src/ip.h
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
40
src/ip.h
40
src/ip.h
@@ -19,6 +19,42 @@ ip_get_version(const uint8_t *data, size_t size)
|
|||||||
return data[0] >> 4;
|
return data[0] >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
ip_read32(const uint8_t *src)
|
||||||
|
{
|
||||||
|
uint32_t ret = src[3];
|
||||||
|
ret |= ((uint32_t)src[2]) << 8;
|
||||||
|
ret |= ((uint32_t)src[1]) << 16;
|
||||||
|
ret |= ((uint32_t)src[0]) << 24;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t
|
||||||
|
ip_read16(const uint8_t *src)
|
||||||
|
{
|
||||||
|
uint16_t ret = src[1];
|
||||||
|
ret |= ((uint16_t)src[0]) << 8;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ip_get_mtu(struct ip_common *ic, const uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
|
if (ic->hdr_size <= 0 || ic->hdr_size + 8 > size)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const uint8_t *p = &data[ic->hdr_size];
|
||||||
|
|
||||||
|
if (ic->version == 4 && ic->proto == 1 && p[0] == 3)
|
||||||
|
return ip_read16(&p[6]);
|
||||||
|
|
||||||
|
// not tested..
|
||||||
|
// if (ic->version == 6 && ic->proto == 58 && p[0] == 2)
|
||||||
|
// return ip_read32(&p[4]);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ip_get_common(struct ip_common *ic, const uint8_t *data, size_t size)
|
ip_get_common(struct ip_common *ic, const uint8_t *data, size_t size)
|
||||||
{
|
{
|
||||||
@@ -29,7 +65,7 @@ ip_get_common(struct ip_common *ic, const uint8_t *data, size_t size)
|
|||||||
ic->tc = data[1];
|
ic->tc = data[1];
|
||||||
ic->proto = data[9];
|
ic->proto = data[9];
|
||||||
ic->hdr_size = (data[0] & 0xF) << 2;
|
ic->hdr_size = (data[0] & 0xF) << 2;
|
||||||
ic->size = ((data[2] << 8) | data[3]);
|
ic->size = ip_read16(&data[2]);
|
||||||
if (ic->size >= 20)
|
if (ic->size >= 20)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
@@ -37,7 +73,7 @@ ip_get_common(struct ip_common *ic, const uint8_t *data, size_t size)
|
|||||||
ic->tc = ((data[0] & 0xF) << 4) | (data[1] >> 4);
|
ic->tc = ((data[0] & 0xF) << 4) | (data[1] >> 4);
|
||||||
ic->proto = data[6];
|
ic->proto = data[6];
|
||||||
ic->hdr_size = 40;
|
ic->hdr_size = 40;
|
||||||
ic->size = ((data[4] << 8) | data[5]) + 40;
|
ic->size = ip_read16(&data[4]) + 40;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
src/main.c
17
src/main.c
@@ -411,17 +411,12 @@ main(int argc, char **argv)
|
|||||||
socklen_t sl = sizeof(ss);
|
socklen_t sl = sizeof(ss);
|
||||||
ssize_t r = recvfrom(icmp_fd, gt.buf.data, gt.buf.size, 0,
|
ssize_t r = recvfrom(icmp_fd, gt.buf.data, gt.buf.size, 0,
|
||||||
(struct sockaddr *)&ss, &sl);
|
(struct sockaddr *)&ss, &sl);
|
||||||
if (r >= 8) {
|
struct ip_common ic;
|
||||||
struct ip_common ic;
|
if (!ip_get_common(&ic, gt.buf.data, r)) {
|
||||||
if (!ip_get_common(&ic, gt.buf.data, r) && ic.proto == 1) {
|
int mtu = ip_get_mtu(&ic, gt.buf.data, r);
|
||||||
unsigned char *data = >.buf.data[ic.hdr_size];
|
if (mtu > 0) {
|
||||||
if (data[0] == 3) {
|
gt_log("received MTU from ICMP: %i\n", mtu);
|
||||||
int mtu = (data[6] << 8) | data[7];
|
mud_set_mtu(mud, GT_MTU(mtu));
|
||||||
if (mtu) {
|
|
||||||
gt_log("received MTU from ICMP: %i\n", mtu);
|
|
||||||
mud_set_mtu(mud, GT_MTU(mtu));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user