module_udp.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. /*
  2. * ZMap Copyright 2013 Regents of the University of Michigan
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. */
  8. /* send module for performing arbitrary UDP scans */
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <stdint.h>
  12. #include <unistd.h>
  13. #include <string.h>
  14. #include <assert.h>
  15. #include "../../lib/includes.h"
  16. #include "../../lib/xalloc.h"
  17. #include "../../lib/lockfd.h"
  18. #include "logger.h"
  19. #include "probe_modules.h"
  20. #include "packet.h"
  21. #include "aesrand.h"
  22. #include "state.h"
  23. #include "module_udp.h"
  24. #define MAX_UDP_PAYLOAD_LEN 1472
  25. #define ICMP_UNREACH_HEADER_SIZE 8
  26. #define UNUSED __attribute__((unused))
  27. static char *udp_send_msg = NULL;
  28. static int udp_send_msg_len = 0;
  29. static int udp_send_substitutions = 0;
  30. static udp_payload_template_t *udp_template = NULL;
  31. static const char *udp_send_msg_default = "GET / HTTP/1.1\r\nHost: www\r\n\r\n";
  32. const char *udp_unreach_strings[] = {
  33. "network unreachable",
  34. "host unreachable",
  35. "protocol unreachable",
  36. "port unreachable",
  37. "fragments required",
  38. "source route failed",
  39. "network unknown",
  40. "host unknown",
  41. "source host isolated",
  42. "network admin. prohibited",
  43. "host admin. prohibited",
  44. "network unreachable TOS",
  45. "host unreachable TOS",
  46. "communication admin. prohibited",
  47. "host presdence violation",
  48. "precedence cutoff"
  49. };
  50. const char *udp_usage_error =
  51. "unknown UDP probe specification (expected file:/path or text:STRING or hex:01020304 or template:/path or template-fields)";
  52. const unsigned char *charset_alphanum = (unsigned char *)"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  53. const unsigned char *charset_alpha = (unsigned char *)"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  54. const unsigned char *charset_digit = (unsigned char *)"0123456789";
  55. const unsigned char charset_all[257] = {
  56. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  57. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
  58. 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
  59. 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
  60. 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
  61. 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
  62. 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
  63. 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  64. 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  65. 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
  66. 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5,
  67. 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
  68. 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3,
  69. 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2,
  70. 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1,
  71. 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
  72. 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
  73. 0x00
  74. };
  75. static int num_ports;
  76. probe_module_t module_udp;
  77. // Field definitions for template parsing and displaying usage
  78. static uint32_t udp_num_template_field_types = 12;
  79. static udp_payload_field_type_def_t udp_payload_template_fields[] = {
  80. {.name = "SADDR_N", .ftype=UDP_SADDR_N, .desc = "Source IP address in network byte order"},
  81. {.name = "SADDR", .ftype=UDP_SADDR_A, .desc = "Source IP address in dotted-quad format"},
  82. {.name = "DADDR_N", .ftype=UDP_DADDR_N, .desc = "Destination IP address in network byte order"},
  83. {.name = "DADDR", .ftype=UDP_DADDR_A, .desc = "Destination IP address in dotted-quad format"},
  84. {.name = "SPORT_N", .ftype=UDP_SPORT_N, .desc = "UDP source port in netowrk byte order"},
  85. {.name = "SPORT", .ftype=UDP_SPORT_A, .desc = "UDP source port in ascii format"},
  86. {.name = "DPORT_N", .ftype=UDP_DPORT_N, .desc = "UDP destination port in network byte order"},
  87. {.name = "DPORT", .ftype=UDP_DPORT_A, .desc = "UDP destination port in ascii format"},
  88. {.name = "RAND_BYTE", .ftype=UDP_RAND_BYTE, .desc = "Random bytes from 0-255"},
  89. {.name = "RAND_DIGIT", .ftype=UDP_RAND_DIGIT, .desc = "Random digits from 0-9"},
  90. {.name = "RAND_ALPHA", .ftype=UDP_RAND_ALPHA, .desc = "Random mixed-case letters (a-z)"},
  91. {.name = "RAND_ALPHANUM", .ftype=UDP_RAND_ALPHANUM, .desc = "Random mixed-case letters (a-z) and numbers"}
  92. };
  93. void udp_set_num_ports(int x)
  94. {
  95. num_ports = x;
  96. }
  97. int udp_global_initialize(struct state_conf *conf) {
  98. char *args, *c;
  99. int i;
  100. unsigned int n;
  101. FILE *inp;
  102. num_ports = conf->source_port_last - conf->source_port_first + 1;
  103. udp_send_msg = strdup(udp_send_msg_default);
  104. udp_send_msg_len = strlen(udp_send_msg);
  105. if (!(conf->probe_args && strlen(conf->probe_args) > 0))
  106. return(0);
  107. args = strdup(conf->probe_args);
  108. if (! args) exit(1);
  109. if (strcmp(args, "template-fields") == 0) {
  110. lock_file(stderr);
  111. fprintf(stderr, "%s",
  112. "List of allowed UDP template fields (name: description)\n\n");
  113. for (uint32_t i = 0; i < udp_num_template_field_types; ++i) {
  114. fprintf(stderr, "%s: %s\n",
  115. udp_payload_template_fields[i].name,
  116. udp_payload_template_fields[i].desc);
  117. }
  118. fprintf(stderr, "%s\n" ,"");
  119. unlock_file(stderr);
  120. exit(0);
  121. }
  122. c = strchr(args, ':');
  123. if (! c) {
  124. free(args);
  125. free(udp_send_msg);
  126. log_fatal("udp", udp_usage_error);
  127. exit(1);
  128. }
  129. *c++ = 0;
  130. if (strcmp(args, "text") == 0) {
  131. free(udp_send_msg);
  132. udp_send_msg = strdup(c);
  133. udp_send_msg_len = strlen(udp_send_msg);
  134. } else if (strcmp(args, "file") == 0 || strcmp(args, "template") == 0) {
  135. inp = fopen(c, "rb");
  136. if (!inp) {
  137. free(args);
  138. free(udp_send_msg);
  139. log_fatal("udp", "could not open UDP data file '%s'\n", c);
  140. exit(1);
  141. }
  142. free(udp_send_msg);
  143. udp_send_msg = xmalloc(MAX_UDP_PAYLOAD_LEN);
  144. udp_send_msg_len = fread(udp_send_msg, 1, MAX_UDP_PAYLOAD_LEN, inp);
  145. fclose(inp);
  146. if (strcmp(args, "template") == 0) {
  147. udp_send_substitutions = 1;
  148. udp_template = udp_template_load(udp_send_msg, udp_send_msg_len);
  149. }
  150. } else if (strcmp(args, "hex") == 0) {
  151. udp_send_msg_len = strlen(c) / 2;
  152. free(udp_send_msg);
  153. udp_send_msg = xmalloc(udp_send_msg_len);
  154. for (i=0; i < udp_send_msg_len; i++) {
  155. if (sscanf(c + (i*2), "%2x", &n) != 1) {
  156. free(args);
  157. free(udp_send_msg);
  158. log_fatal("udp", "non-hex character: '%c'", c[i*2]);
  159. exit(1);
  160. }
  161. udp_send_msg[i] = (n & 0xff);
  162. }
  163. } else {
  164. log_fatal("udp", udp_usage_error);
  165. free(udp_send_msg);
  166. free(args);
  167. exit(1);
  168. }
  169. if (udp_send_msg_len > MAX_UDP_PAYLOAD_LEN) {
  170. log_warn("udp", "warning: reducing UDP payload to %d "
  171. "bytes (from %d) to fit on the wire\n",
  172. MAX_UDP_PAYLOAD_LEN, udp_send_msg_len);
  173. udp_send_msg_len = MAX_UDP_PAYLOAD_LEN;
  174. }
  175. free(args);
  176. return EXIT_SUCCESS;
  177. }
  178. int udp_global_cleanup(__attribute__((unused)) struct state_conf *zconf,
  179. __attribute__((unused)) struct state_send *zsend,
  180. __attribute__((unused)) struct state_recv *zrecv)
  181. {
  182. if (udp_send_msg) {
  183. free(udp_send_msg);
  184. udp_send_msg = NULL;
  185. }
  186. if (udp_template) {
  187. udp_template_free(udp_template);
  188. udp_template = NULL;
  189. }
  190. return EXIT_SUCCESS;
  191. }
  192. int udp_init_perthread(void* buf, macaddr_t *src,
  193. macaddr_t *gw, __attribute__((unused)) port_h_t dst_port,\
  194. void **arg_ptr)
  195. {
  196. memset(buf, 0, MAX_PACKET_SIZE);
  197. struct ether_header *eth_header = (struct ether_header *) buf;
  198. make_eth_header(eth_header, src, gw);
  199. struct ip *ip_header = (struct ip*)(&eth_header[1]);
  200. uint16_t len = htons(sizeof(struct ip) + sizeof(struct udphdr) + udp_send_msg_len);
  201. make_ip_header(ip_header, IPPROTO_UDP, len);
  202. struct udphdr *udp_header = (struct udphdr*)(&ip_header[1]);
  203. len = sizeof(struct udphdr) + udp_send_msg_len;
  204. make_udp_header(udp_header, zconf.target_port, len);
  205. char* payload = (char*)(&udp_header[1]);
  206. module_udp.packet_length = sizeof(struct ether_header) + sizeof(struct ip)
  207. + sizeof(struct udphdr) + udp_send_msg_len;
  208. assert(module_udp.packet_length <= MAX_PACKET_SIZE);
  209. memcpy(payload, udp_send_msg, udp_send_msg_len);
  210. // Seed our random number generator with the global generator
  211. uint32_t seed = aesrand_getword(zconf.aes);
  212. aesrand_t *aes = aesrand_init_from_seed(seed);
  213. *arg_ptr = aes;
  214. return EXIT_SUCCESS;
  215. }
  216. int udp_make_packet(void *buf, ipaddr_n_t src_ip, ipaddr_n_t dst_ip,
  217. uint32_t *validation, int probe_num, void *arg)
  218. {
  219. struct ether_header *eth_header = (struct ether_header *) buf;
  220. struct ip *ip_header = (struct ip*) (&eth_header[1]);
  221. struct udphdr *udp_header= (struct udphdr *) &ip_header[1];
  222. //struct = (struct udphdr*) (&ip_header[1]);
  223. ip_header->ip_src.s_addr = src_ip;
  224. ip_header->ip_dst.s_addr = dst_ip;
  225. udp_header->uh_sport = htons(get_src_port(num_ports, probe_num,
  226. validation));
  227. if (udp_send_substitutions) {
  228. char *payload = (char *) &udp_header[1];
  229. int payload_len = 0;
  230. memset(payload, 0, MAX_UDP_PAYLOAD_LEN);
  231. // Grab our random number generator
  232. aesrand_t *aes = (aesrand_t *) arg;
  233. // The buf is a stack var of our caller of size MAX_PACKET_SIZE
  234. // Recalculate the payload using the loaded template
  235. payload_len = udp_template_build(udp_template, payload, MAX_UDP_PAYLOAD_LEN, ip_header, udp_header, aes);
  236. // If success is zero, the template output was truncated
  237. if (payload_len <= 0) {
  238. log_fatal("udp", "UDP payload template generated an empty payload");
  239. exit(1);
  240. }
  241. // Update the IP and UDP headers to match the new payload length
  242. ip_header->ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + payload_len);
  243. udp_header->uh_ulen = ntohs(sizeof(struct udphdr) + payload_len);
  244. }
  245. ip_header->ip_sum = 0;
  246. ip_header->ip_sum = zmap_ip_checksum((unsigned short *) ip_header);
  247. return EXIT_SUCCESS;
  248. }
  249. void udp_print_packet(FILE *fp, void* packet)
  250. {
  251. struct ether_header *ethh = (struct ether_header *) packet;
  252. struct ip *iph = (struct ip *) &ethh[1];
  253. struct udphdr *udph = (struct udphdr*)(&iph[1]);
  254. fprintf(fp, "udp { source: %u | dest: %u | checksum: %#04X }\n",
  255. ntohs(udph->uh_sport),
  256. ntohs(udph->uh_dport),
  257. ntohs(udph->uh_sum));
  258. fprintf_ip_header(fp, iph);
  259. fprintf_eth_header(fp, ethh);
  260. fprintf(fp, "------------------------------------------------------\n");
  261. }
  262. void udp_process_packet(const u_char *packet, UNUSED uint32_t len, fieldset_t *fs)
  263. {
  264. struct ip *ip_hdr = (struct ip *) &packet[sizeof(struct ether_header)];
  265. if (ip_hdr->ip_p == IPPROTO_UDP) {
  266. struct udphdr *udp = (struct udphdr *) ((char *) ip_hdr + ip_hdr->ip_hl * 4);
  267. fs_add_string(fs, "classification", (char*) "udp", 0);
  268. fs_add_uint64(fs, "success", 1);
  269. fs_add_uint64(fs, "sport", ntohs(udp->uh_sport));
  270. fs_add_uint64(fs, "dport", ntohs(udp->uh_dport));
  271. fs_add_null(fs, "icmp_responder");
  272. fs_add_null(fs, "icmp_type");
  273. fs_add_null(fs, "icmp_code");
  274. fs_add_null(fs, "icmp_unreach_str");
  275. fs_add_uint64(fs, "udp_pkt_size", ntohs(udp->uh_ulen));
  276. // Verify that the UDP length is big enough for the header and at least one byte
  277. uint16_t data_len = ntohs(udp->uh_ulen);
  278. if (data_len > sizeof(struct udphdr)) {
  279. uint32_t overhead = (sizeof(struct udphdr) + (ip_hdr->ip_hl * 4));
  280. uint32_t max_rlen = len - overhead;
  281. uint32_t max_ilen = ntohs(ip_hdr->ip_len) - overhead;
  282. // Verify that the UDP length is inside of our received buffer
  283. if (data_len > max_rlen) {
  284. data_len = max_rlen;
  285. }
  286. // Verify that the UDP length is inside of our IP packet
  287. if (data_len > max_ilen) {
  288. data_len = max_ilen;
  289. }
  290. fs_add_binary(fs, "data", data_len, (void*) &udp[1], 0);
  291. // Some devices reply with a zero UDP length but still return data, ignore the data
  292. } else {
  293. fs_add_null(fs, "data");
  294. }
  295. } else if (ip_hdr->ip_p == IPPROTO_ICMP) {
  296. struct icmp *icmp = (struct icmp *) ((char *) ip_hdr + ip_hdr->ip_hl * 4);
  297. struct ip *ip_inner = (struct ip *) ((char *) icmp + ICMP_UNREACH_HEADER_SIZE);
  298. // ICMP unreach comes from another server (not the one we sent a probe to);
  299. // But we will fix up saddr to be who we sent the probe to, in case you care.
  300. fs_modify_string(fs, "saddr", make_ip_str(ip_inner->ip_dst.s_addr), 1);
  301. fs_add_string(fs, "classification", (char*) "icmp-unreach", 0);
  302. fs_add_uint64(fs, "success", 0);
  303. fs_add_null(fs, "sport");
  304. fs_add_null(fs, "dport");
  305. fs_add_string(fs, "icmp_responder", make_ip_str(ip_hdr->ip_src.s_addr), 1);
  306. fs_add_uint64(fs, "icmp_type", icmp->icmp_type);
  307. fs_add_uint64(fs, "icmp_code", icmp->icmp_code);
  308. if (icmp->icmp_code <= ICMP_UNREACH_PRECEDENCE_CUTOFF) {
  309. fs_add_string(fs, "icmp_unreach_str",
  310. (char*) udp_unreach_strings[icmp->icmp_code], 0);
  311. } else {
  312. fs_add_string(fs, "icmp_unreach_str", (char *) "unknown", 0);
  313. }
  314. fs_add_null(fs, "udp_pkt_size");
  315. fs_add_null(fs, "data");
  316. } else {
  317. fs_add_string(fs, "classification", (char *) "other", 0);
  318. fs_add_uint64(fs, "success", 0);
  319. fs_add_null(fs, "sport");
  320. fs_add_null(fs, "dport");
  321. fs_add_null(fs, "icmp_responder");
  322. fs_add_null(fs, "icmp_type");
  323. fs_add_null(fs, "icmp_code");
  324. fs_add_null(fs, "icmp_unreach_str");
  325. fs_add_null(fs, "udp_pkt_size");
  326. fs_add_null(fs, "data");
  327. }
  328. }
  329. int udp_validate_packet(const struct ip *ip_hdr, uint32_t len,
  330. __attribute__((unused))uint32_t *src_ip, uint32_t *validation)
  331. {
  332. uint16_t dport, sport;
  333. if (ip_hdr->ip_p == IPPROTO_UDP) {
  334. if ((4*ip_hdr->ip_hl + sizeof(struct udphdr)) > len) {
  335. // buffer not large enough to contain expected udp header
  336. return 0;
  337. }
  338. struct udphdr *udp = (struct udphdr*) ((char *) ip_hdr + 4*ip_hdr->ip_hl);
  339. sport = ntohs(udp->uh_dport);
  340. dport = ntohs(udp->uh_sport);
  341. } else if (ip_hdr->ip_p == IPPROTO_ICMP) {
  342. // UDP can return ICMP Destination unreach
  343. // IP( ICMP( IP( UDP ) ) ) for a destination unreach
  344. uint32_t min_len = 4*ip_hdr->ip_hl + ICMP_UNREACH_HEADER_SIZE
  345. + sizeof(struct ip) + sizeof(struct udphdr);
  346. if (len < min_len) {
  347. // Not enough information for us to validate
  348. return 0;
  349. }
  350. struct icmp *icmp = (struct icmp*) ((char *) ip_hdr + 4*ip_hdr->ip_hl);
  351. if (icmp->icmp_type != ICMP_UNREACH) {
  352. return 0;
  353. }
  354. struct ip *ip_inner = (struct ip*) ((char *) icmp + ICMP_UNREACH_HEADER_SIZE);
  355. // Now we know the actual inner ip length, we should recheck the buffer
  356. if (len < 4*ip_inner->ip_hl - sizeof(struct ip) + min_len) {
  357. return 0;
  358. }
  359. // This is the packet we sent
  360. struct udphdr *udp = (struct udphdr *) ((char*) ip_inner + 4*ip_inner->ip_hl);
  361. sport = ntohs(udp->uh_sport);
  362. dport = ntohs(udp->uh_dport);
  363. if (dport != zconf.target_port) {
  364. return 0;
  365. }
  366. } else {
  367. return 0;
  368. }
  369. if (!check_dst_port(sport, num_ports, validation)) {
  370. return 0;
  371. }
  372. return 1;
  373. }
  374. // Add a new field to the template
  375. void udp_template_add_field(udp_payload_template_t *t,
  376. udp_payload_field_type_t ftype, unsigned int length, char *data)
  377. {
  378. udp_payload_field_t *c;
  379. t->fcount++;
  380. t->fields = xrealloc(t->fields, sizeof(udp_payload_field_t) * t->fcount);
  381. if (! t->fields) {
  382. exit(1);
  383. }
  384. t->fields[t->fcount - 1] = xmalloc(sizeof(udp_payload_field_t));
  385. c = t->fields[t->fcount - 1];
  386. if (! c) {
  387. exit(1);
  388. }
  389. c->ftype = ftype;
  390. c->length = length;
  391. c->data = data;
  392. }
  393. // Free all buffers held by the payload template, including its own
  394. void udp_template_free(udp_payload_template_t *t)
  395. {
  396. unsigned int x;
  397. for (x=0; x < t->fcount; x++) {
  398. if (t->fields[x]->data) {
  399. free(t->fields[x]->data);
  400. t->fields[x]->data = NULL;
  401. }
  402. free(t->fields[x]);
  403. t->fields[x] = NULL;
  404. }
  405. free(t->fields);
  406. t->fields = NULL;
  407. t->fcount = 0;
  408. free(t);
  409. }
  410. int udp_random_bytes(char *dst, int len, const unsigned char *charset,
  411. int charset_len, aesrand_t *aes) {
  412. int i;
  413. for(i=0; i<len; i++)
  414. *dst++ = charset[ (aesrand_getword(aes) & 0xFFFFFFFF) % charset_len ];
  415. return i;
  416. }
  417. int udp_template_build(udp_payload_template_t *t, char *out, unsigned int len,
  418. struct ip *ip_hdr, struct udphdr *udp_hdr, aesrand_t *aes)
  419. {
  420. udp_payload_field_t *c;
  421. char *p;
  422. char *max;
  423. char tmp[256];
  424. int full = 0;
  425. unsigned int x, y;
  426. uint32_t *u32;
  427. uint16_t *u16;
  428. max = out + len;
  429. p = out;
  430. for (x=0; x < t->fcount; x++) {
  431. c = t->fields[x];
  432. // Exit the processing loop if our packet buffer would overflow
  433. if (p+c->length >= max) {
  434. full = 1;
  435. return 0;
  436. }
  437. switch (c->ftype) {
  438. // These fields have a specified output length value
  439. case UDP_DATA:
  440. if (! (c->data && c->length))
  441. break;
  442. memcpy(p, c->data, c->length);
  443. p += c->length;
  444. break;
  445. case UDP_RAND_DIGIT:
  446. p += udp_random_bytes(p, c->length, charset_digit, 10, aes);
  447. break;
  448. case UDP_RAND_ALPHA:
  449. p += udp_random_bytes(p, c->length, charset_alpha, 52, aes);
  450. break;
  451. case UDP_RAND_ALPHANUM:
  452. p += udp_random_bytes(p, c->length, charset_alphanum, 62, aes);
  453. break;
  454. case UDP_RAND_BYTE:
  455. p += udp_random_bytes(p, c->length, charset_all, 256, aes);
  456. break;
  457. // These fields need to calculate size on their own
  458. // TODO: Condense these case statements to remove redundant code
  459. case UDP_SADDR_A:
  460. if ( p + 15 >= max) {
  461. full = 1;
  462. break;
  463. }
  464. // Write to stack and then memcpy in order to properly track length
  465. inet_ntop(AF_INET, (char *)&ip_hdr->ip_src, tmp, sizeof(tmp)-1);
  466. memcpy(p, tmp, strlen(tmp));
  467. p += strlen(tmp);
  468. break;
  469. case UDP_DADDR_A:
  470. if ( p + 15 >= max) {
  471. full = 1;
  472. break;
  473. }
  474. // Write to stack and then memcpy in order to properly track length
  475. inet_ntop(AF_INET, (char *)&ip_hdr->ip_dst, tmp, sizeof(tmp)-1);
  476. memcpy(p, tmp, strlen(tmp));
  477. p += strlen(tmp);
  478. break;
  479. case UDP_SADDR_N:
  480. if ( p + 4 >= max) {
  481. full = 1;
  482. break;
  483. }
  484. u32 = (uint32_t *)p;
  485. *u32 = ip_hdr->ip_src.s_addr;
  486. p += 4;
  487. break;
  488. case UDP_DADDR_N:
  489. if ( p + 4 >= max) {
  490. full = 1;
  491. break;
  492. }
  493. u32 = (uint32_t *)p;
  494. *u32 = ip_hdr->ip_dst.s_addr;
  495. p += 4;
  496. break;
  497. case UDP_SPORT_N:
  498. if ( p + 2 >= max) {
  499. full = 1;
  500. break;
  501. }
  502. u16 = (uint16_t *)p;
  503. *u16 = udp_hdr->uh_sport;
  504. p += 2;
  505. break;
  506. case UDP_DPORT_N:
  507. if ( p + 2 >= max) {
  508. full = 1;
  509. break;
  510. }
  511. u16 = (uint16_t *)p;
  512. *u16 = udp_hdr->uh_sport;
  513. p += 2;
  514. break;
  515. case UDP_SPORT_A:
  516. if ( p + 5 >= max) {
  517. full = 1;
  518. break;
  519. }
  520. y = snprintf(tmp, 6, "%d", ntohs(udp_hdr->uh_sport));
  521. memcpy(p, tmp, y);
  522. p += y;
  523. break;
  524. case UDP_DPORT_A:
  525. if ( p + 5 >= max) {
  526. full = 1;
  527. break;
  528. }
  529. y = snprintf(tmp, 6, "%d", ntohs(udp_hdr->uh_sport));
  530. memcpy(p, tmp, y);
  531. p += y;
  532. break;
  533. }
  534. // Bail out if our packet buffer would overflow
  535. if (full == 1) {
  536. return 0;
  537. }
  538. }
  539. return p - out - 1;
  540. }
  541. // Convert a string field name to a field type, parsing any specified length value
  542. int udp_template_field_lookup(char *vname, udp_payload_field_t *c)
  543. {
  544. char *param;
  545. unsigned int f;
  546. unsigned int olen = 0;
  547. unsigned int fcount = sizeof(udp_payload_template_fields)/sizeof(udp_payload_template_fields[0]);
  548. param = strstr((const char*)vname, "=");
  549. if (param) {
  550. *param = '\0';
  551. param++;
  552. }
  553. // Most field types treat their parameter as a generator output length
  554. // unless it is ignored (ADDR, PORT, etc).
  555. if (param) {
  556. olen = atoi((const char *)param);
  557. }
  558. // Find a field that matches the
  559. for (f=0; f<fcount; f++) {
  560. if (strcmp((char *)vname, udp_payload_template_fields[f].name) == 0) {
  561. c->ftype = udp_payload_template_fields[f].ftype;
  562. c->length = olen;
  563. c->data = NULL;
  564. return 1;
  565. }
  566. }
  567. // No match, skip and treat it as a data field
  568. return 0;
  569. }
  570. // Allocate a payload template and populate it by parsing a template file as a binary buffer
  571. udp_payload_template_t * udp_template_load(char *buf, unsigned int len)
  572. {
  573. udp_payload_template_t *t = xmalloc(sizeof(udp_payload_template_t));
  574. // The last $ we encountered outside of a field specifier
  575. char *dollar = NULL;
  576. // The last { we encountered outside of a field specifier
  577. char *lbrack = NULL;
  578. // Track the start pointer of a data field (static)
  579. char *s = buf;
  580. // Track the index into the template
  581. char *p = buf;
  582. char *tmp;
  583. unsigned int tlen;
  584. udp_payload_field_t c;
  585. t->fcount = 0;
  586. t->fields = NULL;
  587. while (p < (buf+len))
  588. {
  589. switch(*p){
  590. case '$':
  591. if ( (dollar && !lbrack) || !dollar) {
  592. dollar = p;
  593. }
  594. p++;
  595. continue;
  596. case '{':
  597. if (dollar && !lbrack) {
  598. lbrack = p;
  599. }
  600. p++;
  601. continue;
  602. case '}':
  603. if (! (dollar && lbrack)) {
  604. p++;
  605. continue;
  606. }
  607. // Store the leading bytes before ${ as a data field
  608. tlen = dollar - s;
  609. if ( tlen > 0) {
  610. tmp = xmalloc(tlen);
  611. memcpy(tmp, s, tlen);
  612. udp_template_add_field(t, UDP_DATA, tlen, tmp);
  613. }
  614. tmp = xcalloc(1, p-lbrack);
  615. memcpy(tmp, lbrack+1, p-lbrack-1);
  616. if (udp_template_field_lookup(tmp, &c)) {
  617. udp_template_add_field(t, c.ftype, c.length, c.data);
  618. // Push the pointer past the } if this was a valid variable
  619. s = p + 1;
  620. } else {
  621. // Rewind back to the ${ sequence if this was an invalid variable
  622. s = dollar;
  623. }
  624. free(tmp);
  625. break;
  626. default:
  627. if (dollar && lbrack) {
  628. p++;
  629. continue;
  630. }
  631. }
  632. dollar = NULL;
  633. lbrack = NULL;
  634. p++;
  635. }
  636. // Store the trailing bytes as a final data field
  637. if ( s < p ) {
  638. tlen = p - s;
  639. tmp = xmalloc(tlen);
  640. memcpy(tmp, s, tlen);
  641. udp_template_add_field(t, UDP_DATA, tlen, tmp);
  642. }
  643. return t;
  644. }
  645. static fielddef_t fields[] = {
  646. {.name = "classification", .type="string", .desc = "packet classification"},
  647. {.name = "success", .type="int", .desc = "is response considered success"},
  648. {.name = "sport", .type = "int", .desc = "UDP source port"},
  649. {.name = "dport", .type = "int", .desc = "UDP destination port"},
  650. {.name = "icmp_responder", .type = "string", .desc = "Source IP of ICMP_UNREACH message"},
  651. {.name = "icmp_type", .type = "int", .desc = "icmp message type"},
  652. {.name = "icmp_code", .type = "int", .desc = "icmp message sub type code"},
  653. {.name = "icmp_unreach_str", .type = "string", .desc = "for icmp_unreach responses, the string version of icmp_code (e.g. network-unreach)"},
  654. {.name = "udp_pkt_size", .type="int", .desc = "UDP packet length"},
  655. {.name = "data", .type="binary", .desc = "UDP payload"}
  656. };
  657. probe_module_t module_udp = {
  658. .name = "udp",
  659. .packet_length = 1,
  660. .pcap_filter = "udp || icmp",
  661. .pcap_snaplen = 1500,
  662. .port_args = 1,
  663. .thread_initialize = &udp_init_perthread,
  664. .global_initialize = &udp_global_initialize,
  665. .make_packet = &udp_make_packet,
  666. .print_packet = &udp_print_packet,
  667. .validate_packet = &udp_validate_packet,
  668. .process_packet = &udp_process_packet,
  669. .close = &udp_global_cleanup,
  670. .helptext = "Probe module that sends UDP packets to hosts. Packets can "
  671. "optionally be templated based on destination host. Specify"
  672. " packet file with --probe-args=file:/path_to_packet_file "
  673. "and templates with template:/path_to_template_file.",
  674. .fields = fields,
  675. .numfields = sizeof(fields)/sizeof(fields[0])
  676. };