int simple_client(eAdrGD* fADRGD,uint8_t* fSostEth,uint8_t* nBlock, uint8_t* fIPAddr,uint8_t* fMACAddr,uint8_t* fPORTNUMBER) { SPI1_Init(); pADRGD=fADRGD; EthSost=fSostEth; EthBlock=nBlock; PORTNUMBER=fPORTNUMBER; MACAddr=fMACAddr; IPAddr=fIPAddr; enc28j60Init(MACAddr); enc28j60PhyWrite(PHLCON,0x476); init_ip_arp_udp_tcp(MACAddr,fIPAddr,*PORTNUMBER); //dat_p=packetloop_arp_icmp_tcp(buf,enc28j60PacketReceive(BUFFER_SIZE, buf)); buf[UDP_DATA_P]='H'; buf[UDP_DATA_P+1]='E'; buf[UDP_DATA_P+2]='L'; buf[UDP_DATA_P+3]='L'; buf[UDP_DATA_P+4]='O'; buf[UDP_DATA_P+5]=' '; buf[UDP_DATA_P+6]='W'; buf[UDP_DATA_P+7]='O'; buf[UDP_DATA_P+8]='R'; buf[UDP_DATA_P+9]='L'; buf[UDP_DATA_P+10]='D'; //Sockets[0].IP_PHASE=0; //make_tcp_ack_from_any(fbuf); // send ack for http get //make_tcp_ack_with_data(fbuf,plen,0); // send data send_udp_prepare(buf,5001,dis_ip,5001,dis_mac); send_udp_transmit(buf,11); }
// the answer to this message will come as a broadcast uint8_t send_dhcp_request(uint8_t *buf,const uint8_t transactionID) { uint8_t i=0; make_dhcp_message_template(buf,transactionID); // option dhcp message type: buf[UDP_DATA_P+DHCP_OPTION_OFFSET]=0x35; // 53 buf[UDP_DATA_P+DHCP_OPTION_OFFSET+1]=1; //len buf[UDP_DATA_P+DHCP_OPTION_OFFSET+2]=DHCP_REQUEST_V; i=3; if (dhcp_opt_server_id[0]!=0){ buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i]=0x36; // 54=server identifier buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i+1]=4; // len memcpy(buf+UDP_DATA_P+DHCP_OPTION_OFFSET+i+2,dhcp_opt_server_id, 4); i=i+6; } if (dhcp_yiaddr[0]!=0){ buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i]=0x32; // 50=requested IP address buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i+1]=4; // len memcpy(buf+UDP_DATA_P+DHCP_OPTION_OFFSET+i+2,dhcp_yiaddr, 4); i=i+6; } // option paramter request list: buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i]=0x37; // 55 // we want: subnet mask, router buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i+1]=2; // len buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i+2]=1; // subnet mask buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i+3]=3; // router=default GW buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i+4]=0xff; // end of options buf[UDP_DATA_P+DHCP_OPTION_OFFSET+i+5]=0; // the length of the udp message part is now DHCP_OPTION_OFFSET+i+5 send_udp_transmit(buf,DHCP_OPTION_OFFSET+i+5); return(0); }
void dnslkup_request(byte *buf,const prog_char *progmem_hostname) { byte i,lenpos,lencnt; char c; haveDNSanswer=0; dns_ansError=0; dnstid_l++; // increment for next request, finally wrap send_udp_prepare(buf,(DNSCLIENT_SRC_PORT_H<<8)|(dnstid_l&0xff),dnsip,53); buf[UDP_DATA_P+1]=dnstid_l; buf[UDP_DATA_P+2]=1; // flags, standard recursive query i=3; while(i<10) buf[UDP_DATA_P+i++]=0; buf[UDP_DATA_P+5]=1; // 1 question lenpos=12; i=13; lencnt=0; while ((c = pgm_read_byte(progmem_hostname++))) { if (c=='.'){ buf[UDP_DATA_P+lenpos]=lencnt; lencnt=0; lenpos=i; } buf[UDP_DATA_P+i]=c; lencnt++; i++; } buf[UDP_DATA_P+lenpos]=lencnt-1; buf[UDP_DATA_P+i++]=0; // terminate with zero, means root domain. buf[UDP_DATA_P+i++]=0; buf[UDP_DATA_P+i++]=1; // type A buf[UDP_DATA_P+i++]=0; buf[UDP_DATA_P+i++]=1; // class IN buf[UDP_DATA_P]=i-12; send_udp_transmit(buf,i); }
// send a DNS udp request packet // See http://www.ietf.org/rfc/rfc1034.txt // and http://www.ietf.org/rfc/rfc1035.txt // //void dnslkup_request(uint8_t *buf,const prog_char *progmem_hostname) void dnslkup_request(uint8_t *buf, uint8_t *hostname) { uint8_t i,lenpos,lencnt; char c; haveDNSanswer=0; dns_ansError=0; dnstid_l++; // increment for next request, finally wrap send_udp_prepare(buf,(DNSCLIENT_SRC_PORT_H<<8)|(dnstid_l&0xff),dnsip,53); // fill tid: //buf[UDP_DATA_P] see below buf[UDP_DATA_P+1]=dnstid_l; buf[UDP_DATA_P+2]=1; // flags, standard recursive query i=3; // most fields are zero, here we zero everything and fill later while(i<10){ buf[UDP_DATA_P+i]=0; i++; } buf[UDP_DATA_P+5]=1; // 1 question // the structure of the domain name // we ask for is always length, string, length, string, ... // for earch portion of the name. // www.twitter.com would become: 3www7twitter3com // // the first len starts at i=12 lenpos=12; i=13; lencnt=1; // while ((c = pgm_read_byte(progmem_hostname++))) { while ((c = *hostname++)) { if (c=='.'){ buf[UDP_DATA_P+lenpos]=lencnt-1; lencnt=0; lenpos=i; } buf[UDP_DATA_P+i]=c; lencnt++; i++; } buf[UDP_DATA_P+lenpos]=lencnt-1; buf[UDP_DATA_P+i]=0; // terminate with zero, means root domain. i++; buf[UDP_DATA_P+i]=0; i++; buf[UDP_DATA_P+i]=1; // type A i++; buf[UDP_DATA_P+i]=0; i++; buf[UDP_DATA_P+i]=1; // class IN i++; // we encode the length into the upper byte of the TID // this way we can easily jump over the query section // of the answer: buf[UDP_DATA_P]=i-12; send_udp_transmit(buf,i); }
// The renew procedure is described in rfc2131. // We send DHCPREQUEST and 'server identifier' MUST NOT be filled // in, 'requested IP address' option MUST NOT be filled in, 'ciaddr' // MUST be filled. // The rfc suggest that I can send the DHCPREQUEST in this case as // a unicast message and not as a broadcast message but test with // various DHCP servers show that not all of them listen to // unicast. We send therefor a broadcast message but we expect // a unicast answer directly to our mac and IP. uint8_t send_dhcp_renew_request(uint8_t *buf,const uint8_t transactionID,uint8_t *yiaddr) { make_dhcp_message_template(buf,transactionID); buf[UDP_DATA_P+4]=2; // set first byte in transaction ID to 2 to indicate renew_request. This trick makes the processing of the DHCPACK message easier. // source IP must be my IP since we renew memcpy(buf+IP_SRC_P, yiaddr, 4); // ip level source IP // memcpy(buf+UDP_DATA_P+12,yiaddr, 4); // ciaddr // option dhcp message type: buf[UDP_DATA_P+DHCP_OPTION_OFFSET]=0x35; // 53 buf[UDP_DATA_P+DHCP_OPTION_OFFSET+1]=1; //len buf[UDP_DATA_P+DHCP_OPTION_OFFSET+2]=DHCP_REQUEST_V; // no option paramter request list is needed at renew send_udp_transmit(buf,DHCP_OPTION_OFFSET+3); // we will get a unicast answer, reception of broadcast packets is turned off return(0); }
// the answer to this message will come as a broadcast uint8_t send_dhcp_discover(uint8_t *buf,const uint8_t transactionID) { make_dhcp_message_template(buf,transactionID); // option dhcp message type: buf[UDP_DATA_P+DHCP_OPTION_OFFSET]=0x35; // 53 buf[UDP_DATA_P+DHCP_OPTION_OFFSET+1]=1; //len buf[UDP_DATA_P+DHCP_OPTION_OFFSET+2]=DHCP_DISCOVER_V; // option paramter request list: buf[UDP_DATA_P+DHCP_OPTION_OFFSET+3]=0x37; // 55 // we want: subnet mask, router buf[UDP_DATA_P+DHCP_OPTION_OFFSET+4]=2; // len buf[UDP_DATA_P+DHCP_OPTION_OFFSET+5]=1; // subnet mask buf[UDP_DATA_P+DHCP_OPTION_OFFSET+6]=3; // router=default GW buf[UDP_DATA_P+DHCP_OPTION_OFFSET+7]=0xff; // end of options buf[UDP_DATA_P+DHCP_OPTION_OFFSET+8]=0; // no padding // the length of the udp message part is now DHCP_OPTION_OFFSET+8 send_udp_transmit(buf,DHCP_OPTION_OFFSET+8); return(0); }
/* UDP message length calculation */ xt = ((buf[UDP_LEN_H_P]<<8)+buf[UDP_LEN_L_P])-8; #if 1 if(coap_parse(&pkt,buf+UDP_DATA_P,xt) != 0) { dbg(PSTR("\r\n> Bad coap packet\r\n")); } else { coap_handle_req(&scratch_buf, &pkt, &rsppkt); xt = sizeof(response); coap_build(response, &xt, &rsppkt); make_udp_reply_from_request(buf,response,xt,COAPPORT); } #endif } clear_flag(new_packet,coap_server_flag); } PT_END(pt); }/*---------------------------------------------------------------------------*/ static PT_THREAD(udp_broadcast_thread(struct pt *pt)) { PT_BEGIN(pt); while(1) { /* TODO: Add debouncing ... */ PT_WAIT_UNTIL(pt,btn1_pressed()); PT_WAIT_UNTIL(pt,!btn1_pressed()); send_udp_prepare(buf,broadcastport,broadcastip,broadcastport,broadcastmac); buf[UDP_DATA_P+0] = 'h'; buf[UDP_DATA_P+1] = 'e'; buf[UDP_DATA_P+2] = 'l'; buf[UDP_DATA_P+3] = 'l'; buf[UDP_DATA_P+4] = 'o'; send_udp_transmit(buf,5); } PT_END(pt); }
// send a DNS udp request packet // See http://www.ietf.org/rfc/rfc1034.txt // and http://www.ietf.org/rfc/rfc1035.txt // gwmac is the internal mac addess of your router // because we use 8.8.8.8 as a DNS server uint8_t dnslkup_request(uint8_t *buf,const char *hostname,const uint8_t *gwmac) { uint8_t i,lenpos,lencnt; haveDNSanswer=0; if(!enc28j60linkup()){ dns_ansError=4; // could not send request, link down return(1); } dns_ansError=0; dnstid_l++; // increment for next request, finally wrap send_udp_prepare(buf,(DNSCLIENT_SRC_PORT_H<<8)|(dnstid_l&0xff),dnsip,53,gwmac); // fill tid: //buf[UDP_DATA_P] see below buf[UDP_DATA_P+1]=dnstid_l; buf[UDP_DATA_P+2]=1; // flags, standard recursive query i=3; // most fields are zero, here we zero everything and fill later while(i<12){ buf[UDP_DATA_P+i]=0; i++; } buf[UDP_DATA_P+5]=1; // 1 question // the structure of the domain name // we ask for is always length, string, length, string, ... // for earch portion of the name. // www.twitter.com would become: 3www7twitter3com // // the first len starts at i=12 lenpos=12; i=13; lencnt=1; // need to start with one as there is no dot before the domain name and the below algorithm assumes lencnt=0 at dot while(*hostname){ if (*hostname=='\0') break; if (*hostname=='.'){ buf[UDP_DATA_P+lenpos]=lencnt-1; // fill the length field lencnt=0; lenpos=i; } buf[UDP_DATA_P+i]=*hostname; lencnt++; i++; hostname++; } buf[UDP_DATA_P+lenpos]=lencnt-1; buf[UDP_DATA_P+i]=0; // terminate with zero, means root domain. i++; buf[UDP_DATA_P+i]=0; i++; buf[UDP_DATA_P+i]=1; // type A i++; buf[UDP_DATA_P+i]=0; i++; buf[UDP_DATA_P+i]=1; // class IN i++; // we encode the length into the upper byte of the TID // this way we can easily jump over the query section // of the answer: buf[UDP_DATA_P]=i-12; send_udp_transmit(buf,i); return(0); }
void EtherShield::ES_send_udp_data(uint8_t *buf,uint16_t dlen,uint16_t source_port, uint8_t *dest_ip, uint16_t dest_port) { send_udp_prepare(buf,source_port, dest_ip, dest_port); send_udp_transmit(buf,dlen); }
void EtherShield::ES_send_udp_data(uint8_t *buf, uint8_t *destmac,uint16_t dlen,uint16_t source_port, uint8_t *dest_ip, uint16_t dest_port) { send_udp_prepare(buf,source_port, dest_ip, dest_port); for(uint8_t i = 0; i< 6; i++ ) buf[ETH_DST_MAC+i] = destmac[i]; send_udp_transmit(buf,dlen); }