OSDN Git Service

update
authornyatla <nyatla@47198e57-cb75-475f-84c4-a814cd6f29e0>
Thu, 23 May 2013 13:20:15 +0000 (13:20 +0000)
committernyatla <nyatla@47198e57-cb75-475f-84c4-a814cd6f29e0>
Thu, 23 May 2013 13:20:15 +0000 (13:20 +0000)
UDPのマルチキャストを追加

git-svn-id: http://svn.osdn.jp/svnroot/mimic/trunk@245 47198e57-cb75-475f-84c4-a814cd6f29e0

lib/src/uip/NyLPC_cIPv4.c
lib/src/uip/NyLPC_cIPv4Arp.c
lib/src/uip/NyLPC_cIPv4Payload_protected.h
lib/src/uip/NyLPC_cUdpSocket.c
lib/src/uip/NyLPC_cUdpSocket.h
lib/src/uip/NyLPC_cUipService.c
lib/src/uip/NyLPC_uip.c
lib/src/uip/NyLPC_uip.h

index 005c55c..b111507 100644 (file)
@@ -53,6 +53,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
  */\r
 #include "NyLPC_stdlib.h"\r
+#include "NyLPC_uip.h"\r
 #include "NyLPC_cIPv4.h"\r
 #include "NyLPC_cIPv4Payload_protected.h"\r
 #include "NyLPC_cTcpSocket_protected.h"\r
@@ -124,7 +125,29 @@ static NyLPC_TcUdpSocket_t* cSocketTbl_getMatchUdpSocket(
                return tp;\r
        }\r
        return NULL;\r
-\r
+}\r
+static NyLPC_TcUdpSocket_t* cSocketTbl_getMatchMulticastUdpSocket(\r
+       NyLPC_TcPtrTbl_t* i_inst,\r
+       struct NyLPC_TIPv4Addr* i_mcast_ip,\r
+       NyLPC_TUInt16 i_lport)\r
+{\r
+       NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf);\r
+       NyLPC_TcUdpSocket_t* tp;\r
+       int i;\r
+       //一致するポートを検索\r
+       for(i=i_inst->size-1;i>=0;i--){\r
+               if(p[i]==NULL || p[i]->_typeid!=NyLPC_TcBaseSocket_TYPEID_UDP_SOCK){\r
+                       continue;\r
+               }\r
+               tp=(NyLPC_TcUdpSocket_t*)p[i];\r
+               //パラメータの一致チェック\r
+               if(i_lport!=tp->uip_udp_conn.lport || NyLPC_TIPv4Addr_isEqual(i_mcast_ip,&(tp->uip_udp_conn.lipaddr)))\r
+               {\r
+                       continue;\r
+               }\r
+               return tp;\r
+       }\r
+       return NULL;\r
 }\r
 \r
 /**\r
@@ -334,7 +357,9 @@ NyLPC_TBool NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,void* i_rx,NyLPC_TUInt16 i_rx_
                //TCP受信処理\r
                return tcp_rx(i_inst,&ipv4);\r
        case UIP_PROTO_UDP:\r
-               return udp_rx(i_inst,&ipv4);\r
+               //UDP処理\r
+               udp_rx(i_inst,&ipv4);//r\r
+               return NyLPC_TBool_FALSE;\r
        case UIP_PROTO_ICMP:\r
                if(!NyLPC_cIPv4IComp_rx(&(inst->_icomp),&ipv4)){\r
                        NyLPC_OnErrorGoto(ERROR_DROP);\r
@@ -414,24 +439,42 @@ static NyLPC_TBool udp_rx(
        NyLPC_TcIPv4Payload_t* i_ipp)\r
 {\r
        NyLPC_TcUdpSocket_t* sock;\r
+       //Multicastか調べる\r
+       if(NyLPC_TIPv4Addr_isEqualWithMask(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){\r
+               //Multicastパケット\r
 \r
-       //自分自身のIPに対する呼び出し?\r
-       if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr)))\r
-       {\r
-               //自分以外のパケットはドロップ\r
-               goto DROP;\r
-       }\r
-       //チェックサムの計算\r
-       if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff))\r
-       {\r
-               //受信エラーのあるパケットはドロップ\r
-               goto DROP;\r
-       }\r
-       //アクティブなUDPソケットを探す。\r
-       sock=cSocketTbl_getMatchUdpSocket(&(i_inst->_socket_tbl),i_ipp->payload.udp->destport);\r
-       if(sock==NULL)\r
-       {\r
-               goto DROP;\r
+               //チェックサムの計算\r
+               if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff))\r
+               {\r
+                       //受信エラーのあるパケットはドロップ\r
+                       goto DROP;\r
+               }\r
+               //マルチキャストに参加している&&portの一致するソケットを検索\r
+               sock=cSocketTbl_getMatchMulticastUdpSocket(&(i_inst->_socket_tbl),&(i_ipp->header->destipaddr),i_ipp->payload.udp->destport);\r
+               if(sock==NULL)\r
+               {\r
+                       goto DROP;\r
+               }\r
+       }else{\r
+               //ユニキャストパケット\r
+               //自分自身のIPに対する呼び出し?\r
+               if(!NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&(i_inst->_ref_config->ip_addr)))\r
+               {\r
+                       //自分以外のパケットはドロップ\r
+                       goto DROP;\r
+               }\r
+               //チェックサムの計算\r
+               if((NyLPC_TIPv4Header_makeTcpChecksum(i_ipp->header) != 0xffff))\r
+               {\r
+                       //受信エラーのあるパケットはドロップ\r
+                       goto DROP;\r
+               }\r
+               //ポートの一致するUDPソケットを探す。\r
+               sock=cSocketTbl_getMatchUdpSocket(&(i_inst->_socket_tbl),i_ipp->payload.udp->destport);\r
+               if(sock==NULL)\r
+               {\r
+                       goto DROP;\r
+               }\r
        }\r
        //既存の接続を処理\r
        return NyLPC_cUdpSocket_parseRx(sock,i_ipp);\r
index 5fef050..f4ea891 100644 (file)
@@ -236,12 +236,8 @@ const struct NyLPC_TEthAddr* NyLPC_cIPv4Arp_IPv4toEthAddr(NyLPC_TcIPv4Arp_t* i_i
        int i;\r
        struct NyLPC_TIPv4Addr ip;\r
        struct NyLPC_TArpTableItem *tabptr;\r
-       //ブロードキャストならそのまま\r
-       if (NyLPC_TIPv4Addr_isEqual(&i_ip_addr,&NyLPC_TIPv4Addr_BROADCAST)) {\r
-               return &NyLPC_TEthAddr_BROADCAST;\r
-       }\r
        //LocalIPでなければ、デフォルトゲートウェイのアドレスに設定。\r
-       if (!NyLPC_cIPv4Config_isLocalIP(i_inst->_cfg, &i_ip_addr)) {\r
+       if (!NyLPC_cIPv4Config_isLocalIP(i_inst->_cfg, &i_ip_addr)){\r
                ip = i_inst->_cfg->dr_addr;\r
        } else {\r
                ip = i_ip_addr;\r
index 17c6cd1..67be974 100644 (file)
@@ -126,6 +126,9 @@ void* NyLPC_cIPv4Payload_initUdpTx(NyLPC_TcIPv4Payload_t* i_inst,NyLPC_TUInt8 i_
  */\r
 void NyLPC_cIPv4Payload_setUdpTxHeaderByConnection(NyLPC_TcIPv4Payload_t* i_inst,const struct uip_udp_conn* i_conn,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port);\r
 \r
