/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * icmp.c - convenience functions for translating ICMP and ICMPv6 packets.
 */

#include <netinet/in.h>
//#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
#include <linux/icmp.h>

#include "logging.h"
#include "icmp.h"

#include "my_header.h"

/* function: icmp_guess_ttl
 * Guesses the number of hops a received packet has traversed based on its TTL.
 * ttl - the ttl of the received packet.
 */
uint8_t icmp_guess_ttl(uint8_t ttl) {
  if (ttl > 128) {
    return 255 - ttl;
  } else if (ttl > 64) {
    return 128 - ttl;
  } else if (ttl > 32) {
    return 64 - ttl;
  } else {
    return 32 - ttl;
  }
}

/* function: is_icmp_error
 * Determines whether an ICMP type is an error message.
 * type: the ICMP type
 */
int is_icmp_error(uint8_t type) {
  return type == 3 || type == 11 || type == 12;
}

/* function: is_icmp6_error
 * Determines whether an ICMPv6 type is an error message.
 * type: the ICMPv6 type
 */
int is_icmp6_error(uint8_t type) {
  return type < 128;
}

/* function: icmp_to_icmp6_type
 * Maps ICMP types to ICMPv6 types. Partial implementation of RFC 6145, section 4.2.
 * type - the ICMPv6 type
 */
uint8_t icmp_to_icmp6_type(uint8_t type, uint8_t code) {
  switch (type) {
    case ICMP_ECHO:
      return ICMP6_ECHO_REQUEST;

    case ICMP_ECHOREPLY:
      return ICMP6_ECHO_REPLY;

    case ICMP_TIME_EXCEEDED:
      return ICMP6_TIME_EXCEEDED;

    case ICMP_DEST_UNREACH:
      // These two types need special translation which we don't support yet.
      if (code != ICMP_UNREACH_PROTOCOL && code != ICMP_UNREACH_NEEDFRAG) {
        return ICMP6_DST_UNREACH;
      }
  }

  // We don't understand this ICMP type. Return parameter problem so the caller will bail out.
  logmsg_dbg(ANDROID_LOG_DEBUG, "icmp_to_icmp6_type: unhandled ICMP type %d", type);
  return ICMP6_PARAM_PROB;
}

/* function: icmp_to_icmp6_code
 * Maps ICMP codes to ICMPv6 codes. Partial implementation of RFC 6145, section 4.2.
 * type - the ICMP type
 * code - the ICMP code
 */
uint8_t icmp_to_icmp6_code(uint8_t type, uint8_t code) {
  switch (type) {
    case ICMP_ECHO:
    case ICMP_ECHOREPLY:
      return 0;

    case ICMP_TIME_EXCEEDED:
      return code;

    case ICMP_DEST_UNREACH:
      switch (code) {
        case ICMP_UNREACH_NET:
        case ICMP_UNREACH_HOST:
          return ICMP6_DST_UNREACH_NOROUTE;

        case ICMP_UNREACH_PORT:
          return ICMP6_DST_UNREACH_NOPORT;

        case ICMP_UNREACH_NET_PROHIB:
        case ICMP_UNREACH_HOST_PROHIB:
        case ICMP_UNREACH_FILTER_PROHIB:
        case ICMP_UNREACH_PRECEDENCE_CUTOFF:
          return ICMP6_DST_UNREACH_ADMIN;

        // Otherwise, we don't understand this ICMP type/code combination. Fall through.
      }
  }
  logmsg_dbg(ANDROID_LOG_DEBUG, "icmp_to_icmp6_code: unhandled ICMP type/code %d/%d", type, code);
  return 0;
}

/* function: icmp6_to_icmp_type
 * Maps ICMPv6 types to ICMP types. Partial implementation of RFC 6145, section 5.2.
 * type - the ICMP type
 */
uint8_t icmp6_to_icmp_type(uint8_t type, uint8_t code) {
  switch (type) {
    case ICMP6_ECHO_REQUEST:
      return ICMP_ECHO;

    case ICMP6_ECHO_REPLY:
      return ICMP_ECHOREPLY;

    case ICMP6_DST_UNREACH:
      return ICMP_DEST_UNREACH;

    case ICMP6_TIME_EXCEEDED:
      return ICMP_TIME_EXCEEDED;
  }

  // We don't understand this ICMP type. Return parameter problem so the caller will bail out.
  logmsg_dbg(ANDROID_LOG_DEBUG, "icmp6_to_icmp_type: unhandled ICMP type/code %d/%d", type, code);
  return ICMP_PARAMETERPROB;
}

/* function: icmp6_to_icmp_code
 * Maps ICMPv6 codes to ICMP codes. Partial implementation of RFC 6145, section 5.2.
 * type - the ICMPv6 type
 * code - the ICMPv6 code
 */
uint8_t icmp6_to_icmp_code(uint8_t type, uint8_t code) {
  switch (type) {
    case ICMP6_ECHO_REQUEST:
    case ICMP6_ECHO_REPLY:
    case ICMP6_TIME_EXCEEDED:
      return code;

    case ICMP6_DST_UNREACH:
      switch (code) {
        case ICMP6_DST_UNREACH_NOROUTE:
          return ICMP_UNREACH_HOST;

        case ICMP6_DST_UNREACH_ADMIN:
          return ICMP_UNREACH_HOST_PROHIB;

        case ICMP6_DST_UNREACH_BEYONDSCOPE:
          return ICMP_UNREACH_HOST;

        case ICMP6_DST_UNREACH_ADDR:
          return ICMP_HOST_UNREACH;

        case ICMP6_DST_UNREACH_NOPORT:
          return ICMP_UNREACH_PORT;

        // Otherwise, we don't understand this ICMPv6 type/code combination. Fall through.
      }
  }

  logmsg_dbg(ANDROID_LOG_DEBUG, "icmp6_to_icmp_code: unhandled ICMP type/code %d/%d", type, code);
  return 0;
}
