/*******************************************************************************Copyright (c) [scl]。保留所有权利。******************************************************************************/#ifndefF1XX_TEMPLATE_W5500_DNS_H#defineF1XX_TEMPLATE_W5500_DNS_H#include"socket.h"#defineTYPE_A1/* Host address */#defineTYPE_NS2/* Name server */#defineTYPE_MD3/* Mail destination (obsolete) */#defineTYPE_MF4/* Mail forwarder (obsolete) */#defineTYPE_CNAME5/* Canonical name */#defineTYPE_SOA6/* Start of Authority */#defineTYPE_MB7/* Mailbox name (experimental) */#defineTYPE_MG8/* Mail group member (experimental) */#defineTYPE_MR9/* Mail rename name (experimental) */#defineTYPE_NULL10/* Null (experimental) */#defineTYPE_WKS11/* Well-known sockets */#defineTYPE_PTR12/* Pointer record */#defineTYPE_HINFO13/* Host information */#defineTYPE_MINFO14/* Mailbox information (experimental)*/#defineTYPE_MX15/* Mail exchanger */#defineTYPE_TXT16/* Text strings */#defineTYPE_ANY255/* Matches any type */#defineMAX_DNS_BUF_SIZE256/* maximum size of DNS buffer. *//*** @memberof delay_ms_cb 毫秒延迟回调* @memberof dns_server_ip: dns 服务ip* @memberof dns_port: dns 端口,默认53*/structdns_conf{void(*delay_ms_cb)(uint32_t ms);uint8_t dns_server_ip[4];uint16_t dns_port;};voiddns_config_set(structdns_conf*cnf);/**** @param s socket num* @param domain_name 服务域名* @param dst_ip [out] 保存解析的数据* @param wait_ms [in] 发送请求后等待时间* @return*/
bool do_dns(SOCKET s,uint8_t*domain_name,uint8_t*dst_ip,uint32_t wait_ms);#endif//F1XX_TEMPLATE_W5500_DNS_H
源文件
/*******************************************************************************Copyright (c) [scl]。保留所有权利。******************************************************************************/#include"w5500_dns.h"#defineDBG_ENABLE#defineDBG_SECTION_NAME"dns"#defineDBG_LEVELDBG_INFO // DBG_LOG DBG_INFO DBG_WARNING DBG_ERROR#include"sys_dbg.h"/* Header for all domain messages */structdhdr{uint16_t id;/* Identification */uint8_t qr;/* Query/Response */uint8_t opcode;uint8_t aa;/* Authoratative answer */uint8_t tc;/* Truncation */uint8_t rd;/* Recursion desired */uint8_t ra;/* Recursion available */uint8_t rcode;/* Response code */uint16_t qdcount;/* Question count */uint16_t ancount;/* Answer count */uint16_t nscount;/* Authority (name server) count */uint16_t arcount;/* Additional record count */};staticuint8_t DNS_BUF[MAX_DNS_BUF_SIZE]={0};staticstructdhdr dhp ={0};/*定义一个结构体用来包含报文头信息*/staticuint16_t MSG_ID =0x1122;structdns_conf*cnf_ptr =NULL;staticintdns_packet_build(uint16_t op,uint8_t*name,uint8_t*buf,uint16_t len);static bool parse_DNS_Response(structdhdr*pdhdr,uint8_t*pbuf,uint8_t*dst_result_ip);staticuint8_t*dns_question(uint8_t*msg,uint8_t*cp);staticuint8_t*dns_answer(uint8_t*msg,uint8_t*cp,uint8_t*dst_result_ip);staticint16_tparse_name(uint8_t*msg,uint8_t*compressed,uint16_t len);voiddns_config_set(structdns_conf*cnf){cnf_ptr = cnf;}/*** dns 解析* @param s* @param domain_name 域名* @return*/
bool do_dns(SOCKET s,uint8_t*domain_name,uint8_t*dst_ip,uint32_t wait_ms){if(cnf_ptr ==NULL){LOG_E("dns_config_set not set");goto _exit_false;}if(udp_client_init(s, cnf_ptr->dns_port)){uint16_t len =dns_packet_build(0, domain_name, DNS_BUF, MAX_DNS_BUF_SIZE);sendto(s, DNS_BUF, len, cnf_ptr->dns_server_ip, cnf_ptr->dns_port);/*发送DNS请求报文给DNS服务器*/for(int i =0; i < wait_ms /2;++i){len =w5500_socket_rx_size_read(s);if(len >0)break;cnf_ptr->delay_ms_cb(2);}if(len >0){if(len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE;recvfrom_simple(s, DNS_BUF, len);if(parse_DNS_Response(&dhp, DNS_BUF, dst_ip)){close(s);/*关闭socket*/return true;/*返回DNS解析成功域名信息*/}else{LOG_W("parse_DNS_Response err");}}else{LOG_D("w5500_socket_rx_size_read not rec data");}}else{LOG_W("udp_client_init error");}_exit_false:return false;}staticintdns_packet_build(uint16_t op,uint8_t*name,uint8_t*buf,uint16_t len){uint8_t*cp = buf;uint8_t*cp1;uint8_t*dname;uint16_t p;uint16_t dlen;MSG_ID++;*(uint16_t*)&cp[0]=htons(MSG_ID);p =(op <<11)|0x0100;*(uint16_t*)&cp[2]=htons(p);*(uint16_t*)&cp[4]=htons(1);*(uint16_t*)&cp[6]=htons(0);*(uint16_t*)&cp[8]=htons(0);*(uint16_t*)&cp[10]=htons(0);cp +=sizeof(uint16_t)*6;dname = name;dlen =strlen((char*) dname);for(;;){/* Look for next dot */cp1 =(unsignedchar*)strchr((char*) dname,'.');if(cp1){/* More to come */len = cp1 - dname;}else{len = dlen;/* Last component */}*cp++= len;/* Write length of component */if(len ==0)break;strncpy((char*) cp,(char*) dname, len);/* Copy component up to (but not including) dot */cp += len;if(!cp1){*cp++=0;/* Last one; write null and finish */break;}dname += len +1;dlen -= len +1;}*(uint16_t*)&cp[0]=htons(0x0001);/* type */*(uint16_t*)&cp[2]=htons(0x0001);/* class */cp +=sizeof(uint16_t)*2;return((int)((uint32_t)(cp)-(uint32_t)(buf)));}static bool parse_DNS_Response(structdhdr*pdhdr,uint8_t*pbuf,uint8_t*dst_result_ip){uint16_t tmp =0, i =0;uint8_t*msg =NULL,*cp =NULL;msg = pbuf;memset(pdhdr,0,sizeof(structdhdr));pdhdr->id =ntohs(*((uint16_t*)&msg[0]));tmp =ntohs(*((uint16_t*)&msg[2]));if(tmp &0x8000)pdhdr->qr =1;pdhdr->opcode =(tmp >>11)&0xf;if(tmp &0x0400)pdhdr->aa =1;if(tmp &0x0200)pdhdr->tc =1;if(tmp &0x0100)pdhdr->rd =1;if(tmp &0x0080)pdhdr->ra =1;pdhdr->rcode = tmp &0xf;pdhdr->qdcount =ntohs(*((uint16_t*)&msg[4]));pdhdr->ancount =ntohs(*((uint16_t*)&msg[6]));pdhdr->nscount =ntohs(*((uint16_t*)&msg[8]));pdhdr->arcount =ntohs(*((uint16_t*)&msg[10]));/* Now parse the variable length sections */cp =&msg[12];/* Question section */for(i =0; i < pdhdr->qdcount; i++){cp =dns_question(msg, cp);}/* Answer section */for(i =0; i < pdhdr->ancount; i++){cp =dns_answer(msg, cp, dst_result_ip);}/* Name server (authority) section */for(i =0; i < pdhdr->nscount; i++){;}/* Additional section */for(i =0; i < pdhdr->arcount; i++){;}if(pdhdr->rcode ==0)return1;elsereturn0;}/**
*@brief 解析回复消息的问询记录
*@param msg - 指向回复信息的指针cp - 指向问询记录的指针
*@return 返回下一个记录指针
*/uint8_t*dns_question(uint8_t*msg,uint8_t*cp){int16_t len =parse_name(msg, cp, MAX_DNS_BUF_SIZE);if(len ==-1)return0;cp += len;cp +=2;/* type */cp +=2;/* class */return cp;}staticuint8_t*dns_answer(uint8_t*msg,uint8_t*cp,uint8_t*dst_result_ip){int16_t len, type;len =parse_name(msg, cp,/*name,*/ MAX_DNS_BUF_SIZE);if(len ==-1)return0;cp += len;type =ntohs(*((uint16_t*)&cp[0]));cp +=2;/* type */cp +=2;/* class */cp +=4;/* ttl */cp +=2;/* len */switch(type){case TYPE_A:dst_result_ip[0]=*cp++;dst_result_ip[1]=*cp++;dst_result_ip[2]=*cp++;dst_result_ip[3]=*cp++;break;case TYPE_CNAME:case TYPE_MB:case TYPE_MG:case TYPE_MR:case TYPE_NS:case TYPE_PTR:/* These types all consist of a single domain name *//* convert it to ascii format */len =parse_name(msg, cp, MAX_DNS_BUF_SIZE);if(len ==-1)return0;cp += len;break;case TYPE_HINFO:len =*cp++;cp += len;len =*cp++;cp += len;break;case TYPE_MX:cp +=2;/* Get domain name of exchanger */len =parse_name(msg, cp, MAX_DNS_BUF_SIZE);if(len ==-1)return0;cp += len;break;case TYPE_SOA:/* Get domain name of name server */len =parse_name(msg, cp, MAX_DNS_BUF_SIZE);if(len ==-1)return0;cp += len;/* Get domain name of responsible person */len =parse_name(msg, cp, MAX_DNS_BUF_SIZE);if(len ==-1)return0;cp += len;cp +=4;cp +=4;cp +=4;cp +=4;cp +=4;break;case TYPE_TXT:/* Just stash */break;default:/* Ignore */break;}return cp;}staticint16_tparse_name(uint8_t*msg,uint8_t*compressed,uint16_t len){staticint8_t name[MAX_DNS_BUF_SIZE];uint16_t slen =0;/* Length of current segment */uint8_t*cp =NULL;int16_t clen =0;/* Total length of compressed name */int16_t indirect =0;/* Set if indirection encountered */int16_t nseg =0;/* Total number of segments in name */int8_t*buf =NULL;buf = name;cp = compressed;for(;;){slen =*cp++;/* Length of this segment */if(!indirect)clen++;if((slen &0xc0)==0xc0){if(!indirect)clen++;indirect =1;/* Follow indirection */cp =&msg[((slen &0x3f)<<8)+*cp];slen =*cp++;}if(slen ==0)/* zero length == all done */break;len -= slen +1;if(len <=0)return-1;if(!indirect)clen += slen;while(slen--!=0)*buf++=(int8_t)*cp++;*buf++='.';nseg++;}if(nseg ==0)/* Root name; represent as single dot */{*buf++='.';len--;}*buf++='\0';len--;return clen;/* Length of compressed message */}
拦截Bean使用之前各个时机的Spring组件
之前使用过的BeanPostProcessor就是在Bean实例化之后,注入属性值之前的时机。 Spring Bean的生命周期本次演示的是在Bean实例化之前的时机,使用BeanFactoryPostProcessor进行验证,以及在加载Bean之前进…