* 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
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
//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
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
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
*/\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
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
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
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
*/\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
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
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
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
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
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