ngrep и utf-8

Mar 23, 2010 04:41

Столкнулся с проблемой: tcpflow и ngrep при выводе на консоль принудительно вырезают из дампа пакета непечатные символы, но считают таковыми весь юникод. При просмотре текстовых протоколов, вроде несжатого Jabber, это весьма раздражает - все юникодные надписи превращаются в многоточия.
Проблему решил небольшим патчем к ngrep. Он достаточно некрасивый, но работает.
Добавляет к ngrep новую опцию -u; если она указана - переключает вывод (-W) в режим none (одна строка - чтобы не рвался юникод при переносе) и принудительно выводит ВСЕ управляющие символы в сыром виде - "как есть". При работе с бинарными данными это может привести к плачевным результатам, зато с текстовыми в юникоде - всё более-менее нормально.
Конечно, по-хорошему стоило бы как-то определять, является ли очередной символ валидным юникодом, но для этого надо видимо устраивать очередь, буферизацию, потом исправлять переносы... В общем, мне и этого патча хватает.

Итак, вот сам патч - ngrep-1.45-unprinted.patch:

--- ngrep-1.45/ngrep.c 2006-11-28 16:38:43.000000000 +0300
+++ ngrep-1.45.mod/ngrep.c 2010-03-23 04:19:14.798948930 +0300
@@ -99,6 +99,13 @@

#include "ngrep.h"

+char unprinted = 0;
+int isprint_u(char c) {
+ if(unprinted)
+ return 1;
+ return isprint(c);
+}
+

static char rcsver[] = "$Revision: 1.93 $";

@@ -195,7 +202,7 @@
signal(SIGWINCH, update_windowsize);
#endif

- while ((c = getopt(argc, argv, "LNhXViwqpevxlDtTRMs:n:c:d:A:I:O:S:P:F:W:")) != EOF) {
+ while ((c = getopt(argc, argv, "LNhXViwqpevxlDtTRMus:n:c:d:A:I:O:S:P:F:W:")) != EOF) {
switch (c) {
case 'W': {
if (!strcasecmp(optarg, "normal"))
@@ -260,6 +267,9 @@
case 'M':
re_multiline_match = 0;
break;
+ case 'u': // print unprinted chars
+ unprinted = 1;
+ dump_func = &dump_unwrapped;
case 'R':
dont_dropprivs = 1;
break;
@@ -953,7 +963,7 @@
const unsigned char *s = data;

while (s < data + len) {
- printf("%c", (*s == '\n' || isprint(*s)) ? *s : nonprint_char);
+ printf("%c", (*s == '\n' || isprint_u(*s)) ? *s : nonprint_char);
s++;
}

@@ -966,7 +976,7 @@
const unsigned char *s = data;

while (s < data + len) {
- printf("%c", isprint(*s) ? *s : nonprint_char);
+ printf("%c", isprint_u(*s) ? *s : nonprint_char);
s++;
}

@@ -996,7 +1006,7 @@

for (j = 0; j < width; j++)
if (i + j < len)
- printf("%c", isprint(str[j]) ? str[j] : nonprint_char);
+ printf("%c", isprint_u(str[j]) ? str[j] : nonprint_char);
else printf(" ");

str += width;
@@ -1244,6 +1254,7 @@
" -W is set the dump format (normal, byline, single, none)\n"
" -c is force the column width to the specified size\n"
" -P is set the non-printable display char to what is specified\n"
+ " -u is force printing all non-printable characters as-is\n"
" -F is read the bpf filter from the specified file\n"
" -N is show sub protocol number\n"
#if defined(_WIN32)
Previous post Next post
Up