You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

528 lines
11 KiB

  1. #line 1 "dnslabeltext.rl"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <string>
  7. #include "dnsname.hh"
  8. #include "namespaces.hh"
  9. #include "dnswriter.hh"
  10. namespace {
  11. void appendSplit(vector<string>& ret, string& segment, char c)
  12. {
  13. if(segment.size()>254) {
  14. ret.push_back(segment);
  15. segment.clear();
  16. }
  17. segment.append(1, c);
  18. }
  19. }
  20. vector<string> segmentDNSText(const string& input )
  21. {
  22. // cerr<<"segmentDNSText("<<input<<")"<<endl;
  23. #line 29 "dnslabeltext.cc"
  24. static const char _dnstext_actions[] = {
  25. 0, 1, 0, 1, 1, 1, 2, 1,
  26. 3, 1, 4, 1, 5, 2, 0, 1,
  27. 2, 4, 5
  28. };
  29. static const char _dnstext_key_offsets[] = {
  30. 0, 0, 1, 3, 5, 7, 9, 11,
  31. 15
  32. };
  33. static const unsigned char _dnstext_trans_keys[] = {
  34. 34u, 34u, 92u, 48u, 57u, 48u, 57u, 48u,
  35. 57u, 34u, 92u, 32u, 34u, 9u, 13u, 34u,
  36. 0
  37. };
  38. static const char _dnstext_single_lengths[] = {
  39. 0, 1, 2, 0, 0, 0, 2, 2,
  40. 1
  41. };
  42. static const char _dnstext_range_lengths[] = {
  43. 0, 0, 0, 1, 1, 1, 0, 1,
  44. 0
  45. };
  46. static const char _dnstext_index_offsets[] = {
  47. 0, 0, 2, 5, 7, 9, 11, 14,
  48. 18
  49. };
  50. static const char _dnstext_trans_targs[] = {
  51. 2, 0, 7, 3, 2, 4, 2, 5,
  52. 0, 6, 0, 7, 3, 2, 8, 2,
  53. 8, 0, 2, 0, 0
  54. };
  55. static const char _dnstext_trans_actions[] = {
  56. 3, 0, 0, 0, 11, 7, 5, 7,
  57. 0, 7, 0, 9, 9, 16, 0, 13,
  58. 0, 0, 13, 0, 0
  59. };
  60. static const char _dnstext_eof_actions[] = {
  61. 0, 0, 0, 0, 0, 0, 0, 1,
  62. 1
  63. };
  64. static const int dnstext_start = 1;
  65. static const int dnstext_first_final = 7;
  66. static const int dnstext_error = 0;
  67. static const int dnstext_en_main = 1;
  68. #line 29 "dnslabeltext.rl"
  69. (void)dnstext_error; // silence warnings
  70. (void)dnstext_en_main;
  71. const char *p = input.c_str(), *pe = input.c_str() + input.length();
  72. const char* eof = pe;
  73. int cs;
  74. char val = 0;
  75. string segment;
  76. vector<string> ret;
  77. #line 99 "dnslabeltext.cc"
  78. {
  79. cs = dnstext_start;
  80. }
  81. #line 104 "dnslabeltext.cc"
  82. {
  83. int _klen;
  84. unsigned int _trans;
  85. const char *_acts;
  86. unsigned int _nacts;
  87. const unsigned char *_keys;
  88. if ( p == pe )
  89. goto _test_eof;
  90. if ( cs == 0 )
  91. goto _out;
  92. _resume:
  93. _keys = _dnstext_trans_keys + _dnstext_key_offsets[cs];
  94. _trans = _dnstext_index_offsets[cs];
  95. _klen = _dnstext_single_lengths[cs];
  96. if ( _klen > 0 ) {
  97. const unsigned char *_lower = _keys;
  98. const unsigned char *_mid;
  99. const unsigned char *_upper = _keys + _klen - 1;
  100. while (1) {
  101. if ( _upper < _lower )
  102. break;
  103. _mid = _lower + ((_upper-_lower) >> 1);
  104. if ( (*p) < *_mid )
  105. _upper = _mid - 1;
  106. else if ( (*p) > *_mid )
  107. _lower = _mid + 1;
  108. else {
  109. _trans += (unsigned int)(_mid - _keys);
  110. goto _match;
  111. }
  112. }
  113. _keys += _klen;
  114. _trans += _klen;
  115. }
  116. _klen = _dnstext_range_lengths[cs];
  117. if ( _klen > 0 ) {
  118. const unsigned char *_lower = _keys;
  119. const unsigned char *_mid;
  120. const unsigned char *_upper = _keys + (_klen<<1) - 2;
  121. while (1) {
  122. if ( _upper < _lower )
  123. break;
  124. _mid = _lower + (((_upper-_lower) >> 1) & ~1);
  125. if ( (*p) < _mid[0] )
  126. _upper = _mid - 2;
  127. else if ( (*p) > _mid[1] )
  128. _lower = _mid + 2;
  129. else {
  130. _trans += (unsigned int)((_mid - _keys)>>1);
  131. goto _match;
  132. }
  133. }
  134. _trans += _klen;
  135. }
  136. _match:
  137. cs = _dnstext_trans_targs[_trans];
  138. if ( _dnstext_trans_actions[_trans] == 0 )
  139. goto _again;
  140. _acts = _dnstext_actions + _dnstext_trans_actions[_trans];
  141. _nacts = (unsigned int) *_acts++;
  142. while ( _nacts-- > 0 )
  143. {
  144. switch ( *_acts++ )
  145. {
  146. case 0:
  147. #line 41 "dnslabeltext.rl"
  148. {
  149. ret.push_back(segment);
  150. segment.clear();
  151. }
  152. break;
  153. case 1:
  154. #line 45 "dnslabeltext.rl"
  155. {
  156. segment.clear();
  157. }
  158. break;
  159. case 2:
  160. #line 49 "dnslabeltext.rl"
  161. {
  162. char c = *p;
  163. appendSplit(ret, segment, c);
  164. }
  165. break;
  166. case 3:
  167. #line 53 "dnslabeltext.rl"
  168. {
  169. char c = *p;
  170. val *= 10;
  171. val += c-'0';
  172. }
  173. break;
  174. case 4:
  175. #line 59 "dnslabeltext.rl"
  176. {
  177. appendSplit(ret, segment, val);
  178. val=0;
  179. }
  180. break;
  181. case 5:
  182. #line 64 "dnslabeltext.rl"
  183. {
  184. appendSplit(ret, segment, *(p));
  185. }
  186. break;
  187. #line 219 "dnslabeltext.cc"
  188. }
  189. }
  190. _again:
  191. if ( cs == 0 )
  192. goto _out;
  193. if ( ++p != pe )
  194. goto _resume;
  195. _test_eof: {}
  196. if ( p == eof )
  197. {
  198. const char *__acts = _dnstext_actions + _dnstext_eof_actions[cs];
  199. unsigned int __nacts = (unsigned int) *__acts++;
  200. while ( __nacts-- > 0 ) {
  201. switch ( *__acts++ ) {
  202. case 0:
  203. #line 41 "dnslabeltext.rl"
  204. {
  205. ret.push_back(segment);
  206. segment.clear();
  207. }
  208. break;
  209. #line 242 "dnslabeltext.cc"
  210. }
  211. }
  212. }
  213. _out: {}
  214. }
  215. #line 77 "dnslabeltext.rl"
  216. if ( cs < dnstext_first_final ) {
  217. throw runtime_error("Unable to parse DNS TXT '"+input+"'");
  218. }
  219. return ret;
  220. };
  221. DNSName::string_t segmentDNSNameRaw(const char* realinput, size_t inputlen)
  222. {
  223. #line 264 "dnslabeltext.cc"
  224. static const char _dnsnameraw_actions[] = {
  225. 0, 1, 0, 1, 1, 1, 2, 1,
  226. 3, 1, 4, 1, 5, 2, 1, 5,
  227. 2, 4, 0, 2, 4, 5
  228. };
  229. static const char _dnsnameraw_key_offsets[] = {
  230. 0, 0, 2, 4, 6, 8, 10, 12
  231. };
  232. static const unsigned char _dnsnameraw_trans_keys[] = {
  233. 46u, 92u, 48u, 57u, 48u, 57u, 48u, 57u,
  234. 46u, 92u, 46u, 92u, 46u, 92u, 0
  235. };
  236. static const char _dnsnameraw_single_lengths[] = {
  237. 0, 2, 0, 0, 0, 2, 2, 2
  238. };
  239. static const char _dnsnameraw_range_lengths[] = {
  240. 0, 0, 1, 1, 1, 0, 0, 0
  241. };
  242. static const char _dnsnameraw_index_offsets[] = {
  243. 0, 0, 3, 5, 7, 9, 12, 15
  244. };
  245. static const char _dnsnameraw_trans_targs[] = {
  246. 0, 2, 5, 3, 5, 4, 0, 7,
  247. 0, 6, 2, 5, 0, 2, 5, 6,
  248. 2, 5, 0
  249. };
  250. static const char _dnsnameraw_trans_actions[] = {
  251. 0, 3, 13, 7, 5, 7, 0, 7,
  252. 0, 1, 0, 11, 0, 3, 13, 16,
  253. 9, 19, 0
  254. };
  255. static const char _dnsnameraw_eof_actions[] = {
  256. 0, 0, 0, 0, 0, 1, 0, 16
  257. };
  258. static const int dnsnameraw_start = 1;
  259. static const int dnsnameraw_first_final = 5;
  260. static const int dnsnameraw_error = 0;
  261. static const int dnsnameraw_en_main = 1;
  262. #line 93 "dnslabeltext.rl"
  263. (void)dnsnameraw_error; // silence warnings
  264. (void)dnsnameraw_en_main;
  265. DNSName::string_t ret;
  266. if(!*realinput || *realinput == '.') {
  267. ret.append(1, (char)0);
  268. return ret;
  269. }
  270. ret.reserve(inputlen+1);
  271. const char *p = realinput, *pe = realinput + inputlen;
  272. const char* eof = pe;
  273. int cs;
  274. char val = 0;
  275. char labellen=0;
  276. unsigned int lenpos=0;
  277. #line 336 "dnslabeltext.cc"
  278. {
  279. cs = dnsnameraw_start;
  280. }
  281. #line 341 "dnslabeltext.cc"
  282. {
  283. int _klen;
  284. unsigned int _trans;
  285. const char *_acts;
  286. unsigned int _nacts;
  287. const unsigned char *_keys;
  288. if ( p == pe )
  289. goto _test_eof;
  290. if ( cs == 0 )
  291. goto _out;
  292. _resume:
  293. _keys = _dnsnameraw_trans_keys + _dnsnameraw_key_offsets[cs];
  294. _trans = _dnsnameraw_index_offsets[cs];
  295. _klen = _dnsnameraw_single_lengths[cs];
  296. if ( _klen > 0 ) {
  297. const unsigned char *_lower = _keys;
  298. const unsigned char *_mid;
  299. const unsigned char *_upper = _keys + _klen - 1;
  300. while (1) {
  301. if ( _upper < _lower )
  302. break;
  303. _mid = _lower + ((_upper-_lower) >> 1);
  304. if ( (*p) < *_mid )
  305. _upper = _mid - 1;
  306. else if ( (*p) > *_mid )
  307. _lower = _mid + 1;
  308. else {
  309. _trans += (unsigned int)(_mid - _keys);
  310. goto _match;
  311. }
  312. }
  313. _keys += _klen;
  314. _trans += _klen;
  315. }
  316. _klen = _dnsnameraw_range_lengths[cs];
  317. if ( _klen > 0 ) {
  318. const unsigned char *_lower = _keys;
  319. const unsigned char *_mid;
  320. const unsigned char *_upper = _keys + (_klen<<1) - 2;
  321. while (1) {
  322. if ( _upper < _lower )
  323. break;
  324. _mid = _lower + (((_upper-_lower) >> 1) & ~1);
  325. if ( (*p) < _mid[0] )
  326. _upper = _mid - 2;
  327. else if ( (*p) > _mid[1] )
  328. _lower = _mid + 2;
  329. else {
  330. _trans += (unsigned int)((_mid - _keys)>>1);
  331. goto _match;
  332. }
  333. }
  334. _trans += _klen;
  335. }
  336. _match:
  337. cs = _dnsnameraw_trans_targs[_trans];
  338. if ( _dnsnameraw_trans_actions[_trans] == 0 )
  339. goto _again;
  340. _acts = _dnsnameraw_actions + _dnsnameraw_trans_actions[_trans];
  341. _nacts = (unsigned int) *_acts++;
  342. while ( _nacts-- > 0 )
  343. {
  344. switch ( *_acts++ )
  345. {
  346. case 0:
  347. #line 113 "dnslabeltext.rl"
  348. {
  349. if (labellen < 0 || labellen > 63) {
  350. throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
  351. }
  352. ret[lenpos]=labellen;
  353. labellen=0;
  354. }
  355. break;
  356. case 1:
  357. #line 120 "dnslabeltext.rl"
  358. {
  359. lenpos=ret.size();
  360. ret.append(1, (char)0);
  361. labellen=0;
  362. }
  363. break;
  364. case 2:
  365. #line 126 "dnslabeltext.rl"
  366. {
  367. char c = *p;
  368. ret.append(1, c);
  369. labellen++;
  370. }
  371. break;
  372. case 3:
  373. #line 131 "dnslabeltext.rl"
  374. {
  375. char c = *p;
  376. val *= 10;
  377. val += c-'0';
  378. }
  379. break;
  380. case 4:
  381. #line 136 "dnslabeltext.rl"
  382. {
  383. ret.append(1, val);
  384. labellen++;
  385. val=0;
  386. }
  387. break;
  388. case 5:
  389. #line 142 "dnslabeltext.rl"
  390. {
  391. ret.append(1, *(p));
  392. labellen++;
  393. }
  394. break;
  395. #line 463 "dnslabeltext.cc"
  396. }
  397. }
  398. _again:
  399. if ( cs == 0 )
  400. goto _out;
  401. if ( ++p != pe )
  402. goto _resume;
  403. _test_eof: {}
  404. if ( p == eof )
  405. {
  406. const char *__acts = _dnsnameraw_actions + _dnsnameraw_eof_actions[cs];
  407. unsigned int __nacts = (unsigned int) *__acts++;
  408. while ( __nacts-- > 0 ) {
  409. switch ( *__acts++ ) {
  410. case 0:
  411. #line 113 "dnslabeltext.rl"
  412. {
  413. if (labellen < 0 || labellen > 63) {
  414. throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
  415. }
  416. ret[lenpos]=labellen;
  417. labellen=0;
  418. }
  419. break;
  420. case 4:
  421. #line 136 "dnslabeltext.rl"
  422. {
  423. ret.append(1, val);
  424. labellen++;
  425. val=0;
  426. }
  427. break;
  428. #line 497 "dnslabeltext.cc"
  429. }
  430. }
  431. }
  432. _out: {}
  433. }
  434. #line 163 "dnslabeltext.rl"
  435. if ( cs < dnsnameraw_first_final ) {
  436. throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': cs="+std::to_string(cs));
  437. }
  438. ret.append(1, (char)0);
  439. return ret;
  440. };
  441. #if 0
  442. int main()
  443. {
  444. //char blah[]="\"blah\" \"bleh\" \"bloeh\\\"bleh\" \"\\97enzo\"";
  445. char blah[]="\"v=spf1 ip4:67.106.74.128/25 ip4:63.138.42.224/28 ip4:65.204.46.224/27 \\013\\010ip4:66.104.217.176/28 \\013\\010ip4:209.48.147.0/27 ~all\"";
  446. //char blah[]="\"abc \\097\\098 def\"";
  447. printf("Input: '%s'\n", blah);
  448. vector<string> res=dnstext(blah);
  449. cerr<<res.size()<<" segments"<<endl;
  450. cerr<<res[0]<<endl;
  451. }
  452. #endif