COSA
An Object-Oriented Platform for Arduino Programming
INET.cpp
Go to the documentation of this file.
1 
21 #include "Cosa/INET.hh"
22 #include <ctype.h>
23 
24 bool
25 INET::is_illegal(uint8_t addr[4], uint16_t port)
26 {
27  return
28  (((addr[0] == 0xff)
29  && (addr[1] == 0xff)
30  && (addr[2] == 0xff)
31  && (addr[3] == 0xff))
32  ||
33  ((addr[0] == 0x00)
34  && (addr[1] == 0x00)
35  && (addr[2] == 0x00)
36  && (addr[3] == 0x00))
37  ||
38  (port == 0x0000));
39 }
40 
41 int
42 INET::aton(const char* addr, uint8_t ip[4], bool progmem)
43 {
44  const char* ap = addr;
45  char c;
46  for (uint8_t i = 0; i < IP_MAX; i++) {
47  uint16_t r = 0;
48  while (isdigit(c = (progmem ? pgm_read_byte(ap++) : *ap++)))
49  r = (r * 10) + (c - '0');
50  if (c != 0) {
51  if (c != '.') return (EINVAL);
52  }
53  else {
54  if (i < IP_MAX - 1) return (E2BIG);
55  }
56  if (r > 255) return (EOVERFLOW);
57  ip[i] = r;
58  }
59  return (0);
60 }
61 
62 int
63 INET::nametopath(const char* hostname, char* path, bool progmem)
64 {
65  const char* hp = hostname;
66  char* sp = path;
67  char* np = path + 1;
68  uint8_t n = 0;
69  int res = 0;
70  while (res < PATH_MAX) {
71  char c = (progmem ? pgm_read_byte(hp++) : *hp++);
72  if (c == 0 || c == '.') {
73  if (UNLIKELY(n == 0)) return (EINVAL);
74  *sp = n;
75  res += n + 1;
76  sp = np++;
77  n = 0;
78  if (c == 0) {
79  *sp = 0;
80  return (res + 1);
81  };
82  }
83  else {
84  *np++ = c;
85  n++;
86  }
87  }
88  return (EINVAL);
89 }
90 
91 void
92 INET::print_path(IOStream& outs, const char* path)
93 {
94  const char* p = path;
95  uint8_t n = *p++;
96  int i = 0;
97  char c;
98  while (i < PATH_MAX) {
99  if (UNLIKELY(n == 0)) return;
100  i += n;
101  while (n--) {
102  c = *p++;
103  outs << c;
104  }
105  n = *p++;
106  if (n != 0) outs << '.';
107  }
108 }
109 
110 void
111 INET::print_mac(IOStream& outs, const uint8_t* mac)
112 {
113  outs << toHEX(mac[0] >> 4) << toHEX(mac[0]);
114  for (uint8_t i = 1; i < MAC_MAX; i++)
115  outs << ':' << toHEX(mac[i] >> 4) << toHEX(mac[i]);
116 }
117 
118 void
119 INET::print_addr(IOStream& outs, const uint8_t* addr, uint16_t port)
120 {
121  outs << addr[0];
122  for (uint8_t i = 1; i < IP_MAX; i++) outs << '.' << addr[i];
123  if (UNLIKELY(port == 0)) return;
124  outs << ':' << port;
125 }
126 
127 uint16_t
128 INET::checksum(const void* buf, size_t count)
129 {
130  // Based on the C-code given in RFC 1071 (Computing the Internet
131  // Checksum by R. Braden, D. Borman, and C. Partridge, 1988).
132  const uint16_t* bp = (const uint16_t*) buf;
133  uint32_t sum = 0L;
134 
135  // Sum up the buffer as 16-bit numbers
136  while (count > 1) {
137  sum += ntoh(*bp++);
138  count -= 2;
139  }
140 
141  // Add last byte if odd number of bytes
142  if (count > 0)
143  sum += *(const uint8_t*) bp;
144 
145  // Add carry bits
146  while (sum >> 16)
147  sum = (sum & 0xffff) + (sum >> 16);
148 
149  // And return the one-complement of the sum
150  return (~sum);
151 }
static void print_mac(IOStream &outs, const uint8_t mac[MAC_MAX])
Definition: INET.cpp:111
#define EINVAL
Definition: Errno.h:49
static int aton(const char *addr, uint8_t ip[IP_MAX], bool progmem=false)
Definition: INET.cpp:42
static bool is_illegal(uint8_t addr[IP_MAX], uint16_t port)
Definition: INET.cpp:25
#define EOVERFLOW
Definition: Errno.h:102
static uint16_t checksum(const void *buf, size_t count)
Definition: INET.cpp:128
char toHEX(uint8_t value)
Definition: Types.h:606
static void print_path(IOStream &outs, const char *path)
Definition: INET.cpp:92
static const uint8_t IP_MAX
Definition: INET.hh:69
#define E2BIG
Definition: Errno.h:34
static const uint8_t MAC_MAX
Definition: INET.hh:68
static void print_addr(IOStream &outs, const uint8_t addr[IP_MAX], uint16_t port=0)
Definition: INET.cpp:119
static const uint8_t PATH_MAX
Definition: INET.hh:67
#define UNLIKELY(x)
Definition: Types.h:153
#define ntoh
Definition: Types.h:583
static int nametopath(const char *hostname, char *path, bool progmem=false)
Definition: INET.cpp:63