Skip to content

Commit

Permalink
[UDP] replace UDP offsets by struct UdpHeader
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnaud authored and Arnaud committed Feb 11, 2019
1 parent b6c47e1 commit ae8fa71
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 170 deletions.
27 changes: 16 additions & 11 deletions examples/SSDP/SSDP.ino
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <EtherCard.h>// |Mac adress|
#include <EtherUtil.h>
const char SSDP_RESPONSE[] PROGMEM = "HTTP/1.1 200 OK\r\nCACHE-CONTROL: max-age=1200\r\nEXT:\r\nSERVER:Arduino\r\nST: upnp:rootdevice\r\nUSN: uuid:abcdefgh-7dec-11d0-a765-7499692d3040\r\nLOCATION: http://"; //dont forget our mac adress USN: uuid:abcdefgh-7dec-11d0-a765-Mac addr
const char SSDP_RESPONSE_XML[] PROGMEM = "/??\r\n\r\n"; // here is the adress of xml file /?? in this exemple but you could use another /upnp.xml\r\n\r\n
const char XML_DESCRIP[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\n\r\n<?xml version='1.0'?>\r<root xmlns='urn:schemas-upnp-org:device-1-0'><device><deviceType>urn:schemas-upnp-org:device:BinaryLight:1</deviceType><presentationURL>/</presentationURL><friendlyName>Arduino</friendlyName><manufacturer>Fredycpu</manufacturer><manufacturerURL>http://fredycpu.pro</manufacturerURL><serialNumber>1</serialNumber><UDN>uuid:abcdefgh-7dec-11d0-a765-7499692d3040</UDN></device></root> ";
Expand Down Expand Up @@ -48,6 +49,10 @@ const char pageD[] PROGMEM =
"</em></p>"
;

void ssdpresp();
void addip(uint8_t *udppos);
void ssdpnotify();

void setup(){
// Change 'SS' to your Slave Select pin, if you arn't using the default pin
ether.begin(sizeof Ethernet::buffer, mymac, SS);
Expand Down Expand Up @@ -96,46 +101,46 @@ void ssdpresp() { //response to m-search
for( int i=0; i<IP_LEN;i++) { //extract source IP of request
ip_dst[i]=Ethernet::buffer[i+26];
}
int udppos = UDP_DATA_P;
uint8_t *udppos = udp_payload();

EtherCard::udpPrepare(1900,ip_dst,port_dst);
memcpy_P(Ethernet::buffer + udppos, SSDP_RESPONSE, sizeof SSDP_RESPONSE);
memcpy_P(udppos, SSDP_RESPONSE, sizeof SSDP_RESPONSE);
udppos = udppos + sizeof SSDP_RESPONSE-1;
addip(udppos);
}

void ssdpnotify() { //Notification
int udppos = UDP_DATA_P;
int udppos = udp_payload();
EtherCard::udpPrepare(1900,ssdp,1900);
memcpy_P(Ethernet::buffer + udppos, SSDP_NOTIFY, sizeof SSDP_NOTIFY);
memcpy_P(udppos, SSDP_NOTIFY, sizeof SSDP_NOTIFY);
udppos = udppos + sizeof SSDP_NOTIFY-1;
addip(udppos);
}

void addip(int udppos) { // add current ip to the request and send it
void addip(uint8_t *udppos) { // add current ip to the request and send it
int adr;
for(int i=0;i<IP_LEN;i++) { // extract the current ip of arduino
adr = ether.myip[i]/100;
if (adr) {
Ethernet::buffer[udppos]=adr+48;
*udppos=adr+48;
udppos++;
}
adr=(ether.myip[i]%100)/10;
if (adr||(ether.myip[i]/100)) {
Ethernet::buffer[udppos]=adr+48;
*udppos=adr+48;
udppos++;
}
adr=ether.myip[i]%10;
Ethernet::buffer[udppos]=adr+48;
*udppos=adr+48;
udppos++;
Ethernet::buffer[udppos]=46;
*udppos=46;
udppos++; //"."
}
udppos--;//erase the last point
memcpy_P(Ethernet::buffer + udppos,SSDP_RESPONSE_XML,sizeof SSDP_RESPONSE_XML);
memcpy_P(udppos,SSDP_RESPONSE_XML,sizeof SSDP_RESPONSE_XML);
udppos = udppos + sizeof SSDP_RESPONSE_XML;
udppos--;
EtherCard::udpTransmit(udppos-UDP_DATA_P); // send all to the computer who make the request on her ip and port who make the request
EtherCard::udpTransmit(udppos-udp_payload()); // send all to the computer who make the request on her ip and port who make the request
}


53 changes: 53 additions & 0 deletions src/EtherUtil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Shortcuts to different protocols headers/payload
// Hence: GPL V2

#ifndef ETHERUTIL_H
#define ETHERUTIL_H

#include "enc28j60.h"
#include "net.h"

#define gPB ether.buffer

inline EthHeader &ethernet_header()
{
uint8_t *iter = gPB; // avoid strict aliasing warning
return *(EthHeader *)iter;
}

inline uint8_t *ethernet_payload()
{
return (uint8_t *)&ethernet_header() + sizeof(EthHeader);
}

inline ArpHeader &arp_header()
{
return *(ArpHeader *)ethernet_payload();
}

inline IpHeader &ip_header()
{
return *(IpHeader *)ethernet_payload();
}

inline uint8_t *ip_payload()
{
return (uint8_t *)&ip_header() + sizeof(IpHeader);
}

inline uint8_t *tcp_header()
{
return (uint8_t *)ip_payload();
}

inline UdpHeader &udp_header()
{
return *(UdpHeader *)ip_payload();
}

inline uint8_t *udp_payload()
{
return (uint8_t *)&udp_header() + sizeof(UdpHeader);
}

#endif /* ETHERUTIL_H */
35 changes: 17 additions & 18 deletions src/dhcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
//#define DHCPDEBUG

#include "EtherCard.h"
#include "EtherUtil.h"
#include "net.h"

#define gPB ether.buffer

#define DHCP_BOOTREQUEST 1
#define DHCP_BOOTRESPONSE 2

Expand Down Expand Up @@ -83,6 +82,7 @@ typedef struct {
uint16_t secs, flags;
byte ciaddr[IP_LEN], yiaddr[IP_LEN], siaddr[IP_LEN], giaddr[IP_LEN];
byte chaddr[16], sname[64], file[128];
uint32_t magicCookie;
// options
} DHCPdata;

Expand Down Expand Up @@ -162,8 +162,6 @@ static void addOption (byte opt, byte len, const byte* data) {

static void send_dhcp_message(uint8_t *requestip) {

memset(gPB, 0, UDP_DATA_P + sizeof( DHCPdata ));

EtherCard::udpPrepare(DHCP_CLIENT_PORT,
(dhcpState == DHCP_STATE_BOUND ? EtherCard::dhcpip : allOnes),
DHCP_SERVER_PORT);
Expand All @@ -174,7 +172,8 @@ static void send_dhcp_message(uint8_t *requestip) {
EtherCard::copyMac(gPB + ETH_DST_MAC, allOnes); //force broadcast mac

// Build DHCP Packet from buf[UDP_DATA_P]
DHCPdata *dhcpPtr = (DHCPdata*) (gPB + UDP_DATA_P);
DHCPdata *dhcpPtr = (DHCPdata*) (udp_payload());
memset(dhcpPtr, 0, sizeof(DHCPdata));
dhcpPtr->op = DHCP_BOOTREQUEST;
dhcpPtr->htype = 1;
dhcpPtr->hlen = 6;
Expand All @@ -184,12 +183,12 @@ static void send_dhcp_message(uint8_t *requestip) {
}
EtherCard::copyMac(dhcpPtr->chaddr, EtherCard::mymac);

// options defined as option, length, value
bufPtr = gPB + UDP_DATA_P + sizeof( DHCPdata );
// DHCP magic cookie
static const byte cookie[] PROGMEM = { 0x63,0x82,0x53,0x63 };
for (byte i = 0; i < sizeof(cookie); i++)
addToBuf(pgm_read_byte(&cookie[i]));
dhcpPtr->magicCookie = HTONL(0x63825363);

// options defined as option, length, value
bufPtr = (uint8_t *)dhcpPtr + sizeof( DHCPdata );

addToBuf(DHCP_OPT_MESSAGE_TYPE); // DHCP_STATE_SELECTING, DHCP_STATE_REQUESTING
addToBuf(1); // Length
addToBuf(dhcpState == DHCP_STATE_INIT ? DHCP_DISCOVER : DHCP_REQUEST);
Expand Down Expand Up @@ -229,18 +228,18 @@ static void send_dhcp_message(uint8_t *requestip) {
addToBuf(DHCP_OPT_END);

// packet size will be under 300 bytes
EtherCard::udpTransmit((bufPtr - gPB) - UDP_DATA_P);
EtherCard::udpTransmit(bufPtr - (uint8_t *)dhcpPtr);
}

static void process_dhcp_offer(uint16_t len, uint8_t *offeredip) {
// Map struct onto payload
DHCPdata *dhcpPtr = (DHCPdata*) (gPB + UDP_DATA_P);
DHCPdata *dhcpPtr = (DHCPdata*) (udp_payload());

// Offered IP address is in yiaddr
EtherCard::copyIp(offeredip, dhcpPtr->yiaddr);

// Search for the server IP
byte *ptr = (byte*) (dhcpPtr + 1) + 4;
byte *ptr = (byte*) (dhcpPtr + 1);
do {
byte option = *ptr++;
byte optionLen = *ptr++;
Expand All @@ -254,13 +253,13 @@ static void process_dhcp_offer(uint16_t len, uint8_t *offeredip) {

static void process_dhcp_ack(uint16_t len) {
// Map struct onto payload
DHCPdata *dhcpPtr = (DHCPdata*) (gPB + UDP_DATA_P);
DHCPdata *dhcpPtr = (DHCPdata*) (udp_payload());

// Allocated IP address is in yiaddr
EtherCard::copyIp(EtherCard::myip, dhcpPtr->yiaddr);

// Scan through variable length option list identifying options we want
byte *ptr = (byte*) (dhcpPtr + 1) + 4;
byte *ptr = (byte*) (dhcpPtr + 1);
bool done = false;
do {
byte option = *ptr++;
Expand Down Expand Up @@ -308,12 +307,12 @@ while (!done && ptr < gPB + len);

static bool dhcp_received_message_type (uint16_t len, byte msgType) {
// Map struct onto payload
DHCPdata *dhcpPtr = (DHCPdata*) (gPB + UDP_DATA_P);
DHCPdata *dhcpPtr = (DHCPdata*) (udp_payload());

if (len >= 70 && gPB[UDP_SRC_PORT_L_P] == DHCP_SERVER_PORT &&
if (len >= 70 && udp_header().sport == HTONS(DHCP_SERVER_PORT) &&
dhcpPtr->xid == currentXid ) {

byte *ptr = (byte*) (dhcpPtr + 1) + 4;
byte *ptr = (byte*) (dhcpPtr + 1);
do {
byte option = *ptr++;
byte optionLen = *ptr++;
Expand Down
27 changes: 14 additions & 13 deletions src/dns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
// 2010-05-20 <[email protected]>

#include "EtherCard.h"
#include "EtherUtil.h"
#include "net.h"

#define gPB ether.buffer

static byte dnstid_l; // a counter for transaction ID
#define DNSCLIENT_SRC_PORT_H 0xE0

Expand All @@ -20,9 +19,11 @@ static void dnsRequest (const char *hostname, bool fromRam) {
if (ether.dnsip[0] == 0)
memset(ether.dnsip, 8, IP_LEN); // use 8.8.8.8 Google DNS as default
ether.udpPrepare((DNSCLIENT_SRC_PORT_H << 8) | dnstid_l, ether.dnsip, DNS_PORT);
memset(gPB + UDP_DATA_P, 0, 12);
uint8_t *udpp = udp_payload();
byte *p = udpp;
memset(p, 0, 12);

byte *p = gPB + UDP_DATA_P + 12;
p += 12;
char c;
do {
byte n = 0;
Expand All @@ -42,11 +43,11 @@ static void dnsRequest (const char *hostname, bool fromRam) {
*p++ = DNS_TYPE_A;
*p++ = 0;
*p++ = DNS_CLASS_IN;
byte i = p - gPB - UDP_DATA_P;
gPB[UDP_DATA_P] = i;
gPB[UDP_DATA_P+1] = dnstid_l;
gPB[UDP_DATA_P+2] = 1; // flags, standard recursive query
gPB[UDP_DATA_P+5] = 1; // 1 question
byte i = p - udpp;
udpp[0] = i;
udpp[1] = dnstid_l;
udpp[2] = 1; // flags, standard recursive query
udpp[5] = 1; // 1 question
ether.udpTransmit(i);
}

Expand All @@ -56,10 +57,10 @@ static void dnsRequest (const char *hostname, bool fromRam) {
@note hisip contains IP address of requested host or 0.0.0.0 on failure
*/
static bool checkForDnsAnswer (uint16_t plen) {
byte *p = gPB + UDP_DATA_P; //start of UDP payload
if (plen < 70 || gPB[UDP_SRC_PORT_L_P] != DNS_PORT || //from DNS source port
gPB[UDP_DST_PORT_H_P] != DNSCLIENT_SRC_PORT_H || //response to same port as we sent from (MSB)
gPB[UDP_DST_PORT_L_P] != dnstid_l || //response to same port as we sent from (LSB)
UdpHeader &udph = udp_header();
byte *p = udp_payload(); //start of UDP payload
if (plen < 70 || udph.sport != HTONS(DNS_PORT) || //from DNS source port
ntohs(udph.dport) != (uint16_t)(DNSCLIENT_SRC_PORT_H << 8 | dnstid_l) || //response to same port as we sent from
p[1] != dnstid_l) //message id same as we sent
return false; //not our DNS response
if((p[3] & 0x0F) != 0)
Expand Down
25 changes: 13 additions & 12 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
# error __BYTE_ORDER__ not defined! PLease define it for your platform
#endif

inline void htons(uint16_t &d, const uint16_t v)
{
((uint8_t *)(&d))[0] = v >> 8;
((uint8_t *)(&d))[1] = v & 0xFF;
}

inline uint16_t htons(const uint16_t v)
{ return HTONS(v); }

Expand Down Expand Up @@ -193,18 +199,13 @@ struct ArpHeader
#define ICMP_DATA_P 0x2a

// ******* UDP *******
#define UDP_HEADER_LEN 8
//
#define UDP_SRC_PORT_H_P 0x22
#define UDP_SRC_PORT_L_P 0x23
#define UDP_DST_PORT_H_P 0x24
#define UDP_DST_PORT_L_P 0x25
//
#define UDP_LEN_H_P 0x26
#define UDP_LEN_L_P 0x27
#define UDP_CHECKSUM_H_P 0x28
#define UDP_CHECKSUM_L_P 0x29
#define UDP_DATA_P 0x2a
struct UdpHeader
{
uint16_t sport;
uint16_t dport;
uint16_t length;
uint16_t checksum;
};

// ******* TCP *******
#define TCP_SRC_PORT_H_P 0x22
Expand Down
Loading

0 comments on commit ae8fa71

Please sign in to comment.