@@ -310,7 +310,7 @@ gt_bind(int argc, char **argv)
|
||||
if (r <= 0) {
|
||||
if (r == -1 && errno != EAGAIN)
|
||||
perror("tun_read");
|
||||
} else if ((!ip_get_common(&ic, buf, r)) && (ic.size == r) &&
|
||||
} else if ((!ip_get_common(&ic, buf, r)) &&
|
||||
(mud_send(mud, buf, r, ic.tc) == -1)) {
|
||||
if (errno == EMSGSIZE) {
|
||||
mtu = gt_setup_mtu(mud, tun_name);
|
||||
@@ -327,7 +327,7 @@ gt_bind(int argc, char **argv)
|
||||
if (r <= 0) {
|
||||
if (r == -1 && errno != EAGAIN)
|
||||
perror("mud_recv");
|
||||
} else if ((!ip_get_common(&ic, buf, r) && (ic.size == r)) &&
|
||||
} else if ((!ip_get_common(&ic, buf, r)) &&
|
||||
(tun_write(tun_fd, buf, r) == -1)) {
|
||||
if (errno != EAGAIN)
|
||||
perror("tun_write");
|
||||
|
||||
57
src/ip.h
57
src/ip.h
@@ -3,32 +3,10 @@
|
||||
#include <stdint.h>
|
||||
|
||||
struct ip_common {
|
||||
uint8_t version;
|
||||
uint8_t tc;
|
||||
uint8_t proto;
|
||||
uint8_t hdr_size;
|
||||
uint16_t size;
|
||||
};
|
||||
|
||||
_pure_ static inline uint8_t
|
||||
ip_get_version(const uint8_t *data, size_t size)
|
||||
{
|
||||
if (size < 20)
|
||||
return 0;
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -37,45 +15,22 @@ ip_read16(const uint8_t *src)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
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 0;
|
||||
|
||||
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 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ip_get_common(struct ip_common *ic, const uint8_t *data, size_t size)
|
||||
{
|
||||
ic->version = ip_get_version(data, size);
|
||||
if (size < 20)
|
||||
return 1;
|
||||
|
||||
switch (ic->version) {
|
||||
switch (data[0] >> 4) {
|
||||
case 4:
|
||||
ic->tc = data[1];
|
||||
ic->proto = data[9];
|
||||
ic->hdr_size = (data[0] & 0xF) << 2;
|
||||
ic->size = ip_read16(&data[2]);
|
||||
if (ic->size >= 20)
|
||||
return 0;
|
||||
break;
|
||||
return size != ip_read16(&data[2]);
|
||||
case 6:
|
||||
ic->tc = ((data[0] & 0xF) << 4) | (data[1] >> 4);
|
||||
ic->proto = data[6];
|
||||
ic->hdr_size = 40;
|
||||
ic->size = ip_read16(&data[4]) + 40;
|
||||
return 0;
|
||||
return size != ip_read16(&data[4]) + 40;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user