%%% @copyright 2012-2023 Michael Santos %%% All rights reserved. %%% %%% Redistribution and use in source and binary forms, with or without %%% modification, are permitted provided that the following conditions %%% are met: %%% %%% 1. Redistributions of source code must retain the above copyright notice, %%% this list of conditions and the following disclaimer. %%% %%% 2. Redistributions in binary form must reproduce the above copyright %%% notice, this list of conditions and the following disclaimer in the %%% documentation and/or other materials provided with the distribution. %%% %%% 3. Neither the name of the copyright holder nor the names of its %%% contributors may be used to endorse or promote products derived from %%% this software without specific prior written permission. %%% %%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS %%% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT %%% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR %%% A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT %%% HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, %%% SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED %%% TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR %%% PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF %%% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING %%% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS %%% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -module(icmp_message). -include_lib("pkt/include/pkt.hrl"). -export([ type_to_uint8/1, code_to_uint8/1, type/1, code/1 ]). type_to_uint8(Type) when is_integer(Type) -> Type; type_to_uint8(Type) when is_atom(Type) -> type(Type). code_to_uint8(Code) when is_integer(Code) -> Code; code_to_uint8(Code) when is_atom(Code) -> code(Code). %% %% ICMP control message: types %% type(?ICMP_ECHOREPLY) -> echoreply; type(?ICMP_DEST_UNREACH) -> dest_unreach; type(?ICMP_SOURCE_QUENCH) -> source_quench; type(?ICMP_REDIRECT) -> redirect; type(?ICMP_ECHO) -> echo; type(?ICMP_TIME_EXCEEDED) -> time_exceeded; type(?ICMP_PARAMETERPROB) -> parameterprob; type(?ICMP_TIMESTAMP) -> timestamp; type(?ICMP_TIMESTAMPREPLY) -> timestampreply; type(?ICMP_INFO_REQUEST) -> info_request; type(?ICMP_INFO_REPLY) -> info_reply; type(?ICMP_ADDRESS) -> address; type(?ICMP_ADDRESSREPLY) -> addressreply; type(echoreply) -> ?ICMP_ECHOREPLY; type(dest_unreach) -> ?ICMP_DEST_UNREACH; type(source_quench) -> ?ICMP_SOURCE_QUENCH; type(redirect) -> ?ICMP_REDIRECT; type(echo) -> ?ICMP_ECHO; type(time_exceeded) -> ?ICMP_TIME_EXCEEDED; type(parameterprob) -> ?ICMP_PARAMETERPROB; type(timestamp) -> ?ICMP_TIMESTAMP; type(timestampreply) -> ?ICMP_TIMESTAMPREPLY; type(info_request) -> ?ICMP_INFO_REQUEST; type(info_reply) -> ?ICMP_INFO_REPLY; type(address) -> ?ICMP_ADDRESS; type(addressreply) -> ?ICMP_ADDRESSREPLY. %% %% ICMP control message: codes %% % destination unreachable code(unreach_net) -> ?ICMP_UNREACH_NET; code(unreach_host) -> ?ICMP_UNREACH_HOST; code(unreach_protocol) -> ?ICMP_UNREACH_PROTOCOL; code(unreach_port) -> ?ICMP_UNREACH_PORT; code(unreach_needfrag) -> ?ICMP_UNREACH_NEEDFRAG; code(unreach_srcfail) -> ?ICMP_UNREACH_SRCFAIL; % redirect code(redirect_net) -> ?ICMP_REDIRECT_NET; code(redirect_host) -> ?ICMP_REDIRECT_HOST; code(redirect_tosnet) -> ?ICMP_REDIRECT_TOSNET; code(redirect_toshost) -> ?ICMP_REDIRECT_TOSHOST; % time_exceeded code(timxceed_intrans) -> ?ICMP_TIMXCEED_INTRANS; code(timxceed_reass) -> ?ICMP_TIMXCEED_REASS; % XXX create a fake code so: % XXX e.g., code(code({?ICMP_ECHO, 0})) == 0 code(Code) when Code == echoreply; Code == source_quench; Code == echo; Code == parameterprob; Code == timestamp; Code == timestampreply; Code == info_request; Code == info_reply; Code == address; Code == addressreply -> 0; code({?ICMP_ECHOREPLY, 0}) -> echoreply; code({?ICMP_DEST_UNREACH, ?ICMP_UNREACH_NET}) -> unreach_net; code({?ICMP_DEST_UNREACH, ?ICMP_UNREACH_HOST}) -> unreach_host; code({?ICMP_DEST_UNREACH, ?ICMP_UNREACH_PROTOCOL}) -> unreach_protocol; code({?ICMP_DEST_UNREACH, ?ICMP_UNREACH_PORT}) -> unreach_port; code({?ICMP_DEST_UNREACH, ?ICMP_UNREACH_NEEDFRAG}) -> unreach_needfrag; code({?ICMP_DEST_UNREACH, ?ICMP_UNREACH_SRCFAIL}) -> unreach_srcfail; code({?ICMP_SOURCE_QUENCH, 0}) -> source_quench; code({?ICMP_REDIRECT, ?ICMP_REDIRECT_NET}) -> redirect_net; code({?ICMP_REDIRECT, ?ICMP_REDIRECT_HOST}) -> redirect_host; code({?ICMP_REDIRECT, ?ICMP_REDIRECT_TOSNET}) -> redirect_tosnet; code({?ICMP_REDIRECT, ?ICMP_REDIRECT_TOSHOST}) -> redirect_toshost; code({?ICMP_ECHO, 0}) -> echo; code({?ICMP_TIME_EXCEEDED, ?ICMP_TIMXCEED_INTRANS}) -> timxceed_intrans; code({?ICMP_TIME_EXCEEDED, ?ICMP_TIMXCEED_REASS}) -> timxceed_reass; code({?ICMP_PARAMETERPROB, 0}) -> parameterprob; code({?ICMP_TIMESTAMP, 0}) -> timestamp; code({?ICMP_TIMESTAMPREPLY, 0}) -> timestampreply; code({?ICMP_INFO_REQUEST, 0}) -> info_request; code({?ICMP_INFO_REPLY, 0}) -> info_reply; code({?ICMP_ADDRESS, 0}) -> address; code({?ICMP_ADDRESSREPLY, 0}) -> addressreply; code({Type, Code}) when is_integer(Type), is_integer(Code) -> {unknown, Type, Code}.