This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NyLPC_cIPv4.c Source File

NyLPC_cIPv4.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_cIPv4.h"
00056 #include "NyLPC_stdlib.h"
00057 #include "NyLPC_os.h"
00058 #include "NyLPC_cIPv4Payload_protected.h"
00059 #include "NyLPC_cMiMicIpTcpSocket_protected.h"
00060 #include "NyLPC_cMiMicIpTcpListener_protected.h"
00061 #include "NyLPC_cMiMicIpUdpSocket_protected.h"
00062 #include "NyLPC_cIPv4IComp_protected.h"
00063 #include "NyLPC_cMiMicIpNetIf_protected.h"
00064 
00065 
00066 
00067 
00068 
00069 /****************************************************
00070  * NyLPC_cIPv4
00071  ***************************************************/
00072 
00073 /**
00074  * Static関数
00075  */
00076 
00077 static void* tcp_rx(
00078     NyLPC_TcIPv4_t* i_inst,
00079     const NyLPC_TcIPv4Payload_t* i_ipp);
00080 
00081 static NyLPC_TBool udp_rx(
00082     NyLPC_TcIPv4_t* i_inst,
00083     NyLPC_TcIPv4Payload_t* i_ipp);
00084 
00085 /**
00086  * See Header file.
00087  */
00088 void NyLPC_cIPv4_initialize(
00089     NyLPC_TcIPv4_t* i_inst)
00090 {
00091     //IP制御パケットの為に40バイト以上のシステムTXメモリが必要。
00092     NyLPC_ArgAssert(NyLPC_cMiMicIpNetIf_SYS_TX_BUF_SIZE>40);
00093     //instanceの初期化
00094     NyLPC_cMutex_initialize(&(i_inst->_sock_mutex));
00095     NyLPC_cMutex_initialize(&(i_inst->_listener_mutex));
00096     i_inst->tcp_port_counter=0;
00097     i_inst->_ref_config=NULL;
00098     return;
00099 }
00100 
00101 /**
00102  * See header file.
00103  */
00104 void NyLPC_cIPv4_finalize(
00105     NyLPC_TcIPv4_t* i_inst)
00106 {
00107     NyLPC_cMutex_finalize(&(i_inst->_sock_mutex));
00108     NyLPC_cMutex_finalize(&(i_inst->_listener_mutex));
00109     return;
00110 }
00111 
00112 /**
00113  * See header file.
00114  */
00115 void NyLPC_cIPv4_start(
00116     NyLPC_TcIPv4_t* i_inst,
00117     const NyLPC_TcIPv4Config_t* i_ref_configlation)
00118 {
00119     NyLPC_ArgAssert(i_ref_configlation!=NULL);
00120     //リストの初期化、ここでするべき?しないべき?
00121     i_inst->_ref_config=i_ref_configlation;
00122     //configulationのアップデートを登録されてるソケットに通知
00123     NyLPC_cMiMicIpNetIf_callSocketStart(i_ref_configlation);
00124     return;
00125 }
00126 
00127 /**
00128  * See header file.
00129  */
00130 void NyLPC_cIPv4_stop(
00131     NyLPC_TcIPv4_t* i_inst)
00132 {
00133     NyLPC_cMiMicIpNetIf_callSocketStop();
00134     i_inst->_ref_config=NULL;
00135     return;
00136 }
00137 
00138 
00139 
00140 #define IS_START(i_inst) ((i_inst)->_ref_config!=NULL)
00141 
00142 /**
00143  * 稼動時に、1s置きに呼び出す関数です。
00144  */
00145 void NyLPC_cIPv4_periodec(NyLPC_TcIPv4_t* i_inst)
00146 {
00147     NyLPC_cMiMicIpNetIf_callPeriodic();
00148 }
00149 
00150 
00151 /**
00152  * IPv4ペイロードを処理する関数。
00153  * この関数は、パケット受信タスクから実行します。
00154  * @param i_rx
00155  * 先頭ポインタ。
00156  * @return
00157  * TRUEなら、i_rxに応答パケットをセットして返します。
00158  */
00159 void* NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,const void* i_rx,NyLPC_TUInt16 i_rx_size)
00160 {
00161     NyLPC_TcMiMicIpNetIf_t* inst=_NyLPC_TcMiMicIpNetIf_inst;
00162     NyLPC_TcIPv4Payload_t ipv4;
00163     //NOT開始状態なら受け付けないよ。
00164     if(!IS_START(i_inst)){
00165         NyLPC_OnErrorGoto(ERROR_DROP);
00166     }
00167 
00168     NyLPC_cIPv4Payload_initialize(&ipv4);
00169     //IPフラグメントを読出し用にセットする。
00170     if(!NyLPC_cIPv4Payload_attachRxBuf(&ipv4,i_rx,i_rx_size))
00171     {
00172         NyLPC_OnErrorGoto(ERROR_DROP);
00173     }
00174     switch(ipv4.header->proto)
00175     {
00176     case UIP_PROTO_TCP:
00177         //TCP受信処理
00178         return tcp_rx(i_inst,&ipv4);
00179     case UIP_PROTO_UDP:
00180         //UDP処理
00181         udp_rx(i_inst,&ipv4);//r
00182         return NyLPC_TBool_FALSE;
00183     case UIP_PROTO_ICMP:
00184         return NyLPC_cIPv4IComp_rx(&(inst->_icomp),&ipv4);
00185     }
00186     return NULL;
00187 ERROR_DROP:
00188     return NULL;
00189 }
00190 
00191 NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst)
00192 {
00193     NyLPC_TUInt16 i,n;
00194     for(i=0;i<0x0fff;i--){
00195         i_inst->tcp_port_counter=(i_inst->tcp_port_counter+1)%0x0fff;
00196         n=i_inst->tcp_port_counter+49152;
00197         if(NyLPC_cMiMicIpNetIf_isClosedTcpPort(n))
00198         {
00199             return n;
00200         }
00201     }
00202     return 0;
00203 }
00204 
00205 
00206 /**********************************************************************
00207  *
00208  * packet handler
00209  *
00210  **********************************************************************/
00211 
00212 
00213 static void* tcp_rx(
00214     NyLPC_TcIPv4_t* i_inst,
00215     const NyLPC_TcIPv4Payload_t* i_ipp)
00216 {
00217     NyLPC_TcMiMicIpTcpSocket_t* sock;
00218     NyLPC_TcMiMicIpTcpListener_t* listener;
00219 
00220     //自分自身のIPに対する呼び出し?
00221     if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr)))
00222     {
00223         //自分以外のパケットはドロップ
00224         goto DROP;
00225     }
00226     //チェックサムの計算
00227     if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff))
00228     {
00229         //受信エラーのあるパケットはドロップ
00230         goto DROP;
00231     }
00232     //アクティブなTCPソケットを探す。
00233     sock=NyLPC_cMiMicIpNetIf_getMatchTcpSocket(i_ipp->payload.tcp->destport,i_ipp->header->srcipaddr,i_ipp->payload.tcp->srcport);
00234     if(sock!=NULL)
00235     {
00236         //既存の接続を処理
00237         return NyLPC_cMiMicIpTcpSocket_parseRx(sock,i_ipp);
00238     }
00239 
00240     //このポートに対応したListenerを得る。
00241     listener=NyLPC_cMiMicIpNetIf_getListenerByPeerPort(i_ipp->payload.tcp->destport);
00242     if(listener==NULL){
00243         //Listen対象ではない。RST送信
00244         return NyLPC_cMiMicIpTcpSocket_allocTcpReverseRstAck(i_ipp);
00245     }
00246     //リスナにソケットのバインドを依頼する。
00247     NyLPC_cMiMicIpTcpListener_synPacket(listener,i_ipp);
00248     return NULL;//LISTEN成功。送信データなし
00249 DROP:
00250     return NULL;
00251 }
00252 
00253 
00254 
00255 static NyLPC_TBool udp_rx(
00256     NyLPC_TcIPv4_t* i_inst,
00257     NyLPC_TcIPv4Payload_t* i_ipp)
00258 {
00259     NyLPC_TcMiMicIpUdpSocket_t* sock=NULL;
00260     if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr)))
00261     {
00262         sock=NyLPC_cMiMicIpNetIf_getMatchUdpSocket(i_ipp->payload.udp->destport);
00263     }else{
00264         if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){
00265         //MultiCast?
00266             //マルチキャストに参加している&&portの一致するソケットを検索
00267             sock=NyLPC_cMiMicIpNetIf_getMatchMulticastUdpSocket(&(i_ipp->header->destipaddr),i_ipp->payload.udp->destport);
00268         }else if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_BROADCAST)){
00269         //Broadcast?
00270             sock=NyLPC_cMiMicIpNetIf_getMatchUdpSocket(i_ipp->payload.udp->destport);
00271         }
00272     }
00273     if(sock==NULL)
00274     {
00275         goto DROP;
00276     }
00277     //パケットのエラーチェック
00278     if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff))
00279     {
00280         //受信エラーのあるパケットはドロップ
00281         goto DROP;
00282     }
00283     //既存の接続を処理
00284     return NyLPC_cMiMicIpUdpSocket_parseRx(sock,i_ipp);
00285 DROP:
00286     return NyLPC_TBool_FALSE;
00287 }
00288 
00289