23 #include <sys/select.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
39 #define COAP_RESOURCE_CHECK_TIME 2
41 #define RD_ROOT_STR ((unsigned char *)"rd")
42 #define RD_ROOT_SIZE 2
45 #define min(a,b) ((a) < (b) ? (a) : (b))
65 memset(rd, 0,
sizeof(
rd_t));
104 if (rd && rd->
data.
s)
137 debug(
"hnd_put_rd: cannot allocate storage for new rd\n");
167 debug(
"cannot create response for message %d\n", request->
hdr->
id);
175 debug(
"hnd_get_rd: cannot send response for message %d\n",
204 unsigned char buf[3];
217 unsigned char *data,
size_t data_len,
str *result) {
220 memset(result, 0,
sizeof(
str));
225 while (search_len <= data_len) {
228 if (memcmp(search, data, search_len) == 0) {
230 data_len -= search_len;
233 if (!data_len || *data ==
'=' || *data ==
'&') {
234 while (data_len && *data !=
'=') {
238 if (data_len > 1 && result) {
242 while (--data_len && *data !=
'&') {
252 while (--data_len && *data++ !=
'&')
271 switch(peer->addr.sa.sa_family) {
278 n += snprintf(buf + n,
BUFSIZE - n,
279 "[%02x%02x:%02x%02x:%02x%02x:%02x%02x" \
280 ":%02x%02x:%02x%02x:%02x%02x:%02x%02x]",
281 peer->addr.sin6.sin6_addr.s6_addr[0],
282 peer->addr.sin6.sin6_addr.s6_addr[1],
283 peer->addr.sin6.sin6_addr.s6_addr[2],
284 peer->addr.sin6.sin6_addr.s6_addr[3],
285 peer->addr.sin6.sin6_addr.s6_addr[4],
286 peer->addr.sin6.sin6_addr.s6_addr[5],
287 peer->addr.sin6.sin6_addr.s6_addr[6],
288 peer->addr.sin6.sin6_addr.s6_addr[7],
289 peer->addr.sin6.sin6_addr.s6_addr[8],
290 peer->addr.sin6.sin6_addr.s6_addr[9],
291 peer->addr.sin6.sin6_addr.s6_addr[10],
292 peer->addr.sin6.sin6_addr.s6_addr[11],
293 peer->addr.sin6.sin6_addr.s6_addr[12],
294 peer->addr.sin6.sin6_addr.s6_addr[13],
295 peer->addr.sin6.sin6_addr.s6_addr[14],
296 peer->addr.sin6.sin6_addr.s6_addr[15]);
300 snprintf(buf + n,
BUFSIZE - n,
":%d", peer->addr.sin6.sin6_port);
325 debug(
"hnd_get_rd: cannot allocate storage for rd\n");
332 debug(
"hnd_get_rd: cannot allocate storage for rd->data\n");
358 str h = {0, NULL}, ins = {0, NULL}, rt = {0, NULL}, lt = {0, NULL};
369 loc[loc_size++] =
'/';
388 if (ins.length && loc_size > 1) {
389 loc[loc_size++] =
'-';
390 memcpy((
char *)(loc + loc_size),
391 ins.s,
min(ins.length,
LOCSIZE - loc_size - 1));
392 loc_size +=
min(ins.length,
LOCSIZE - loc_size - 1);
397 snprintf((
char *)(loc + loc_size),
LOCSIZE - loc_size - 1,
398 "%x", request->
hdr->
id);
402 loc[loc_size++] =
'-';
403 memcpy((
char *)(loc + loc_size),
404 ins.s,
min(ins.length,
LOCSIZE - loc_size - 1));
405 loc_size +=
min(ins.length,
LOCSIZE - loc_size - 1);
411 snprintf((
char *)(loc + loc_size),
LOCSIZE - loc_size - 1,
427 buf = (
unsigned char *)
coap_malloc(ins.length + 2);
431 memcpy(buf + 1, ins.s, ins.length);
432 buf[ins.length + 1] =
'"';
442 memcpy(buf + 1, rt.s, rt.length);
443 buf[rt.length + 1] =
'"';
470 unsigned char *b = _b;
471 size_t buflen =
sizeof(_b);
491 coap_add_attr(r, (
unsigned char *)
"ct", 2, (
unsigned char *)
"40", 2, 0);
492 coap_add_attr(r, (
unsigned char *)
"rt", 2, (
unsigned char *)
"\"core-rd\"", 9, 0);
493 coap_add_attr(r, (
unsigned char *)
"ins", 2, (
unsigned char *)
"\"default\"", 9, 0);
500 usage(
const char *program,
const char *version) {
503 p = strrchr( program,
'/' );
507 fprintf( stderr,
"%s v%s -- CoRE Resource Directory implementation\n"
508 "(c) 2011-2012 Olaf Bergmann <bergmann@tzi.org>\n\n"
509 "usage: %s [-A address] [-p port]\n\n"
510 "\t-A address\tinterface address to bind to\n"
511 "\t-p port\t\tlisten on specified port\n"
512 "\t-v num\t\tverbosity level (default: 3)\n",
513 program, version, program );
520 struct addrinfo hints;
521 struct addrinfo *result, *rp;
523 memset(&hints, 0,
sizeof(
struct addrinfo));
524 hints.ai_family = AF_UNSPEC;
525 hints.ai_socktype = SOCK_DGRAM;
526 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
528 s = getaddrinfo(node, port, &hints, &result);
530 fprintf(stderr,
"getaddrinfo: %s\n", gai_strerror(s));
535 for (rp = result; rp != NULL; rp = rp->ai_next) {
538 if (rp->ai_addrlen <=
sizeof(addr.addr)) {
540 addr.size = rp->ai_addrlen;
541 memcpy(&addr.addr, rp->ai_addr, rp->ai_addrlen);
551 fprintf(stderr,
"no context available for interface '%s'\n", node);
554 freeaddrinfo(result);
560 struct ipv6_mreq mreq;
561 struct addrinfo *reslocal = NULL, *resmulti = NULL, hints, *ainfo;
565 memset(&hints, 0,
sizeof(hints));
566 hints.ai_family = AF_INET6;
567 hints.ai_socktype = SOCK_DGRAM;
569 result = getaddrinfo(
"::", NULL, &hints, &reslocal);
571 perror(
"join: cannot resolve link-local interface");
576 for (ainfo = reslocal; ainfo != NULL; ainfo = ainfo->ai_next) {
577 if ( ainfo->ai_family == AF_INET6 ) {
578 mreq.ipv6mr_interface =
579 ((
struct sockaddr_in6 *)ainfo->ai_addr)->sin6_scope_id;
584 memset(&hints, 0,
sizeof(hints));
585 hints.ai_family = AF_INET6;
586 hints.ai_socktype = SOCK_DGRAM;
589 result = getaddrinfo(group_name, NULL, &hints, &resmulti);
592 perror(
"join: cannot resolve multicast address");
596 for (ainfo = resmulti; ainfo != NULL; ainfo = ainfo->ai_next) {
597 if ( ainfo->ai_family == AF_INET6 ) {
598 mreq.ipv6mr_multiaddr =
599 ((
struct sockaddr_in6 *)ainfo->ai_addr)->sin6_addr;
604 result = setsockopt( ctx->
sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
605 (
char *)&mreq,
sizeof(mreq) );
607 perror(
"join: setsockopt");
610 freeaddrinfo(resmulti);
611 freeaddrinfo(reslocal);
620 struct timeval tv, *timeout;
624 char addr_str[NI_MAXHOST] =
"::";
625 char port_str[NI_MAXSERV] =
"5683";
630 while ((opt = getopt(argc, argv,
"A:g:p:v:")) != -1) {
633 strncpy(addr_str, optarg, NI_MAXHOST-1);
634 addr_str[NI_MAXHOST - 1] =
'\0';
640 strncpy(port_str, optarg, NI_MAXSERV-1);
641 port_str[NI_MAXSERV - 1] =
'\0';
644 log_level = strtol(optarg, NULL, 10);
667 FD_SET( ctx->
sockfd, &readfds );
672 while ( nextpdu && nextpdu->
t <= now ) {
687 result = select( FD_SETSIZE, &readfds, 0, 0, timeout );
692 }
else if ( result > 0 ) {
693 if ( FD_ISSET( ctx->
sockfd, &readfds ) ) {