Newer
Older
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* MG_ENABLE_MQTT_BROKER */
#endif /* CS_MONGOOSE_SRC_MQTT_BROKER_H_ */
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
/*
#ifndef CS_MONGOOSE_SRC_DNS_H_
#define CS_MONGOOSE_SRC_DNS_H_
/* Amalgamated: #include "mg_net.h" */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define MG_DNS_A_RECORD 0x01 /* Lookup IP address */
#define MG_DNS_CNAME_RECORD 0x05 /* Lookup CNAME */
#define MG_DNS_PTR_RECORD 0x0c /* Lookup PTR */
#define MG_DNS_TXT_RECORD 0x10 /* Lookup TXT */
#define MG_DNS_AAAA_RECORD 0x1c /* Lookup IPv6 address */
#define MG_DNS_SRV_RECORD 0x21 /* Lookup SRV */
#define MG_DNS_MX_RECORD 0x0f /* Lookup mail server for domain */
#define MG_DNS_ANY_RECORD 0xff
#define MG_DNS_NSEC_RECORD 0x2f
#define MG_MAX_DNS_QUESTIONS 32
#define MG_MAX_DNS_ANSWERS 32
#define MG_DNS_MESSAGE 100 /* High-level DNS message event */
MG_DNS_INVALID_RECORD = 0,
MG_DNS_QUESTION,
MG_DNS_ANSWER
};
/* DNS resource record. */
struct mg_str name; /* buffer with compressed name */
int rtype;
int rclass;
int ttl;
struct mg_str rdata; /* protocol data (can be a compressed name) */
};
/* DNS message (request and response). */
struct mg_str pkt; /* packet body */
uint16_t flags;
uint16_t transaction_id;
int num_questions;
int num_answers;
struct mg_dns_resource_record questions[MG_MAX_DNS_QUESTIONS];
struct mg_dns_resource_record answers[MG_MAX_DNS_ANSWERS];
struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev);
* Parses the record data from a DNS resource record.
*
* - A: struct in_addr *ina
* - AAAA: struct in6_addr *ina
* - CNAME: char buffer
*
* Returns -1 on error.
*
* TODO(mkm): MX
*/
int mg_dns_parse_record_data(struct mg_dns_message *msg,
struct mg_dns_resource_record *rr, void *data,
size_t data_len);
void mg_send_dns_query(struct mg_connection *nc, const char *name,
int query_type);
int mg_dns_insert_header(struct mbuf *io, size_t pos,
struct mg_dns_message *msg);
* Appends already encoded questions from an existing message.
*
* This is useful when generating a DNS reply message which includes
* all question records.
*
int mg_dns_copy_questions(struct mbuf *io, struct mg_dns_message *msg);
* Encodes and appends a DNS resource record to an IO buffer.
*
* The record metadata is taken from the `rr` parameter, while the name and data
* are taken from the parameters, encoded in the appropriate format depending on
* record type and stored in the IO buffer. The encoded values might contain
* offsets within the IO buffer. It's thus important that the IO buffer doesn't
* get trimmed while a sequence of records are encoded while preparing a DNS
*
* This function doesn't update the `name` and `rdata` pointers in the `rr`
* struct because they might be invalidated as soon as the IO buffer grows
* again.
* Returns the number of bytes appended or -1 in case of error.
int mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,
const char *name, size_t nlen, const void *rdata,
size_t rlen);
/*
* Encodes a DNS name.
*/
int mg_dns_encode_name(struct mbuf *io, const char *name, size_t len);
/* Low-level: parses a DNS response. */
int mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg);
* The containing DNS message is required because of the compressed encoding
* and reference suffixes present elsewhere in the packet.
*
* If the name is less than `dst_len` characters long, the remainder
* of `dst` is terminated with `\0` characters. Otherwise, `dst` is not
* terminated.
*
* If `dst_len` is 0 `dst` can be NULL.
size_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,
char *dst, int dst_len);
* Attaches a built-in DNS event handler to the given listening connection.
* The DNS event handler parses the incoming UDP packets, treating them as DNS
* requests. If an incoming packet gets successfully parsed by the DNS event
* handler, a user event handler will receive an `MG_DNS_REQUEST` event, with
* `ev_data` pointing to the parsed `struct mg_dns_message`.
*
* See
* [captive_dns_server](https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server)
* example on how to handle DNS request and send DNS reply.
*/
void mg_set_protocol_dns(struct mg_connection *nc);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CS_MONGOOSE_SRC_DNS_H_ */
#line 1 "mongoose/src/mg_dns_server.h"
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
/*
* Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.
#ifndef CS_MONGOOSE_SRC_DNS_SERVER_H_
#define CS_MONGOOSE_SRC_DNS_SERVER_H_
#if MG_ENABLE_DNS_SERVER
/* Amalgamated: #include "mg_dns.h" */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define MG_DNS_SERVER_DEFAULT_TTL 3600
struct mbuf *io;
size_t start;
};
/*
*
* The reply will be based on an existing query message `msg`.
* The query body will be appended to the output buffer.
* "reply + recursion allowed" will be added to the message flags and the
* message's num_answers will be set to 0.
*
* Answer records can be appended with `mg_dns_send_reply` or by lower
* level function defined in the DNS API.
*
* In order to send a reply use `mg_dns_send_reply`.
* It's possible to use a connection's send buffer as reply buffer,
* and it will work for both UDP and TCP connections.
*
* Example:
*
* for (i = 0; i < msg->num_questions; i++) {
* rr = &msg->questions[i];
* if (rr->rtype == MG_DNS_A_RECORD) {
* mg_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
* }
* }
struct mg_dns_reply mg_dns_create_reply(struct mbuf *io,
struct mg_dns_message *msg);
* Appends a DNS reply record to the IO buffer and to the DNS message.
* The message's num_answers field will be incremented. It's the caller's duty
* to ensure num_answers is properly initialised.
*
* Returns -1 on error.
*/
int mg_dns_reply_record(struct mg_dns_reply *reply,
struct mg_dns_resource_record *question,
const char *name, int rtype, int ttl, const void *rdata,
size_t rdata_len);
* Sends a DNS reply through a connection.
*
* The DNS data is stored in an IO buffer pointed by reply structure in `r`.
* This function mutates the content of that buffer in order to ensure that
* the DNS header reflects the size and flags of the message, that might have
* been updated either with `mg_dns_reply_record` or by direct manipulation of
* `r->message`.
*
* Once sent, the IO buffer will be trimmed unless the reply IO buffer
* is the connection's send buffer and the connection is not in UDP mode.
*/
void mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* MG_ENABLE_DNS_SERVER */
#endif /* CS_MONGOOSE_SRC_DNS_SERVER_H_ */
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
/*
#ifndef CS_MONGOOSE_SRC_RESOLV_H_
#define CS_MONGOOSE_SRC_RESOLV_H_
/* Amalgamated: #include "mg_dns.h" */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
enum mg_resolve_err {
MG_RESOLVE_OK = 0,
MG_RESOLVE_NO_ANSWERS = 1,
MG_RESOLVE_EXCEEDED_RETRY_COUNT = 2,
MG_RESOLVE_TIMEOUT = 3
};
typedef void (*mg_resolve_callback_t)(struct mg_dns_message *dns_message,
void *user_data, enum mg_resolve_err);
/* Options for `mg_resolve_async_opt`. */
struct mg_resolve_async_opts {
int max_retries; /* defaults to 2 if zero */
int timeout; /* in seconds; defaults to 5 if zero */
int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
int only_literal; /* only resolves literal addrs; sync cb invocation */
struct mg_connection **dns_conn; /* return DNS connection */
};
/* See `mg_resolve_async_opt()` */
int mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,
mg_resolve_callback_t cb, void *data);
/* Set default DNS server */
void mg_set_nameserver(struct mg_mgr *mgr, const char *nameserver);
/*
* Resolved a DNS name asynchronously.
*
* Upon successful resolution, the user callback will be invoked
* with the full DNS response message and a pointer to the user's
* context `data`.
*
* In case of timeout while performing the resolution the callback
* will receive a NULL `msg`.
*
* The DNS answers can be extracted with `mg_next_record` and
*
* [source,c]
* ----
* struct in_addr ina;
* struct mg_dns_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,
* ----
*/
int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
mg_resolve_callback_t cb, void *data,
struct mg_resolve_async_opts opts);
/*
* Resolve a name from `/etc/hosts`.
*
* Returns 0 on success, -1 on failure.
*/
int mg_resolve_from_hosts_file(const char *host, union socket_address *usa);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CS_MONGOOSE_SRC_RESOLV_H_ */
/*
* Copyright (c) 2015 Cesanta Software Limited
* All rights reserved
* This software is dual-licensed: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. For the terms of this
* license, see <http://www.gnu.org/licenses/>.
*
* You are free to use this software under the terms of the GNU General
* Public License, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* Alternatively, you can license this software under a commercial
* license, as set out in <https://www.cesanta.com/license>.
*/
/*
*
* CoAP message format:
*
* ```
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
* |Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ...
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
* | Options (if any) ... |1 1 1 1 1 1 1 1| Payload (if any) ...
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
* ```
#ifndef CS_MONGOOSE_SRC_COAP_H_
#define CS_MONGOOSE_SRC_COAP_H_
#define MG_COAP_MSG_TYPE_FIELD 0x2
#define MG_COAP_CODE_CLASS_FIELD 0x4
#define MG_COAP_CODE_DETAIL_FIELD 0x8
#define MG_COAP_MSG_ID_FIELD 0x10
#define MG_COAP_TOKEN_FIELD 0x20
#define MG_COAP_OPTIOMG_FIELD 0x40
#define MG_COAP_PAYLOAD_FIELD 0x80
#define MG_COAP_ERROR 0x10000
#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)
#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)
#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)
#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)
#define MG_COAP_MSG_CON 0
#define MG_COAP_MSG_NOC 1
#define MG_COAP_MSG_ACK 2
#define MG_COAP_MSG_RST 3
#define MG_COAP_MSG_MAX 3
#define MG_COAP_CODECLASS_REQUEST 0
#define MG_COAP_CODECLASS_RESP_OK 2
#define MG_COAP_CODECLASS_CLIENT_ERR 4
#define MG_COAP_CODECLASS_SRV_ERR 5
#define MG_COAP_EVENT_BASE 300
#define MG_EV_COAP_CON (MG_COAP_EVENT_BASE + MG_COAP_MSG_CON)
#define MG_EV_COAP_NOC (MG_COAP_EVENT_BASE + MG_COAP_MSG_NOC)
#define MG_EV_COAP_ACK (MG_COAP_EVENT_BASE + MG_COAP_MSG_ACK)
#define MG_EV_COAP_RST (MG_COAP_EVENT_BASE + MG_COAP_MSG_RST)
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
/*
* CoAP options.
* Use mg_coap_add_option and mg_coap_free_options
* for creation and destruction.
*/
struct mg_coap_option {
struct mg_coap_option *next;
uint32_t number;
struct mg_str value;
};
/* CoAP message. See RFC 7252 for details. */
struct mg_coap_message {
uint32_t flags;
uint8_t msg_type;
uint8_t code_class;
uint8_t code_detail;
uint16_t msg_id;
struct mg_str token;
struct mg_coap_option *options;
struct mg_str payload;
struct mg_coap_option *optiomg_tail;
};
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Sets CoAP protocol handler - triggers CoAP specific events. */
int mg_set_protocol_coap(struct mg_connection *nc);
/*
* Adds a new option to mg_coap_message structure.
* Returns pointer to the newly created option.
* Note: options must be freed by using mg_coap_free_options
*/
struct mg_coap_option *mg_coap_add_option(struct mg_coap_message *cm,
uint32_t number, char *value,
size_t len);
/*
* Frees the memory allocated for options.
* If the cm parameter doesn't contain any option it does nothing.
*/
void mg_coap_free_options(struct mg_coap_message *cm);
/*
* Composes a CoAP message from `mg_coap_message`
* and sends it into `nc` connection.
* Returns 0 on success. On error, it is a bitmask:
* - `#define MG_COAP_ERROR 0x10000`
* - `#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)`
* - `#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)`
* - `#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)`
* - `#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)`
*/
uint32_t mg_coap_send_message(struct mg_connection *nc,
struct mg_coap_message *cm);
/*
* Composes CoAP acknowledgement from `mg_coap_message`
* and sends it into `nc` connection.
* Return value: see `mg_coap_send_message()`
*/
uint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id);
/*
* Parses CoAP message and fills mg_coap_message and returns cm->flags.
* This is a helper function.
*
* NOTE: usually CoAP works over UDP, so lack of data means format error.
* But, in theory, it is possible to use CoAP over TCP (according to RFC)
* The caller has to check results and treat COAP_NOT_ENOUGH_DATA according to
* underlying protocol:
*
* - in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR,
* - in case of TCP client can try to receive more data
*
* Return value: see `mg_coap_send_message()`
*/
uint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm);
/*
* Composes CoAP message from mg_coap_message structure.
* This is a helper function.
* Return value: see `mg_coap_send_message()`
*/
uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* MG_ENABLE_COAP */
#endif /* CS_MONGOOSE_SRC_COAP_H_ */
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
#endif
/*
* Copyright (c) 2016 Cesanta Software Limited
* All rights reserved
*/
#ifndef CS_MONGOOSE_SRC_SNTP_H_
#define CS_MONGOOSE_SRC_SNTP_H_
#if MG_ENABLE_SNTP
#define MG_SNTP_EVENT_BASE 500
/*
* Received reply from time server. Event handler parameter contains
* pointer to mg_sntp_message structure
*/
#define MG_SNTP_REPLY (MG_SNTP_EVENT_BASE + 1)
/* Received malformed SNTP packet */
#define MG_SNTP_MALFORMED_REPLY (MG_SNTP_EVENT_BASE + 2)
/* Failed to get time from server (timeout etc) */
#define MG_SNTP_FAILED (MG_SNTP_EVENT_BASE + 3)
struct mg_sntp_message {
/* if server sends this flags, user should not send requests to it */
int kiss_of_death;
/* usual mg_time */
double time;
};
/* Establishes connection to given sntp server */
struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr,
MG_CB(mg_event_handler_t event_handler,
void *user_data),
const char *sntp_server_name);
/* Sends time request to given connection */
void mg_sntp_send_request(struct mg_connection *c);
/*
* Helper function
* Establishes connection to time server, tries to send request
* repeats sending SNTP_ATTEMPTS times every SNTP_TIMEOUT sec
* (if needed)
* See sntp_client example
*/
struct mg_connection *mg_sntp_get_time(struct mg_mgr *mgr,
mg_event_handler_t event_handler,
const char *sntp_server_name);
#endif
#endif /* CS_MONGOOSE_SRC_SNTP_H_ */
#endif
/*
* Copyright (c) 2017 Cesanta Software Limited
* All rights reserved
*/
#ifndef CS_MONGOOSE_SRC_SOCKS_H_
#define CS_MONGOOSE_SRC_SOCKS_H_
#if MG_ENABLE_SOCKS
#define MG_SOCKS_VERSION 5
#define MG_SOCKS_HANDSHAKE_DONE MG_F_USER_1
#define MG_SOCKS_CONNECT_DONE MG_F_USER_2
/* SOCKS5 handshake methods */
enum mg_socks_handshake_method {
MG_SOCKS_HANDSHAKE_NOAUTH = 0, /* Handshake method - no authentication */
MG_SOCKS_HANDSHAKE_GSSAPI = 1, /* Handshake method - GSSAPI auth */
MG_SOCKS_HANDSHAKE_USERPASS = 2, /* Handshake method - user/password auth */
MG_SOCKS_HANDSHAKE_FAILURE = 0xff, /* Handshake method - failure */
};
/* SOCKS5 commands */
enum mg_socks_command {
MG_SOCKS_CMD_CONNECT = 1, /* Command: CONNECT */
MG_SOCKS_CMD_BIND = 2, /* Command: BIND */
MG_SOCKS_CMD_UDP_ASSOCIATE = 3, /* Command: UDP ASSOCIATE */
};
/* SOCKS5 address types */
enum mg_socks_address_type {
MG_SOCKS_ADDR_IPV4 = 1, /* Address type: IPv4 */
MG_SOCKS_ADDR_DOMAIN = 3, /* Address type: Domain name */
MG_SOCKS_ADDR_IPV6 = 4, /* Address type: IPv6 */
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
};
/* SOCKS5 response codes */
enum mg_socks_response {
MG_SOCKS_SUCCESS = 0, /* Response: success */
MG_SOCKS_FAILURE = 1, /* Response: failure */
MG_SOCKS_NOT_ALLOWED = 2, /* Response: connection not allowed */
MG_SOCKS_NET_UNREACHABLE = 3, /* Response: network unreachable */
MG_SOCKS_HOST_UNREACHABLE = 4, /* Response: network unreachable */
MG_SOCKS_CONN_REFUSED = 5, /* Response: network unreachable */
MG_SOCKS_TTL_EXPIRED = 6, /* Response: network unreachable */
MG_SOCKS_CMD_NOT_SUPPORTED = 7, /* Response: network unreachable */
MG_SOCKS_ADDR_NOT_SUPPORTED = 8, /* Response: network unreachable */
};
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Turn the connection into the SOCKS server */
void mg_set_protocol_socks(struct mg_connection *c);
/* Create socks tunnel for the client connection */
struct mg_iface *mg_socks_mk_iface(struct mg_mgr *, const char *proxy_addr);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
#endif