This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
NyLPC_NetIf_ip_types.c
00001 /********************************************************************************* 00002 * PROJECT: MiMic 00003 * -------------------------------------------------------------------------------- 00004 * 00005 * This file is part of MiMic 00006 * Copyright (C)2011 Ryo Iizuka 00007 * 00008 * MiMic is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published 00010 * by the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00020 * 00021 * For further information please contact. 00022 * http://nyatla.jp/ 00023 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> 00024 * 00025 * 00026 * Parts of this file were leveraged from uIP: 00027 * 00028 * Copyright (c) 2001-2003, Adam Dunkels. 00029 * All rights reserved. 00030 * 00031 * Redistribution and use in source and binary forms, with or without 00032 * modification, are permitted provided that the following conditions 00033 * are met: 00034 * 1. Redistributions of source code must retain the above copyright 00035 * notice, this list of conditions and the following disclaimer. 00036 * 2. Redistributions in binary form must reproduce the above copyright 00037 * notice, this list of conditions and the following disclaimer in the 00038 * documentation and/or other materials provided with the distribution. 00039 * 3. The name of the author may not be used to endorse or promote 00040 * products derived from this software without specific prior 00041 * written permission. 00042 * 00043 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00044 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00045 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00046 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00047 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00048 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00049 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00050 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00051 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00052 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00053 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00054 */ 00055 #include "NyLPC_NetIf_ip_types.h" 00056 00057 00058 00059 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO={0x00000000}; 00060 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL ={0xffffffff}; 00061 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST = { 0xffffffff }; 00062 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST = NyLPC_TIPv4Addr_pack(224,0,0,0); 00063 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK = NyLPC_TIPv4Addr_pack(224,0,0,0); 00064 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_APIPA_MASK = NyLPC_TIPv4Addr_pack(255,255,0,0); 00065 00066 NyLPC_TInt16 NyLPC_TIPv4Addr_toString(const struct NyLPC_TIPv4Addr* i_ip,NyLPC_TChar* i_buf) 00067 { 00068 NyLPC_TUInt32 ip; 00069 NyLPC_TChar* p=i_buf; 00070 NyLPC_TUInt8 v; 00071 NyLPC_TInt8 l; 00072 //IPをホストオーダーにする。 00073 ip=NyLPC_NTOHL(i_ip->v); 00074 for(l=3;l>=0;l--){ 00075 v=(ip>>(8*l))&0xff; 00076 if(v>=100){ 00077 *p=(v/100)+'0'; 00078 p++; 00079 } 00080 if(v>=10){ 00081 *p=((v%100)/10)+'0'; 00082 p++; 00083 } 00084 *p=(v%10)+'0'; 00085 *(p+1)='.'; 00086 p+=2; 00087 } 00088 *(p-1)='\0'; 00089 return p-i_buf-1; 00090 } 00091 00092 00093 NyLPC_TUInt16 NyLPC_uip_chksum(NyLPC_TUInt16 sum, const NyLPC_TUInt8 *data, NyLPC_TUInt16 len) 00094 { 00095 NyLPC_TUInt16 t; 00096 const NyLPC_TUInt8 *dataptr; 00097 const NyLPC_TUInt8 *last_byte; 00098 00099 dataptr = data; 00100 last_byte = data + len - 1; 00101 00102 while (dataptr < last_byte) { /* At least two more bytes */ 00103 t = (dataptr[0] << 8) + dataptr[1]; 00104 sum += t; 00105 if (sum < t) { 00106 sum++; /* carry */ 00107 } 00108 dataptr += 2; 00109 } 00110 00111 if (dataptr == last_byte) { 00112 t = (dataptr[0] << 8) + 0; 00113 sum += t; 00114 if (sum < t) { 00115 sum++; /* carry */ 00116 } 00117 } 00118 00119 /* Return sum in host byte order. */ 00120 return sum; 00121 } 00122 00123 /*-------------------------------------------------------------------------------- 00124 * 00125 * struct NyLPC_TEthernetIIHeader 00126 * 00127 *------------------------------------------------------------------------------*/ 00128 00129 /** 00130 * Ethernetヘッダの内容を、ARPパケットの内容に一致するように書き換えます。 00131 * i_structの後方にあるものと仮定します。 00132 * 戻り値は、フレームの長さです。 00133 */ 00134 NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setArpTx( 00135 struct NyLPC_TEthernetIIHeader* i_struct, 00136 const struct NyLPC_TEthAddr* i_my_eth_addr) 00137 { 00138 struct NyLPC_TArpHeader* arph=(struct NyLPC_TArpHeader*)(((NyLPC_TUInt8*)i_struct)+sizeof(struct NyLPC_TEthernetIIHeader)); 00139 00140 i_struct->type = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP); 00141 switch(arph->opcode){ 00142 case NyLPC_HTONS(ARP_REPLY): 00143 memcpy(i_struct->src.addr, i_my_eth_addr->addr, 6); 00144 memcpy(i_struct->dest.addr, arph->dhwaddr.addr, 6); 00145 break; 00146 case NyLPC_HTONS(ARP_REQUEST): 00147 memset(i_struct->dest.addr, 0xff, 6); 00148 memcpy(i_struct->src.addr, i_my_eth_addr->addr, 6); 00149 break; 00150 } 00151 return sizeof(struct NyLPC_TEthernetIIHeader)+sizeof(struct NyLPC_TArpHeader); 00152 } 00153 00154 /** 00155 * イーサネットヘッダをIPv4向けにセットアップする。 00156 * 関数は、ペイロードをIPv4ヘッダとして、フレームサイズを計算する。 00157 */ 00158 NyLPC_TUInt16 NyLPC_TEthernetIIHeader_setIPv4Tx( 00159 struct NyLPC_TEthernetIIHeader* i_eth, 00160 const struct NyLPC_TEthAddr* i_src_eth_addr, 00161 const struct NyLPC_TEthAddr* i_dest_eth_addr) 00162 { 00163 struct NyLPC_TIPv4Header* iph=(struct NyLPC_TIPv4Header*)(((NyLPC_TUInt8*)i_eth)+sizeof(struct NyLPC_TEthernetIIHeader)); 00164 00165 i_eth->type = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP); 00166 /* Build an ethernet header. */ 00167 memcpy(i_eth->dest.addr,i_dest_eth_addr, 6); 00168 memcpy(i_eth->src.addr, i_src_eth_addr->addr, 6); 00169 00170 00171 //IPフラグメントに応じたサイズ計算 00172 switch(iph->proto){ 00173 case UIP_PROTO_TCP: 00174 return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); 00175 case UIP_PROTO_UDP: 00176 return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); 00177 case UIP_PROTO_ICMP: 00178 return sizeof(struct NyLPC_TEthernetIIHeader)+NyLPC_htons(iph->len16); 00179 } 00180 return 0; 00181 } 00182 /*-------------------------------------------------------------------------------- 00183 * 00184 * struct NyLPC_TIPv4Header 00185 * 00186 *------------------------------------------------------------------------------*/ 00187 00188 /** 00189 * based on uip_ipchksum 00190 */ 00191 NyLPC_TUInt16 NyLPC_TIPv4Header_makeIpChecksum(const struct NyLPC_TIPv4Header* ip_header) 00192 { 00193 NyLPC_TUInt16 sum; 00194 sum = NyLPC_uip_chksum(0, (const NyLPC_TUInt8 *)ip_header,NyLPC_TIPv4Header_getHeaderLength(ip_header)); 00195 return (sum == 0) ? 0xffff : NyLPC_htons(sum); 00196 } 00197 00198 00199 00200 NyLPC_TBool NyLPC_TIPv4Header_isCorrectIpCheckSum(const struct NyLPC_TIPv4Header* ip_header) 00201 { 00202 return (NyLPC_TIPv4Header_makeIpChecksum(ip_header)==0xffff); 00203 } 00204 00205 NyLPC_TBool NyLPC_cIPv4Packet_isCorrectTcpCheckSum(const struct NyLPC_TIPv4Header* ip_header) 00206 { 00207 return (NyLPC_TIPv4Header_makeTcpChecksum(ip_header) == 0xffff); 00208 } 00209 00210 00211 00212 00213 /** 00214 * TCPチェックサムを計算します。 00215 * ペイロードはIPヘッダの後方に連続して存在する物と仮定します。 00216 * i_lenは、ペイロード長さ 00217 */ 00218 NyLPC_TUInt16 NyLPC_TIPv4Header_makeTcpChecksum( 00219 const struct NyLPC_TIPv4Header* i_iph) 00220 { 00221 NyLPC_TUInt16 sum; 00222 NyLPC_TUInt16 iph_len=NyLPC_TIPv4Header_getHeaderLength(i_iph); 00223 NyLPC_TUInt16 len = NyLPC_ntohs((i_iph)->len16)- iph_len; 00224 NyLPC_ArgAssert(i_iph!=NULL); 00225 /*TCP疑似ヘッダ部分*/ 00226 /* IP protocol and length fields. This addition cannot carry. */ 00227 sum = len + i_iph->proto; 00228 /* Sum IP source and destination addresses. */ 00229 sum = NyLPC_uip_chksum(sum, (NyLPC_TUInt8 *) &(i_iph->srcipaddr), 2 * sizeof(struct NyLPC_TIPv4Addr)); 00230 /* Sum TCP header and data. */ 00231 sum = NyLPC_uip_chksum(sum, (((NyLPC_TUInt8 *)(i_iph))+iph_len),len); 00232 // sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], i_len_of_data); 00233 return (sum == 0) ? 0xffff : NyLPC_htons(sum); 00234 } 00235 00236 static NyLPC_TUInt16 pid=0x3939; 00237 /** 00238 * IPヘッダを送信パケット用に設定する。 00239 * ipid16にはコールされるたびに新しい値を設定する。 00240 * ipcecksumには0を設定する。 00241 * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。 00242 */ 00243 void NyLPC_TIPv4Header_writeTxIpHeader( 00244 struct NyLPC_TIPv4Header* i_struct, 00245 NyLPC_TUInt8 i_proto) 00246 { 00247 //IPパケットのセット 00248 i_struct->proto=i_proto; 00249 i_struct->ttl = UIP_DEFAULT_IP_TTL; 00250 i_struct->tos = 0; 00251 i_struct->ipid16=(pid++); 00252 i_struct->ipoffset=0;//NyLPC_HTONS(0|0x4000); 00253 i_struct->ipchksum = 0; 00254 } 00255 /*-------------------------------------------------------------------------------- 00256 * 00257 * struct NyLPC_TIPv6Header 00258 * 00259 *------------------------------------------------------------------------------*/ 00260 #define IPV6_HEADER_SIZE 40 00261 /** 00262 * IPヘッダーを作って埋める関数 00263 */ 00264 void NyLPC_TIPv6Header_setSendHeader( 00265 struct NyLPC_TIPv6Header* i_iph, 00266 uip_ip6addr_t i_src, 00267 uip_ip6addr_t i_dest, 00268 NyLPC_TUInt8 i_proto, 00269 NyLPC_TUInt8 i_ttl, 00270 NyLPC_TUInt16 i_len) 00271 { 00272 i_iph->srcipaddr=i_src; 00273 i_iph->destipaddr=i_dest; 00274 i_iph->proto=i_proto; 00275 i_iph->ttl = i_ttl; 00276 i_iph->vtc = 0x60; 00277 i_iph->tcflow = 0x00; 00278 i_iph->flow = 0x00; 00279 i_iph->len16= NyLPC_htons(i_len - IPV6_HEADER_SIZE); 00280 return; 00281 } 00282 00283 00284 /** 00285 * チェックサムは、TCP疑似ヘッダから計算。 00286 * i_tcpiphの送信/受信アドレス、ProtocolID,DATAフィールドは有効であること。 00287 */ 00288 NyLPC_TUInt16 NyLPC_TIPv6Header_makeTcpChecksum( 00289 struct NyLPC_TIPv6Header* i_iph, 00290 NyLPC_TUInt16 i_len) 00291 { 00292 NyLPC_TUInt16 sum; 00293 NyLPC_TUInt16 len; 00294 len = i_len; 00295 /*TCP疑似ヘッダ部分*/ 00296 /* IP protocol and length fields. This addition cannot carry. */ 00297 sum = len + i_iph->proto; 00298 /* Sum IP source and destination addresses. */ 00299 sum = NyLPC_uip_chksum(sum, (NyLPC_TUInt8 *) &(i_iph->srcipaddr), 2 * sizeof(uip_ip6addr_t)); 00300 /* Sum TCP header and data. */ 00301 sum = NyLPC_uip_chksum(sum, (((NyLPC_TUInt8 *)(i_iph))+IPV6_HEADER_SIZE),len); 00302 // sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], i_len_of_data); 00303 return (sum == 0) ? 0xffff : NyLPC_htons(sum); 00304 } 00305 00306 00307 00308 /*-------------------------------------------------------------------------------- 00309 * 00310 * struct NyLPC_TTcpHeader 00311 * 00312 *------------------------------------------------------------------------------*/ 00313 00314 00315 /** 00316 * MMSオプションの値を返す。 00317 */ 00318 NyLPC_TBool NyLPC_TTcpHeader_getTcpMmsOpt( 00319 const struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt16* o_val) 00320 { 00321 NyLPC_TUInt8* opt; 00322 opt=NyLPC_TTcpHeader_getTcpOptFragmentPtr(i_struct,TCP_OPT_MSS); 00323 if(opt!=NULL){ 00324 if (*(opt+1) == TCP_OPT_MSS_LEN) 00325 { 00326 // An MSS option with the right option length. 00327 *o_val = ((NyLPC_TUInt16) (*(opt+2)) << 8) | (NyLPC_TUInt16) (*(opt + 3)); 00328 //And we are done processing options. 00329 return NyLPC_TBool_TRUE; 00330 } 00331 } 00332 return NyLPC_TBool_FALSE; 00333 } 00334 00335 #define DEFAULT_TCP_HEADER_LEN 20 00336 /** 00337 * TCPフラグメントのポインタを返す。 00338 */ 00339 NyLPC_TUInt8* NyLPC_TTcpHeader_getTcpOptFragmentPtr( 00340 const struct NyLPC_TTcpHeader* i_struct, 00341 NyLPC_TUInt8 i_opt_id) 00342 { 00343 NyLPC_TUInt8 opt; 00344 int c; 00345 NyLPC_TUInt8* opt_buf=((NyLPC_TUInt8*)(i_struct+1)); 00346 00347 /* Parse the TCP MSS option, if present. */ 00348 if ((i_struct->tcpoffset & 0xf0) > 0x50){ 00349 for (c = 0; c < ((i_struct->tcpoffset >> 4) - 5) << 2;) 00350 { 00351 opt=opt_buf[c]; 00352 if(opt==i_opt_id){ 00353 return opt_buf+c;//found! 00354 } 00355 switch(opt) 00356 { 00357 case TCP_OPT_NOOP: 00358 continue;//NOP option. 00359 case TCP_OPT_END: 00360 return NULL;//End of options. 00361 default: 00362 // All other options have a length field, so that we easily can skip past them. 00363 if (opt_buf[1 + c] == 0) { 00364 // If the length field is zero, the options are malformed and we don't process them further. 00365 NyLPC_OnErrorGoto(ERROR_INVALID_OPTION); 00366 } 00367 c += opt_buf[1 + c]; 00368 } 00369 } 00370 } 00371 ERROR_INVALID_OPTION: 00372 return NULL; 00373 } 00374 /* 00375 * Optionパラメタを書きだす。 00376 */ 00377 void NyLPC_TTcpHeader_setMmsOpt(NyLPC_TUInt8* i_opt_addr,NyLPC_TUInt16 i_mms) 00378 { 00379 i_opt_addr[0] = TCP_OPT_MSS; 00380 i_opt_addr[1] = TCP_OPT_MSS_LEN; 00381 i_opt_addr[2] = (i_mms) / 256; 00382 i_opt_addr[3] = (i_mms) & 255; 00383 return; 00384 } 00385 00386 00387 NyLPC_TUInt16 NyLPC_TTcpHeader_getHeaderLength(const struct NyLPC_TTcpHeader* ip_header) 00388 { 00389 return (ip_header->tcpoffset>>4)*4; 00390 } 00391 /*-------------------------------------------------------------------------------- 00392 * 00393 * struct NyLPC_TUdpHeader 00394 * 00395 *------------------------------------------------------------------------------*/ 00396 00397 00398 00399 /*-------------------------------------------------------------------------------- 00400 * 00401 * struct NyLPC_TArpHeader 00402 * 00403 *------------------------------------------------------------------------------*/ 00404 /** 00405 * i_req_addrを問い合わせるARP_REQUESTを生成します。 00406 */ 00407 void NyLPC_TArpHeader_setArpRequest( 00408 struct NyLPC_TArpHeader* i_struct, 00409 const struct NyLPC_TIPv4Addr i_saddr, 00410 const struct NyLPC_TEthAddr* i_srceth, 00411 const struct NyLPC_TIPv4Addr* i_req_addr) 00412 { 00413 memset(i_struct->dhwaddr.addr, 0x00, 6); 00414 memcpy(i_struct->shwaddr.addr, i_srceth, 6); 00415 i_struct->dipaddr=*i_req_addr; 00416 i_struct->sipaddr=i_saddr; 00417 i_struct->opcode = NyLPC_HTONS(ARP_REQUEST); /* ARP request. */ 00418 i_struct->hwtype = NyLPC_HTONS(ARP_HWTYPE_ETH); 00419 i_struct->protocol = NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IP); 00420 i_struct->hwlen = 6; 00421 i_struct->protolen = 4; 00422 return; 00423 } 00424 00425 /*-------------------------------------------------------------------------------- 00426 * 00427 * class IPv4Route 00428 * 00429 *------------------------------------------------------------------------------*/ 00430 00431 00432
Generated on Tue Jul 12 2022 15:46:17 by 1.7.2