6 #include <dnscrypt/plugin.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)
30 dcplugin_description(DCPlugin
* const dcplugin
)
32 return "Apply the OpenDNS settings defined for a specific IP address";
36 dcplugin_long_description(DCPlugin
* const dcplugin
)
39 "The IP address must be a hex-encoded IPv4 address.\n"
43 "# dnscrypt-proxy --plugin \\\n"
44 " libdcplugin_example_ldns_opendns_set_client_ip.la,7f000001";
48 dcplugin_init(DCPlugin
* const dcplugin
, int argc
, char *argv
[])
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
) {
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);
69 dcplugin_destroy(DCPlugin
*dcplugin
)
71 free(dcplugin_get_user_data(dcplugin
));
77 fill_with_random_hex_data(char * const str
, size_t size
)
79 size_t i
= (size_t) 0U;
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
)
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
);
113 ldns_pkt_free(packet
);
115 return DCP_SYNC_FILTER_RESULT_OK
;