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