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

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

libMiMic(MiMic library for mbed)は、WebService機能を提供するSDKです。 mbedでWebAPIに対応したネットワークデバイスを簡単に作ることが出来ます。

libMiMicはMiMic projectで開発しています。MiMic projectについてはこちらをご覧ください。 http://nyatla.jp/mimic/wp/

構成

libMiMicはmbedRTOS上で動作し、ユーザアプリケーションにAPIを提供します。コアAPIはC言語で記述されていますが、使用頻度の高いものについてはmbed向けのC++APIが準備されています。

/media/uploads/nyatla/libmimic-sdk.png

※libMiMicはmbedの標準イーサネットドライバをしようしていません。

標準イーサネットドライバと同時に使用することはできません。

  • MiMicIP - IPv4スタックです。レテンシとメモリ消費量を抑えたuipベースのライブラリです。
  • ARP/ICMP/UDP/TCP - 基礎的なソケットAPIを提供します。APIは独自です。
  • HTTP/1.1 Server - HTTP/1.1に対応したサーバです。マルチセッション・Chunked・持続性接続に対応しています。
  • HTTP Modules - HTTP/1.1の機能モジュールです。以下のモジュールがあります。
    • ROM file provider - ROMに格納したファイルイメージを公開します。
    • File system provider - mbedファイルシステムを公開します。
    • Onchip configuration - プログラムフラッシュを利用して設定を保存します。
    • MiMicVM processor - RPCリクエスト(MiMicVM)を処理します。
    • FileUpload - ファイルアップロードを受け取ります。
    • URL decoder - HTTPリクエストを解析します。
    • UPnP handler -UPnPメッセージを処理します。
    • WebSocket - Websocketサーバです。
  • mDNS - マルチキャストDNSサービスです。
  • UPnP - UPnP/1.0の機能を提供します。UPnP handlerと協調して動作します。(現在はデバイス探索(SSDP)・デスクリプション(Description)のみ実装してあります。)
  • DHCP/APIPA - ゼロコンフィギュレーション用のモジュールです。
  • HTTP/1.1 Client
  • mbed C++ class library - mbed向けのC++CPIです。C言語のものより簡単です。

対応機種

  • mbed(mbed LPC1768)
  • LPCXpresso1769

プログラム

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

サンプル

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

チュートリアル

English

libMiMic(MiMic library for mbed) is SDK which provides Webservice functions. It can be created networking device easily using mbed.

See more MiMic information, See MiMic project website. http://nyatla.jp/mimic/wp/

Structure

libMiMic run on mbed RTOS and provides networking API to user application. This library has C++ class API for the mbed, and low-level C language API.

/media/uploads/nyatla/libmimic-sdk.png

For WebService general, it can be written in a simple C + + API.

libMiMic does not have the standard Ethernet driver of mbed. It is not possible that will be used with the standard Ethernet driver.

  • MiMicIP - IPv4 protocol stack. This is based uip which is reduced memory and latency.
  • ARP / ICMP / UDP / TCP - Those are provide basic IP protocols.
  • HTTP/1.1 Server - The Http server compatible HTTP/1.1. It supports multi-session, chunked transport, persistent connection.
  • HTTP Modules - There are addon-module for HTTP server. The following modules.
    • ROM file module - Publish the file images in ROM.
    • File system module - Publish thefiles in mbed file system.
    • Onchip configuration module - To save the network settings to the program flash via REST.
    • MiMicVM module - To handle the (MiMicVM) RPC request.
    • FileUpload module - Accept a file via HTTP POST.
    • URL dedoce module - A versatility URL decoder.
    • UPnP handle module - To handle UPnP messages.
    • UPnP - This provides UPnP/1.0 device functions. It works together with UPnP handler.
    • Websocket - websocket (version13) server
  • mDNS Service - DNS-SD protocol server.
  • UPnP - This provides UPnP/1.0 device functions which works with UPnP handler. (You have been implemented (SSDP) ? description only (Description) device search now.) It is a module zero configuration for - DHCP / APIPA. mbed C + + class library - C of mbed for + + is the CPI. It is simple than that of the C language.
  • DHCP/APIPA - It support zero-cpnfigulation.
  • mbed C++ class library. Almost APIs for Web applications are available.
  • HTTP/1.1 Client

Supported target

  • mbed(mbed LPC1768)
  • LPCXpresso1769

Application

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

Sample

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

Tutorial

