blob: 936958c2cbb905c83abdf7754f0b459164350c15 [file] [log] [blame]
xf.lif1aed282024-02-06 00:31:51 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * icmp.c - convenience functions for translating ICMP and ICMPv6 packets.
17 */
18
19#include <netinet/in.h>
20//#include <netinet/ip_icmp.h>
21#include <netinet/icmp6.h>
22#include <linux/icmp.h>
23
24#include "logging.h"
25#include "icmp.h"
26
27#include "my_header.h"
28
29/* function: icmp_guess_ttl
30 * Guesses the number of hops a received packet has traversed based on its TTL.
31 * ttl - the ttl of the received packet.
32 */
33uint8_t icmp_guess_ttl(uint8_t ttl) {
34 if (ttl > 128) {
35 return 255 - ttl;
36 } else if (ttl > 64) {
37 return 128 - ttl;
38 } else if (ttl > 32) {
39 return 64 - ttl;
40 } else {
41 return 32 - ttl;
42 }
43}
44
45/* function: is_icmp_error
46 * Determines whether an ICMP type is an error message.
47 * type: the ICMP type
48 */
49int is_icmp_error(uint8_t type) {
50 return type == 3 || type == 11 || type == 12;
51}
52
53/* function: is_icmp6_error
54 * Determines whether an ICMPv6 type is an error message.
55 * type: the ICMPv6 type
56 */
57int is_icmp6_error(uint8_t type) {
58 return type < 128;
59}
60
61/* function: icmp_to_icmp6_type
62 * Maps ICMP types to ICMPv6 types. Partial implementation of RFC 6145, section 4.2.
63 * type - the ICMPv6 type
64 */
65uint8_t icmp_to_icmp6_type(uint8_t type, uint8_t code) {
66 switch (type) {
67 case ICMP_ECHO:
68 return ICMP6_ECHO_REQUEST;
69
70 case ICMP_ECHOREPLY:
71 return ICMP6_ECHO_REPLY;
72
73 case ICMP_TIME_EXCEEDED:
74 return ICMP6_TIME_EXCEEDED;
75
76 case ICMP_DEST_UNREACH:
77 // These two types need special translation which we don't support yet.
78 if (code != ICMP_UNREACH_PROTOCOL && code != ICMP_UNREACH_NEEDFRAG) {
79 return ICMP6_DST_UNREACH;
80 }
81 }
82
83 // We don't understand this ICMP type. Return parameter problem so the caller will bail out.
84 logmsg_dbg(ANDROID_LOG_DEBUG, "icmp_to_icmp6_type: unhandled ICMP type %d", type);
85 return ICMP6_PARAM_PROB;
86}
87
88/* function: icmp_to_icmp6_code
89 * Maps ICMP codes to ICMPv6 codes. Partial implementation of RFC 6145, section 4.2.
90 * type - the ICMP type
91 * code - the ICMP code
92 */
93uint8_t icmp_to_icmp6_code(uint8_t type, uint8_t code) {
94 switch (type) {
95 case ICMP_ECHO:
96 case ICMP_ECHOREPLY:
97 return 0;
98
99 case ICMP_TIME_EXCEEDED:
100 return code;
101
102 case ICMP_DEST_UNREACH:
103 switch (code) {
104 case ICMP_UNREACH_NET:
105 case ICMP_UNREACH_HOST:
106 return ICMP6_DST_UNREACH_NOROUTE;
107
108 case ICMP_UNREACH_PORT:
109 return ICMP6_DST_UNREACH_NOPORT;
110
111 case ICMP_UNREACH_NET_PROHIB:
112 case ICMP_UNREACH_HOST_PROHIB:
113 case ICMP_UNREACH_FILTER_PROHIB:
114 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
115 return ICMP6_DST_UNREACH_ADMIN;
116
117 // Otherwise, we don't understand this ICMP type/code combination. Fall through.
118 }
119 }
120 logmsg_dbg(ANDROID_LOG_DEBUG, "icmp_to_icmp6_code: unhandled ICMP type/code %d/%d", type, code);
121 return 0;
122}
123
124/* function: icmp6_to_icmp_type
125 * Maps ICMPv6 types to ICMP types. Partial implementation of RFC 6145, section 5.2.
126 * type - the ICMP type
127 */
128uint8_t icmp6_to_icmp_type(uint8_t type, uint8_t code) {
129 switch (type) {
130 case ICMP6_ECHO_REQUEST:
131 return ICMP_ECHO;
132
133 case ICMP6_ECHO_REPLY:
134 return ICMP_ECHOREPLY;
135
136 case ICMP6_DST_UNREACH:
137 return ICMP_DEST_UNREACH;
138
139 case ICMP6_TIME_EXCEEDED:
140 return ICMP_TIME_EXCEEDED;
141 }
142
143 // We don't understand this ICMP type. Return parameter problem so the caller will bail out.
144 logmsg_dbg(ANDROID_LOG_DEBUG, "icmp6_to_icmp_type: unhandled ICMP type/code %d/%d", type, code);
145 return ICMP_PARAMETERPROB;
146}
147
148/* function: icmp6_to_icmp_code
149 * Maps ICMPv6 codes to ICMP codes. Partial implementation of RFC 6145, section 5.2.
150 * type - the ICMPv6 type
151 * code - the ICMPv6 code
152 */
153uint8_t icmp6_to_icmp_code(uint8_t type, uint8_t code) {
154 switch (type) {
155 case ICMP6_ECHO_REQUEST:
156 case ICMP6_ECHO_REPLY:
157 case ICMP6_TIME_EXCEEDED:
158 return code;
159
160 case ICMP6_DST_UNREACH:
161 switch (code) {
162 case ICMP6_DST_UNREACH_NOROUTE:
163 return ICMP_UNREACH_HOST;
164
165 case ICMP6_DST_UNREACH_ADMIN:
166 return ICMP_UNREACH_HOST_PROHIB;
167
168 case ICMP6_DST_UNREACH_BEYONDSCOPE:
169 return ICMP_UNREACH_HOST;
170
171 case ICMP6_DST_UNREACH_ADDR:
172 return ICMP_HOST_UNREACH;
173
174 case ICMP6_DST_UNREACH_NOPORT:
175 return ICMP_UNREACH_PORT;
176
177 // Otherwise, we don't understand this ICMPv6 type/code combination. Fall through.
178 }
179 }
180
181 logmsg_dbg(ANDROID_LOG_DEBUG, "icmp6_to_icmp_code: unhandled ICMP type/code %d/%d", type, code);
182 return 0;
183}