dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / dnscrypt / src / plugins / example-ldns-opendns-set-client-ip / example-ldns-opendns-set-client-ip.c
blobaa522b41710bcb95fa16c81ffd2ab718ce60832c
2 #include <assert.h>
3 #include <stdio.h>
4 #include <string.h>
6 #include <dnscrypt/plugin.h>
7 #include <ldns/ldns.h>
8 #include <ldns/util.h>
10 DCPLUGIN_MAIN(__FILE__);
12 #define EDNS_HEADER "4f56" "0014" "4f444e5300" "00"
13 #define EDNS_HEADER_CLIENT_IP "10"
14 #define EDNS_CLIENT_IP "7f000001"
15 #define EDNS_HEADER_FODDER "40"
16 #define EDNS_FODDER "deadbeefabad1dea"
18 #define EDNS_DATA EDNS_HEADER \
19 EDNS_HEADER_CLIENT_IP EDNS_CLIENT_IP EDNS_HEADER_FODDER EDNS_FODDER
21 #define EDNS_CLIENT_IP_OFFSET (sizeof EDNS_HEADER - 1U + \
22 sizeof EDNS_HEADER_CLIENT_IP - 1U)
24 #define EDNS_FODDER_OFFSET (sizeof EDNS_HEADER - 1U + \
25 sizeof EDNS_HEADER_CLIENT_IP - 1U + \
26 sizeof EDNS_CLIENT_IP - 1U + \
27 sizeof EDNS_HEADER_FODDER - 1U)
29 const char *
30 dcplugin_description(DCPlugin * const dcplugin)
32 return "Apply the OpenDNS settings defined for a specific IP address";
35 const char *
36 dcplugin_long_description(DCPlugin * const dcplugin)
38 return
39 "The IP address must be a hex-encoded IPv4 address.\n"
40 "\n"
41 "Usage:\n"
42 "\n"
43 "# dnscrypt-proxy --plugin \\\n"
44 " libdcplugin_example_ldns_opendns_set_client_ip.la,7f000001";
47 int
48 dcplugin_init(DCPlugin * const dcplugin, int argc, char *argv[])
50 char *edns_hex;
51 size_t edns_hex_size = sizeof EDNS_DATA;
53 ldns_init_random(NULL, 0U);
54 edns_hex = malloc(edns_hex_size);
55 dcplugin_set_user_data(dcplugin, edns_hex);
56 if (edns_hex == NULL) {
57 return -1;
59 memcpy(edns_hex, EDNS_DATA, edns_hex_size);
60 assert(sizeof EDNS_CLIENT_IP - 1U == (size_t) 8U);
61 if (argc > 1 && strlen(argv[1]) == (size_t) 8U) {
62 memcpy(edns_hex + EDNS_CLIENT_IP_OFFSET,
63 argv[1], sizeof EDNS_CLIENT_IP - 1U);
65 return 0;
68 int
69 dcplugin_destroy(DCPlugin *dcplugin)
71 free(dcplugin_get_user_data(dcplugin));
73 return 0;
76 static void
77 fill_with_random_hex_data(char * const str, size_t size)
79 size_t i = (size_t) 0U;
80 uint16_t rnd;
82 while (i < size) {
83 rnd = ldns_get_random();
84 str[i++] = "0123456789abcdef"[rnd & 0xf];
85 str[i++] = "0123456789abcdef"[(rnd >> 8) & 0xf];
89 DCPluginSyncFilterResult
90 dcplugin_sync_pre_filter(DCPlugin *dcplugin, DCPluginDNSPacket *dcp_packet)
92 uint8_t *new_packet;
93 ldns_rdf *edns_data;
94 char *edns_data_str;
95 ldns_pkt *packet;
96 size_t new_packet_size;
98 ldns_wire2pkt(&packet, dcplugin_get_wire_data(dcp_packet),
99 dcplugin_get_wire_data_len(dcp_packet));
101 edns_data_str = dcplugin_get_user_data(dcplugin);
102 fill_with_random_hex_data(edns_data_str + EDNS_FODDER_OFFSET,
103 sizeof EDNS_FODDER - 1U);
104 edns_data = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_HEX, edns_data_str);
105 ldns_pkt_set_edns_data(packet, edns_data);
107 ldns_pkt2wire(&new_packet, packet, &new_packet_size);
108 if (dcplugin_get_wire_data_max_len(dcp_packet) >= new_packet_size) {
109 dcplugin_set_wire_data(dcp_packet, new_packet, new_packet_size);
112 free(new_packet);
113 ldns_pkt_free(packet);
115 return DCP_SYNC_FILTER_RESULT_OK;