Committer:
nyatla
Date:
Sun Oct 19 08:44:52 2014 +0000
Revision:
97:6ca5900a2d68
Parent:
96:e6a0db86988e
Child:
98:6284ce9a0476
Bugfix LPC4088 driver; Bugfix mDNS TTL;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nyatla 37:fc4b4fd6a649 1 /*********************************************************************************
nyatla 37:fc4b4fd6a649 2 * PROJECT: MiMic
nyatla 37:fc4b4fd6a649 3 * --------------------------------------------------------------------------------
nyatla 37:fc4b4fd6a649 4 *
nyatla 37:fc4b4fd6a649 5 * This file is part of MiMic
nyatla 37:fc4b4fd6a649 6 * Copyright (C)2011 Ryo Iizuka
nyatla 37:fc4b4fd6a649 7 *
nyatla 37:fc4b4fd6a649 8 * MiMic is free software: you can redistribute it and/or modify
nyatla 37:fc4b4fd6a649 9 * it under the terms of the GNU Lesser General Public License as published
nyatla 37:fc4b4fd6a649 10 * by the Free Software Foundation, either version 3 of the License, or
nyatla 37:fc4b4fd6a649 11 * (at your option) any later version.
nyatla 37:fc4b4fd6a649 12 *
nyatla 37:fc4b4fd6a649 13 * This program is distributed in the hope that it will be useful,
nyatla 37:fc4b4fd6a649 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nyatla 37:fc4b4fd6a649 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nyatla 37:fc4b4fd6a649 16 * GNU General Public License for more details.
nyatla 37:fc4b4fd6a649 17 *
nyatla 37:fc4b4fd6a649 18 * You should have received a copy of the GNU Lesser General Public License
nyatla 37:fc4b4fd6a649 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
nyatla 37:fc4b4fd6a649 20 *
nyatla 37:fc4b4fd6a649 21 * For further information please contact.
nyatla 37:fc4b4fd6a649 22 * http://nyatla.jp/
nyatla 37:fc4b4fd6a649 23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
nyatla 37:fc4b4fd6a649 24 *
nyatla 37:fc4b4fd6a649 25 *********************************************************************************/
nyatla 37:fc4b4fd6a649 26 #include "NyLPC_cMDnsServer.h"
nyatla 37:fc4b4fd6a649 27 #include "NyLPC_uipService.h"
nyatla 37:fc4b4fd6a649 28 #include "NyLPC_http.h"
nyatla 37:fc4b4fd6a649 29 #include "NyLPC_utils.h"
nyatla 37:fc4b4fd6a649 30 #include <stdio.h>
nyatla 37:fc4b4fd6a649 31 #include <string.h>
nyatla 37:fc4b4fd6a649 32
nyatla 37:fc4b4fd6a649 33
nyatla 37:fc4b4fd6a649 34 /**
nyatla 37:fc4b4fd6a649 35 * mDNSのポート番号
nyatla 37:fc4b4fd6a649 36 */
nyatla 37:fc4b4fd6a649 37 #define MDNS_MCAST_PORT 5353
nyatla 37:fc4b4fd6a649 38 static const struct NyLPC_TIPv4Addr MDNS_MCAST_IPADDR=NyLPC_TIPv4Addr_pack(224,0,0,251);
nyatla 37:fc4b4fd6a649 39 #define TIMEOUT_IN_MS 1000
nyatla 96:e6a0db86988e 40 #define NyLPC_TcMDns_TTL (30*60) //30min
nyatla 37:fc4b4fd6a649 41
nyatla 37:fc4b4fd6a649 42
nyatla 37:fc4b4fd6a649 43 struct NyLPC_TDnsHeader
nyatla 37:fc4b4fd6a649 44 {
nyatla 37:fc4b4fd6a649 45 NyLPC_TUInt16 id;
nyatla 37:fc4b4fd6a649 46 NyLPC_TUInt16 flag;
nyatla 37:fc4b4fd6a649 47 NyLPC_TUInt16 qd;
nyatla 37:fc4b4fd6a649 48 NyLPC_TUInt16 an;
nyatla 37:fc4b4fd6a649 49 NyLPC_TUInt16 ns;
nyatla 37:fc4b4fd6a649 50 NyLPC_TUInt16 ar;
nyatla 37:fc4b4fd6a649 51 }PACK_STRUCT_END;
nyatla 37:fc4b4fd6a649 52
nyatla 37:fc4b4fd6a649 53 #define NyLPC_TDnsHeader_FLAG_MASK_QR 0x8000
nyatla 37:fc4b4fd6a649 54 #define NyLPC_TDnsHeader_FLAG_MASK_OPCODE 0x7800
nyatla 37:fc4b4fd6a649 55 #define NyLPC_TDnsHeader_FLAG_MASK_AA 0x0400
nyatla 37:fc4b4fd6a649 56 #define NyLPC_TDnsHeader_FLAG_MASK_TC 0x0200
nyatla 37:fc4b4fd6a649 57 #define NyLPC_TDnsHeader_FLAG_MASK_RD 0x0100
nyatla 37:fc4b4fd6a649 58 #define NyLPC_TDnsHeader_FLAG_MASK_RA 0x0080
nyatla 37:fc4b4fd6a649 59 #define NyLPC_TDnsHeader_FLAG_MASK_Z 0x0070
nyatla 37:fc4b4fd6a649 60 #define NyLPC_TDnsHeader_FLAG_MASK_RECODE 0x000F
nyatla 37:fc4b4fd6a649 61
nyatla 37:fc4b4fd6a649 62 struct NyLPC_TDnsQuestion
nyatla 37:fc4b4fd6a649 63 {
nyatla 37:fc4b4fd6a649 64 const char* qname;
nyatla 37:fc4b4fd6a649 65 NyLPC_TUInt16 qtype;
nyatla 37:fc4b4fd6a649 66 NyLPC_TUInt16 qclass;
nyatla 37:fc4b4fd6a649 67 };
nyatla 37:fc4b4fd6a649 68 #define NyLPC_TDnsQuestion_QTYPR_A 1
nyatla 37:fc4b4fd6a649 69 #define NyLPC_TDnsQuestion_QTYPR_NS 2
nyatla 37:fc4b4fd6a649 70 #define NyLPC_TDnsQuestion_QTYPR_CNAME 5
nyatla 37:fc4b4fd6a649 71 #define NyLPC_TDnsQuestion_QTYPR_SOA 6
nyatla 37:fc4b4fd6a649 72 #define NyLPC_TDnsQuestion_QTYPR_PTR 12
nyatla 37:fc4b4fd6a649 73 #define NyLPC_TDnsQuestion_QTYPR_MX 15
nyatla 37:fc4b4fd6a649 74 #define NyLPC_TDnsQuestion_QTYPR_TXT 16
nyatla 37:fc4b4fd6a649 75 #define NyLPC_TDnsQuestion_QTYPR_ANY 255
nyatla 37:fc4b4fd6a649 76 #define NyLPC_TDnsQuestion_QCLASS_IN 1
nyatla 37:fc4b4fd6a649 77 #define NyLPC_TDnsQuestion_QCLASS_CH 3
nyatla 37:fc4b4fd6a649 78 #define NyLPC_TDnsQuestion_QCLASS_HS 4
nyatla 37:fc4b4fd6a649 79 #define NyLPC_TDnsQuestion_QTYPR_SRV 33
nyatla 37:fc4b4fd6a649 80
nyatla 37:fc4b4fd6a649 81 /**************************************************
nyatla 37:fc4b4fd6a649 82 * TLabelCache
nyatla 37:fc4b4fd6a649 83 **************************************************/
nyatla 37:fc4b4fd6a649 84
nyatla 37:fc4b4fd6a649 85 struct TLabelCache
nyatla 37:fc4b4fd6a649 86 {
nyatla 37:fc4b4fd6a649 87 NyLPC_TUInt16 idx;
nyatla 37:fc4b4fd6a649 88 const char* str;
nyatla 37:fc4b4fd6a649 89 };
nyatla 37:fc4b4fd6a649 90 static void TLabelCache_reset(struct TLabelCache* i_struct)
nyatla 37:fc4b4fd6a649 91 {
nyatla 37:fc4b4fd6a649 92 i_struct->idx=0;
nyatla 37:fc4b4fd6a649 93 i_struct->str=NULL;
nyatla 37:fc4b4fd6a649 94 }
nyatla 37:fc4b4fd6a649 95 static NyLPC_TInt16 TLabelCache_compress(struct TLabelCache* i_struct,NyLPC_TChar* i_src)
nyatla 37:fc4b4fd6a649 96 {
nyatla 37:fc4b4fd6a649 97 NyLPC_TInt16 s;
nyatla 37:fc4b4fd6a649 98 NyLPC_TInt16 k;
nyatla 37:fc4b4fd6a649 99 const NyLPC_TChar* q;
nyatla 37:fc4b4fd6a649 100 const NyLPC_TChar* d;
nyatla 37:fc4b4fd6a649 101 //初めてのインデクスは保存
nyatla 37:fc4b4fd6a649 102 if(i_struct->idx==0){
nyatla 37:fc4b4fd6a649 103 i_struct->idx=12;
nyatla 37:fc4b4fd6a649 104 i_struct->str=i_src;
nyatla 37:fc4b4fd6a649 105 }else{
nyatla 37:fc4b4fd6a649 106 d=i_struct->str;
nyatla 37:fc4b4fd6a649 107 do{
nyatla 37:fc4b4fd6a649 108 q=i_src;
nyatla 37:fc4b4fd6a649 109 do{
nyatla 37:fc4b4fd6a649 110 if(strcmp(q,d)==0){
nyatla 37:fc4b4fd6a649 111 //一致,インデクスを計算
nyatla 37:fc4b4fd6a649 112 s=(NyLPC_TInt16)(q-i_src);
nyatla 37:fc4b4fd6a649 113 k=(NyLPC_TInt16)(d-i_struct->str);
nyatla 37:fc4b4fd6a649 114 //新しい長さを返す
nyatla 37:fc4b4fd6a649 115 *((NyLPC_TInt16*)(i_src+s))=NyLPC_HTONS(0xC000|(i_struct->idx+k));
nyatla 37:fc4b4fd6a649 116 return s+2;
nyatla 37:fc4b4fd6a649 117 }
nyatla 37:fc4b4fd6a649 118 q+=*q+1;
nyatla 37:fc4b4fd6a649 119 }while(*q!=0);
nyatla 37:fc4b4fd6a649 120 d+=*d+1;
nyatla 37:fc4b4fd6a649 121 }while(*d!=0);
nyatla 37:fc4b4fd6a649 122 }
nyatla 37:fc4b4fd6a649 123 return (NyLPC_TInt16)(strlen(i_src)+1);
nyatla 37:fc4b4fd6a649 124 }
nyatla 37:fc4b4fd6a649 125
nyatla 37:fc4b4fd6a649 126
nyatla 37:fc4b4fd6a649 127
nyatla 37:fc4b4fd6a649 128
nyatla 37:fc4b4fd6a649 129
nyatla 37:fc4b4fd6a649 130 /**
nyatla 37:fc4b4fd6a649 131 * 受領可能なQuestionか確認する
nyatla 37:fc4b4fd6a649 132 * @return
nyatla 37:fc4b4fd6a649 133 * 受領可能なQuestionの数
nyatla 37:fc4b4fd6a649 134 *
nyatla 37:fc4b4fd6a649 135 */
nyatla 37:fc4b4fd6a649 136 static NyLPC_TUInt16 getNumberOfQuestion(const void* i_packet,NyLPC_TUInt16 i_len)
nyatla 37:fc4b4fd6a649 137 {
nyatla 37:fc4b4fd6a649 138 struct NyLPC_TDnsHeader* ptr=(struct NyLPC_TDnsHeader*)i_packet;
nyatla 37:fc4b4fd6a649 139 NyLPC_TUInt16 t;
nyatla 37:fc4b4fd6a649 140 if(i_len<12){
nyatla 37:fc4b4fd6a649 141 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 142 }
nyatla 37:fc4b4fd6a649 143 //questrionの確認
nyatla 37:fc4b4fd6a649 144 //QR==0 && op==0 && tc=0
nyatla 37:fc4b4fd6a649 145 t=NyLPC_ntohs(ptr->flag);
nyatla 37:fc4b4fd6a649 146 if( ((t & NyLPC_TDnsHeader_FLAG_MASK_QR)!=0) &&
nyatla 37:fc4b4fd6a649 147 ((t & NyLPC_TDnsHeader_FLAG_MASK_OPCODE)!=0) &&
nyatla 37:fc4b4fd6a649 148 ((t & NyLPC_TDnsHeader_FLAG_MASK_TC)!=0))
nyatla 37:fc4b4fd6a649 149 {
nyatla 37:fc4b4fd6a649 150 //this is response
nyatla 37:fc4b4fd6a649 151 return 0;
nyatla 37:fc4b4fd6a649 152 }
nyatla 37:fc4b4fd6a649 153 return NyLPC_ntohs(ptr->qd);
nyatla 37:fc4b4fd6a649 154 }
nyatla 37:fc4b4fd6a649 155
nyatla 37:fc4b4fd6a649 156 static NyLPC_TInt16 NyLPC_TDnsQuestion_parse(const void* i_qpacket,NyLPC_TUInt16 i_len,struct NyLPC_TDnsQuestion* o_val)
nyatla 37:fc4b4fd6a649 157 {
nyatla 37:fc4b4fd6a649 158 NyLPC_TUInt16 l;
nyatla 37:fc4b4fd6a649 159 NyLPC_TUInt16 i;
nyatla 37:fc4b4fd6a649 160 const char* p=(const char*)i_qpacket;
nyatla 37:fc4b4fd6a649 161 //QNameのパース'0終端'
nyatla 38:b0604fee76b0 162 l=i_len-4-1;//スキャン長はパケットサイズ-5まで
nyatla 37:fc4b4fd6a649 163 for(i=0;i<l;i++){
nyatla 37:fc4b4fd6a649 164 if(*(p+i)==0){
nyatla 37:fc4b4fd6a649 165 l=i+1;//NULL終端を加味した文字列長
nyatla 37:fc4b4fd6a649 166 o_val->qname=p;
nyatla 37:fc4b4fd6a649 167 p+=l;
nyatla 37:fc4b4fd6a649 168 o_val->qtype=NyLPC_ntohs(*(NyLPC_TUInt16*)p);
nyatla 37:fc4b4fd6a649 169 o_val->qclass=NyLPC_ntohs(*(NyLPC_TUInt16*)(p+sizeof(NyLPC_TUInt16)));
nyatla 37:fc4b4fd6a649 170 //OK
nyatla 37:fc4b4fd6a649 171 return l+4;
nyatla 37:fc4b4fd6a649 172 }
nyatla 37:fc4b4fd6a649 173 }
nyatla 37:fc4b4fd6a649 174 return 0;
nyatla 37:fc4b4fd6a649 175 }
nyatla 37:fc4b4fd6a649 176
nyatla 37:fc4b4fd6a649 177 /**
nyatla 37:fc4b4fd6a649 178 * .区切りラベル文字列とDNSラベル文字列を比較する。
nyatla 37:fc4b4fd6a649 179 * @param record
nyatla 37:fc4b4fd6a649 180 * .区切りのドメイン名
nyatla 37:fc4b4fd6a649 181 * @param question
nyatla 37:fc4b4fd6a649 182 * QuestionName文字列
nyatla 37:fc4b4fd6a649 183 */
nyatla 37:fc4b4fd6a649 184 inline static NyLPC_TBool isEqualName(const char* record,const char* question)
nyatla 37:fc4b4fd6a649 185 {
nyatla 37:fc4b4fd6a649 186 char s;
nyatla 37:fc4b4fd6a649 187 const char* q=question;
nyatla 37:fc4b4fd6a649 188 const char* m=record;
nyatla 37:fc4b4fd6a649 189 for(;;){
nyatla 37:fc4b4fd6a649 190 if(*m=='\0'){
nyatla 37:fc4b4fd6a649 191 //questionは最後のフラグメントが残るはず
nyatla 37:fc4b4fd6a649 192 return memcmp(q,"\5local\0",7)==0;
nyatla 37:fc4b4fd6a649 193 }
nyatla 37:fc4b4fd6a649 194 s=*q;
nyatla 37:fc4b4fd6a649 195 switch(*q)
nyatla 37:fc4b4fd6a649 196 {
nyatla 37:fc4b4fd6a649 197 case 0x00:
nyatla 37:fc4b4fd6a649 198 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 199 case 0xc0:
nyatla 37:fc4b4fd6a649 200 return NyLPC_TBool_FALSE;//offset
nyatla 37:fc4b4fd6a649 201 default:
nyatla 37:fc4b4fd6a649 202 q++;
nyatla 37:fc4b4fd6a649 203 if(strncmp(m,q,s)!=0){
nyatla 37:fc4b4fd6a649 204 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 205 }
nyatla 37:fc4b4fd6a649 206 m+=s;
nyatla 37:fc4b4fd6a649 207 q+=s;
nyatla 37:fc4b4fd6a649 208 }
nyatla 37:fc4b4fd6a649 209 m++;
nyatla 37:fc4b4fd6a649 210 }
nyatla 37:fc4b4fd6a649 211 }
nyatla 37:fc4b4fd6a649 212 /**
nyatla 37:fc4b4fd6a649 213 * DNSレコードのPRTフィールドとDNSラベル文字列を比較する。
nyatla 37:fc4b4fd6a649 214 */
nyatla 37:fc4b4fd6a649 215 static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchPtrIdx(const struct NyLPC_TDnsRecord* i_struct,const NyLPC_TChar* question)
nyatla 37:fc4b4fd6a649 216 {
nyatla 37:fc4b4fd6a649 217 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 218 for(i=0;i<i_struct->num_of_srv;i++){
nyatla 37:fc4b4fd6a649 219 if(isEqualName(i_struct->srv[i].protocol,question)){
nyatla 37:fc4b4fd6a649 220 return i;
nyatla 37:fc4b4fd6a649 221 }
nyatla 37:fc4b4fd6a649 222 }
nyatla 37:fc4b4fd6a649 223 return -1;
nyatla 37:fc4b4fd6a649 224 }
nyatla 37:fc4b4fd6a649 225 static NyLPC_TInt16 NyLPC_TDnsRecord_getMatchSrvIdx(const struct NyLPC_TDnsRecord* i_struct,const NyLPC_TChar* question)
nyatla 37:fc4b4fd6a649 226 {
nyatla 37:fc4b4fd6a649 227 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 228 NyLPC_TInt16 l=(NyLPC_TInt16)strlen(i_struct->name);
nyatla 37:fc4b4fd6a649 229 //Aレコードをチェック
nyatla 37:fc4b4fd6a649 230 if(l!=question[0] || memcmp(question+1,i_struct->name,l)!=0){
nyatla 37:fc4b4fd6a649 231 return -1;
nyatla 37:fc4b4fd6a649 232 }
nyatla 37:fc4b4fd6a649 233 for(i=0;i<i_struct->num_of_srv;i++){
nyatla 37:fc4b4fd6a649 234 if(isEqualName(i_struct->srv[i].protocol,question+l+1)){
nyatla 37:fc4b4fd6a649 235 return i;
nyatla 37:fc4b4fd6a649 236 }
nyatla 37:fc4b4fd6a649 237 }
nyatla 37:fc4b4fd6a649 238 return -1;
nyatla 37:fc4b4fd6a649 239 }
nyatla 37:fc4b4fd6a649 240 /**
nyatla 37:fc4b4fd6a649 241 * _services._dns-sd._udp.localであるか確認する。
nyatla 37:fc4b4fd6a649 242 */
nyatla 37:fc4b4fd6a649 243 static NyLPC_TBool NyLPC_TDnsRecord_isServicesDnsSd(const NyLPC_TChar* question)
nyatla 37:fc4b4fd6a649 244 {
nyatla 37:fc4b4fd6a649 245 return memcmp(question,"\x09_services\x07_dns-sd\x04_udp\5local\x00",30)==0;
nyatla 37:fc4b4fd6a649 246 }
nyatla 37:fc4b4fd6a649 247
nyatla 37:fc4b4fd6a649 248
nyatla 37:fc4b4fd6a649 249 /**
nyatla 37:fc4b4fd6a649 250 * '.'区切り文字列をDNS形式の[n]text[n]text\0へ変換する。
nyatla 37:fc4b4fd6a649 251 * @return
nyatla 37:fc4b4fd6a649 252 * 変換後のデータブロックの長さin byte
nyatla 37:fc4b4fd6a649 253 * 終端の\0の長さを含みます。
nyatla 37:fc4b4fd6a649 254 */
nyatla 37:fc4b4fd6a649 255 static NyLPC_TInt16 str2label(NyLPC_TChar* buf,const NyLPC_TChar* name)
nyatla 37:fc4b4fd6a649 256 {
nyatla 37:fc4b4fd6a649 257 //proto文字列の変換
nyatla 37:fc4b4fd6a649 258 NyLPC_TChar* lp;
nyatla 37:fc4b4fd6a649 259 const NyLPC_TChar* n=name;
nyatla 37:fc4b4fd6a649 260 NyLPC_TChar* b=buf;
nyatla 37:fc4b4fd6a649 261 while(*n!='\0'){
nyatla 37:fc4b4fd6a649 262 lp=b;
nyatla 37:fc4b4fd6a649 263 b++;
nyatla 37:fc4b4fd6a649 264 for(;strchr(".\0",*n)==NULL;){
nyatla 37:fc4b4fd6a649 265 *b=*n;
nyatla 37:fc4b4fd6a649 266 b++;
nyatla 37:fc4b4fd6a649 267 n++;
nyatla 37:fc4b4fd6a649 268 }
nyatla 37:fc4b4fd6a649 269 *lp=(char)(b-lp-1);
nyatla 37:fc4b4fd6a649 270 if(*n!='\0'){
nyatla 37:fc4b4fd6a649 271 n++;
nyatla 37:fc4b4fd6a649 272 }
nyatla 37:fc4b4fd6a649 273 }
nyatla 37:fc4b4fd6a649 274 *b='\0';
nyatla 37:fc4b4fd6a649 275 b++;
nyatla 37:fc4b4fd6a649 276 return b-buf;
nyatla 37:fc4b4fd6a649 277 }
nyatla 37:fc4b4fd6a649 278
nyatla 37:fc4b4fd6a649 279 /**
nyatla 37:fc4b4fd6a649 280 * ResourceHeaderのライタ
nyatla 37:fc4b4fd6a649 281 */
nyatla 37:fc4b4fd6a649 282 static NyLPC_TInt16 writeResourceHeader(char* buf,NyLPC_TInt16 len,const char* i_name,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class)
nyatla 37:fc4b4fd6a649 283 {
nyatla 37:fc4b4fd6a649 284 NyLPC_TInt16 s;
nyatla 37:fc4b4fd6a649 285 NyLPC_TInt16 l=1+(NyLPC_TInt16)strlen(i_name)+1+5+1;
nyatla 37:fc4b4fd6a649 286 if(len<l+4+4){
nyatla 37:fc4b4fd6a649 287 return 0;
nyatla 37:fc4b4fd6a649 288 }
nyatla 37:fc4b4fd6a649 289 s=str2label(buf,i_name);
nyatla 37:fc4b4fd6a649 290 str2label(buf+s-1,"local");
nyatla 37:fc4b4fd6a649 291 (*(NyLPC_TUInt16*)(buf+l))=NyLPC_HTONS(i_type);
nyatla 37:fc4b4fd6a649 292 (*(NyLPC_TUInt16*)(buf+l+2))=NyLPC_HTONS(i_class);
nyatla 37:fc4b4fd6a649 293 (*(NyLPC_TUInt32*)(buf+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 294 return l+2+2+4;
nyatla 37:fc4b4fd6a649 295 }
nyatla 37:fc4b4fd6a649 296
nyatla 37:fc4b4fd6a649 297 inline static NyLPC_TInt16 writeSrvResourceHeader(char* buf,NyLPC_TInt16 len,const struct NyLPC_TDnsRecord* i_recode,int i_sid,NyLPC_TUInt16 i_type,NyLPC_TUInt16 i_class,struct TLabelCache* i_ca)
nyatla 37:fc4b4fd6a649 298 {
nyatla 37:fc4b4fd6a649 299 NyLPC_TInt16 l=(NyLPC_TInt16)(1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1);
nyatla 37:fc4b4fd6a649 300 if(len<l+2+2+4){
nyatla 37:fc4b4fd6a649 301 return 0;
nyatla 37:fc4b4fd6a649 302 }
nyatla 37:fc4b4fd6a649 303 l=str2label(buf,i_recode->name)-1;
nyatla 37:fc4b4fd6a649 304 l+=str2label(buf+l,i_recode->srv[i_sid].protocol)-1;
nyatla 37:fc4b4fd6a649 305 l+=str2label(buf+l,"local");
nyatla 37:fc4b4fd6a649 306 l=TLabelCache_compress(i_ca,buf);//圧縮
nyatla 37:fc4b4fd6a649 307 (*(NyLPC_TUInt16*)(buf+l))=NyLPC_HTONS(i_type);
nyatla 37:fc4b4fd6a649 308 (*(NyLPC_TUInt16*)(buf+l+2))=NyLPC_HTONS(i_class);
nyatla 37:fc4b4fd6a649 309 (*(NyLPC_TUInt32*)(buf+l+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 310 return l+2+2+4;
nyatla 37:fc4b4fd6a649 311 }
nyatla 37:fc4b4fd6a649 312
nyatla 37:fc4b4fd6a649 313 inline static NyLPC_TUInt16 setResponseHeader(char* obuf,const struct NyLPC_TDnsHeader* i_in_dns_header,NyLPC_TUInt16 i_an_count,NyLPC_TUInt16 i_ns_count,NyLPC_TUInt16 i_ar_count)
nyatla 37:fc4b4fd6a649 314 {
nyatla 37:fc4b4fd6a649 315 struct NyLPC_TDnsHeader* p=(struct NyLPC_TDnsHeader*)obuf;
nyatla 37:fc4b4fd6a649 316 if(i_in_dns_header!=NULL){
nyatla 37:fc4b4fd6a649 317 memcpy(p,i_in_dns_header,sizeof(struct NyLPC_TDnsHeader));
nyatla 37:fc4b4fd6a649 318 p->flag=p->flag | NyLPC_HTONS(NyLPC_TDnsHeader_FLAG_MASK_QR|NyLPC_TDnsHeader_FLAG_MASK_AA);
nyatla 37:fc4b4fd6a649 319 p->flag=p->flag & NyLPC_HTONS(~(NyLPC_TDnsHeader_FLAG_MASK_RECODE|NyLPC_TDnsHeader_FLAG_MASK_TC|NyLPC_TDnsHeader_FLAG_MASK_RA));
nyatla 37:fc4b4fd6a649 320 }else{
nyatla 37:fc4b4fd6a649 321 p->flag=0;
nyatla 37:fc4b4fd6a649 322 p->id=0;
nyatla 37:fc4b4fd6a649 323 }
nyatla 37:fc4b4fd6a649 324 p->qd=0;
nyatla 37:fc4b4fd6a649 325 p->an=NyLPC_HTONS(i_an_count);
nyatla 37:fc4b4fd6a649 326 p->ns=NyLPC_HTONS(i_ns_count);
nyatla 37:fc4b4fd6a649 327 p->ar=NyLPC_HTONS(i_ar_count);
nyatla 37:fc4b4fd6a649 328 return sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 329 }
nyatla 37:fc4b4fd6a649 330 inline static NyLPC_TInt16 writeARecord(char* obuf,NyLPC_TInt16 obuflen,const NyLPC_TChar* a_rec,const struct NyLPC_TIPv4Addr* ip)
nyatla 37:fc4b4fd6a649 331 {
nyatla 37:fc4b4fd6a649 332 NyLPC_TInt16 ret;
nyatla 37:fc4b4fd6a649 333 //AnswerはAレコードのみ
nyatla 37:fc4b4fd6a649 334 //A record header
nyatla 37:fc4b4fd6a649 335 ret=writeResourceHeader(obuf,obuflen,a_rec,NyLPC_TDnsQuestion_QTYPR_A,NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 37:fc4b4fd6a649 336 if(ret==0 || obuflen-ret<8){
nyatla 37:fc4b4fd6a649 337 return 0;
nyatla 37:fc4b4fd6a649 338 }
nyatla 37:fc4b4fd6a649 339 //Aレコードを書く
nyatla 37:fc4b4fd6a649 340 //IPADDR
nyatla 37:fc4b4fd6a649 341 (*(NyLPC_TUInt16*)(obuf+ret))=NyLPC_HTONS(4);
nyatla 37:fc4b4fd6a649 342 (*(NyLPC_TUInt32*)(obuf+ret+2))=ip->v;
nyatla 37:fc4b4fd6a649 343 return ret+8;
nyatla 37:fc4b4fd6a649 344 }
nyatla 37:fc4b4fd6a649 345 static NyLPC_TInt16 writeSdPtrRecord(const char* i_qname,const struct NyLPC_TMDnsServiceRecord* i_srvlec,char* obuf,NyLPC_TInt16 obuflen)
nyatla 37:fc4b4fd6a649 346 {
nyatla 37:fc4b4fd6a649 347 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 348 //Header
nyatla 37:fc4b4fd6a649 349 s=(NyLPC_TInt16)strlen(i_qname)+1;
nyatla 37:fc4b4fd6a649 350 //Headerの長さチェック
nyatla 37:fc4b4fd6a649 351 if(obuflen<s+2+2+4){
nyatla 37:fc4b4fd6a649 352 return 0;
nyatla 37:fc4b4fd6a649 353 }
nyatla 37:fc4b4fd6a649 354 //Header書込み
nyatla 37:fc4b4fd6a649 355 memcpy(obuf,i_qname,s);
nyatla 37:fc4b4fd6a649 356 (*(NyLPC_TUInt16*)(obuf+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
nyatla 37:fc4b4fd6a649 357 (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 37:fc4b4fd6a649 358 (*(NyLPC_TUInt32*)(obuf+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 359 l=s+2+2+4;
nyatla 37:fc4b4fd6a649 360
nyatla 37:fc4b4fd6a649 361 //Resourceの書込み
nyatla 37:fc4b4fd6a649 362 s=(NyLPC_TInt16)(1+strlen(i_srvlec->protocol)+1+5+1);//逆引き文字列の長さ(デリミタ×3+1)
nyatla 37:fc4b4fd6a649 363 if(obuflen<s+l+2){
nyatla 37:fc4b4fd6a649 364 return 0;
nyatla 37:fc4b4fd6a649 365 }
nyatla 37:fc4b4fd6a649 366 (*(NyLPC_TUInt16*)(obuf+l))=NyLPC_ntohs(s);
nyatla 37:fc4b4fd6a649 367 l+=2;
nyatla 37:fc4b4fd6a649 368 l+=str2label(obuf+l,i_srvlec->protocol)-1;
nyatla 37:fc4b4fd6a649 369 l+=str2label(obuf+l,"local");
nyatla 37:fc4b4fd6a649 370 return l;
nyatla 37:fc4b4fd6a649 371 }
nyatla 37:fc4b4fd6a649 372 static NyLPC_TInt16 writePtrRecord(const struct NyLPC_TDnsRecord* i_recode,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca)
nyatla 37:fc4b4fd6a649 373 {
nyatla 37:fc4b4fd6a649 374 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 375 NyLPC_TUInt16* rlen;
nyatla 37:fc4b4fd6a649 376 //Header:開始文字数(1)+プレフィクス(n)+終端(1)+local(5)+1
nyatla 37:fc4b4fd6a649 377 s=(NyLPC_TInt16)(1+strlen(i_recode->srv[i_sid].protocol)+1+5+1);
nyatla 37:fc4b4fd6a649 378 //Headerの長さチェック
nyatla 37:fc4b4fd6a649 379 if(obuflen<s+2+2+4){
nyatla 37:fc4b4fd6a649 380 return 0;
nyatla 37:fc4b4fd6a649 381 }
nyatla 37:fc4b4fd6a649 382 //Header書込み
nyatla 37:fc4b4fd6a649 383 s=str2label(obuf,i_recode->srv[i_sid].protocol)-1;
nyatla 37:fc4b4fd6a649 384 s+=str2label(obuf+s,"local");
nyatla 37:fc4b4fd6a649 385 s=TLabelCache_compress(i_ca,obuf);
nyatla 37:fc4b4fd6a649 386 (*(NyLPC_TUInt16*)(obuf+s))=NyLPC_HTONS(NyLPC_TDnsQuestion_QTYPR_PTR);
nyatla 37:fc4b4fd6a649 387 (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(NyLPC_TDnsQuestion_QCLASS_IN);
nyatla 97:6ca5900a2d68 388 (*(NyLPC_TUInt32*)(obuf+s+4))=NyLPC_HTONL(NyLPC_TcMDns_TTL);
nyatla 37:fc4b4fd6a649 389 l=s+2+2+4;
nyatla 37:fc4b4fd6a649 390
nyatla 37:fc4b4fd6a649 391 //Resourceの書込み
nyatla 37:fc4b4fd6a649 392 s=1+strlen(i_recode->name)+1+strlen(i_recode->srv[i_sid].protocol)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1)
nyatla 37:fc4b4fd6a649 393 if(obuflen<s+l+2){
nyatla 37:fc4b4fd6a649 394 return 0;
nyatla 37:fc4b4fd6a649 395 }
nyatla 37:fc4b4fd6a649 396 rlen=(NyLPC_TUInt16*)(obuf+l);
nyatla 37:fc4b4fd6a649 397 l+=2;
nyatla 37:fc4b4fd6a649 398 s=str2label(obuf+l,i_recode->name)-1;
nyatla 37:fc4b4fd6a649 399 s+=str2label(obuf+l+s,i_recode->srv[i_sid].protocol)-1;
nyatla 37:fc4b4fd6a649 400 s+=str2label(obuf+l+s,"local");
nyatla 37:fc4b4fd6a649 401 s=TLabelCache_compress(i_ca,obuf+l);//圧縮
nyatla 37:fc4b4fd6a649 402 (*rlen)=NyLPC_ntohs(s);
nyatla 37:fc4b4fd6a649 403 return l+s;
nyatla 37:fc4b4fd6a649 404 }
nyatla 37:fc4b4fd6a649 405
nyatla 37:fc4b4fd6a649 406
nyatla 37:fc4b4fd6a649 407 static NyLPC_TInt16 writeSRVRecord(NyLPC_TcMDnsServer_t* i_inst,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca)
nyatla 37:fc4b4fd6a649 408 {
nyatla 37:fc4b4fd6a649 409 NyLPC_TInt16 l,s;
nyatla 37:fc4b4fd6a649 410 NyLPC_TUInt16* rlen;
nyatla 37:fc4b4fd6a649 411
nyatla 37:fc4b4fd6a649 412 //SRV Record
nyatla 37:fc4b4fd6a649 413 s=writeSrvResourceHeader(obuf,obuflen,i_inst->_ref_record,i_sid,NyLPC_TDnsQuestion_QTYPR_SRV,NyLPC_TDnsQuestion_QCLASS_IN,i_ca);
nyatla 37:fc4b4fd6a649 414 if(s==0){
nyatla 37:fc4b4fd6a649 415 return 0;
nyatla 37:fc4b4fd6a649 416 }
nyatla 37:fc4b4fd6a649 417
nyatla 37:fc4b4fd6a649 418 l=1+strlen(i_inst->_ref_record->a)+1+5+1;//逆引き文字列の長さ(デリミタ×3+1)
nyatla 37:fc4b4fd6a649 419 if(obuflen-s-l<8){
nyatla 37:fc4b4fd6a649 420 return 0;
nyatla 37:fc4b4fd6a649 421 }
nyatla 37:fc4b4fd6a649 422 //IPADDR
nyatla 37:fc4b4fd6a649 423 rlen=(NyLPC_TUInt16*)(obuf+s);
nyatla 37:fc4b4fd6a649 424 (*(NyLPC_TUInt16*)(obuf+s+2))=NyLPC_HTONS(0);//Priority
nyatla 37:fc4b4fd6a649 425 (*(NyLPC_TUInt16*)(obuf+s+4))=NyLPC_HTONS(0);//Weight
nyatla 37:fc4b4fd6a649 426 (*(NyLPC_TUInt16*)(obuf+s+6))=NyLPC_HTONS(i_inst->_ref_record->srv[i_sid].port);//PORT
nyatla 37:fc4b4fd6a649 427 l=4*2+s;
nyatla 37:fc4b4fd6a649 428 s=str2label(obuf+l,i_inst->_ref_record->a)-1;
nyatla 37:fc4b4fd6a649 429 s+=str2label(obuf+l+s,"local");
nyatla 37:fc4b4fd6a649 430 s=TLabelCache_compress(i_ca,obuf+l);//圧縮
nyatla 37:fc4b4fd6a649 431 (*rlen)=NyLPC_HTONS(2+2+2+s);
nyatla 37:fc4b4fd6a649 432 return l+s;
nyatla 37:fc4b4fd6a649 433 }
nyatla 37:fc4b4fd6a649 434 static NyLPC_TInt16 writeTXTRecord(NyLPC_TcMDnsServer_t* i_inst,NyLPC_TInt16 i_sid,char* obuf,NyLPC_TInt16 obuflen,struct TLabelCache* i_ca)
nyatla 37:fc4b4fd6a649 435 {
nyatla 37:fc4b4fd6a649 436 NyLPC_TInt16 ret;
nyatla 37:fc4b4fd6a649 437 NyLPC_TInt16 l;
nyatla 37:fc4b4fd6a649 438 //Answer
nyatla 37:fc4b4fd6a649 439 ret=writeSrvResourceHeader(obuf,obuflen,i_inst->_ref_record,i_sid,NyLPC_TDnsQuestion_QTYPR_TXT,NyLPC_TDnsQuestion_QCLASS_IN,i_ca);
nyatla 37:fc4b4fd6a649 440 if(ret==0){
nyatla 37:fc4b4fd6a649 441 return 0;
nyatla 37:fc4b4fd6a649 442 }
nyatla 37:fc4b4fd6a649 443 //name.proto.localを返す。
nyatla 37:fc4b4fd6a649 444 if(obuflen-ret<2){
nyatla 37:fc4b4fd6a649 445 return 0;
nyatla 37:fc4b4fd6a649 446 }
nyatla 37:fc4b4fd6a649 447 (*(NyLPC_TUInt16*)(obuf+ret))=NyLPC_ntohs(0);
nyatla 37:fc4b4fd6a649 448 //proto.name.local.
nyatla 37:fc4b4fd6a649 449 l=ret+2;
nyatla 37:fc4b4fd6a649 450 return l;
nyatla 37:fc4b4fd6a649 451 }
nyatla 37:fc4b4fd6a649 452
nyatla 37:fc4b4fd6a649 453
nyatla 37:fc4b4fd6a649 454
nyatla 37:fc4b4fd6a649 455
nyatla 37:fc4b4fd6a649 456
nyatla 37:fc4b4fd6a649 457
nyatla 37:fc4b4fd6a649 458 static void sendAnnounse(NyLPC_TcMDnsServer_t* i_inst)
nyatla 37:fc4b4fd6a649 459 {
nyatla 37:fc4b4fd6a649 460 char* obuf;
nyatla 37:fc4b4fd6a649 461 NyLPC_TUInt16 obuflen;
nyatla 37:fc4b4fd6a649 462 NyLPC_TUInt16 l,s;
nyatla 37:fc4b4fd6a649 463 int i2;
nyatla 37:fc4b4fd6a649 464 struct TLabelCache cache;
nyatla 37:fc4b4fd6a649 465 for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
nyatla 37:fc4b4fd6a649 466 TLabelCache_reset(&cache);
nyatla 37:fc4b4fd6a649 467 //Bufferの取得
nyatla 37:fc4b4fd6a649 468 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,TIMEOUT_IN_MS);
nyatla 37:fc4b4fd6a649 469 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 470 return;
nyatla 37:fc4b4fd6a649 471 }
nyatla 37:fc4b4fd6a649 472 l=setResponseHeader(obuf,NULL,1,0,3);
nyatla 37:fc4b4fd6a649 473 s=writePtrRecord(i_inst->_ref_record,i2,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 474 if(s<=0){
nyatla 37:fc4b4fd6a649 475 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 476 }
nyatla 37:fc4b4fd6a649 477 l+=s;
nyatla 37:fc4b4fd6a649 478 s=writeSRVRecord(i_inst,i2,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 479 if(s<=0){
nyatla 37:fc4b4fd6a649 480 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 481 }
nyatla 37:fc4b4fd6a649 482 l+=s;
nyatla 37:fc4b4fd6a649 483 s=writeTXTRecord(i_inst,i2,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 484 if(s<=0){
nyatla 37:fc4b4fd6a649 485 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 486 }
nyatla 37:fc4b4fd6a649 487 l+=s;
nyatla 37:fc4b4fd6a649 488 //Aレコード
nyatla 37:fc4b4fd6a649 489 s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 37:fc4b4fd6a649 490 if(s<=0){
nyatla 37:fc4b4fd6a649 491 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 492 }
nyatla 37:fc4b4fd6a649 493 l+=s;
nyatla 37:fc4b4fd6a649 494 if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
nyatla 37:fc4b4fd6a649 495 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 496 }
nyatla 37:fc4b4fd6a649 497 }
nyatla 37:fc4b4fd6a649 498 return;
nyatla 37:fc4b4fd6a649 499 ERROR:
nyatla 37:fc4b4fd6a649 500 NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
nyatla 37:fc4b4fd6a649 501 return;
nyatla 37:fc4b4fd6a649 502 }
nyatla 37:fc4b4fd6a649 503
nyatla 37:fc4b4fd6a649 504
nyatla 37:fc4b4fd6a649 505 static void sendReply2(NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsHeader* i_dns_header,const struct NyLPC_TDnsQuestion* q)
nyatla 37:fc4b4fd6a649 506 {
nyatla 37:fc4b4fd6a649 507 NyLPC_TInt16 ptr_recode;
nyatla 37:fc4b4fd6a649 508 NyLPC_TInt16 i2;
nyatla 37:fc4b4fd6a649 509 char* obuf;
nyatla 37:fc4b4fd6a649 510 NyLPC_TUInt16 obuflen;
nyatla 37:fc4b4fd6a649 511 NyLPC_TUInt16 l,s;
nyatla 37:fc4b4fd6a649 512 struct TLabelCache cache;
nyatla 37:fc4b4fd6a649 513 TLabelCache_reset(&cache);
nyatla 37:fc4b4fd6a649 514 //パケットヘッダの生成
nyatla 37:fc4b4fd6a649 515 switch(q->qtype){
nyatla 37:fc4b4fd6a649 516 case NyLPC_TDnsQuestion_QTYPR_SRV:
nyatla 37:fc4b4fd6a649 517 //SRV,A record
nyatla 37:fc4b4fd6a649 518 ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q->qname);
nyatla 37:fc4b4fd6a649 519 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 520 goto DROP;
nyatla 37:fc4b4fd6a649 521 }
nyatla 37:fc4b4fd6a649 522 //Bufferの取得
nyatla 37:fc4b4fd6a649 523 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 524 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 525 goto DROP;
nyatla 37:fc4b4fd6a649 526 }
nyatla 37:fc4b4fd6a649 527 l=setResponseHeader(obuf,i_dns_header,1,0,2);
nyatla 37:fc4b4fd6a649 528 s=writeSRVRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 529 if(s<=0){
nyatla 37:fc4b4fd6a649 530 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 531 }
nyatla 37:fc4b4fd6a649 532 l+=s;
nyatla 37:fc4b4fd6a649 533 s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 534 if(s<=0){
nyatla 37:fc4b4fd6a649 535 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 536 }
nyatla 37:fc4b4fd6a649 537 l+=s;
nyatla 37:fc4b4fd6a649 538 //Aレコード
nyatla 37:fc4b4fd6a649 539 s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 37:fc4b4fd6a649 540 if(s<=0){
nyatla 37:fc4b4fd6a649 541 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 542 }
nyatla 37:fc4b4fd6a649 543 l+=s;
nyatla 37:fc4b4fd6a649 544 break;
nyatla 37:fc4b4fd6a649 545 case NyLPC_TDnsQuestion_QTYPR_A:
nyatla 37:fc4b4fd6a649 546 //自分宛?(name.local)
nyatla 37:fc4b4fd6a649 547 if(!isEqualName(i_inst->_ref_record->a,q->qname)){
nyatla 37:fc4b4fd6a649 548 goto DROP;
nyatla 37:fc4b4fd6a649 549 }
nyatla 37:fc4b4fd6a649 550 //Bufferの取得
nyatla 37:fc4b4fd6a649 551 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 552 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 553 goto DROP;
nyatla 37:fc4b4fd6a649 554 }
nyatla 37:fc4b4fd6a649 555 //Headerのコピー
nyatla 37:fc4b4fd6a649 556 l=setResponseHeader(obuf,i_dns_header,1,0,0);
nyatla 37:fc4b4fd6a649 557 //Aレコードのみ
nyatla 37:fc4b4fd6a649 558 s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 37:fc4b4fd6a649 559 if(s<=0){
nyatla 37:fc4b4fd6a649 560 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 561 }
nyatla 37:fc4b4fd6a649 562 l+=s;
nyatla 37:fc4b4fd6a649 563 break;
nyatla 37:fc4b4fd6a649 564 case NyLPC_TDnsQuestion_QTYPR_PTR:
nyatla 37:fc4b4fd6a649 565 if(NyLPC_TDnsRecord_isServicesDnsSd(q->qname)){
nyatla 37:fc4b4fd6a649 566 //Bufferの取得
nyatla 37:fc4b4fd6a649 567 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 568 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 569 goto DROP;
nyatla 37:fc4b4fd6a649 570 }
nyatla 37:fc4b4fd6a649 571 l=setResponseHeader(obuf,i_dns_header,i_inst->_ref_record->num_of_srv,0,0);
nyatla 37:fc4b4fd6a649 572 for(i2=0;i2<i_inst->_ref_record->num_of_srv;i2++){
nyatla 37:fc4b4fd6a649 573 s=writeSdPtrRecord(q->qname,&(i_inst->_ref_record->srv[i2]),obuf+l,obuflen-l);
nyatla 37:fc4b4fd6a649 574 if(s<=0){
nyatla 37:fc4b4fd6a649 575 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 576 }
nyatla 37:fc4b4fd6a649 577 l+=s;
nyatla 37:fc4b4fd6a649 578 }
nyatla 37:fc4b4fd6a649 579 }else{
nyatla 37:fc4b4fd6a649 580 //自分宛?(proto.local)
nyatla 37:fc4b4fd6a649 581 ptr_recode=NyLPC_TDnsRecord_getMatchPtrIdx(i_inst->_ref_record,q->qname);
nyatla 37:fc4b4fd6a649 582 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 583 goto DROP;
nyatla 37:fc4b4fd6a649 584 }
nyatla 37:fc4b4fd6a649 585 //Bufferの取得
nyatla 37:fc4b4fd6a649 586 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 587 if(obuf==NULL){
nyatla 37:fc4b4fd6a649 588 goto DROP;
nyatla 37:fc4b4fd6a649 589 }
nyatla 37:fc4b4fd6a649 590 l=setResponseHeader(obuf,i_dns_header,1,0,3);
nyatla 37:fc4b4fd6a649 591 s=writePtrRecord(i_inst->_ref_record,ptr_recode,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 592 if(s<=0){
nyatla 37:fc4b4fd6a649 593 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 594 }
nyatla 37:fc4b4fd6a649 595 l+=s;
nyatla 37:fc4b4fd6a649 596 s=writeSRVRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 597 if(s<=0){
nyatla 37:fc4b4fd6a649 598 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 599 }
nyatla 37:fc4b4fd6a649 600 l+=s;
nyatla 37:fc4b4fd6a649 601 s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 602 if(s<=0){
nyatla 37:fc4b4fd6a649 603 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 604 }
nyatla 37:fc4b4fd6a649 605 l+=s;
nyatla 37:fc4b4fd6a649 606 //Aレコード
nyatla 37:fc4b4fd6a649 607 s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 37:fc4b4fd6a649 608 if(s<=0){
nyatla 37:fc4b4fd6a649 609 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 610 }
nyatla 37:fc4b4fd6a649 611 l+=s;
nyatla 37:fc4b4fd6a649 612 }
nyatla 37:fc4b4fd6a649 613 break;
nyatla 37:fc4b4fd6a649 614 case NyLPC_TDnsQuestion_QTYPR_TXT:
nyatla 37:fc4b4fd6a649 615 //自分宛?(proto.local)
nyatla 37:fc4b4fd6a649 616 ptr_recode=NyLPC_TDnsRecord_getMatchSrvIdx(i_inst->_ref_record,q->qname);
nyatla 37:fc4b4fd6a649 617 if(ptr_recode<0){
nyatla 37:fc4b4fd6a649 618 goto DROP;
nyatla 37:fc4b4fd6a649 619 }
nyatla 37:fc4b4fd6a649 620 //Bufferの取得
nyatla 37:fc4b4fd6a649 621 obuf=NyLPC_cUdpSocket_allocSendBuf(&(i_inst->_super),512,&obuflen,0);
nyatla 37:fc4b4fd6a649 622 l=setResponseHeader(obuf,i_dns_header,1,0,1);
nyatla 37:fc4b4fd6a649 623 s=writeTXTRecord(i_inst,ptr_recode,obuf+l,obuflen-l,&cache);
nyatla 37:fc4b4fd6a649 624 if(s<=0){
nyatla 37:fc4b4fd6a649 625 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 626 }
nyatla 37:fc4b4fd6a649 627 l+=s;
nyatla 37:fc4b4fd6a649 628 s=writeARecord(obuf+l,obuflen-l,i_inst->_ref_record->a,&(i_inst->_super.uip_udp_conn.lipaddr));
nyatla 37:fc4b4fd6a649 629 if(s<=0){
nyatla 37:fc4b4fd6a649 630 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 631 }
nyatla 37:fc4b4fd6a649 632 l+=s;
nyatla 37:fc4b4fd6a649 633 break;
nyatla 37:fc4b4fd6a649 634 default:
nyatla 37:fc4b4fd6a649 635 goto DROP;
nyatla 37:fc4b4fd6a649 636 }
nyatla 37:fc4b4fd6a649 637 if(!NyLPC_cUdpSocket_psend(&(i_inst->_super),&MDNS_MCAST_IPADDR,MDNS_MCAST_PORT,obuf,l)){
nyatla 37:fc4b4fd6a649 638 NyLPC_OnErrorGoto(ERROR);
nyatla 37:fc4b4fd6a649 639 }
nyatla 37:fc4b4fd6a649 640 return;
nyatla 37:fc4b4fd6a649 641 ERROR:
nyatla 37:fc4b4fd6a649 642 NyLPC_cUdpSocket_releaseSendBuf(&(i_inst->_super),obuf);
nyatla 37:fc4b4fd6a649 643 DROP:
nyatla 37:fc4b4fd6a649 644 return;
nyatla 37:fc4b4fd6a649 645 }
nyatla 37:fc4b4fd6a649 646 #define CTRL_FLAG_INIT 0x00
nyatla 37:fc4b4fd6a649 647 #define CTRL_FLAG_STARTED 0x80
nyatla 37:fc4b4fd6a649 648 #define CTRL_FLAG_STOP_REQUESTED 0x40
nyatla 37:fc4b4fd6a649 649 #define CTRL_FLAG_PROCESS_PACKET 0x20 //パケット処理中の間1
nyatla 37:fc4b4fd6a649 650
nyatla 37:fc4b4fd6a649 651 static NyLPC_TBool onPacket(NyLPC_TcUdpSocket_t* i_inst,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info)
nyatla 37:fc4b4fd6a649 652 {
nyatla 37:fc4b4fd6a649 653 NyLPC_TUInt16 in_len=i_info->size;
nyatla 37:fc4b4fd6a649 654 NyLPC_TUInt16 num_of_query;
nyatla 37:fc4b4fd6a649 655 const char* qptr;
nyatla 37:fc4b4fd6a649 656 struct NyLPC_TDnsQuestion q;
nyatla 37:fc4b4fd6a649 657 NyLPC_TUInt16 s;
nyatla 37:fc4b4fd6a649 658 NyLPC_TInt16 i;
nyatla 37:fc4b4fd6a649 659
nyatla 37:fc4b4fd6a649 660 if(i_info->peer_port!=MDNS_MCAST_PORT || !NyLPC_TIPv4Addr_isEqual(&MDNS_MCAST_IPADDR,&i_info->ip)){
nyatla 37:fc4b4fd6a649 661 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 662 }
nyatla 37:fc4b4fd6a649 663
nyatla 37:fc4b4fd6a649 664 num_of_query=getNumberOfQuestion(i_buf,in_len);
nyatla 37:fc4b4fd6a649 665 if(num_of_query==0){
nyatla 37:fc4b4fd6a649 666 goto DROP;
nyatla 37:fc4b4fd6a649 667 }
nyatla 37:fc4b4fd6a649 668 qptr=(const char*)i_buf+sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 669 in_len-=sizeof(struct NyLPC_TDnsHeader);
nyatla 37:fc4b4fd6a649 670 for(i=0;i<num_of_query;i++){
nyatla 37:fc4b4fd6a649 671 //Queryのパース
nyatla 37:fc4b4fd6a649 672 s=NyLPC_TDnsQuestion_parse(qptr,in_len,&q);
nyatla 37:fc4b4fd6a649 673 if(s==0){
nyatla 37:fc4b4fd6a649 674 goto DROP;
nyatla 37:fc4b4fd6a649 675 }
nyatla 37:fc4b4fd6a649 676 qptr+=s;
nyatla 37:fc4b4fd6a649 677 in_len-=s;
nyatla 37:fc4b4fd6a649 678 sendReply2((NyLPC_TcMDnsServer_t*)i_inst,(const struct NyLPC_TDnsHeader*)i_buf,&q);
nyatla 37:fc4b4fd6a649 679 }
nyatla 37:fc4b4fd6a649 680 //パケット処理終了
nyatla 37:fc4b4fd6a649 681 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 682 DROP:
nyatla 37:fc4b4fd6a649 683 return NyLPC_TBool_FALSE;
nyatla 37:fc4b4fd6a649 684 }
nyatla 37:fc4b4fd6a649 685
nyatla 37:fc4b4fd6a649 686 static void onPeriodic(NyLPC_TcUdpSocket_t* i_inst)
nyatla 37:fc4b4fd6a649 687 {
nyatla 37:fc4b4fd6a649 688
nyatla 37:fc4b4fd6a649 689 if(NyLPC_cStopwatch_isExpired(&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw)){
nyatla 37:fc4b4fd6a649 690 //アナウンス
nyatla 37:fc4b4fd6a649 691 sendAnnounse(((NyLPC_TcMDnsServer_t*)i_inst));
nyatla 37:fc4b4fd6a649 692 //TTL(msec)*1000*80%
nyatla 96:e6a0db86988e 693 NyLPC_cStopwatch_startExpire((&((NyLPC_TcMDnsServer_t*)i_inst)->_periodic_sw),NyLPC_TcMDns_TTL*1000/2);
nyatla 37:fc4b4fd6a649 694 }
nyatla 37:fc4b4fd6a649 695 }
nyatla 37:fc4b4fd6a649 696
nyatla 37:fc4b4fd6a649 697 NyLPC_TBool NyLPC_cMDnsServer_initialize(
nyatla 48:00d211aac2ec 698 NyLPC_TcMDnsServer_t* i_inst,const struct NyLPC_TDnsRecord* i_ref_record)
nyatla 37:fc4b4fd6a649 699 {
nyatla 37:fc4b4fd6a649 700 NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));
nyatla 37:fc4b4fd6a649 701 NyLPC_cStopwatch_startExpire(&(i_inst->_periodic_sw),1000);
nyatla 37:fc4b4fd6a649 702 NyLPC_cUdpSocket_initialize(&(i_inst->_super),MDNS_MCAST_PORT,NULL,0);
nyatla 37:fc4b4fd6a649 703 NyLPC_cUdpSocket_setOnRxHandler(&(i_inst->_super),onPacket);
nyatla 48:00d211aac2ec 704 NyLPC_cUdpSocket_setOnPeriodicHandler(&(i_inst->_super),onPeriodic);
nyatla 37:fc4b4fd6a649 705 NyLPC_cUdpSocket_joinMulticast(&(i_inst->_super),&MDNS_MCAST_IPADDR);
nyatla 37:fc4b4fd6a649 706 i_inst->_ref_record=i_ref_record;
nyatla 37:fc4b4fd6a649 707 return NyLPC_TBool_TRUE;
nyatla 37:fc4b4fd6a649 708 }
nyatla 37:fc4b4fd6a649 709 void NyLPC_cMDnsServer_finalize(
nyatla 37:fc4b4fd6a649 710 NyLPC_TcMDnsServer_t* i_inst)
nyatla 37:fc4b4fd6a649 711 {
nyatla 37:fc4b4fd6a649 712 NyLPC_cUdpSocket_finalize(&(i_inst->_super));
nyatla 37:fc4b4fd6a649 713 NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw));
nyatla 37:fc4b4fd6a649 714 }
nyatla 37:fc4b4fd6a649 715
nyatla 37:fc4b4fd6a649 716
nyatla 37:fc4b4fd6a649 717