+void NyLPC_cIPv4Payload_closeUdpTxPacket(\r
+       NyLPC_TcIPv4Payload_t* i_inst);\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif /* __cplusplus */\r
index 9b61de3..3d138e3 100644 (file)
@@ -69,6 +69,7 @@ NyLPC_TBool NyLPC_cUdpSocket_initialize(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt1
        NyLPC_Assert(NyLPC_TcUipService_isInitService());\r
        i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4));\r
        i_inst->uip_udp_conn.lport=NyLPC_htons(i_port);\r
+       i_inst->uip_udp_conn.mcastaddr=NyLPC_TIPv4Addr_ZERO;\r
 \r
        NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len);\r
        //管理リストへ登録。\r
@@ -88,6 +89,10 @@ void NyLPC_cUdpSocket_finalize(NyLPC_TcUdpSocket_t* i_inst)
        NyLPC_cBaseSocket_finalize(&(i_inst->_super));\r
        return;\r
 }\r
+void NyLPC_cUdpSocket_joinMulticast(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr)\r
+{\r
+       i_inst->uip_udp_conn.mcastaddr=*i_addr;\r
+}\r
 \r
 struct TRxHeader\r
 {\r
@@ -133,7 +138,7 @@ NyLPC_TBool NyLPC_cUdpSocket_parseRx(
        NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),&dheader,sizeof(struct TRxHeader));\r
        NyLPC_cFifoBuffer_push(&(i_inst->rxbuf),data_offset,dheader.size);\r
        unlockResource(i_inst);\r
-       return NyLPC_TBool_TRUE;\r
+       return NyLPC_TBool_FALSE;//UDPはReturnパケットなし\r
 DROP:\r
        unlockResource(i_inst);\r
        return NyLPC_TBool_FALSE;\r
index b9de1c3..5940202 100644 (file)
@@ -24,6 +24,8 @@ typedef struct NyLPC_TcUdpSocket NyLPC_TcUdpSocket_t;
  */\r
 struct uip_udp_conn{\r
        struct NyLPC_TIPv4Addr lipaddr;   /**< The IP address of the remote peer. */\r
+       /** マルチキャスとアドレス(ZEROで無効)*/\r
+       struct NyLPC_TIPv4Addr mcastaddr;\r
        NyLPC_TUInt16 lport;        /**< The local port number in network byte order. */\r
 //     NyLPC_TUInt8  ttl;          /** 今はとりあえずデフォルトのみ*/\r
 };\r
