Skip to content

Commit

Permalink
add ipv6
Browse files Browse the repository at this point in the history
  • Loading branch information
SrimantaBarua authored and XVilka committed Jul 23, 2017
1 parent 1b6a772 commit 1d764b5
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 2 deletions.
7 changes: 7 additions & 0 deletions libr/bin/format/pcap/pcap.c
Expand Up @@ -40,6 +40,13 @@ void read_pcap_pktrec_ipv4(pcap_pktrec_ipv4_t *hdr, const ut8 *buf, int swap_end
hdr->chksum = r_read_be16 (&hdr->chksum);
}

void read_pcap_pktrec_ipv6(pcap_pktrec_ipv6_t *hdr, const ut8 *buf, int swap_endian) {
memcpy (hdr, buf, sizeof (pcap_pktrec_ipv6_t));
if (swap_endian) {
hdr->plen = r_swap_ut16 (hdr->plen);
}
}

void read_pcap_pktrec_tcp(pcap_pktrec_tcp_t *hdr, const ut8 *buf, int swap_endian) {
memcpy (hdr, buf, sizeof (pcap_pktrec_tcp_t));
hdr->src_port = r_read_be16 (&hdr->src_port);
Expand Down
13 changes: 12 additions & 1 deletion libr/bin/format/pcap/pcap.h
Expand Up @@ -79,7 +79,7 @@ typedef struct pcak_pktrec_hdr {
typedef struct pcap_pktrec_ether {
ut8 dst[6]; // Destination MAC address
ut8 src[6]; // Source MAC address
ut16 type; // 0x0080 = IPV4, etc
ut16 type; // 0x0080 = IPV4, 0xdd86 = IPV6 etc
} pcap_pktrec_ether_t;

// IPV4 header, atleast 20 bytes
Expand All @@ -96,6 +96,16 @@ typedef struct pcap_pktrec_ipv4 {
ut32 dst; // Destination IP
} pcap_pktrec_ipv4_t;

// IPV6 header
typedef struct pcap_pktrec_ipv6 {
ut32 vc_flow; // version, class, flow
ut16 plen; // payload length
ut8 nxt; // next header
ut8 hlim; // hop limit
ut8 src[16]; // source address
ut8 dest[16]; // destination address
} pcap_pktrec_ipv6_t;

// TCP header, 20 - 60 bytes
typedef struct pcap_pktrec_tcp {
ut16 src_port; // Port on source
Expand All @@ -115,6 +125,7 @@ void read_pcap_file_hdr(pcap_file_hdr_t *hdr, const ut8 *buf, int swap_endian);
void read_pcap_pktrec_hdr(pcap_pktrec_hdr_t *hdr, const ut8 *buf, int swap_endian);
void read_pcap_pktrec_ether(pcap_pktrec_ether_t *hdr, const ut8 *buf, int swap_endian);
void read_pcap_pktrec_ipv4(pcap_pktrec_ipv4_t *hdr, const ut8 *buf, int swap_endian);
void read_pcap_pktrec_ipv6(pcap_pktrec_ipv6_t *hdr, const ut8 *buf, int swap_endian);
void read_pcap_pktrec_tcp(pcap_pktrec_tcp_t *hdr, const ut8 *buf, int swap_endian);

const char* pcap_net_type (ut32 net);
Expand Down
88 changes: 87 additions & 1 deletion libr/bin/p/bin_pcap.c
Expand Up @@ -114,7 +114,7 @@ static void _read_ipv4_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, int e
}
pcap_pktrec_ipv4_t ipv4;
read_pcap_pktrec_ipv4 (&ipv4, &buf[off], endian);
ptr->name = r_str_newf ("0x%x: IPV%d, Src: %d.%d.%d.%d, Dst: %d.%d.%d.%d",
ptr->name = r_str_newf ("0x%"PFMT64x": IPV%d, Src: %d.%d.%d.%d, Dst: %d.%d.%d.%d",
off, (ipv4.ver_len >> 4) & 0x0F, (ipv4.src >> 24) & 0xFF,
(ipv4.src >> 16) & 0xFF, (ipv4.src >> 8) & 0xFF,
ipv4.src && 0xFF, (ipv4.dst >> 24) & 0xFF,
Expand All @@ -134,6 +134,89 @@ static void _read_ipv4_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, int e
}
}

static void _write_ipv6_addr(const ut8 *addr, char *buf, int len) {
struct { int start, len; } best, cur;
ut16 words[8] = { 0 };
int i;
char *ptr = buf;
best.start = cur.start = -1;
best.len = cur.len = 0;
for (i = 0; i < 8; i++) {
words[i] = (addr[i * 2] << 4) | addr[i * 2 + 1];
if (words[i] == 0) {
if (cur.start == -1) {
cur.start = i;
cur.len = 1;
} else {
cur.len++;
}
continue;
}
if (cur.start != -1) {
if (best.start == -1 || cur.len > best.len) {
best.start = cur.start;
best.len = cur.len;
}
cur.start = -1;
}
}
if (best.start == -1 || cur.len > best.len) {
best.start = cur.start;
best.len = cur.len;
}
if (best.len < 2) {
best.start = -1;
}
for (i = 0; i < 8; i++) {
if (i == best.start) {
*ptr++ = ':';
continue;
}
if (best.start != -1 && i > best.start && i < best.start + best.len) {
continue;
}
if (i != 0) {
*ptr++ = ':';
}
ptr += snprintf (ptr, len - (ptr - buf), "%x", words[i]);
}
}

static void _read_ipv6_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, int endian) {
RBinSymbol *ptr = NULL;
if (!(ptr = R_NEW0 (RBinSymbol))) {
return;
}
char write_buf[256] = { 0 };
pcap_pktrec_ipv6_t ipv6;
int len;
read_pcap_pktrec_ipv6 (&ipv6, &buf[off], endian);
snprintf (write_buf, sizeof (write_buf) - 1, "0x%"PFMT64x": IPV6, Src: ", off);
len = strlen (write_buf);
_write_ipv6_addr (ipv6.src, write_buf + len, sizeof (write_buf) - len);
len += strlen (write_buf + len);
strcpy (write_buf + len, ", Dst: ");
len += strlen (write_buf + len);
_write_ipv6_addr (ipv6.dest, write_buf + len, sizeof (write_buf) - len);

if (!(ptr->name = strdup (write_buf))) {
free (ptr);
return;
}
ptr->paddr = ptr->vaddr = off;
r_list_append (list, ptr);
if (off + ipv6.plen + sizeof (pcap_pktrec_ipv6_t) > sz) {
return;
}
off += sizeof (pcap_pktrec_ipv6_t);

// For now, if not TCP, continue. TODO others
switch (ipv6.nxt) {
case 6:
_read_tcp_sym (list, buf, off, sz, ipv6.plen, endian);
}
}

static void _read_ether_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, int endian) {
RBinSymbol *ptr = NULL;
if (!(ptr = R_NEW0 (RBinSymbol))) {
Expand All @@ -156,6 +239,9 @@ static void _read_ether_sym(RList *list, const ut8 *buf, ut64 off, ut64 sz, int
switch (ether.type) {
case 0x08:
_read_ipv4_sym (list, buf, off, sz, endian);
break;
case 0xdd86:
_read_ipv6_sym (list, buf, off, sz, endian);
}
}

Expand Down

0 comments on commit 1d764b5

Please sign in to comment.