#!/bin/sh # this script require user to be in same group as tcpick # with tcpick capabilities set to cap_net_admin,cap_net_raw+eip # # accsniffer -- capture account ids, add to char db # change result quoting when needed # # IMPORTANT: sniffer assumes mapserver is on same IP as login server # # IMPORTANT: sniffer captures only separate payloads of 0x095 followed by # 0x0195 packets and will miss all IDs in crowded places # use pysniffer instead # # despite accsniffer provides ghetto circular cache # better option would be obviously doubly linked list # # it's not recommended to set large cachelimit with current caching # default is 50 # # options: # $1 -- server name; e.g. server.themanaworld.org # $2 -- tmww config with all required options : ${1?Usage: accsniffer servername config} # INTERFACE=eth0 AWK="/usr/bin/mawk -Winteractive" cachelimit=50 /usr/bin/stdbuf -oL /usr/sbin/tcpick ${INTERFACE:+ -i $INTERFACE} \ "src $1 && port 5122 && \ tcp[((tcp[12:1] & 0xf0) >> 2):2] = 0x9500" -yH \ | $AWK -F "" -v config="$2" -v cachelimit="${cachelimit}" -- ' # nccache (char cache counter) and npcache (party cache counter) are # char/party circular cache pointers; # should be arrays to be globally available inside function BEGIN { nccache[0] = 0; npcache[0] = 0 } # push line to particular cache, applying stack limit function push(line,counter,cache) { for (i in cache) { if ( cache[i] == line ) return 0 } cache[ counter[0]++ ] = line if ( counter[0] >= cachelimit ) counter[0] = 0 return 1 } # decode from something like 00 0a 23 cd into binary function decode(nm, char) { if ( nm == "" ) return "" char = "" while ((a = substr(nm,1,2)) != "00" && a != "" ) { char = char sprintf("%c", int("0x" a)) nm = substr(nm,4) } return char } { # check could be moved to pcap expression but anyway tcpick spams intro/outro if ( substr($0,16,2) == "00" ) { # offset: n*3+1, length: n*2+n-1 id1 = substr($0,7,2) id2 = substr($0,10,2) id3 = substr($0,13,2) id4 = substr($0,16,2) accid = int("0x" id4 id3 id2 id1) # offset 6, length 24 name = substr($0,19,71) decoded_name = decode(name) # cache char if ( push(accid decoded_name, nccache, ccache) ) { # action gsub("'\''","'\''\"'\''\"'\''",decoded_name) add_char = sprintf("id %i char '\''%s'\''", accid, decoded_name) # print add_char # system("tmww -ya alts " config " char add " add_char) system("tmww -ya alts " config " char resolve " add_char) } # check if next following packet is 0x0195 - party name # offset 30 check = substr($0,91,5) if ( check != "" && check == "95 01" ) { # offset 36, length 23 party = substr($0,109,68) decoded_party = decode(party) # cache party if ( push(decoded_party decoded_char, npcache, pcache) ) { # action gsub("'\''","'\''\"'\''\"'\''",decoded_party) add_party = sprintf ("party '\''%s'\'' char '\''%s'\''", decoded_party, decoded_name) # print add_party system("tmww -ya alts " config " party add " add_party) } } } } '