@@ -46,6 +48,11 @@ struct NyLPC_TcUdpSocket
 NyLPC_TBool NyLPC_cUdpSocket_initialize(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_port,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len);\r
 void NyLPC_cUdpSocket_finalize(NyLPC_TcUdpSocket_t* i_inst);\r
 \r
+/**\r
+ * マルチキャストアドレスに参加する。\r
+ */\r
+void NyLPC_cUdpSocket_joinMulticast(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr);\r
+\r
 \r
 /**\r
  * この関数は、ソケットの受信バッファの読み取り位置と、読み出せるデータサイズを返却します。\r
index 5c232f8..bc09fec 100644 (file)
@@ -555,6 +555,20 @@ static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len)
        return;\r
 }\r
 \r
+/**\r
+ * マルチキャスとアドレスへ変換する。\r
+ */\r
+static void ip2MulticastEmacAddr(const struct NyLPC_TIPv4Addr* i_addr,struct NyLPC_TEthAddr* o_emac)\r
+{\r
+       NyLPC_TUInt32 n=NyLPC_htonl(i_addr->v);\r
+       o_emac->addr[0]=0x01;\r
+       o_emac->addr[1]=0x00;\r
+       o_emac->addr[2]=0x5E;\r
+       o_emac->addr[3]=((n>>16) & 0x7f);\r
+       o_emac->addr[4]=((n>> 8) & 0xff);\r
+       o_emac->addr[5]=(n & 0xff);\r
+       return;\r
+};\r
 \r
 /**\r
  * ペイロードをIPパケットとしてネットワークへ送出します。\r
@@ -566,23 +580,29 @@ static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len)
 static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf)\r
 {\r
        NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst;\r
+       struct NyLPC_TEthAddr emac;\r
        NyLPC_TUInt16 tx_len;\r
+       const struct NyLPC_TEthAddr* eth_dest;\r
        struct TEthPacket* ethbuf=(struct TEthPacket*)(i_eth_buf+1);\r
-NyLPC_Trace();\r
        //ペイロードのアドレスから、イーサネットフレームバッファのアドレスを復元\r
-       //const struct NyLPC_TEthAddr* eth_dest=uip_arp_IPv4toEthAddr(ethbuf->data.ipv4.destipaddr);\r
-       const struct NyLPC_TEthAddr* eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,ethbuf->data.ipv4.destipaddr);\r
-       //IP->MAC変換をテスト。\r
-       if(eth_dest==NULL){\r
-               //失敗\r
-NyLPC_Trace();\r
-               return NyLPC_TBool_FALSE;\r
+\r
+       if(NyLPC_TIPv4Addr_isEqual(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_BROADCAST)) {\r
+               //ブロードキャストならそのまま\r
+               eth_dest=&NyLPC_TEthAddr_BROADCAST;\r
+       }else if(NyLPC_TIPv4Addr_isEqualWithMask(&(ethbuf->data.ipv4.destipaddr),&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK)){\r
+               //マルチキャスト\r
+               ip2MulticastEmacAddr(&(ethbuf->data.ipv4.destipaddr),&emac);\r
+               eth_dest=&emac;\r
+       }else{\r
+               eth_dest=NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,ethbuf->data.ipv4.destipaddr);\r
+               //IP->MAC変換をテスト。\r
+               if(eth_dest==NULL){\r
+                       return NyLPC_TBool_FALSE;\r
+               }\r
        }\r
-NyLPC_Trace();\r
        //変換可能なら、イーサネットヘッダを更新して、送信処理へ。\r
        tx_len=NyLPC_TEthernetIIHeader_setIPv4Tx(&(ethbuf->header),&(inst->_ref_config->eth_mac),eth_dest);\r
        inst->_ethif->sendTxEthFrame(i_eth_buf,tx_len);\r
-NyLPC_Trace();\r
        return NyLPC_TBool_TRUE;\r
 }\r
 \r
index 756196d..331aac9 100644 (file)
@@ -59,6 +59,8 @@
 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO={0x00000000};\r
 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL ={0xffffffff};\r
 const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST = { 0xfffffff };\r
+const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST = NyLPC_TIPv4Addr_pack(224,0,0,0);\r
+const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK = NyLPC_TIPv4Addr_pack(224,0,0,0);\r
 \r
 \r
 \r
index aa753cf..1729769 100644 (file)
@@ -93,6 +93,8 @@ struct NyLPC_TIPv4Addr
 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ZERO;\r
 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_ALL;\r
 extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_BROADCAST;\r
+extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST;\r
+extern const struct NyLPC_TIPv4Addr NyLPC_TIPv4Addr_MULTICAST_MASK;\r
 \r
 /**\r
  * addr1とaddr2が全く同じであるかをテストします。\r