libcoap  4.1.2
coap_io.c
Go to the documentation of this file.
1 /* coap_io.h -- Default network I/O functions for libcoap
2  *
3  * Copyright (C) 2012,2014 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use.
7  */
8 
9 #include "coap_config.h"
10 
11 #ifdef HAVE_STDIO_H
12 # include <stdio.h>
13 #endif
14 
15 #ifdef HAVE_SYS_SELECT_H
16 # include <sys/select.h>
17 #endif
18 #ifdef HAVE_SYS_SOCKET_H
19 # include <sys/socket.h>
20 #endif
21 #ifdef HAVE_NETINET_IN_H
22 # include <netinet/in.h>
23 #endif
24 #ifdef HAVE_SYS_UIO_H
25 # include <sys/uio.h>
26 #endif
27 #ifdef HAVE_UNISTD_H
28 # include <unistd.h>
29 #endif
30 #include <errno.h>
31 
32 #ifdef WITH_CONTIKI
33 # include "uip.h"
34 #endif
35 
36 #include "debug.h"
37 #include "mem.h"
38 #include "coap_io.h"
39 
40 #ifdef WITH_POSIX
41 /* define generic PKTINFO for IPv4 */
42 #if defined(IP_PKTINFO)
43 # define GEN_IP_PKTINFO IP_PKTINFO
44 #elif defined(IP_RECVDSTADDR)
45 # define GEN_IP_PKTINFO IP_RECVDSTADDR
46 #else
47 # error "Need IP_PKTINFO or IP_RECVDSTADDR to request ancillary data from OS."
48 #endif /* IP_PKTINFO */
49 
50 /* define generic KTINFO for IPv6 */
51 #ifdef IPV6_RECVPKTINFO
52 # define GEN_IPV6_PKTINFO IPV6_RECVPKTINFO
53 #elif defined(IPV6_PKTINFO)
54 # define GEN_IPV6_PKTINFO IPV6_PKTINFO
55 #else
56 # error "Need IPV6_PKTINFO or IPV6_RECVPKTINFO to request ancillary data from OS."
57 #endif /* IPV6_RECVPKTINFO */
58 
59 struct coap_packet_t {
64 
65  int ifindex;
66  void *session;
68  size_t length;
69  unsigned char payload[];
70 };
71 #endif
72 
73 #ifndef CUSTOM_COAP_NETWORK_ENDPOINT
74 
75 #ifdef WITH_CONTIKI
76 static int ep_initialized = 0;
77 
78 static inline struct coap_endpoint_t *
79 coap_malloc_contiki_endpoint() {
80  static struct coap_endpoint_t ep;
81 
82  if (ep_initialized) {
83  return NULL;
84  } else {
85  ep_initialized = 1;
86  return &ep;
87  }
88 }
89 
90 static inline void
91 coap_free_contiki_endpoint(struct coap_endpoint_t *ep) {
92  ep_initialized = 0;
93 }
94 
97  struct coap_endpoint_t *ep = coap_malloc_contiki_endpoint();
98 
99  if (ep) {
100  memset(ep, 0, sizeof(struct coap_endpoint_t));
101  ep->handle.conn = udp_new(NULL, 0, NULL);
102 
103  if (!ep->handle.conn) {
104  coap_free_endpoint(ep);
105  return NULL;
106  }
107 
108  coap_address_init(&ep->addr);
109  uip_ipaddr_copy(&ep->addr.addr, &addr->addr);
110  ep->addr.port = addr->port;
111  udp_bind((struct uip_udp_conn *)ep->handle.conn, addr->port);
112  }
113  return ep;
114 }
115 
116 void
118  if (ep) {
119  if (ep->handle.conn) {
120  uip_udp_remove((struct uip_udp_conn *)ep->handle.conn);
121  }
122  coap_free_contiki_endpoint(ep);
123  }
124 }
125 
126 #else /* WITH_CONTIKI */
127 static inline struct coap_endpoint_t *
129  return (struct coap_endpoint_t *)coap_malloc(sizeof(struct coap_endpoint_t));
130 }
131 
132 static inline void
134  coap_free(ep);
135 }
136 
139  int sockfd = socket(addr->addr.sa.sa_family, SOCK_DGRAM, 0);
140  int on = 1;
141  struct coap_endpoint_t *ep;
142 
143  if (sockfd < 0) {
144  coap_log(LOG_WARNING, "coap_new_endpoint: socket");
145  return NULL;
146  }
147 
148  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
149  coap_log(LOG_WARNING, "coap_new_endpoint: setsockopt SO_REUSEADDR");
150 
151  on = 1;
152  switch(addr->addr.sa.sa_family) {
153  case AF_INET:
154  if (setsockopt(sockfd, IPPROTO_IP, GEN_IP_PKTINFO, &on, sizeof(on)) < 0)
155  coap_log(LOG_ALERT, "coap_new_endpoint: setsockopt IP_PKTINFO\n");
156  break;
157  case AF_INET6:
158  if (setsockopt(sockfd, IPPROTO_IPV6, GEN_IPV6_PKTINFO, &on, sizeof(on)) < 0)
159  coap_log(LOG_ALERT, "coap_new_endpoint: setsockopt IPV6_PKTINFO\n");
160  break;
161  default:
162  coap_log(LOG_ALERT, "coap_new_endpoint: unsupported sa_family\n");
163  }
164 
165  if (bind(sockfd, &addr->addr.sa, addr->size) < 0) {
166  coap_log(LOG_WARNING, "coap_new_endpoint: bind");
167  close (sockfd);
168  return NULL;
169  }
170 
172  if (!ep) {
173  coap_log(LOG_WARNING, "coap_new_endpoint: malloc");
174  close(sockfd);
175  return NULL;
176  }
177 
178  memset(ep, 0, sizeof(struct coap_endpoint_t));
179  ep->handle.fd = sockfd;
180  ep->flags = flags;
181 
182  ep->addr.size = addr->size;
183  if (getsockname(sockfd, &ep->addr.addr.sa, &ep->addr.size) < 0) {
184  coap_log(LOG_WARNING, "coap_new_endpoint: cannot determine local address");
185  close (sockfd);
186  return NULL;
187  }
188 
189 #ifndef NDEBUG
190  if (LOG_DEBUG <= coap_get_log_level()) {
191 #ifndef INET6_ADDRSTRLEN
192 #define INET6_ADDRSTRLEN 40
193 #endif
194  unsigned char addr_str[INET6_ADDRSTRLEN+8];
195 
196  if (coap_print_addr(&ep->addr, addr_str, INET6_ADDRSTRLEN+8)) {
197  debug("created %sendpoint %s\n",
198  ep->flags & COAP_ENDPOINT_DTLS ? "DTLS " : "",
199  addr_str);
200  }
201  }
202 #endif /* NDEBUG */
203 
204  return (coap_endpoint_t *)ep;
205 }
206 
207 void
209  if(ep) {
210  if (ep->handle.fd >= 0)
211  close(ep->handle.fd);
213  }
214 }
215 
216 #endif /* WITH_CONTIKI */
217 #endif /* CUSTOM_COAP_NETWORK_ENDPOINT */
218 
219 #ifndef CUSTOM_COAP_NETWORK_SEND
220 
221 #if defined(WITH_POSIX) != defined(HAVE_NETINET_IN_H)
222 /* define struct in6_pktinfo and struct in_pktinfo if not available
223  FIXME: check with configure
224 */
225 struct in6_pktinfo {
226  struct in6_addr ipi6_addr; /* src/dst IPv6 address */
227  unsigned int ipi6_ifindex; /* send/recv interface index */
228 };
229 
230 struct in_pktinfo {
232  struct in_addr ipi_spec_dst;
233  struct in_addr ipi_addr;
234 };
235 #endif
236 
237 #if defined(WITH_POSIX) && !defined(SOL_IP)
238 /* Solaris expects level IPPROTO_IP for ancillary data. */
239 #define SOL_IP IPPROTO_IP
240 #endif
241 
242 #ifdef __GNUC__
243 #define UNUSED_PARAM __attribute__ ((unused))
244 #else /* not a GCC */
245 #define UNUSED_PARAM
246 #endif /* GCC */
247 
248 ssize_t
250  const coap_endpoint_t *local_interface,
251  const coap_address_t *dst,
252  unsigned char *data,
253  size_t datalen) {
254 
255  struct coap_endpoint_t *ep =
256  (struct coap_endpoint_t *)local_interface;
257 
258 #ifndef WITH_CONTIKI
259  /* a buffer large enough to hold all protocol address types */
260  char buf[CMSG_LEN(sizeof(struct sockaddr_storage))];
261  struct msghdr mhdr;
262  struct iovec iov[1];
263 
264  assert(local_interface);
265 
266  iov[0].iov_base = data;
267  iov[0].iov_len = datalen;
268 
269  memset(&mhdr, 0, sizeof(struct msghdr));
270  mhdr.msg_name = (void *)&dst->addr;
271  mhdr.msg_namelen = dst->size;
272 
273  mhdr.msg_iov = iov;
274  mhdr.msg_iovlen = 1;
275 
276  switch (dst->addr.sa.sa_family) {
277  case AF_INET6: {
278  struct cmsghdr *cmsg;
279  struct in6_pktinfo *pktinfo;
280 
281  mhdr.msg_control = buf;
282  mhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
283 
284  cmsg = CMSG_FIRSTHDR(&mhdr);
285  cmsg->cmsg_level = IPPROTO_IPV6;
286  cmsg->cmsg_type = IPV6_PKTINFO;
287  cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
288 
289  pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
290  memset(pktinfo, 0, sizeof(struct in6_pktinfo));
291 
292  pktinfo->ipi6_ifindex = ep->ifindex;
293  if (coap_is_mcast(&local_interface->addr)) {
294  /* We cannot send with multicast address as source address
295  * and hence let the kernel pick the outgoing interface. */
296  pktinfo->ipi6_ifindex = 0;
297  memset(&pktinfo->ipi6_addr, 0, sizeof(pktinfo->ipi6_addr));
298  } else {
299  pktinfo->ipi6_ifindex = ep->ifindex;
300  memcpy(&pktinfo->ipi6_addr,
301  &local_interface->addr.addr.sin6.sin6_addr,
302  local_interface->addr.size);
303  }
304  break;
305  }
306  case AF_INET: {
307 #if defined(IP_PKTINFO)
308  struct cmsghdr *cmsg;
309  struct in_pktinfo *pktinfo;
310 
311  mhdr.msg_control = buf;
312  mhdr.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
313 
314  cmsg = CMSG_FIRSTHDR(&mhdr);
315  cmsg->cmsg_level = SOL_IP;
316  cmsg->cmsg_type = IP_PKTINFO;
317  cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
318 
319  pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
320  memset(pktinfo, 0, sizeof(struct in_pktinfo));
321 
322  if (coap_is_mcast(&local_interface->addr)) {
323  /* We cannot send with multicast address as source address
324  * and hence let the kernel pick the outgoing interface. */
325  pktinfo->ipi_ifindex = 0;
326  memset(&pktinfo->ipi_spec_dst, 0, sizeof(pktinfo->ipi_spec_dst));
327  } else {
328  pktinfo->ipi_ifindex = ep->ifindex;
329  memcpy(&pktinfo->ipi_spec_dst,
330  &local_interface->addr.addr.sin.sin_addr,
331  local_interface->addr.size);
332  }
333 #endif /* IP_PKTINFO */
334  break;
335  }
336  default:
337  /* error */
338  coap_log(LOG_WARNING, "protocol not supported\n");
339  return -1;
340  }
341 
342  return sendmsg(ep->handle.fd, &mhdr, 0);
343 #else /* WITH_CONTIKI */
344  /* FIXME: untested */
345  /* FIXME: is there a way to check if send was successful? */
346  uip_udp_packet_sendto((struct uip_udp_conn *)ep->handle.conn, data, datalen,
347  &dst->addr, dst->port);
348  return datalen;
349 #endif /* WITH_CONTIKI */
350 }
351 
352 #endif /* CUSTOM_COAP_NETWORK_SEND */
353 
354 #ifndef CUSTOM_COAP_NETWORK_READ
355 
356 #define SIN6(A) ((struct sockaddr_in6 *)(A))
357 
358 #ifdef WITH_POSIX
359 static coap_packet_t *
361  coap_packet_t *packet;
362  const size_t need = sizeof(coap_packet_t) + COAP_MAX_PDU_SIZE;
363 
364  packet = (coap_packet_t *)coap_malloc(need);
365  if (packet) {
366  memset(packet, 0, need);
367  }
368  return packet;
369 }
370 
371 void
373  coap_free(packet);
374 }
375 #endif /* WITH_POSIX */
376 #ifdef WITH_CONTIKI
377 static inline coap_packet_t *
378 coap_malloc_packet(void) {
380 }
381 
382 void
384  coap_free_type(COAP_PACKET, packet);
385 }
386 #endif /* WITH_CONTIKI */
387 
388 static inline size_t
390  return COAP_MAX_PDU_SIZE;
391 }
392 
393 void
395 {
396  target->handle = packet->interface->handle;
397  memcpy(&target->addr, &packet->dst, sizeof(target->addr));
398  target->ifindex = packet->ifindex;
399  target->flags = 0; /* FIXME */
400 }
401 void
403 {
404  memcpy(target, &packet->src, sizeof(coap_address_t));
405 }
406 void
407 coap_packet_get_memmapped(coap_packet_t *packet, unsigned char **address, size_t *length)
408 {
409  *address = packet->payload;
410  *length = packet->length;
411 }
412 
418 static inline int
420  return coap_address_isany(local) || coap_address_equals(dst, local) ||
421  coap_is_mcast(dst);
422 }
423 
424 ssize_t
426  ssize_t len = -1;
427 
428 #ifdef WITH_POSIX
429  char msg_control[CMSG_LEN(sizeof(struct sockaddr_storage))];
430  struct msghdr mhdr;
431  struct iovec iov[1];
432 #endif /* WITH_POSIX */
433 
434  assert(ep);
435  assert(packet);
436 
437  *packet = coap_malloc_packet();
438 
439  if (!*packet) {
440  warn("coap_network_read: insufficient memory, drop packet\n");
441  return -1;
442  }
443 
444  coap_address_init(&(*packet)->dst); /* the local interface address */
445  coap_address_init(&(*packet)->src); /* the remote peer */
446 
447 #ifdef WITH_POSIX
448  iov[0].iov_base = (*packet)->payload;
449  iov[0].iov_len = coap_get_max_packetlength(*packet);
450 
451  memset(&mhdr, 0, sizeof(struct msghdr));
452 
453  mhdr.msg_name = &(*packet)->src.addr.st;
454  mhdr.msg_namelen = sizeof((*packet)->src.addr.st);
455 
456  mhdr.msg_iov = iov;
457  mhdr.msg_iovlen = 1;
458 
459  mhdr.msg_control = msg_control;
460  mhdr.msg_controllen = sizeof(msg_control);
461  assert(sizeof(msg_control) == CMSG_LEN(sizeof(struct sockaddr_storage)));
462 
463  len = recvmsg(ep->handle.fd, &mhdr, 0);
464 
465  if (len < 0) {
466  coap_log(LOG_WARNING, "coap_network_read: %s\n", strerror(errno));
467  goto error;
468  } else {
469  struct cmsghdr *cmsg;
470 
471  coap_log(LOG_DEBUG, "received %d bytes on fd %d\n", (int)len, ep->handle.fd);
472 
473  /* use getsockname() to get the local port */
474  (*packet)->dst.size = sizeof((*packet)->dst.addr);
475  if (getsockname(ep->handle.fd, &(*packet)->dst.addr.sa, &(*packet)->dst.size) < 0) {
476  coap_log(LOG_DEBUG, "cannot determine local port\n");
477  goto error;
478  }
479 
480  (*packet)->length = len;
481 
482  /* Walk through ancillary data records until the local interface
483  * is found where the data was received. */
484  for (cmsg = CMSG_FIRSTHDR(&mhdr); cmsg; cmsg = CMSG_NXTHDR(&mhdr, cmsg)) {
485 
486  /* get the local interface for IPv6 */
487  if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
488  union {
489  unsigned char *c;
490  struct in6_pktinfo *p;
491  } u;
492  u.c = CMSG_DATA(cmsg);
493  (*packet)->ifindex = (int)(u.p->ipi6_ifindex);
494 
495  memcpy(&(*packet)->dst.addr.sin6.sin6_addr,
496  &u.p->ipi6_addr, sizeof(struct in6_addr));
497 
498  (*packet)->src.size = sizeof(struct sockaddr_in6);
499  if ((*packet)->src.size != mhdr.msg_namelen) {
500  coap_log(LOG_DEBUG, "wrong IPv6 address length detected, dropped packet\n");
501  goto error;
502  }
503 
504  (*packet)->src.addr.sin6.sin6_family = SIN6(mhdr.msg_name)->sin6_family;
505  (*packet)->src.addr.sin6.sin6_addr = SIN6(mhdr.msg_name)->sin6_addr;
506  (*packet)->src.addr.sin6.sin6_port = SIN6(mhdr.msg_name)->sin6_port;
507 
508  break;
509  }
510 
511  /* local interface for IPv4 */
512 #if defined(IP_PKTINFO)
513  if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO) {
514  union {
515  unsigned char *c;
516  struct in_pktinfo *p;
517  } u;
518 
519  u.c = CMSG_DATA(cmsg);
520  (*packet)->ifindex = u.p->ipi_ifindex;
521 
522  memcpy(&(*packet)->dst.addr.sin.sin_addr,
523  &u.p->ipi_addr, sizeof(struct in_addr));
524 
525  (*packet)->src.size = sizeof(struct sockaddr_in);
526  if ((*packet)->src.size != mhdr.msg_namelen) {
527  coap_log(LOG_DEBUG, "wrong IPv4 address length detected, dropped packet\n");
528  goto error;
529  }
530 
531  assert(memcmp(&(*packet)->src.addr.st, mhdr.msg_name, (*packet)->src.size) == 0);
532 
533  break;
534  }
535 #elif defined(IP_RECVDSTADDR)
536  if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) {
537  (*packet)->ifindex = 0;
538 
539  memcpy(&(*packet)->dst.addr.sin.sin_addr,
540  CMSG_DATA(cmsg), sizeof(struct in_addr));
541 
542  (*packet)->src.size = sizeof(struct sockaddr_in);
543  if ((*packet)->src.size != mhdr.msg_namelen) {
544  coap_log(LOG_DEBUG, "wrong IPv4 address length detected, dropped packet\n");
545  goto error;
546  }
547 
548  assert(memcmp(&(*packet)->src.addr.st, mhdr.msg_name, (*packet)->src.size) == 0);
549 
550  break;
551  }
552 #endif /* IP_PKTINFO */
553  }
554 
555  if (!is_local_if(&ep->addr, &(*packet)->dst)) {
556  coap_log(LOG_DEBUG, "packet received on wrong interface, dropped\n");
557  goto error;
558  }
559  }
560 #endif /* WITH_POSIX */
561 #ifdef WITH_CONTIKI
562  /* FIXME: untested, make this work */
563 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
564 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN])
565 
566  if(uip_newdata()) {
567  uip_ipaddr_copy(&(*packet)->src.addr, &UIP_IP_BUF->srcipaddr);
568  (*packet)->src.port = UIP_UDP_BUF->srcport;
569  uip_ipaddr_copy(&(*packet)->dst.addr, &UIP_IP_BUF->destipaddr);
570  (*packet)->dst.port = UIP_UDP_BUF->destport;
571 
572  if (!is_local_if(&ep->addr, &(*packet)->dst)) {
573  coap_log(LOG_DEBUG, "packet received on wrong interface, dropped\n");
574  goto error;
575  }
576 
577  len = uip_datalen();
578 
579  if (len > coap_get_max_packetlength(*packet)) {
580  /* FIXME: we might want to send back a response */
581  warn("discarded oversized packet\n");
582  return -1;
583  }
584 
585  ((char *)uip_appdata)[len] = 0;
586 #ifndef NDEBUG
587  if (LOG_DEBUG <= coap_get_log_level()) {
588 #ifndef INET6_ADDRSTRLEN
589 #define INET6_ADDRSTRLEN 40
590 #endif
591  unsigned char addr_str[INET6_ADDRSTRLEN+8];
592 
593  if (coap_print_addr(&(*packet)->src, addr_str, INET6_ADDRSTRLEN+8)) {
594  debug("received %zd bytes from %s\n", len, addr_str);
595  }
596  }
597 #endif /* NDEBUG */
598 
599  (*packet)->length = len;
600  memcpy(&(*packet)->payload, uip_appdata, len);
601  }
602 
603 #undef UIP_IP_BUF
604 #undef UIP_UDP_BUF
605 #endif /* WITH_CONTIKI */
606 #ifdef WITH_LWIP
607 #error "coap_network_read() not implemented on this platform"
608 #endif
609 
610  (*packet)->interface = ep;
611 
612  return len;
613  error:
614  coap_free_packet(*packet);
615  *packet = NULL;
616  return -1;
617 }
618 
619 #undef SIN6
620 
621 #endif /* CUSTOM_COAP_NETWORK_READ */
void * conn
opaque connection (e.g.
Definition: coap_io.h:39
ssize_t coap_network_send(struct coap_context_t *context UNUSED_PARAM, const coap_endpoint_t *local_interface, const coap_address_t *dst, unsigned char *data, size_t datalen)
Definition: coap_io.c:249
#define warn(...)
Definition: debug.h:65
coap_address_t addr
local interface address
Definition: coap_io.h:50
struct sockaddr_in6 sin6
Definition: address.h:65
struct sockaddr_in sin
Definition: address.h:64
static void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
Definition: mem.h:70
void coap_packet_get_memmapped(coap_packet_t *packet, unsigned char **address, size_t *length)
Given a packet, set msg and msg_len to an address and length of the packet&#39;s data in memory...
Definition: coap_io.c:407
multi-purpose address abstraction
Definition: address.h:59
void coap_free_endpoint(coap_endpoint_t *ep)
Definition: coap_io.c:208
int ifindex
Definition: coap_io.c:65
coap_endpoint_t * coap_new_endpoint(const coap_address_t *addr, int flags)
Definition: coap_io.c:138
struct in_addr ipi_spec_dst
Definition: coap_io.c:232
struct coap_packet_t coap_packet_t
Definition: coap_io.h:27
static size_t coap_get_max_packetlength(const coap_packet_t *packet UNUSED_PARAM)
Definition: coap_io.c:389
Abstraction of virtual endpoint that can be attached to coap_context_t.
Definition: coap_io.h:35
static struct coap_endpoint_t * coap_malloc_posix_endpoint(void)
Definition: coap_io.c:128
size_t coap_print_addr(const struct coap_address_t *addr, unsigned char *buf, size_t len)
Definition: debug.c:162
#define debug(...)
Definition: debug.h:66
int fd
on POSIX systems
Definition: coap_io.h:38
struct in6_addr ipi6_addr
Definition: coap_io.c:226
void * session
opaque session data
Definition: coap_io.c:66
void coap_packet_populate_endpoint(coap_packet_t *packet, coap_endpoint_t *target)
Populate the coap_endpoint_t *target from the incoming packet&#39;s destination data. ...
Definition: coap_io.c:394
coap_address_t src
the packet&#39;s source address
Definition: coap_io.c:61
coap_if_handle_t hnd
the interface handle
Definition: coap_io.c:60
const coap_endpoint_t * interface
Definition: coap_io.c:63
void coap_free_packet(coap_packet_t *packet)
Releases the storage allocated for packet.
Definition: coap_io.c:372
unsigned char payload[]
payload
Definition: coap_io.c:69
#define assert(...)
Definition: mem.c:17
#define UNUSED_PARAM
Definition: coap_io.c:245
ssize_t coap_network_read(coap_endpoint_t *ep, coap_packet_t **packet)
Function interface for reading data.
Definition: coap_io.c:425
#define COAP_MAX_PDU_SIZE
Definition: pdu.h:27
#define COAP_ENDPOINT_DTLS
Definition: coap_io.h:56
#define SIN6(A)
Definition: coap_io.c:356
static int is_local_if(const coap_address_t *local, const coap_address_t *dst)
Checks if a message with destination address dst matches the local interface with address local...
Definition: coap_io.c:419
static coap_packet_t * coap_malloc_packet(void)
Definition: coap_io.c:360
static int coap_address_isany(const coap_address_t *a)
Checks if given address object a denotes the wildcard address.
Definition: address.h:130
int coap_address_equals(const coap_address_t *a, const coap_address_t *b)
Compares given address objects a and b.
Definition: address.c:18
static void coap_address_init(coap_address_t *addr)
Resets the given coap_address_t object addr to its default values.
Definition: address.h:102
coap_address_t dst
the packet&#39;s destination address
Definition: coap_io.c:62
size_t length
length of payload
Definition: coap_io.c:68
void coap_packet_copy_source(coap_packet_t *packet, coap_address_t *target)
Given an incoming packet, copy its source address into an address struct.
Definition: coap_io.c:402
static void coap_free_posix_endpoint(struct coap_endpoint_t *ep)
Definition: coap_io.c:133
#define SOL_IP
Definition: coap_io.c:239
static void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
Definition: mem.h:77
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
#define INET6_ADDRSTRLEN
int ipi_ifindex
Definition: coap_io.c:231
union coap_address_t::@0 addr
unsigned int ipi6_ifindex
Definition: coap_io.c:227
socklen_t size
size of addr
Definition: address.h:60
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
#define coap_log(...)
Definition: debug.h:58
int coap_is_mcast(const coap_address_t *a)
Checks if given address a denotes a multicast address.
Definition: address.c:41
union coap_endpoint_t::@1 handle
opaque handle to identify this endpoint
coap_log_t coap_get_log_level(void)
Returns the current log level.
Definition: debug.c:60
int coap_if_handle_t
Abstract handle that is used to identify a local network interface.
Definition: coap_io.h:21
The CoAP stack&#39;s global state is stored in a coap_context_t object.
Definition: net.h:76
struct sockaddr sa
Definition: address.h:62