#!/usr/bin/perl # xtcptrace - a tcpdump "wrapper" to decode X KeyCodes # Dave Plonka , Aug 27 1998 # # Affected: # Digital Unix 4.0E # SuSE Linux 6.1 # Red Hat Linux 6.0 # Solaris 2.6 $tcpdump='/path/to/tcpdump'; if (! -x ${tcpdump}) { print STDERR "You don't seem to have execute permission on \"${tcpdump}\".\n"; exit 1 } # X KeyCodes... These can be determined using xkeycaps(1), for example. # I assume these are well documented somewhere. # Remember we're watching key presses here, not the resulting X KeySym or # ASCII character. So a '[SHIFT]' preceeding an 'A' is probably a capital # letter A, etc. %code = ( 0x0A => '1', 0x0B => '2', 0x0C => '3', 0x0D => '4', 0x0E => '5', 0x0F => '6', 0x10 => '7', 0x11 => '8', 0x12 => '9', 0x13 => '0', 0x26 => 'A', 0x38 => 'B', 0x36 => 'C', 0x28 => 'D', 0x1A => 'E', 0x29 => 'F', 0x2A => 'G', 0x2B => 'H', 0x1F => 'I', 0x2C => 'J', 0x2D => 'K', 0x2E => 'L', 0x3A => 'M', 0x39 => 'N', 0x20 => 'O', 0x21 => 'P', 0x18 => 'Q', 0x1B => 'R', 0x27 => 'S', 0x1C => 'T', 0x1E => 'U', 0x37 => 'V', 0x19 => 'W', 0x35 => 'X', 0x1D => 'Y', 0x34 => 'Z', 0x40 => '[ALT]', 0x41 => ' ', 0x42 => '[CAPS LOCK]', 0x32 => '[SHIFT]', 0x24 => '[RETURN]', 0x16 => '[BACK SPACE]', ); open(STDIN, "${tcpdump} -l -x -s 65535 -v @ARGV|") || die; select(STDIN); $| = 1; select(STDOUT); $| = 1; while () { # This is a total kludge below - we only look at 32 byte packets since # that is the size of an xEvent. However, we may miss some events because # they can be grouped together in one packet. So really, any multiple of # 32 (e.g. 64, 96) could also contain xEvents. if (m/^\d\d:\d\d:\d\d\.\d+\s+.*\.6000\s+>\s+.*\(32\)/) { scalar(); # discard scalar(); # discard $_ = scalar(); [2000]# Another kludge - the magic numbers in the line below (0x5018, 0x7d78, [2000]# etc.) were discovered by watching xEvents with tcpdump(1). I don't [2000]# know that they'll have those values from all X servers or what. [2000]# Probably, the xEvent typedef struct, as defined in , [2000]# should be grokked to implement this correctly. [2000]# The Right Thing(tm) would probably be to pack the packet content as [2000]# a 32-byte scalar, then unpack it into it's appropriate structure [2000]# members. if (m/5018\s+7d78\s+[0-9a-f][0-9a-f][0-9a-f][0-9a-f]\s+0000\s+03([0-9a-f][0-9a-f])/) { if ($c = $code{hex($1)}) { print "$c\n" } else { print "KeyCode 0x$1\n" } } } } exit # www.hack.co.za [2000]#