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
57 #include "../include/NyLPC_config.h"
\r
58 #include "../include/NyLPC_stdlib.h"
\r
59 #include "NyLPC_uip_ethernet.h"
\r
63 #endif /* __cplusplus */
\r
65 #define UIP_PROTO_ICMP 1
\r
66 #define UIP_PROTO_TCP 6
\r
67 #define UIP_PROTO_UDP 17
\r
68 #define UIP_PROTO_ICMP6 58
\r
70 #define ARP_REQUEST 1
\r
72 #define ARP_HWTYPE_ETH 1
\r
75 #ifndef PACK_STRUCT_END
\r
76 #define PACK_STRUCT_END __attribute((packed))
\r
79 /**********************************************************************
\r
83 **********************************************************************/
\r
87 * IPアドレスは、ネットワークオーダーで設定します。
\r
89 struct NyLPC_TIPv4Addr
\r
93 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO;
\r
94 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL;
\r
95 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST;
\r
96 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST;
\r
97 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK;
\r
98 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_APIPA_MASK;
\r
101 * addr1とaddr2が全く同じであるかをテストします。
\r
104 #define NyLPC_TIPv4Addr_isEqual(v1,v2) ((v1)->v==(v2)->v)
\r
106 * addr1とaddr2をmaskでマスクした結果を比較します。
\r
109 #define NyLPC_TIPv4Addr_isEqualWithMask(addr1, addr2, mask) ((((addr1)->v) & ((mask)->v))==(((addr2)->v) & ((mask)->v)))
\r
112 * 変数にIP v4アドレスをセットします。
\r
115 NyLPC_TIPv4Addr ip;
\r
116 NyLPC_TIpv4Addr_set(&ip,1,2,3,4);
\r
119 #define NyLPC_TIPv4Addr_set(s,a0,a1,a2,a3) (s)->v=NyLPC_htonl((0xff000000&(((NyLPC_TUInt32)(a0))<<24))|(0x00ff0000&(((NyLPC_TUInt32)(a1))<<16))|(0x0000ff00&(((NyLPC_TUInt32)(a2))<<8))|(0x000000ff&((NyLPC_TUInt32)(a3))))
\r
120 #define NyLPC_TIPv4Addr_pack(a0,a1,a2,a3) {NyLPC_HTONL((0xff000000&(((NyLPC_TUInt32)(a0))<<24))|(0x00ff0000&(((NyLPC_TUInt32)(a1))<<16))|(0x0000ff00&(((NyLPC_TUInt32)(a2))<<8))|(0x000000ff&((NyLPC_TUInt32)(a3))))}
\r
123 * IPアドレスを文字列に変換して返します。
\r
125 NyLPC_TInt16 NyLPC_TIPv4Addr_toString(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf);
\r
133 NyLPC_TUInt16 v[8];
\r
136 typedef struct uip_ip6addr uip_ip6addr_t;
\r
138 NyLPC_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLPC_TUInt16 len);
\r
146 #define UIP_DEFAULT_IP_TTL 64
\r
151 * The maximum number of times a segment should be retransmitted
\r
152 * before the connection should be aborted.
\r
154 * This should not be changed.
\r
156 #define UIP_MAXRTX 8
\r
162 # if UIP_BYTE_ORDER == NyLPC_ENDIAN_BIG
\r
163 # define NyLPC_HTONS(n) (n)
\r
164 # define NyLPC_htons(n) (n)
\r
165 # define NyLPC_ntohs(n) (n)
\r
166 # define NyLPC_htonl(n) (n)
\r
167 # define NyLPC_ntohl(n) (n)
\r
168 # define NyLPC_HTONS(n) (n)
\r
169 # define NyLPC_NTOHS(n) (n)
\r
171 # define NyLPC_htonl(n) NyLPC_TUInt32_bswap(n)
\r
172 # define NyLPC_ntohl(n) NyLPC_TUInt32_bswap(n)
\r
173 # define NyLPC_htons(n) NyLPC_TUInt16_bswap(n)
\r
174 # define NyLPC_ntohs(n) NyLPC_TUInt16_bswap(n)
\r
175 # define NyLPC_HTONS(n) NyLPC_TUInt16_BSWAP(n)
\r
176 # define NyLPC_NTOHS(n) NyLPC_TUInt16_BSWAP(n)
\r
177 # define NyLPC_NTOHL(n) NyLPC_TUInt32_BSWAP(n)
\r
178 # define NyLPC_HTONL(n) NyLPC_TUInt32_BSWAP(n)
\r
179 #endif /* NyLPC_HTONS */
\r
184 /**********************************************************************
\r
186 * struct NyLPC_TEthernetIIHeader
\r
188 **********************************************************************/
\r
190 #define NyLPC_TEthernetIIHeader_TYPE_IP 0x0800
\r
191 #define NyLPC_TEthernetIIHeader_TYPE_ARP 0x0806
\r
192 #define NyLPC_TEthernetIIHeader_TYPE_IPV6 0x86DD
\r
193 //#define UIP_ETHTYPE_IP 0x0800
\r
194 //#define UIP_ETHTYPE_ARP 0x0806
\r
195 //#define UIP_ETHTYPE_IP6 0x86dd
\r
197 struct NyLPC_TEthernetIIHeader
\r
199 struct NyLPC_TEthAddr dest;
\r
200 struct NyLPC_TEthAddr src;
\r
201 NyLPC_TUInt16 type;
\r
205 NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setArpTx(
\r
206 struct NyLPC_TEthernetIIHeader* i_struct,
\r
207 const struct NyLPC_TEthAddr* i_my_eth_addr);
\r
209 NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setIPv4Tx(
\r
210 struct NyLPC_TEthernetIIHeader* i_eth,
\r
211 const struct NyLPC_TEthAddr* i_src_eth_addr,
\r
212 const struct NyLPC_TEthAddr* i_dest_eth_addr);
\r
213 /**********************************************************************
\r
215 * struct NyLPC_TIPv4Header
\r
217 **********************************************************************/
\r
221 * IPパケットヘッダのメモリマップ構造体
\r
224 struct NyLPC_TIPv4Header
\r
228 NyLPC_TUInt16 len16;
\r
229 NyLPC_TUInt16 ipid16;
\r
230 NyLPC_TUInt16 ipoffset;
\r
232 NyLPC_TUInt8 proto;
\r
233 NyLPC_TUInt16 ipchksum;
\r
234 struct NyLPC_TIPv4Addr srcipaddr;
\r
235 struct NyLPC_TIPv4Addr destipaddr;
\r
241 NyLPC_TBool NyLPC_TIPv4Header_isCorrectIpCheckSum(
\r
242 const struct NyLPC_TIPv4Header* ip_header);
\r
244 NyLPC_TBool NyLPC_cIPv4Packet_isCorrectTcpCheckSum(
\r
245 const struct NyLPC_TIPv4Header* ip_header);
\r
247 NyLPC_TUInt16 NyLPC_TIPv4Header_makeIpChecksum(const struct NyLPC_TIPv4Header* ip_header);
\r
250 NyLPC_TUInt16 NyLPC_TIPv4Header_makeTcpChecksum(
\r
251 const struct NyLPC_TIPv4Header* i_iph);
\r
253 #define NyLPC_TIPv4Header_isDestAddrEqual(i_struct,i_addr) ((i_struct)->destipaddr==(i_addr))
\r
254 #define NyLPC_TIPv4Header_isSrcAddrEqual(i_struct,i_addr) ((i_struct)->srcipaddr==(i_addr))
\r
259 #define NyLPC_TIPv4Header_getHeaderLength(i_iph) (((i_iph)->vhl & 0x0f)*4)
\r
263 #define NyLPC_TIPv4Header_getPacketLength(i_iph) (NyLPC_ntohs((i_iph)->len16))
\r
266 * IPヘッダを送信パケット用に設定する。
\r
267 * ipid16にはコールされるたびに新しい値を設定する。
\r
268 * ipcecksumには0を設定する。
\r
269 * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。
\r
271 void NyLPC_TIPv4Header_writeTxIpHeader(
\r
272 struct NyLPC_TIPv4Header* i_struct,
\r
273 NyLPC_TUInt8 i_proto);
\r
274 /**********************************************************************
\r
276 * struct NyLPC_TIPv6Header
\r
278 **********************************************************************/
\r
281 struct NyLPC_TIPv6Header
\r
285 NyLPC_TUInt8 tcflow;
\r
286 NyLPC_TUInt16 flow;
\r
287 NyLPC_TUInt8 len16;
\r
288 NyLPC_TUInt8 proto, ttl;
\r
289 uip_ip6addr_t srcipaddr;
\r
290 uip_ip6addr_t destipaddr;
\r
293 void NyLPC_TIPv6Header_setSendHeader(
\r
294 struct NyLPC_TIPv6Header* i_iph,
\r
295 uip_ip6addr_t i_src,
\r
296 uip_ip6addr_t i_dest,
\r
297 NyLPC_TUInt8 i_proto,
\r
298 NyLPC_TUInt8 i_ttl,
\r
299 NyLPC_TUInt16 i_len);
\r
301 NyLPC_TUInt16 NyLPC_TIPv6Header_makeTcpChecksum(
\r
302 struct NyLPC_TIPv6Header* i_iph,
\r
303 NyLPC_TUInt16 i_len);
\r
305 #define NyLPC_TIPv6Header_isDestAddrEqual(i_struct,i_addr) (memcmp((i_struct)->destipaddr,(i_addr),sizeof(uip_ip6addr_t)))
\r
306 #define NyLPC_TIPv6Header_isSrcAddrEqual(i_struct,i_addr) (memcmp(i_struct)->srcipaddr,(i_addr),sizeof(uip_ip6addr_t)))
\r
307 /**********************************************************************
\r
309 * struct NyLPC_TTcpHeader
\r
311 **********************************************************************/
\r
312 #define TCP_OPT_END 0 /* End of TCP options list */
\r
313 #define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
\r
314 #define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
\r
315 #define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
\r
318 * TCP/IPヘッダのメモリマップ構造体
\r
319 * マルチバイトの値は、全てネットワークオーダーです。
321 struct NyLPC_TTcpHeader
\r
324 NyLPC_TUInt16 srcport;
\r
325 NyLPC_TUInt16 destport;
\r
326 NyLPC_TUInt32 seqno32;
\r
327 NyLPC_TUInt32 ackno32;
\r
328 NyLPC_TUInt8 tcpoffset;
\r
329 NyLPC_TUInt8 flags;
\r
330 NyLPC_TUInt16 wnd16;
\r
331 NyLPC_TUInt16 tcpchksum;
\r
332 NyLPC_TUInt8 urgp[2];
\r
333 // NyLPC_TUInt8 optdata[4];
\r
337 NyLPC_TUInt8* NyLPC_TTcpHeader_getTcpOptFragmentPtr(
\r
338 const struct NyLPC_TTcpHeader* i_struct,
\r
339 NyLPC_TUInt8 i_opt_id);
\r
341 NyLPC_TBool NyLPC_TTcpHeader_getTcpMmsOpt(
\r
342 const struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt16* o_val);
\r
345 * この関数は、TCPヘッダの長さを返します。ヘッダの長さは、i_structのフィールドから計算します。
\r
349 NyLPC_TUInt16 NyLPC_TTcpHeader_getHeaderLength(const struct NyLPC_TTcpHeader* i_struct);
\r
352 * この関数は、指定したアドレスに、mmsオプション値を書き込みます。
354 void NyLPC_TTcpHeader_setMmsOpt(NyLPC_TUInt8* i_opt_addr,NyLPC_TUInt16 i_mms);
\r
357 /**********************************************************************
\r
359 * struct NyLPC_TUdpHeader
\r
361 **********************************************************************/
\r
364 * UDP/IPヘッダのメモリマップ構造体
\r
366 struct NyLPC_TUdpHeader
\r
368 NyLPC_TUInt16 srcport;
\r
369 NyLPC_TUInt16 destport;
\r
370 NyLPC_TUInt16 udplen;
\r
371 NyLPC_TUInt16 udpchksum;
\r
377 #define NyLPC_TUdpHeader_getHeaderLength(i_struct) (8)
\r
379 /**********************************************************************
\r
381 * struct NyLPC_TIcmpipHeader
\r
383 **********************************************************************/
\r
386 struct NyLPC_TIcmpHeader
\r
388 /* ICMP (echo) header. */
\r
389 NyLPC_TUInt8 type, icode;
\r
390 NyLPC_TUInt16 icmpchksum;
\r
392 NyLPC_TUInt16 id, seqno;
\r
393 #else /* !UIP_CONF_IPV6 */
\r
394 NyLPC_TUInt8 flags, reserved1, reserved2, reserved3;
\r
395 NyLPC_TUInt8 icmp6data[16];
\r
396 NyLPC_TUInt8 options[1];
\r
397 #endif /* !UIP_CONF_IPV6 */
\r
400 /**********************************************************************
\r
402 * struct NyLPC_TIcmpipHeader
\r
404 **********************************************************************/
\r
406 struct NyLPC_TArpHeader
\r
408 NyLPC_TUInt16 hwtype;
\r
409 NyLPC_TUInt16 protocol;
\r
410 NyLPC_TUInt8 hwlen;
\r
411 NyLPC_TUInt8 protolen;
\r
412 NyLPC_TUInt16 opcode;
\r
413 struct NyLPC_TEthAddr shwaddr;
\r
414 struct NyLPC_TIPv4Addr sipaddr;
\r
415 struct NyLPC_TEthAddr dhwaddr;
\r
416 struct NyLPC_TIPv4Addr dipaddr;
\r
421 * i_req_addrを問い合わせるARP_REQUESTを生成します。
\r
423 void NyLPC_TArpHeader_setArpRequest(
\r
424 struct NyLPC_TArpHeader* i_struct,
\r
425 const struct NyLPC_TIPv4Addr i_saddr,
\r
426 const struct NyLPC_TEthAddr* i_srceth,
\r
427 const struct NyLPC_TIPv4Addr* i_req_addr);
\r
430 typedef struct NyLPC_TcEthernetIIPayload NyLPC_TcEthernetIIPayload_t;
\r
435 /**********************************************************************
\r
437 * NyLPC_TIPv6Payload
\r
439 **********************************************************************/
\r
442 struct NyLPC_TIPv6Payload
\r
444 struct NyLPC_TIPv6Header* header;
\r
453 struct NyLPC_TcEthernetIIPayload
\r
455 struct NyLPC_TEthernetIIHeader* header;
\r
458 struct NyLPC_TArpHeader* arp;
\r
459 struct NyLPC_TIPv4Payload* ipv4;
\r
460 struct NyLPC_TIPv6Payload* ipv6;
\r
471 #endif /* __cplusplus */
\r