-
Notifications
You must be signed in to change notification settings - Fork 0
/
ip.c
146 lines (127 loc) · 4.05 KB
/
ip.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
* Copyright (c) 2018-present VoerEir AB - All Rights Reserved.
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Created by Ashok Kumar <ashok@voereir.com>, Dec 2018
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <netinet/in.h>
#include <rte_ethdev.h>
#include <rte_ip.h>
#include <rte_ether.h>
#include "ip.h"
#include "icmp.h"
#define DOT "."
static void
ipv4_addr_to_dot(uint32_t be_ipv4_addr, char *buf)
{
uint32_t ipv4_addr;
ipv4_addr = rte_be_to_cpu_32(be_ipv4_addr);
sprintf(buf, "%d.%d.%d.%d", (ipv4_addr >> 24) & 0xFF,
(ipv4_addr >> 16) & 0xFF, (ipv4_addr >> 8) & 0xFF,
ipv4_addr & 0xFF);
}
static void ipv6_to_str(const uint8_t* ipv6_addr, char *buf) {
sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
ipv6_addr[0] & 0xFF, ipv6_addr[1] & 0xFF,
ipv6_addr[2] & 0xFF, ipv6_addr[3] & 0xFF,
ipv6_addr[4] & 0xFF, ipv6_addr[5] & 0xFF,
ipv6_addr[6] & 0xFF, ipv6_addr[7] & 0xFF,
ipv6_addr[8] & 0xFF, ipv6_addr[9] & 0xFF,
ipv6_addr[10] & 0xFF, ipv6_addr[11] & 0xFF,
ipv6_addr[12] & 0xFF, ipv6_addr[13] & 0xFF,
ipv6_addr[14] & 0xFF, ipv6_addr[15] & 0xFF);
}
bool is_ip6_equal(const uint8_t *a, const uint8_t *b) {
bool equal = true;
for(int i=0; i<IPV6_ADDR_LEN; ++i) {
if(a[i] != b[i]) {
equal = false;
break;
}
}
return equal;
}
void ipv4_uint32_t_addr_dump(const char *what, uint32_t be_ipv4_addr)
{
char buf[16];
ipv4_addr_to_dot(be_ipv4_addr, buf);
if (what)
printf("%s", what);
printf("%s", buf);
fflush(stdout);
}
void ipv4_addr_dump(const char *what, const struct in_addr * be_ipv4_addr)
{
char buf[16];
ipv4_addr_to_dot(be_ipv4_addr->s_addr, buf);
if (what)
printf("%s", what);
printf("%s", buf);
fflush(stdout);
}
void ipv6_addr_dump(const char *what, const struct in6_addr *ipv6_addr)
{
char buf[40];
ipv6_to_str(ipv6_addr->s6_addr, buf);
if (what)
printf("%s", what);
printf("%s", buf);
fflush(stdout);
}
void ipv6_hdr_dump(const char *what, const struct ipv6_hdr *ipv6_addr)
{
char src[40], dst[40];
ipv6_to_str(ipv6_addr->src_addr, src);
ipv6_to_str(ipv6_addr->dst_addr, dst);
if (what)
printf("%s", what);
printf("Proto: %x, Payload Length: %x, Source IP: %s, Destination IP: %s\n",
ipv6_addr->proto, ipv6_addr->payload_len, src, dst);
fflush(stdout);
}
void ether_addr_dump(const char *what, const struct ether_addr *ea)
{
char buf[ETHER_ADDR_FMT_SIZE];
ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, ea);
if (what)
printf("%s", what);
printf("%s", buf);
fflush(stdout);
}
uint16_t ipv4_hdr_cksum(struct ipv4_hdr *ip_h)
{
uint16_t *v16_h;
uint32_t ip_cksum;
/*
* Compute the sum of successive 16-bit words of the IPv4 header,
* skipping the checksum field of the header.
*/
v16_h = (unaligned_uint16_t *) ip_h;
ip_cksum = v16_h[0] + v16_h[1] + v16_h[2] + v16_h[3] +
v16_h[4] + v16_h[6] + v16_h[7] + v16_h[8] + v16_h[9];
/* reduce 32 bit checksum to 16 bits and complement it */
ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
ip_cksum = (~ip_cksum) & 0x0000FFFF;
return (ip_cksum == 0) ? 0xFFFF : (uint16_t) ip_cksum;
}
uint16_t ipv6_pseudohdr_sum(const struct ipv6_hdr *ip6_hdr)
{
uint32_t ip6_sum;
ip6_sum = ip6_hdr->proto + ip6_hdr->payload_len;
for(int i=IPV6_ADDR_LEN - 1; i>0; i-= 2) {
ip6_sum += (ip6_hdr->src_addr[i-1] << 8) + ip6_hdr->src_addr[i];
}
for(int i=IPV6_ADDR_LEN - 1; i>0; i-= 2) {
ip6_sum += (ip6_hdr->dst_addr[i-1] << 8) + ip6_hdr->dst_addr[i];
}
/* reduce 32 bit sum to 16 bits */
while (ip6_sum > 0xFFFF) {
ip6_sum = (ip6_sum & 0xffff) + (ip6_sum >> 16);
}
return (uint16_t) ip6_sum;
}