1 /*********************************************************************************
\r
3 * --------------------------------------------------------------------------------
\r
5 * This file is part of MiMic
\r
6 * Copyright (C)2011 Ryo Iizuka
\r
8 * MiMic is free software: you can redistribute it and/or modify
\r
9 * it under the terms of the GNU Lesser General Public License as published
\r
10 * by the Free Software Foundation, either version 3 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU Lesser General Public License
\r
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
21 * For further information please contact.
\r
23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
\r
26 * Parts of this file were leveraged from uIP:
\r
28 * Copyright (c) 2001-2003, Adam Dunkels.
\r
29 * All rights reserved.
\r
31 * Redistribution and use in source and binary forms, with or without
\r
32 * modification, are permitted provided that the following conditions
\r
34 * 1. Redistributions of source code must retain the above copyright
\r
35 * notice, this list of conditions and the following disclaimer.
\r
36 * 2. Redistributions in binary form must reproduce the above copyright
\r
37 * notice, this list of conditions and the following disclaimer in the
\r
38 * documentation and/or other materials provided with the distribution.
\r
39 * 3. The name of the author may not be used to endorse or promote
\r
40 * products derived from this software without specific prior
\r
41 * written permission.
\r
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
\r
44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
\r
45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
\r
47 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
\r
49 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
\r
50 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
\r
51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
52 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
53 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
55 #define ICMP6_ECHO_REPLY 129
\r
56 #define ICMP6_ECHO 128
\r
57 #define ICMP6_NEIGHBOR_SOLICITATION 135
\r
58 #define ICMP6_NEIGHBOR_ADVERTISEMENT 136
\r
60 #define ICMP6_FLAG_S (1 << 6)
\r
62 #define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
\r
63 #define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
\r
65 void uip_process_ICMP6(
\r
66 const void* in_packet)
\r
70 /* This is IPv6 ICMPv6 processing code. */
\r
71 DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
\r
74 UIP_STAT(++uip_stat.icmp.recv);
\r
76 /* If we get a neighbor solicitation for our address we should send
\r
77 a neighbor advertisement message back. */
\r
78 if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
\r
79 if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
\r
81 if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
\r
82 /* Save the sender's address in our neighbor list. */
\r
83 uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
\r
86 /* We should now send a neighbor advertisement back to where the
\r
87 neighbor solicication came from. */
\r
88 ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
\r
89 ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
\r
91 ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
\r
93 uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
\r
94 uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
\r
95 ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
\r
96 ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
\r
97 memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
\r
98 ICMPBUF->icmpchksum = 0;
\r
99 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
\r
106 } else if(ICMPBUF->type == ICMP6_ECHO) {
\r
107 /* ICMP echo (i.e., ping) processing. This is simple, we only
\r
108 change the ICMP type from ECHO to ECHO_REPLY and update the
\r
109 ICMP checksum before we return the packet. */
\r
111 ICMPBUF->type = ICMP6_ECHO_REPLY;
\r
113 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
\r
114 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
\r
115 ICMPBUF->icmpchksum = 0;
\r
116 ICMPBUF->icmpchksum = ~uip_icmp6chksum();
\r
118 UIP_STAT(++uip_stat.icmp.sent);
\r
121 DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
\r
122 UIP_STAT(++uip_stat.icmp.drop);
\r
123 UIP_STAT(++uip_stat.icmp.typeerr);
\r
124 UIP_LOG("icmp: unknown ICMP message.");
\r
137 void uip_icmp6_v6(void)
\r
139 // if (uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
\r
140 /* If we are configured to use ping IP address configuration and
\r
141 hasn't been assigned an IP address yet, we accept all ICMP
\r
146 /* For IPv6, packet reception is a little trickier as we need to
\r
147 make sure that we listen to certain multicast addresses (all
\r
148 hosts multicast address, and the solicited-node multicast
\r
149 address) as well. However, we will cheat here and accept all
\r
150 multicast packets that are sent to the ff02::/16 addresses. */
\r
151 /* if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
\r
152 BUF->destipaddr[0] != NyLPC_HTONS(0xff02)) {
\r
153 UIP_STAT(++uip_stat.header.drop);
\r