print-rx.c 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893
  1. /*
  2. * Copyright: (c) 2000 United States Government as represented by the
  3. * Secretary of the Navy. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. * 3. The names of the authors may not be used to endorse or promote
  16. * products derived from this software without specific prior
  17. * written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  22. */
  23. /* \summary: AFS RX printer */
  24. /*
  25. * This code unmangles RX packets. RX is the mutant form of RPC that AFS
  26. * uses to communicate between clients and servers.
  27. *
  28. * In this code, I mainly concern myself with decoding the AFS calls, not
  29. * with the guts of RX, per se.
  30. *
  31. * Bah. If I never look at rx_packet.h again, it will be too soon.
  32. *
  33. * Ken Hornstein <kenh@cmf.nrl.navy.mil>
  34. */
  35. #ifdef HAVE_CONFIG_H
  36. #include "config.h"
  37. #endif
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <netdissect-stdinc.h>
  42. #include "netdissect.h"
  43. #include "addrtoname.h"
  44. #include "extract.h"
  45. #include "ip.h"
  46. #define FS_RX_PORT 7000
  47. #define CB_RX_PORT 7001
  48. #define PROT_RX_PORT 7002
  49. #define VLDB_RX_PORT 7003
  50. #define KAUTH_RX_PORT 7004
  51. #define VOL_RX_PORT 7005
  52. #define ERROR_RX_PORT 7006 /* Doesn't seem to be used */
  53. #define BOS_RX_PORT 7007
  54. #define AFSNAMEMAX 256
  55. #define AFSOPAQUEMAX 1024
  56. #define PRNAMEMAX 64
  57. #define VLNAMEMAX 65
  58. #define KANAMEMAX 64
  59. #define BOSNAMEMAX 256
  60. #define PRSFS_READ 1 /* Read files */
  61. #define PRSFS_WRITE 2 /* Write files */
  62. #define PRSFS_INSERT 4 /* Insert files into a directory */
  63. #define PRSFS_LOOKUP 8 /* Lookup files into a directory */
  64. #define PRSFS_DELETE 16 /* Delete files */
  65. #define PRSFS_LOCK 32 /* Lock files */
  66. #define PRSFS_ADMINISTER 64 /* Change ACL's */
  67. struct rx_header {
  68. nd_uint32_t epoch;
  69. nd_uint32_t cid;
  70. nd_uint32_t callNumber;
  71. nd_uint32_t seq;
  72. nd_uint32_t serial;
  73. nd_uint8_t type;
  74. #define RX_PACKET_TYPE_DATA 1
  75. #define RX_PACKET_TYPE_ACK 2
  76. #define RX_PACKET_TYPE_BUSY 3
  77. #define RX_PACKET_TYPE_ABORT 4
  78. #define RX_PACKET_TYPE_ACKALL 5
  79. #define RX_PACKET_TYPE_CHALLENGE 6
  80. #define RX_PACKET_TYPE_RESPONSE 7
  81. #define RX_PACKET_TYPE_DEBUG 8
  82. #define RX_PACKET_TYPE_PARAMS 9
  83. #define RX_PACKET_TYPE_VERSION 13
  84. nd_uint8_t flags;
  85. #define RX_CLIENT_INITIATED 1
  86. #define RX_REQUEST_ACK 2
  87. #define RX_LAST_PACKET 4
  88. #define RX_MORE_PACKETS 8
  89. #define RX_FREE_PACKET 16
  90. #define RX_SLOW_START_OK 32
  91. #define RX_JUMBO_PACKET 32
  92. nd_uint8_t userStatus;
  93. nd_uint8_t securityIndex;
  94. nd_uint16_t spare; /* How clever: even though the AFS */
  95. nd_uint16_t serviceId; /* header files indicate that the */
  96. }; /* serviceId is first, it's really */
  97. /* encoded _after_ the spare field */
  98. /* I wasted a day figuring that out! */
  99. #define NUM_RX_FLAGS 7
  100. #define RX_MAXACKS 255
  101. struct rx_ackPacket {
  102. uint16_t bufferSpace; /* Number of packet buffers available */
  103. uint16_t maxSkew; /* Max diff between ack'd packet and */
  104. /* highest packet received */
  105. uint32_t firstPacket; /* The first packet in ack list */
  106. uint32_t previousPacket; /* Previous packet recv'd (obsolete) */
  107. uint32_t serial; /* # of packet that prompted the ack */
  108. uint8_t reason; /* Reason for acknowledgement */
  109. uint8_t nAcks; /* Number of acknowledgements */
  110. uint8_t acks[RX_MAXACKS]; /* Up to RX_MAXACKS acknowledgements */
  111. };
  112. /*
  113. * Values for the acks array
  114. */
  115. #define RX_ACK_TYPE_NACK 0 /* Don't have this packet */
  116. #define RX_ACK_TYPE_ACK 1 /* I have this packet */
  117. static const struct tok rx_types[] = {
  118. { RX_PACKET_TYPE_DATA, "data" },
  119. { RX_PACKET_TYPE_ACK, "ack" },
  120. { RX_PACKET_TYPE_BUSY, "busy" },
  121. { RX_PACKET_TYPE_ABORT, "abort" },
  122. { RX_PACKET_TYPE_ACKALL, "ackall" },
  123. { RX_PACKET_TYPE_CHALLENGE, "challenge" },
  124. { RX_PACKET_TYPE_RESPONSE, "response" },
  125. { RX_PACKET_TYPE_DEBUG, "debug" },
  126. { RX_PACKET_TYPE_PARAMS, "params" },
  127. { RX_PACKET_TYPE_VERSION, "version" },
  128. { 0, NULL },
  129. };
  130. static const struct double_tok {
  131. int flag; /* Rx flag */
  132. int packetType; /* Packet type */
  133. const char *s; /* Flag string */
  134. } rx_flags[] = {
  135. { RX_CLIENT_INITIATED, 0, "client-init" },
  136. { RX_REQUEST_ACK, 0, "req-ack" },
  137. { RX_LAST_PACKET, 0, "last-pckt" },
  138. { RX_MORE_PACKETS, 0, "more-pckts" },
  139. { RX_FREE_PACKET, 0, "free-pckt" },
  140. { RX_SLOW_START_OK, RX_PACKET_TYPE_ACK, "slow-start" },
  141. { RX_JUMBO_PACKET, RX_PACKET_TYPE_DATA, "jumbogram" }
  142. };
  143. static const struct tok fs_req[] = {
  144. { 130, "fetch-data" },
  145. { 131, "fetch-acl" },
  146. { 132, "fetch-status" },
  147. { 133, "store-data" },
  148. { 134, "store-acl" },
  149. { 135, "store-status" },
  150. { 136, "remove-file" },
  151. { 137, "create-file" },
  152. { 138, "rename" },
  153. { 139, "symlink" },
  154. { 140, "link" },
  155. { 141, "makedir" },
  156. { 142, "rmdir" },
  157. { 143, "oldsetlock" },
  158. { 144, "oldextlock" },
  159. { 145, "oldrellock" },
  160. { 146, "get-stats" },
  161. { 147, "give-cbs" },
  162. { 148, "get-vlinfo" },
  163. { 149, "get-vlstats" },
  164. { 150, "set-vlstats" },
  165. { 151, "get-rootvl" },
  166. { 152, "check-token" },
  167. { 153, "get-time" },
  168. { 154, "nget-vlinfo" },
  169. { 155, "bulk-stat" },
  170. { 156, "setlock" },
  171. { 157, "extlock" },
  172. { 158, "rellock" },
  173. { 159, "xstat-ver" },
  174. { 160, "get-xstat" },
  175. { 161, "dfs-lookup" },
  176. { 162, "dfs-flushcps" },
  177. { 163, "dfs-symlink" },
  178. { 220, "residency" },
  179. { 65536, "inline-bulk-status" },
  180. { 65537, "fetch-data-64" },
  181. { 65538, "store-data-64" },
  182. { 65539, "give-up-all-cbs" },
  183. { 65540, "get-caps" },
  184. { 65541, "cb-rx-conn-addr" },
  185. { 0, NULL },
  186. };
  187. static const struct tok cb_req[] = {
  188. { 204, "callback" },
  189. { 205, "initcb" },
  190. { 206, "probe" },
  191. { 207, "getlock" },
  192. { 208, "getce" },
  193. { 209, "xstatver" },
  194. { 210, "getxstat" },
  195. { 211, "initcb2" },
  196. { 212, "whoareyou" },
  197. { 213, "initcb3" },
  198. { 214, "probeuuid" },
  199. { 215, "getsrvprefs" },
  200. { 216, "getcellservdb" },
  201. { 217, "getlocalcell" },
  202. { 218, "getcacheconf" },
  203. { 65536, "getce64" },
  204. { 65537, "getcellbynum" },
  205. { 65538, "tellmeaboutyourself" },
  206. { 0, NULL },
  207. };
  208. static const struct tok pt_req[] = {
  209. { 500, "new-user" },
  210. { 501, "where-is-it" },
  211. { 502, "dump-entry" },
  212. { 503, "add-to-group" },
  213. { 504, "name-to-id" },
  214. { 505, "id-to-name" },
  215. { 506, "delete" },
  216. { 507, "remove-from-group" },
  217. { 508, "get-cps" },
  218. { 509, "new-entry" },
  219. { 510, "list-max" },
  220. { 511, "set-max" },
  221. { 512, "list-entry" },
  222. { 513, "change-entry" },
  223. { 514, "list-elements" },
  224. { 515, "same-mbr-of" },
  225. { 516, "set-fld-sentry" },
  226. { 517, "list-owned" },
  227. { 518, "get-cps2" },
  228. { 519, "get-host-cps" },
  229. { 520, "update-entry" },
  230. { 521, "list-entries" },
  231. { 530, "list-super-groups" },
  232. { 0, NULL },
  233. };
  234. static const struct tok vldb_req[] = {
  235. { 501, "create-entry" },
  236. { 502, "delete-entry" },
  237. { 503, "get-entry-by-id" },
  238. { 504, "get-entry-by-name" },
  239. { 505, "get-new-volume-id" },
  240. { 506, "replace-entry" },
  241. { 507, "update-entry" },
  242. { 508, "setlock" },
  243. { 509, "releaselock" },
  244. { 510, "list-entry" },
  245. { 511, "list-attrib" },
  246. { 512, "linked-list" },
  247. { 513, "get-stats" },
  248. { 514, "probe" },
  249. { 515, "get-addrs" },
  250. { 516, "change-addr" },
  251. { 517, "create-entry-n" },
  252. { 518, "get-entry-by-id-n" },
  253. { 519, "get-entry-by-name-n" },
  254. { 520, "replace-entry-n" },
  255. { 521, "list-entry-n" },
  256. { 522, "list-attrib-n" },
  257. { 523, "linked-list-n" },
  258. { 524, "update-entry-by-name" },
  259. { 525, "create-entry-u" },
  260. { 526, "get-entry-by-id-u" },
  261. { 527, "get-entry-by-name-u" },
  262. { 528, "replace-entry-u" },
  263. { 529, "list-entry-u" },
  264. { 530, "list-attrib-u" },
  265. { 531, "linked-list-u" },
  266. { 532, "regaddr" },
  267. { 533, "get-addrs-u" },
  268. { 534, "list-attrib-n2" },
  269. { 0, NULL },
  270. };
  271. static const struct tok kauth_req[] = {
  272. { 1, "auth-old" },
  273. { 21, "authenticate" },
  274. { 22, "authenticate-v2" },
  275. { 2, "change-pw" },
  276. { 3, "get-ticket-old" },
  277. { 23, "get-ticket" },
  278. { 4, "set-pw" },
  279. { 5, "set-fields" },
  280. { 6, "create-user" },
  281. { 7, "delete-user" },
  282. { 8, "get-entry" },
  283. { 9, "list-entry" },
  284. { 10, "get-stats" },
  285. { 11, "debug" },
  286. { 12, "get-pw" },
  287. { 13, "get-random-key" },
  288. { 14, "unlock" },
  289. { 15, "lock-status" },
  290. { 0, NULL },
  291. };
  292. static const struct tok vol_req[] = {
  293. { 100, "create-volume" },
  294. { 101, "delete-volume" },
  295. { 102, "restore" },
  296. { 103, "forward" },
  297. { 104, "end-trans" },
  298. { 105, "clone" },
  299. { 106, "set-flags" },
  300. { 107, "get-flags" },
  301. { 108, "trans-create" },
  302. { 109, "dump" },
  303. { 110, "get-nth-volume" },
  304. { 111, "set-forwarding" },
  305. { 112, "get-name" },
  306. { 113, "get-status" },
  307. { 114, "sig-restore" },
  308. { 115, "list-partitions" },
  309. { 116, "list-volumes" },
  310. { 117, "set-id-types" },
  311. { 118, "monitor" },
  312. { 119, "partition-info" },
  313. { 120, "reclone" },
  314. { 121, "list-one-volume" },
  315. { 122, "nuke" },
  316. { 123, "set-date" },
  317. { 124, "x-list-volumes" },
  318. { 125, "x-list-one-volume" },
  319. { 126, "set-info" },
  320. { 127, "x-list-partitions" },
  321. { 128, "forward-multiple" },
  322. { 65536, "convert-ro" },
  323. { 65537, "get-size" },
  324. { 65538, "dump-v2" },
  325. { 0, NULL },
  326. };
  327. static const struct tok bos_req[] = {
  328. { 80, "create-bnode" },
  329. { 81, "delete-bnode" },
  330. { 82, "set-status" },
  331. { 83, "get-status" },
  332. { 84, "enumerate-instance" },
  333. { 85, "get-instance-info" },
  334. { 86, "get-instance-parm" },
  335. { 87, "add-superuser" },
  336. { 88, "delete-superuser" },
  337. { 89, "list-superusers" },
  338. { 90, "list-keys" },
  339. { 91, "add-key" },
  340. { 92, "delete-key" },
  341. { 93, "set-cell-name" },
  342. { 94, "get-cell-name" },
  343. { 95, "get-cell-host" },
  344. { 96, "add-cell-host" },
  345. { 97, "delete-cell-host" },
  346. { 98, "set-t-status" },
  347. { 99, "shutdown-all" },
  348. { 100, "restart-all" },
  349. { 101, "startup-all" },
  350. { 102, "set-noauth-flag" },
  351. { 103, "re-bozo" },
  352. { 104, "restart" },
  353. { 105, "start-bozo-install" },
  354. { 106, "uninstall" },
  355. { 107, "get-dates" },
  356. { 108, "exec" },
  357. { 109, "prune" },
  358. { 110, "set-restart-time" },
  359. { 111, "get-restart-time" },
  360. { 112, "start-bozo-log" },
  361. { 113, "wait-all" },
  362. { 114, "get-instance-strings" },
  363. { 115, "get-restricted" },
  364. { 116, "set-restricted" },
  365. { 0, NULL },
  366. };
  367. static const struct tok ubik_req[] = {
  368. { 10000, "vote-beacon" },
  369. { 10001, "vote-debug-old" },
  370. { 10002, "vote-sdebug-old" },
  371. { 10003, "vote-getsyncsite" },
  372. { 10004, "vote-debug" },
  373. { 10005, "vote-sdebug" },
  374. { 10006, "vote-xdebug" },
  375. { 10007, "vote-xsdebug" },
  376. { 20000, "disk-begin" },
  377. { 20001, "disk-commit" },
  378. { 20002, "disk-lock" },
  379. { 20003, "disk-write" },
  380. { 20004, "disk-getversion" },
  381. { 20005, "disk-getfile" },
  382. { 20006, "disk-sendfile" },
  383. { 20007, "disk-abort" },
  384. { 20008, "disk-releaselocks" },
  385. { 20009, "disk-truncate" },
  386. { 20010, "disk-probe" },
  387. { 20011, "disk-writev" },
  388. { 20012, "disk-interfaceaddr" },
  389. { 20013, "disk-setversion" },
  390. { 0, NULL },
  391. };
  392. #define VOTE_LOW 10000
  393. #define VOTE_HIGH 10007
  394. #define DISK_LOW 20000
  395. #define DISK_HIGH 20013
  396. static const struct tok cb_types[] = {
  397. { 1, "exclusive" },
  398. { 2, "shared" },
  399. { 3, "dropped" },
  400. { 0, NULL },
  401. };
  402. static const struct tok ubik_lock_types[] = {
  403. { 1, "read" },
  404. { 2, "write" },
  405. { 3, "wait" },
  406. { 0, NULL },
  407. };
  408. static const char *voltype[] = { "read-write", "read-only", "backup" };
  409. static const struct tok afs_fs_errors[] = {
  410. { 101, "salvage volume" },
  411. { 102, "no such vnode" },
  412. { 103, "no such volume" },
  413. { 104, "volume exist" },
  414. { 105, "no service" },
  415. { 106, "volume offline" },
  416. { 107, "voline online" },
  417. { 108, "diskfull" },
  418. { 109, "diskquota exceeded" },
  419. { 110, "volume busy" },
  420. { 111, "volume moved" },
  421. { 112, "AFS IO error" },
  422. { 0xffffff9c, "restarting fileserver" }, /* -100, sic! */
  423. { 0, NULL }
  424. };
  425. /*
  426. * Reasons for acknowledging a packet
  427. */
  428. static const struct tok rx_ack_reasons[] = {
  429. { 1, "ack requested" },
  430. { 2, "duplicate packet" },
  431. { 3, "out of sequence" },
  432. { 4, "exceeds window" },
  433. { 5, "no buffer space" },
  434. { 6, "ping" },
  435. { 7, "ping response" },
  436. { 8, "delay" },
  437. { 9, "idle" },
  438. { 0, NULL },
  439. };
  440. /*
  441. * Cache entries we keep around so we can figure out the RX opcode
  442. * numbers for replies. This allows us to make sense of RX reply packets.
  443. */
  444. struct rx_cache_entry {
  445. uint32_t callnum; /* Call number (net order) */
  446. struct in_addr client; /* client IP address (net order) */
  447. struct in_addr server; /* server IP address (net order) */
  448. int dport; /* server port (host order) */
  449. u_short serviceId; /* Service identifier (net order) */
  450. uint32_t opcode; /* RX opcode (host order) */
  451. };
  452. #define RX_CACHE_SIZE 64
  453. static struct rx_cache_entry rx_cache[RX_CACHE_SIZE];
  454. static int rx_cache_next = 0;
  455. static int rx_cache_hint = 0;
  456. static void rx_cache_insert(netdissect_options *, const u_char *, const struct ip *, int);
  457. static int rx_cache_find(const struct rx_header *, const struct ip *,
  458. int, int32_t *);
  459. static void fs_print(netdissect_options *, const u_char *, int);
  460. static void fs_reply_print(netdissect_options *, const u_char *, int, int32_t);
  461. static void acl_print(netdissect_options *, u_char *, int, u_char *);
  462. static void cb_print(netdissect_options *, const u_char *, int);
  463. static void cb_reply_print(netdissect_options *, const u_char *, int, int32_t);
  464. static void prot_print(netdissect_options *, const u_char *, int);
  465. static void prot_reply_print(netdissect_options *, const u_char *, int, int32_t);
  466. static void vldb_print(netdissect_options *, const u_char *, int);
  467. static void vldb_reply_print(netdissect_options *, const u_char *, int, int32_t);
  468. static void kauth_print(netdissect_options *, const u_char *, int);
  469. static void kauth_reply_print(netdissect_options *, const u_char *, int, int32_t);
  470. static void vol_print(netdissect_options *, const u_char *, int);
  471. static void vol_reply_print(netdissect_options *, const u_char *, int, int32_t);
  472. static void bos_print(netdissect_options *, const u_char *, int);
  473. static void bos_reply_print(netdissect_options *, const u_char *, int, int32_t);
  474. static void ubik_print(netdissect_options *, const u_char *);
  475. static void ubik_reply_print(netdissect_options *, const u_char *, int, int32_t);
  476. static void rx_ack_print(netdissect_options *, const u_char *, int);
  477. static int is_ubik(uint32_t);
  478. /*
  479. * Handle the rx-level packet. See if we know what port it's going to so
  480. * we can peek at the afs call inside
  481. */
  482. void
  483. rx_print(netdissect_options *ndo,
  484. register const u_char *bp, int length, int sport, int dport,
  485. const u_char *bp2)
  486. {
  487. register const struct rx_header *rxh;
  488. int i;
  489. int32_t opcode;
  490. if (ndo->ndo_snapend - bp < (int)sizeof (struct rx_header)) {
  491. ND_PRINT((ndo, " [|rx] (%d)", length));
  492. return;
  493. }
  494. rxh = (const struct rx_header *) bp;
  495. ND_PRINT((ndo, " rx %s", tok2str(rx_types, "type %d", rxh->type)));
  496. if (ndo->ndo_vflag) {
  497. int firstflag = 0;
  498. if (ndo->ndo_vflag > 1)
  499. ND_PRINT((ndo, " cid %08x call# %d",
  500. (int) EXTRACT_32BITS(&rxh->cid),
  501. (int) EXTRACT_32BITS(&rxh->callNumber)));
  502. ND_PRINT((ndo, " seq %d ser %d",
  503. (int) EXTRACT_32BITS(&rxh->seq),
  504. (int) EXTRACT_32BITS(&rxh->serial)));
  505. if (ndo->ndo_vflag > 2)
  506. ND_PRINT((ndo, " secindex %d serviceid %hu",
  507. (int) rxh->securityIndex,
  508. EXTRACT_16BITS(&rxh->serviceId)));
  509. if (ndo->ndo_vflag > 1)
  510. for (i = 0; i < NUM_RX_FLAGS; i++) {
  511. if (rxh->flags & rx_flags[i].flag &&
  512. (!rx_flags[i].packetType ||
  513. rxh->type == rx_flags[i].packetType)) {
  514. if (!firstflag) {
  515. firstflag = 1;
  516. ND_PRINT((ndo, " "));
  517. } else {
  518. ND_PRINT((ndo, ","));
  519. }
  520. ND_PRINT((ndo, "<%s>", rx_flags[i].s));
  521. }
  522. }
  523. }
  524. /*
  525. * Try to handle AFS calls that we know about. Check the destination
  526. * port and make sure it's a data packet. Also, make sure the
  527. * seq number is 1 (because otherwise it's a continuation packet,
  528. * and we can't interpret that). Also, seems that reply packets
  529. * do not have the client-init flag set, so we check for that
  530. * as well.
  531. */
  532. if (rxh->type == RX_PACKET_TYPE_DATA &&
  533. EXTRACT_32BITS(&rxh->seq) == 1 &&
  534. rxh->flags & RX_CLIENT_INITIATED) {
  535. /*
  536. * Insert this call into the call cache table, so we
  537. * have a chance to print out replies
  538. */
  539. rx_cache_insert(ndo, bp, (const struct ip *) bp2, dport);
  540. switch (dport) {
  541. case FS_RX_PORT: /* AFS file service */
  542. fs_print(ndo, bp, length);
  543. break;
  544. case CB_RX_PORT: /* AFS callback service */
  545. cb_print(ndo, bp, length);
  546. break;
  547. case PROT_RX_PORT: /* AFS protection service */
  548. prot_print(ndo, bp, length);
  549. break;
  550. case VLDB_RX_PORT: /* AFS VLDB service */
  551. vldb_print(ndo, bp, length);
  552. break;
  553. case KAUTH_RX_PORT: /* AFS Kerberos auth service */
  554. kauth_print(ndo, bp, length);
  555. break;
  556. case VOL_RX_PORT: /* AFS Volume service */
  557. vol_print(ndo, bp, length);
  558. break;
  559. case BOS_RX_PORT: /* AFS BOS service */
  560. bos_print(ndo, bp, length);
  561. break;
  562. default:
  563. ;
  564. }
  565. /*
  566. * If it's a reply (client-init is _not_ set, but seq is one)
  567. * then look it up in the cache. If we find it, call the reply
  568. * printing functions Note that we handle abort packets here,
  569. * because printing out the return code can be useful at times.
  570. */
  571. } else if (((rxh->type == RX_PACKET_TYPE_DATA &&
  572. EXTRACT_32BITS(&rxh->seq) == 1) ||
  573. rxh->type == RX_PACKET_TYPE_ABORT) &&
  574. (rxh->flags & RX_CLIENT_INITIATED) == 0 &&
  575. rx_cache_find(rxh, (const struct ip *) bp2,
  576. sport, &opcode)) {
  577. switch (sport) {
  578. case FS_RX_PORT: /* AFS file service */
  579. fs_reply_print(ndo, bp, length, opcode);
  580. break;
  581. case CB_RX_PORT: /* AFS callback service */
  582. cb_reply_print(ndo, bp, length, opcode);
  583. break;
  584. case PROT_RX_PORT: /* AFS PT service */
  585. prot_reply_print(ndo, bp, length, opcode);
  586. break;
  587. case VLDB_RX_PORT: /* AFS VLDB service */
  588. vldb_reply_print(ndo, bp, length, opcode);
  589. break;
  590. case KAUTH_RX_PORT: /* AFS Kerberos auth service */
  591. kauth_reply_print(ndo, bp, length, opcode);
  592. break;
  593. case VOL_RX_PORT: /* AFS Volume service */
  594. vol_reply_print(ndo, bp, length, opcode);
  595. break;
  596. case BOS_RX_PORT: /* AFS BOS service */
  597. bos_reply_print(ndo, bp, length, opcode);
  598. break;
  599. default:
  600. ;
  601. }
  602. /*
  603. * If it's an RX ack packet, then use the appropriate ack decoding
  604. * function (there isn't any service-specific information in the
  605. * ack packet, so we can use one for all AFS services)
  606. */
  607. } else if (rxh->type == RX_PACKET_TYPE_ACK)
  608. rx_ack_print(ndo, bp, length);
  609. ND_PRINT((ndo, " (%d)", length));
  610. }
  611. /*
  612. * Insert an entry into the cache. Taken from print-nfs.c
  613. */
  614. static void
  615. rx_cache_insert(netdissect_options *ndo,
  616. const u_char *bp, const struct ip *ip, int dport)
  617. {
  618. struct rx_cache_entry *rxent;
  619. const struct rx_header *rxh = (const struct rx_header *) bp;
  620. if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t)))
  621. return;
  622. rxent = &rx_cache[rx_cache_next];
  623. if (++rx_cache_next >= RX_CACHE_SIZE)
  624. rx_cache_next = 0;
  625. rxent->callnum = EXTRACT_32BITS(&rxh->callNumber);
  626. UNALIGNED_MEMCPY(&rxent->client, &ip->ip_src, sizeof(uint32_t));
  627. UNALIGNED_MEMCPY(&rxent->server, &ip->ip_dst, sizeof(uint32_t));
  628. rxent->dport = dport;
  629. rxent->serviceId = EXTRACT_32BITS(&rxh->serviceId);
  630. rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  631. }
  632. /*
  633. * Lookup an entry in the cache. Also taken from print-nfs.c
  634. *
  635. * Note that because this is a reply, we're looking at the _source_
  636. * port.
  637. */
  638. static int
  639. rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,
  640. int32_t *opcode)
  641. {
  642. int i;
  643. struct rx_cache_entry *rxent;
  644. uint32_t clip;
  645. uint32_t sip;
  646. UNALIGNED_MEMCPY(&clip, &ip->ip_dst, sizeof(uint32_t));
  647. UNALIGNED_MEMCPY(&sip, &ip->ip_src, sizeof(uint32_t));
  648. /* Start the search where we last left off */
  649. i = rx_cache_hint;
  650. do {
  651. rxent = &rx_cache[i];
  652. if (rxent->callnum == EXTRACT_32BITS(&rxh->callNumber) &&
  653. rxent->client.s_addr == clip &&
  654. rxent->server.s_addr == sip &&
  655. rxent->serviceId == EXTRACT_32BITS(&rxh->serviceId) &&
  656. rxent->dport == sport) {
  657. /* We got a match! */
  658. rx_cache_hint = i;
  659. *opcode = rxent->opcode;
  660. return(1);
  661. }
  662. if (++i >= RX_CACHE_SIZE)
  663. i = 0;
  664. } while (i != rx_cache_hint);
  665. /* Our search failed */
  666. return(0);
  667. }
  668. /*
  669. * These extrememly grody macros handle the printing of various AFS stuff.
  670. */
  671. #define FIDOUT() { unsigned long n1, n2, n3; \
  672. ND_TCHECK2(bp[0], sizeof(int32_t) * 3); \
  673. n1 = EXTRACT_32BITS(bp); \
  674. bp += sizeof(int32_t); \
  675. n2 = EXTRACT_32BITS(bp); \
  676. bp += sizeof(int32_t); \
  677. n3 = EXTRACT_32BITS(bp); \
  678. bp += sizeof(int32_t); \
  679. ND_PRINT((ndo, " fid %d/%d/%d", (int) n1, (int) n2, (int) n3)); \
  680. }
  681. #define STROUT(MAX) { unsigned int _i; \
  682. ND_TCHECK2(bp[0], sizeof(int32_t)); \
  683. _i = EXTRACT_32BITS(bp); \
  684. if (_i > (MAX)) \
  685. goto trunc; \
  686. bp += sizeof(int32_t); \
  687. ND_PRINT((ndo, " \"")); \
  688. if (fn_printn(ndo, bp, _i, ndo->ndo_snapend)) \
  689. goto trunc; \
  690. ND_PRINT((ndo, "\"")); \
  691. bp += ((_i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \
  692. }
  693. #define INTOUT() { int _i; \
  694. ND_TCHECK2(bp[0], sizeof(int32_t)); \
  695. _i = (int) EXTRACT_32BITS(bp); \
  696. bp += sizeof(int32_t); \
  697. ND_PRINT((ndo, " %d", _i)); \
  698. }
  699. #define UINTOUT() { unsigned long _i; \
  700. ND_TCHECK2(bp[0], sizeof(int32_t)); \
  701. _i = EXTRACT_32BITS(bp); \
  702. bp += sizeof(int32_t); \
  703. ND_PRINT((ndo, " %lu", _i)); \
  704. }
  705. #define UINT64OUT() { uint64_t _i; \
  706. ND_TCHECK2(bp[0], sizeof(uint64_t)); \
  707. _i = EXTRACT_64BITS(bp); \
  708. bp += sizeof(uint64_t); \
  709. ND_PRINT((ndo, " %" PRIu64, _i)); \
  710. }
  711. #define DATEOUT() { time_t _t; struct tm *tm; char str[256]; \
  712. ND_TCHECK2(bp[0], sizeof(int32_t)); \
  713. _t = (time_t) EXTRACT_32BITS(bp); \
  714. bp += sizeof(int32_t); \
  715. tm = localtime(&_t); \
  716. strftime(str, 256, "%Y/%m/%d %H:%M:%S", tm); \
  717. ND_PRINT((ndo, " %s", str)); \
  718. }
  719. #define STOREATTROUT() { unsigned long mask, _i; \
  720. ND_TCHECK2(bp[0], (sizeof(int32_t)*6)); \
  721. mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
  722. if (mask) ND_PRINT((ndo, " StoreStatus")); \
  723. if (mask & 1) { ND_PRINT((ndo, " date")); DATEOUT(); } \
  724. else bp += sizeof(int32_t); \
  725. _i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
  726. if (mask & 2) ND_PRINT((ndo, " owner %lu", _i)); \
  727. _i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
  728. if (mask & 4) ND_PRINT((ndo, " group %lu", _i)); \
  729. _i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
  730. if (mask & 8) ND_PRINT((ndo, " mode %lo", _i & 07777)); \
  731. _i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
  732. if (mask & 16) ND_PRINT((ndo, " segsize %lu", _i)); \
  733. /* undocumented in 3.3 docu */ \
  734. if (mask & 1024) ND_PRINT((ndo, " fsync")); \
  735. }
  736. #define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \
  737. ND_TCHECK2(bp[0], sizeof(int32_t) * 2); \
  738. epoch = EXTRACT_32BITS(bp); \
  739. bp += sizeof(int32_t); \
  740. counter = EXTRACT_32BITS(bp); \
  741. bp += sizeof(int32_t); \
  742. ND_PRINT((ndo, " %d.%d", epoch, counter)); \
  743. }
  744. #define AFSUUIDOUT() {uint32_t temp; int _i; \
  745. ND_TCHECK2(bp[0], 11*sizeof(uint32_t)); \
  746. temp = EXTRACT_32BITS(bp); \
  747. bp += sizeof(uint32_t); \
  748. ND_PRINT((ndo, " %08x", temp)); \
  749. temp = EXTRACT_32BITS(bp); \
  750. bp += sizeof(uint32_t); \
  751. ND_PRINT((ndo, "%04x", temp)); \
  752. temp = EXTRACT_32BITS(bp); \
  753. bp += sizeof(uint32_t); \
  754. ND_PRINT((ndo, "%04x", temp)); \
  755. for (_i = 0; _i < 8; _i++) { \
  756. temp = EXTRACT_32BITS(bp); \
  757. bp += sizeof(uint32_t); \
  758. ND_PRINT((ndo, "%02x", (unsigned char) temp)); \
  759. } \
  760. }
  761. /*
  762. * This is the sickest one of all
  763. */
  764. #define VECOUT(MAX) { u_char *sp; \
  765. u_char s[AFSNAMEMAX]; \
  766. int k; \
  767. if ((MAX) + 1 > sizeof(s)) \
  768. goto trunc; \
  769. ND_TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \
  770. sp = s; \
  771. for (k = 0; k < (MAX); k++) { \
  772. *sp++ = (u_char) EXTRACT_32BITS(bp); \
  773. bp += sizeof(int32_t); \
  774. } \
  775. s[(MAX)] = '\0'; \
  776. ND_PRINT((ndo, " \"")); \
  777. fn_print(ndo, s, NULL); \
  778. ND_PRINT((ndo, "\"")); \
  779. }
  780. #define DESTSERVEROUT() { unsigned long n1, n2, n3; \
  781. ND_TCHECK2(bp[0], sizeof(int32_t) * 3); \
  782. n1 = EXTRACT_32BITS(bp); \
  783. bp += sizeof(int32_t); \
  784. n2 = EXTRACT_32BITS(bp); \
  785. bp += sizeof(int32_t); \
  786. n3 = EXTRACT_32BITS(bp); \
  787. bp += sizeof(int32_t); \
  788. ND_PRINT((ndo, " server %d:%d:%d", (int) n1, (int) n2, (int) n3)); \
  789. }
  790. /*
  791. * Handle calls to the AFS file service (fs)
  792. */
  793. static void
  794. fs_print(netdissect_options *ndo,
  795. register const u_char *bp, int length)
  796. {
  797. int fs_op;
  798. unsigned long i;
  799. if (length <= (int)sizeof(struct rx_header))
  800. return;
  801. if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
  802. goto trunc;
  803. }
  804. /*
  805. * Print out the afs call we're invoking. The table used here was
  806. * gleaned from fsint/afsint.xg
  807. */
  808. fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  809. ND_PRINT((ndo, " fs call %s", tok2str(fs_req, "op#%d", fs_op)));
  810. /*
  811. * Print out arguments to some of the AFS calls. This stuff is
  812. * all from afsint.xg
  813. */
  814. bp += sizeof(struct rx_header) + 4;
  815. /*
  816. * Sigh. This is gross. Ritchie forgive me.
  817. */
  818. switch (fs_op) {
  819. case 130: /* Fetch data */
  820. FIDOUT();
  821. ND_PRINT((ndo, " offset"));
  822. UINTOUT();
  823. ND_PRINT((ndo, " length"));
  824. UINTOUT();
  825. break;
  826. case 131: /* Fetch ACL */
  827. case 132: /* Fetch Status */
  828. case 143: /* Old set lock */
  829. case 144: /* Old extend lock */
  830. case 145: /* Old release lock */
  831. case 156: /* Set lock */
  832. case 157: /* Extend lock */
  833. case 158: /* Release lock */
  834. FIDOUT();
  835. break;
  836. case 135: /* Store status */
  837. FIDOUT();
  838. STOREATTROUT();
  839. break;
  840. case 133: /* Store data */
  841. FIDOUT();
  842. STOREATTROUT();
  843. ND_PRINT((ndo, " offset"));
  844. UINTOUT();
  845. ND_PRINT((ndo, " length"));
  846. UINTOUT();
  847. ND_PRINT((ndo, " flen"));
  848. UINTOUT();
  849. break;
  850. case 134: /* Store ACL */
  851. {
  852. char a[AFSOPAQUEMAX+1];
  853. FIDOUT();
  854. ND_TCHECK2(bp[0], 4);
  855. i = EXTRACT_32BITS(bp);
  856. bp += sizeof(int32_t);
  857. ND_TCHECK2(bp[0], i);
  858. i = min(AFSOPAQUEMAX, i);
  859. strncpy(a, (const char *) bp, i);
  860. a[i] = '\0';
  861. acl_print(ndo, (u_char *) a, sizeof(a), (u_char *) a + i);
  862. break;
  863. }
  864. case 137: /* Create file */
  865. case 141: /* MakeDir */
  866. FIDOUT();
  867. STROUT(AFSNAMEMAX);
  868. STOREATTROUT();
  869. break;
  870. case 136: /* Remove file */
  871. case 142: /* Remove directory */
  872. FIDOUT();
  873. STROUT(AFSNAMEMAX);
  874. break;
  875. case 138: /* Rename file */
  876. ND_PRINT((ndo, " old"));
  877. FIDOUT();
  878. STROUT(AFSNAMEMAX);
  879. ND_PRINT((ndo, " new"));
  880. FIDOUT();
  881. STROUT(AFSNAMEMAX);
  882. break;
  883. case 139: /* Symlink */
  884. FIDOUT();
  885. STROUT(AFSNAMEMAX);
  886. ND_PRINT((ndo, " link to"));
  887. STROUT(AFSNAMEMAX);
  888. break;
  889. case 140: /* Link */
  890. FIDOUT();
  891. STROUT(AFSNAMEMAX);
  892. ND_PRINT((ndo, " link to"));
  893. FIDOUT();
  894. break;
  895. case 148: /* Get volume info */
  896. STROUT(AFSNAMEMAX);
  897. break;
  898. case 149: /* Get volume stats */
  899. case 150: /* Set volume stats */
  900. ND_PRINT((ndo, " volid"));
  901. UINTOUT();
  902. break;
  903. case 154: /* New get volume info */
  904. ND_PRINT((ndo, " volname"));
  905. STROUT(AFSNAMEMAX);
  906. break;
  907. case 155: /* Bulk stat */
  908. case 65536: /* Inline bulk stat */
  909. {
  910. unsigned long j;
  911. ND_TCHECK2(bp[0], 4);
  912. j = EXTRACT_32BITS(bp);
  913. bp += sizeof(int32_t);
  914. for (i = 0; i < j; i++) {
  915. FIDOUT();
  916. if (i != j - 1)
  917. ND_PRINT((ndo, ","));
  918. }
  919. if (j == 0)
  920. ND_PRINT((ndo, " <none!>"));
  921. }
  922. case 65537: /* Fetch data 64 */
  923. FIDOUT();
  924. ND_PRINT((ndo, " offset"));
  925. UINT64OUT();
  926. ND_PRINT((ndo, " length"));
  927. UINT64OUT();
  928. break;
  929. case 65538: /* Store data 64 */
  930. FIDOUT();
  931. STOREATTROUT();
  932. ND_PRINT((ndo, " offset"));
  933. UINT64OUT();
  934. ND_PRINT((ndo, " length"));
  935. UINT64OUT();
  936. ND_PRINT((ndo, " flen"));
  937. UINT64OUT();
  938. break;
  939. case 65541: /* CallBack rx conn address */
  940. ND_PRINT((ndo, " addr"));
  941. UINTOUT();
  942. default:
  943. ;
  944. }
  945. return;
  946. trunc:
  947. ND_PRINT((ndo, " [|fs]"));
  948. }
  949. /*
  950. * Handle replies to the AFS file service
  951. */
  952. static void
  953. fs_reply_print(netdissect_options *ndo,
  954. register const u_char *bp, int length, int32_t opcode)
  955. {
  956. unsigned long i;
  957. const struct rx_header *rxh;
  958. if (length <= (int)sizeof(struct rx_header))
  959. return;
  960. rxh = (const struct rx_header *) bp;
  961. /*
  962. * Print out the afs call we're invoking. The table used here was
  963. * gleaned from fsint/afsint.xg
  964. */
  965. ND_PRINT((ndo, " fs reply %s", tok2str(fs_req, "op#%d", opcode)));
  966. bp += sizeof(struct rx_header);
  967. /*
  968. * If it was a data packet, interpret the response
  969. */
  970. if (rxh->type == RX_PACKET_TYPE_DATA) {
  971. switch (opcode) {
  972. case 131: /* Fetch ACL */
  973. {
  974. char a[AFSOPAQUEMAX+1];
  975. ND_TCHECK2(bp[0], 4);
  976. i = EXTRACT_32BITS(bp);
  977. bp += sizeof(int32_t);
  978. ND_TCHECK2(bp[0], i);
  979. i = min(AFSOPAQUEMAX, i);
  980. strncpy(a, (const char *) bp, i);
  981. a[i] = '\0';
  982. acl_print(ndo, (u_char *) a, sizeof(a), (u_char *) a + i);
  983. break;
  984. }
  985. case 137: /* Create file */
  986. case 141: /* MakeDir */
  987. ND_PRINT((ndo, " new"));
  988. FIDOUT();
  989. break;
  990. case 151: /* Get root volume */
  991. ND_PRINT((ndo, " root volume"));
  992. STROUT(AFSNAMEMAX);
  993. break;
  994. case 153: /* Get time */
  995. DATEOUT();
  996. break;
  997. default:
  998. ;
  999. }
  1000. } else if (rxh->type == RX_PACKET_TYPE_ABORT) {
  1001. /*
  1002. * Otherwise, just print out the return code
  1003. */
  1004. ND_TCHECK2(bp[0], sizeof(int32_t));
  1005. i = (int) EXTRACT_32BITS(bp);
  1006. bp += sizeof(int32_t);
  1007. ND_PRINT((ndo, " error %s", tok2str(afs_fs_errors, "#%d", i)));
  1008. } else {
  1009. ND_PRINT((ndo, " strange fs reply of type %d", rxh->type));
  1010. }
  1011. return;
  1012. trunc:
  1013. ND_PRINT((ndo, " [|fs]"));
  1014. }
  1015. /*
  1016. * Print out an AFS ACL string. An AFS ACL is a string that has the
  1017. * following format:
  1018. *
  1019. * <positive> <negative>
  1020. * <uid1> <aclbits1>
  1021. * ....
  1022. *
  1023. * "positive" and "negative" are integers which contain the number of
  1024. * positive and negative ACL's in the string. The uid/aclbits pair are
  1025. * ASCII strings containing the UID/PTS record and and a ascii number
  1026. * representing a logical OR of all the ACL permission bits
  1027. */
  1028. static void
  1029. acl_print(netdissect_options *ndo,
  1030. u_char *s, int maxsize, u_char *end)
  1031. {
  1032. int pos, neg, acl;
  1033. int n, i;
  1034. char *user;
  1035. char fmt[1024];
  1036. if ((user = (char *)malloc(maxsize)) == NULL)
  1037. return;
  1038. if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2)
  1039. goto finish;
  1040. s += n;
  1041. if (s > end)
  1042. goto finish;
  1043. /*
  1044. * This wacky order preserves the order used by the "fs" command
  1045. */
  1046. #define ACLOUT(acl) \
  1047. ND_PRINT((ndo, "%s%s%s%s%s%s%s", \
  1048. acl & PRSFS_READ ? "r" : "", \
  1049. acl & PRSFS_LOOKUP ? "l" : "", \
  1050. acl & PRSFS_INSERT ? "i" : "", \
  1051. acl & PRSFS_DELETE ? "d" : "", \
  1052. acl & PRSFS_WRITE ? "w" : "", \
  1053. acl & PRSFS_LOCK ? "k" : "", \
  1054. acl & PRSFS_ADMINISTER ? "a" : ""));
  1055. for (i = 0; i < pos; i++) {
  1056. snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1);
  1057. if (sscanf((char *) s, fmt, user, &acl, &n) != 2)
  1058. goto finish;
  1059. s += n;
  1060. ND_PRINT((ndo, " +{"));
  1061. fn_print(ndo, (u_char *)user, NULL);
  1062. ND_PRINT((ndo, " "));
  1063. ACLOUT(acl);
  1064. ND_PRINT((ndo, "}"));
  1065. if (s > end)
  1066. goto finish;
  1067. }
  1068. for (i = 0; i < neg; i++) {
  1069. snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1);
  1070. if (sscanf((char *) s, fmt, user, &acl, &n) != 2)
  1071. goto finish;
  1072. s += n;
  1073. ND_PRINT((ndo, " -{"));
  1074. fn_print(ndo, (u_char *)user, NULL);
  1075. ND_PRINT((ndo, " "));
  1076. ACLOUT(acl);
  1077. ND_PRINT((ndo, "}"));
  1078. if (s > end)
  1079. goto finish;
  1080. }
  1081. finish:
  1082. free(user);
  1083. return;
  1084. }
  1085. #undef ACLOUT
  1086. /*
  1087. * Handle calls to the AFS callback service
  1088. */
  1089. static void
  1090. cb_print(netdissect_options *ndo,
  1091. register const u_char *bp, int length)
  1092. {
  1093. int cb_op;
  1094. unsigned long i;
  1095. if (length <= (int)sizeof(struct rx_header))
  1096. return;
  1097. if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
  1098. goto trunc;
  1099. }
  1100. /*
  1101. * Print out the afs call we're invoking. The table used here was
  1102. * gleaned from fsint/afscbint.xg
  1103. */
  1104. cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  1105. ND_PRINT((ndo, " cb call %s", tok2str(cb_req, "op#%d", cb_op)));
  1106. bp += sizeof(struct rx_header) + 4;
  1107. /*
  1108. * Print out the afs call we're invoking. The table used here was
  1109. * gleaned from fsint/afscbint.xg
  1110. */
  1111. switch (cb_op) {
  1112. case 204: /* Callback */
  1113. {
  1114. unsigned long j, t;
  1115. ND_TCHECK2(bp[0], 4);
  1116. j = EXTRACT_32BITS(bp);
  1117. bp += sizeof(int32_t);
  1118. for (i = 0; i < j; i++) {
  1119. FIDOUT();
  1120. if (i != j - 1)
  1121. ND_PRINT((ndo, ","));
  1122. }
  1123. if (j == 0)
  1124. ND_PRINT((ndo, " <none!>"));
  1125. ND_TCHECK_32BITS(bp);
  1126. j = EXTRACT_32BITS(bp);
  1127. bp += sizeof(int32_t);
  1128. if (j != 0)
  1129. ND_PRINT((ndo, ";"));
  1130. for (i = 0; i < j; i++) {
  1131. ND_PRINT((ndo, " ver"));
  1132. INTOUT();
  1133. ND_PRINT((ndo, " expires"));
  1134. DATEOUT();
  1135. ND_TCHECK2(bp[0], 4);
  1136. t = EXTRACT_32BITS(bp);
  1137. bp += sizeof(int32_t);
  1138. tok2str(cb_types, "type %d", t);
  1139. }
  1140. }
  1141. case 214: {
  1142. ND_PRINT((ndo, " afsuuid"));
  1143. AFSUUIDOUT();
  1144. break;
  1145. }
  1146. default:
  1147. ;
  1148. }
  1149. return;
  1150. trunc:
  1151. ND_PRINT((ndo, " [|cb]"));
  1152. }
  1153. /*
  1154. * Handle replies to the AFS Callback Service
  1155. */
  1156. static void
  1157. cb_reply_print(netdissect_options *ndo,
  1158. register const u_char *bp, int length, int32_t opcode)
  1159. {
  1160. const struct rx_header *rxh;
  1161. if (length <= (int)sizeof(struct rx_header))
  1162. return;
  1163. rxh = (const struct rx_header *) bp;
  1164. /*
  1165. * Print out the afs call we're invoking. The table used here was
  1166. * gleaned from fsint/afscbint.xg
  1167. */
  1168. ND_PRINT((ndo, " cb reply %s", tok2str(cb_req, "op#%d", opcode)));
  1169. bp += sizeof(struct rx_header);
  1170. /*
  1171. * If it was a data packet, interpret the response.
  1172. */
  1173. if (rxh->type == RX_PACKET_TYPE_DATA)
  1174. switch (opcode) {
  1175. case 213: /* InitCallBackState3 */
  1176. AFSUUIDOUT();
  1177. break;
  1178. default:
  1179. ;
  1180. }
  1181. else {
  1182. /*
  1183. * Otherwise, just print out the return code
  1184. */
  1185. ND_PRINT((ndo, " errcode"));
  1186. INTOUT();
  1187. }
  1188. return;
  1189. trunc:
  1190. ND_PRINT((ndo, " [|cb]"));
  1191. }
  1192. /*
  1193. * Handle calls to the AFS protection database server
  1194. */
  1195. static void
  1196. prot_print(netdissect_options *ndo,
  1197. register const u_char *bp, int length)
  1198. {
  1199. unsigned long i;
  1200. int pt_op;
  1201. if (length <= (int)sizeof(struct rx_header))
  1202. return;
  1203. if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
  1204. goto trunc;
  1205. }
  1206. /*
  1207. * Print out the afs call we're invoking. The table used here was
  1208. * gleaned from ptserver/ptint.xg
  1209. */
  1210. pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  1211. ND_PRINT((ndo, " pt"));
  1212. if (is_ubik(pt_op)) {
  1213. ubik_print(ndo, bp);
  1214. return;
  1215. }
  1216. ND_PRINT((ndo, " call %s", tok2str(pt_req, "op#%d", pt_op)));
  1217. /*
  1218. * Decode some of the arguments to the PT calls
  1219. */
  1220. bp += sizeof(struct rx_header) + 4;
  1221. switch (pt_op) {
  1222. case 500: /* I New User */
  1223. STROUT(PRNAMEMAX);
  1224. ND_PRINT((ndo, " id"));
  1225. INTOUT();
  1226. ND_PRINT((ndo, " oldid"));
  1227. INTOUT();
  1228. break;
  1229. case 501: /* Where is it */
  1230. case 506: /* Delete */
  1231. case 508: /* Get CPS */
  1232. case 512: /* List entry */
  1233. case 514: /* List elements */
  1234. case 517: /* List owned */
  1235. case 518: /* Get CPS2 */
  1236. case 519: /* Get host CPS */
  1237. case 530: /* List super groups */
  1238. ND_PRINT((ndo, " id"));
  1239. INTOUT();
  1240. break;
  1241. case 502: /* Dump entry */
  1242. ND_PRINT((ndo, " pos"));
  1243. INTOUT();
  1244. break;
  1245. case 503: /* Add to group */
  1246. case 507: /* Remove from group */
  1247. case 515: /* Is a member of? */
  1248. ND_PRINT((ndo, " uid"));
  1249. INTOUT();
  1250. ND_PRINT((ndo, " gid"));
  1251. INTOUT();
  1252. break;
  1253. case 504: /* Name to ID */
  1254. {
  1255. unsigned long j;
  1256. ND_TCHECK2(bp[0], 4);
  1257. j = EXTRACT_32BITS(bp);
  1258. bp += sizeof(int32_t);
  1259. /*
  1260. * Who designed this chicken-shit protocol?
  1261. *
  1262. * Each character is stored as a 32-bit
  1263. * integer!
  1264. */
  1265. for (i = 0; i < j; i++) {
  1266. VECOUT(PRNAMEMAX);
  1267. }
  1268. if (j == 0)
  1269. ND_PRINT((ndo, " <none!>"));
  1270. }
  1271. break;
  1272. case 505: /* Id to name */
  1273. {
  1274. unsigned long j;
  1275. ND_PRINT((ndo, " ids:"));
  1276. ND_TCHECK2(bp[0], 4);
  1277. i = EXTRACT_32BITS(bp);
  1278. bp += sizeof(int32_t);
  1279. for (j = 0; j < i; j++)
  1280. INTOUT();
  1281. if (j == 0)
  1282. ND_PRINT((ndo, " <none!>"));
  1283. }
  1284. break;
  1285. case 509: /* New entry */
  1286. STROUT(PRNAMEMAX);
  1287. ND_PRINT((ndo, " flag"));
  1288. INTOUT();
  1289. ND_PRINT((ndo, " oid"));
  1290. INTOUT();
  1291. break;
  1292. case 511: /* Set max */
  1293. ND_PRINT((ndo, " id"));
  1294. INTOUT();
  1295. ND_PRINT((ndo, " gflag"));
  1296. INTOUT();
  1297. break;
  1298. case 513: /* Change entry */
  1299. ND_PRINT((ndo, " id"));
  1300. INTOUT();
  1301. STROUT(PRNAMEMAX);
  1302. ND_PRINT((ndo, " oldid"));
  1303. INTOUT();
  1304. ND_PRINT((ndo, " newid"));
  1305. INTOUT();
  1306. break;
  1307. case 520: /* Update entry */
  1308. ND_PRINT((ndo, " id"));
  1309. INTOUT();
  1310. STROUT(PRNAMEMAX);
  1311. break;
  1312. default:
  1313. ;
  1314. }
  1315. return;
  1316. trunc:
  1317. ND_PRINT((ndo, " [|pt]"));
  1318. }
  1319. /*
  1320. * Handle replies to the AFS protection service
  1321. */
  1322. static void
  1323. prot_reply_print(netdissect_options *ndo,
  1324. register const u_char *bp, int length, int32_t opcode)
  1325. {
  1326. const struct rx_header *rxh;
  1327. unsigned long i;
  1328. if (length < (int)sizeof(struct rx_header))
  1329. return;
  1330. rxh = (const struct rx_header *) bp;
  1331. /*
  1332. * Print out the afs call we're invoking. The table used here was
  1333. * gleaned from ptserver/ptint.xg. Check to see if it's a
  1334. * Ubik call, however.
  1335. */
  1336. ND_PRINT((ndo, " pt"));
  1337. if (is_ubik(opcode)) {
  1338. ubik_reply_print(ndo, bp, length, opcode);
  1339. return;
  1340. }
  1341. ND_PRINT((ndo, " reply %s", tok2str(pt_req, "op#%d", opcode)));
  1342. bp += sizeof(struct rx_header);
  1343. /*
  1344. * If it was a data packet, interpret the response
  1345. */
  1346. if (rxh->type == RX_PACKET_TYPE_DATA)
  1347. switch (opcode) {
  1348. case 504: /* Name to ID */
  1349. {
  1350. unsigned long j;
  1351. ND_PRINT((ndo, " ids:"));
  1352. ND_TCHECK2(bp[0], 4);
  1353. i = EXTRACT_32BITS(bp);
  1354. bp += sizeof(int32_t);
  1355. for (j = 0; j < i; j++)
  1356. INTOUT();
  1357. if (j == 0)
  1358. ND_PRINT((ndo, " <none!>"));
  1359. }
  1360. break;
  1361. case 505: /* ID to name */
  1362. {
  1363. unsigned long j;
  1364. ND_TCHECK2(bp[0], 4);
  1365. j = EXTRACT_32BITS(bp);
  1366. bp += sizeof(int32_t);
  1367. /*
  1368. * Who designed this chicken-shit protocol?
  1369. *
  1370. * Each character is stored as a 32-bit
  1371. * integer!
  1372. */
  1373. for (i = 0; i < j; i++) {
  1374. VECOUT(PRNAMEMAX);
  1375. }
  1376. if (j == 0)
  1377. ND_PRINT((ndo, " <none!>"));
  1378. }
  1379. break;
  1380. case 508: /* Get CPS */
  1381. case 514: /* List elements */
  1382. case 517: /* List owned */
  1383. case 518: /* Get CPS2 */
  1384. case 519: /* Get host CPS */
  1385. {
  1386. unsigned long j;
  1387. ND_TCHECK2(bp[0], 4);
  1388. j = EXTRACT_32BITS(bp);
  1389. bp += sizeof(int32_t);
  1390. for (i = 0; i < j; i++) {
  1391. INTOUT();
  1392. }
  1393. if (j == 0)
  1394. ND_PRINT((ndo, " <none!>"));
  1395. }
  1396. break;
  1397. case 510: /* List max */
  1398. ND_PRINT((ndo, " maxuid"));
  1399. INTOUT();
  1400. ND_PRINT((ndo, " maxgid"));
  1401. INTOUT();
  1402. break;
  1403. default:
  1404. ;
  1405. }
  1406. else {
  1407. /*
  1408. * Otherwise, just print out the return code
  1409. */
  1410. ND_PRINT((ndo, " errcode"));
  1411. INTOUT();
  1412. }
  1413. return;
  1414. trunc:
  1415. ND_PRINT((ndo, " [|pt]"));
  1416. }
  1417. /*
  1418. * Handle calls to the AFS volume location database service
  1419. */
  1420. static void
  1421. vldb_print(netdissect_options *ndo,
  1422. register const u_char *bp, int length)
  1423. {
  1424. int vldb_op;
  1425. unsigned long i;
  1426. if (length <= (int)sizeof(struct rx_header))
  1427. return;
  1428. if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
  1429. goto trunc;
  1430. }
  1431. /*
  1432. * Print out the afs call we're invoking. The table used here was
  1433. * gleaned from vlserver/vldbint.xg
  1434. */
  1435. vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  1436. ND_PRINT((ndo, " vldb"));
  1437. if (is_ubik(vldb_op)) {
  1438. ubik_print(ndo, bp);
  1439. return;
  1440. }
  1441. ND_PRINT((ndo, " call %s", tok2str(vldb_req, "op#%d", vldb_op)));
  1442. /*
  1443. * Decode some of the arguments to the VLDB calls
  1444. */
  1445. bp += sizeof(struct rx_header) + 4;
  1446. switch (vldb_op) {
  1447. case 501: /* Create new volume */
  1448. case 517: /* Create entry N */
  1449. VECOUT(VLNAMEMAX);
  1450. break;
  1451. case 502: /* Delete entry */
  1452. case 503: /* Get entry by ID */
  1453. case 507: /* Update entry */
  1454. case 508: /* Set lock */
  1455. case 509: /* Release lock */
  1456. case 518: /* Get entry by ID N */
  1457. ND_PRINT((ndo, " volid"));
  1458. INTOUT();
  1459. ND_TCHECK2(bp[0], sizeof(int32_t));
  1460. i = EXTRACT_32BITS(bp);
  1461. bp += sizeof(int32_t);
  1462. if (i <= 2)
  1463. ND_PRINT((ndo, " type %s", voltype[i]));
  1464. break;
  1465. case 504: /* Get entry by name */
  1466. case 519: /* Get entry by name N */
  1467. case 524: /* Update entry by name */
  1468. case 527: /* Get entry by name U */
  1469. STROUT(VLNAMEMAX);
  1470. break;
  1471. case 505: /* Get new vol id */
  1472. ND_PRINT((ndo, " bump"));
  1473. INTOUT();
  1474. break;
  1475. case 506: /* Replace entry */
  1476. case 520: /* Replace entry N */
  1477. ND_PRINT((ndo, " volid"));
  1478. INTOUT();
  1479. ND_TCHECK2(bp[0], sizeof(int32_t));
  1480. i = EXTRACT_32BITS(bp);
  1481. bp += sizeof(int32_t);
  1482. if (i <= 2)
  1483. ND_PRINT((ndo, " type %s", voltype[i]));
  1484. VECOUT(VLNAMEMAX);
  1485. break;
  1486. case 510: /* List entry */
  1487. case 521: /* List entry N */
  1488. ND_PRINT((ndo, " index"));
  1489. INTOUT();
  1490. break;
  1491. default:
  1492. ;
  1493. }
  1494. return;
  1495. trunc:
  1496. ND_PRINT((ndo, " [|vldb]"));
  1497. }
  1498. /*
  1499. * Handle replies to the AFS volume location database service
  1500. */
  1501. static void
  1502. vldb_reply_print(netdissect_options *ndo,
  1503. register const u_char *bp, int length, int32_t opcode)
  1504. {
  1505. const struct rx_header *rxh;
  1506. unsigned long i;
  1507. if (length < (int)sizeof(struct rx_header))
  1508. return;
  1509. rxh = (const struct rx_header *) bp;
  1510. /*
  1511. * Print out the afs call we're invoking. The table used here was
  1512. * gleaned from vlserver/vldbint.xg. Check to see if it's a
  1513. * Ubik call, however.
  1514. */
  1515. ND_PRINT((ndo, " vldb"));
  1516. if (is_ubik(opcode)) {
  1517. ubik_reply_print(ndo, bp, length, opcode);
  1518. return;
  1519. }
  1520. ND_PRINT((ndo, " reply %s", tok2str(vldb_req, "op#%d", opcode)));
  1521. bp += sizeof(struct rx_header);
  1522. /*
  1523. * If it was a data packet, interpret the response
  1524. */
  1525. if (rxh->type == RX_PACKET_TYPE_DATA)
  1526. switch (opcode) {
  1527. case 510: /* List entry */
  1528. ND_PRINT((ndo, " count"));
  1529. INTOUT();
  1530. ND_PRINT((ndo, " nextindex"));
  1531. INTOUT();
  1532. case 503: /* Get entry by id */
  1533. case 504: /* Get entry by name */
  1534. { unsigned long nservers, j;
  1535. VECOUT(VLNAMEMAX);
  1536. ND_TCHECK2(bp[0], sizeof(int32_t));
  1537. bp += sizeof(int32_t);
  1538. ND_PRINT((ndo, " numservers"));
  1539. ND_TCHECK2(bp[0], sizeof(int32_t));
  1540. nservers = EXTRACT_32BITS(bp);
  1541. bp += sizeof(int32_t);
  1542. ND_PRINT((ndo, " %lu", nservers));
  1543. ND_PRINT((ndo, " servers"));
  1544. for (i = 0; i < 8; i++) {
  1545. ND_TCHECK2(bp[0], sizeof(int32_t));
  1546. if (i < nservers)
  1547. ND_PRINT((ndo, " %s",
  1548. intoa(((const struct in_addr *) bp)->s_addr)));
  1549. bp += sizeof(int32_t);
  1550. }
  1551. ND_PRINT((ndo, " partitions"));
  1552. for (i = 0; i < 8; i++) {
  1553. ND_TCHECK2(bp[0], sizeof(int32_t));
  1554. j = EXTRACT_32BITS(bp);
  1555. if (i < nservers && j <= 26)
  1556. ND_PRINT((ndo, " %c", 'a' + (int)j));
  1557. else if (i < nservers)
  1558. ND_PRINT((ndo, " %lu", j));
  1559. bp += sizeof(int32_t);
  1560. }
  1561. ND_TCHECK2(bp[0], 8 * sizeof(int32_t));
  1562. bp += 8 * sizeof(int32_t);
  1563. ND_PRINT((ndo, " rwvol"));
  1564. UINTOUT();
  1565. ND_PRINT((ndo, " rovol"));
  1566. UINTOUT();
  1567. ND_PRINT((ndo, " backup"));
  1568. UINTOUT();
  1569. }
  1570. break;
  1571. case 505: /* Get new volume ID */
  1572. ND_PRINT((ndo, " newvol"));
  1573. UINTOUT();
  1574. break;
  1575. case 521: /* List entry */
  1576. case 529: /* List entry U */
  1577. ND_PRINT((ndo, " count"));
  1578. INTOUT();
  1579. ND_PRINT((ndo, " nextindex"));
  1580. INTOUT();
  1581. case 518: /* Get entry by ID N */
  1582. case 519: /* Get entry by name N */
  1583. { unsigned long nservers, j;
  1584. VECOUT(VLNAMEMAX);
  1585. ND_PRINT((ndo, " numservers"));
  1586. ND_TCHECK2(bp[0], sizeof(int32_t));
  1587. nservers = EXTRACT_32BITS(bp);
  1588. bp += sizeof(int32_t);
  1589. ND_PRINT((ndo, " %lu", nservers));
  1590. ND_PRINT((ndo, " servers"));
  1591. for (i = 0; i < 13; i++) {
  1592. ND_TCHECK2(bp[0], sizeof(int32_t));
  1593. if (i < nservers)
  1594. ND_PRINT((ndo, " %s",
  1595. intoa(((const struct in_addr *) bp)->s_addr)));
  1596. bp += sizeof(int32_t);
  1597. }
  1598. ND_PRINT((ndo, " partitions"));
  1599. for (i = 0; i < 13; i++) {
  1600. ND_TCHECK2(bp[0], sizeof(int32_t));
  1601. j = EXTRACT_32BITS(bp);
  1602. if (i < nservers && j <= 26)
  1603. ND_PRINT((ndo, " %c", 'a' + (int)j));
  1604. else if (i < nservers)
  1605. ND_PRINT((ndo, " %lu", j));
  1606. bp += sizeof(int32_t);
  1607. }
  1608. ND_TCHECK2(bp[0], 13 * sizeof(int32_t));
  1609. bp += 13 * sizeof(int32_t);
  1610. ND_PRINT((ndo, " rwvol"));
  1611. UINTOUT();
  1612. ND_PRINT((ndo, " rovol"));
  1613. UINTOUT();
  1614. ND_PRINT((ndo, " backup"));
  1615. UINTOUT();
  1616. }
  1617. break;
  1618. case 526: /* Get entry by ID U */
  1619. case 527: /* Get entry by name U */
  1620. { unsigned long nservers, j;
  1621. VECOUT(VLNAMEMAX);
  1622. ND_PRINT((ndo, " numservers"));
  1623. ND_TCHECK2(bp[0], sizeof(int32_t));
  1624. nservers = EXTRACT_32BITS(bp);
  1625. bp += sizeof(int32_t);
  1626. ND_PRINT((ndo, " %lu", nservers));
  1627. ND_PRINT((ndo, " servers"));
  1628. for (i = 0; i < 13; i++) {
  1629. if (i < nservers) {
  1630. ND_PRINT((ndo, " afsuuid"));
  1631. AFSUUIDOUT();
  1632. } else {
  1633. ND_TCHECK2(bp[0], 44);
  1634. bp += 44;
  1635. }
  1636. }
  1637. ND_TCHECK2(bp[0], 4 * 13);
  1638. bp += 4 * 13;
  1639. ND_PRINT((ndo, " partitions"));
  1640. for (i = 0; i < 13; i++) {
  1641. ND_TCHECK2(bp[0], sizeof(int32_t));
  1642. j = EXTRACT_32BITS(bp);
  1643. if (i < nservers && j <= 26)
  1644. ND_PRINT((ndo, " %c", 'a' + (int)j));
  1645. else if (i < nservers)
  1646. ND_PRINT((ndo, " %lu", j));
  1647. bp += sizeof(int32_t);
  1648. }
  1649. ND_TCHECK2(bp[0], 13 * sizeof(int32_t));
  1650. bp += 13 * sizeof(int32_t);
  1651. ND_PRINT((ndo, " rwvol"));
  1652. UINTOUT();
  1653. ND_PRINT((ndo, " rovol"));
  1654. UINTOUT();
  1655. ND_PRINT((ndo, " backup"));
  1656. UINTOUT();
  1657. }
  1658. default:
  1659. ;
  1660. }
  1661. else {
  1662. /*
  1663. * Otherwise, just print out the return code
  1664. */
  1665. ND_PRINT((ndo, " errcode"));
  1666. INTOUT();
  1667. }
  1668. return;
  1669. trunc:
  1670. ND_PRINT((ndo, " [|vldb]"));
  1671. }
  1672. /*
  1673. * Handle calls to the AFS Kerberos Authentication service
  1674. */
  1675. static void
  1676. kauth_print(netdissect_options *ndo,
  1677. register const u_char *bp, int length)
  1678. {
  1679. int kauth_op;
  1680. if (length <= (int)sizeof(struct rx_header))
  1681. return;
  1682. if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
  1683. goto trunc;
  1684. }
  1685. /*
  1686. * Print out the afs call we're invoking. The table used here was
  1687. * gleaned from kauth/kauth.rg
  1688. */
  1689. kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  1690. ND_PRINT((ndo, " kauth"));
  1691. if (is_ubik(kauth_op)) {
  1692. ubik_print(ndo, bp);
  1693. return;
  1694. }
  1695. ND_PRINT((ndo, " call %s", tok2str(kauth_req, "op#%d", kauth_op)));
  1696. /*
  1697. * Decode some of the arguments to the KA calls
  1698. */
  1699. bp += sizeof(struct rx_header) + 4;
  1700. switch (kauth_op) {
  1701. case 1: /* Authenticate old */
  1702. case 21: /* Authenticate */
  1703. case 22: /* Authenticate-V2 */
  1704. case 2: /* Change PW */
  1705. case 5: /* Set fields */
  1706. case 6: /* Create user */
  1707. case 7: /* Delete user */
  1708. case 8: /* Get entry */
  1709. case 14: /* Unlock */
  1710. case 15: /* Lock status */
  1711. ND_PRINT((ndo, " principal"));
  1712. STROUT(KANAMEMAX);
  1713. STROUT(KANAMEMAX);
  1714. break;
  1715. case 3: /* GetTicket-old */
  1716. case 23: /* GetTicket */
  1717. {
  1718. int i;
  1719. ND_PRINT((ndo, " kvno"));
  1720. INTOUT();
  1721. ND_PRINT((ndo, " domain"));
  1722. STROUT(KANAMEMAX);
  1723. ND_TCHECK2(bp[0], sizeof(int32_t));
  1724. i = (int) EXTRACT_32BITS(bp);
  1725. bp += sizeof(int32_t);
  1726. ND_TCHECK2(bp[0], i);
  1727. bp += i;
  1728. ND_PRINT((ndo, " principal"));
  1729. STROUT(KANAMEMAX);
  1730. STROUT(KANAMEMAX);
  1731. break;
  1732. }
  1733. case 4: /* Set Password */
  1734. ND_PRINT((ndo, " principal"));
  1735. STROUT(KANAMEMAX);
  1736. STROUT(KANAMEMAX);
  1737. ND_PRINT((ndo, " kvno"));
  1738. INTOUT();
  1739. break;
  1740. case 12: /* Get password */
  1741. ND_PRINT((ndo, " name"));
  1742. STROUT(KANAMEMAX);
  1743. break;
  1744. default:
  1745. ;
  1746. }
  1747. return;
  1748. trunc:
  1749. ND_PRINT((ndo, " [|kauth]"));
  1750. }
  1751. /*
  1752. * Handle replies to the AFS Kerberos Authentication Service
  1753. */
  1754. static void
  1755. kauth_reply_print(netdissect_options *ndo,
  1756. register const u_char *bp, int length, int32_t opcode)
  1757. {
  1758. const struct rx_header *rxh;
  1759. if (length <= (int)sizeof(struct rx_header))
  1760. return;
  1761. rxh = (const struct rx_header *) bp;
  1762. /*
  1763. * Print out the afs call we're invoking. The table used here was
  1764. * gleaned from kauth/kauth.rg
  1765. */
  1766. ND_PRINT((ndo, " kauth"));
  1767. if (is_ubik(opcode)) {
  1768. ubik_reply_print(ndo, bp, length, opcode);
  1769. return;
  1770. }
  1771. ND_PRINT((ndo, " reply %s", tok2str(kauth_req, "op#%d", opcode)));
  1772. bp += sizeof(struct rx_header);
  1773. /*
  1774. * If it was a data packet, interpret the response.
  1775. */
  1776. if (rxh->type == RX_PACKET_TYPE_DATA)
  1777. /* Well, no, not really. Leave this for later */
  1778. ;
  1779. else {
  1780. /*
  1781. * Otherwise, just print out the return code
  1782. */
  1783. ND_PRINT((ndo, " errcode"));
  1784. INTOUT();
  1785. }
  1786. return;
  1787. trunc:
  1788. ND_PRINT((ndo, " [|kauth]"));
  1789. }
  1790. /*
  1791. * Handle calls to the AFS Volume location service
  1792. */
  1793. static void
  1794. vol_print(netdissect_options *ndo,
  1795. register const u_char *bp, int length)
  1796. {
  1797. int vol_op;
  1798. if (length <= (int)sizeof(struct rx_header))
  1799. return;
  1800. if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
  1801. goto trunc;
  1802. }
  1803. /*
  1804. * Print out the afs call we're invoking. The table used here was
  1805. * gleaned from volser/volint.xg
  1806. */
  1807. vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  1808. ND_PRINT((ndo, " vol call %s", tok2str(vol_req, "op#%d", vol_op)));
  1809. bp += sizeof(struct rx_header) + 4;
  1810. switch (vol_op) {
  1811. case 100: /* Create volume */
  1812. ND_PRINT((ndo, " partition"));
  1813. UINTOUT();
  1814. ND_PRINT((ndo, " name"));
  1815. STROUT(AFSNAMEMAX);
  1816. ND_PRINT((ndo, " type"));
  1817. UINTOUT();
  1818. ND_PRINT((ndo, " parent"));
  1819. UINTOUT();
  1820. break;
  1821. case 101: /* Delete volume */
  1822. case 107: /* Get flags */
  1823. ND_PRINT((ndo, " trans"));
  1824. UINTOUT();
  1825. break;
  1826. case 102: /* Restore */
  1827. ND_PRINT((ndo, " totrans"));
  1828. UINTOUT();
  1829. ND_PRINT((ndo, " flags"));
  1830. UINTOUT();
  1831. break;
  1832. case 103: /* Forward */
  1833. ND_PRINT((ndo, " fromtrans"));
  1834. UINTOUT();
  1835. ND_PRINT((ndo, " fromdate"));
  1836. DATEOUT();
  1837. DESTSERVEROUT();
  1838. ND_PRINT((ndo, " desttrans"));
  1839. INTOUT();
  1840. break;
  1841. case 104: /* End trans */
  1842. ND_PRINT((ndo, " trans"));
  1843. UINTOUT();
  1844. break;
  1845. case 105: /* Clone */
  1846. ND_PRINT((ndo, " trans"));
  1847. UINTOUT();
  1848. ND_PRINT((ndo, " purgevol"));
  1849. UINTOUT();
  1850. ND_PRINT((ndo, " newtype"));
  1851. UINTOUT();
  1852. ND_PRINT((ndo, " newname"));
  1853. STROUT(AFSNAMEMAX);
  1854. break;
  1855. case 106: /* Set flags */
  1856. ND_PRINT((ndo, " trans"));
  1857. UINTOUT();
  1858. ND_PRINT((ndo, " flags"));
  1859. UINTOUT();
  1860. break;
  1861. case 108: /* Trans create */
  1862. ND_PRINT((ndo, " vol"));
  1863. UINTOUT();
  1864. ND_PRINT((ndo, " partition"));
  1865. UINTOUT();
  1866. ND_PRINT((ndo, " flags"));
  1867. UINTOUT();
  1868. break;
  1869. case 109: /* Dump */
  1870. case 655537: /* Get size */
  1871. ND_PRINT((ndo, " fromtrans"));
  1872. UINTOUT();
  1873. ND_PRINT((ndo, " fromdate"));
  1874. DATEOUT();
  1875. break;
  1876. case 110: /* Get n-th volume */
  1877. ND_PRINT((ndo, " index"));
  1878. UINTOUT();
  1879. break;
  1880. case 111: /* Set forwarding */
  1881. ND_PRINT((ndo, " tid"));
  1882. UINTOUT();
  1883. ND_PRINT((ndo, " newsite"));
  1884. UINTOUT();
  1885. break;
  1886. case 112: /* Get name */
  1887. case 113: /* Get status */
  1888. ND_PRINT((ndo, " tid"));
  1889. break;
  1890. case 114: /* Signal restore */
  1891. ND_PRINT((ndo, " name"));
  1892. STROUT(AFSNAMEMAX);
  1893. ND_PRINT((ndo, " type"));
  1894. UINTOUT();
  1895. ND_PRINT((ndo, " pid"));
  1896. UINTOUT();
  1897. ND_PRINT((ndo, " cloneid"));
  1898. UINTOUT();
  1899. break;
  1900. case 116: /* List volumes */
  1901. ND_PRINT((ndo, " partition"));
  1902. UINTOUT();
  1903. ND_PRINT((ndo, " flags"));
  1904. UINTOUT();
  1905. break;
  1906. case 117: /* Set id types */
  1907. ND_PRINT((ndo, " tid"));
  1908. UINTOUT();
  1909. ND_PRINT((ndo, " name"));
  1910. STROUT(AFSNAMEMAX);
  1911. ND_PRINT((ndo, " type"));
  1912. UINTOUT();
  1913. ND_PRINT((ndo, " pid"));
  1914. UINTOUT();
  1915. ND_PRINT((ndo, " clone"));
  1916. UINTOUT();
  1917. ND_PRINT((ndo, " backup"));
  1918. UINTOUT();
  1919. break;
  1920. case 119: /* Partition info */
  1921. ND_PRINT((ndo, " name"));
  1922. STROUT(AFSNAMEMAX);
  1923. break;
  1924. case 120: /* Reclone */
  1925. ND_PRINT((ndo, " tid"));
  1926. UINTOUT();
  1927. break;
  1928. case 121: /* List one volume */
  1929. case 122: /* Nuke volume */
  1930. case 124: /* Extended List volumes */
  1931. case 125: /* Extended List one volume */
  1932. case 65536: /* Convert RO to RW volume */
  1933. ND_PRINT((ndo, " partid"));
  1934. UINTOUT();
  1935. ND_PRINT((ndo, " volid"));
  1936. UINTOUT();
  1937. break;
  1938. case 123: /* Set date */
  1939. ND_PRINT((ndo, " tid"));
  1940. UINTOUT();
  1941. ND_PRINT((ndo, " date"));
  1942. DATEOUT();
  1943. break;
  1944. case 126: /* Set info */
  1945. ND_PRINT((ndo, " tid"));
  1946. UINTOUT();
  1947. break;
  1948. case 128: /* Forward multiple */
  1949. ND_PRINT((ndo, " fromtrans"));
  1950. UINTOUT();
  1951. ND_PRINT((ndo, " fromdate"));
  1952. DATEOUT();
  1953. {
  1954. unsigned long i, j;
  1955. ND_TCHECK2(bp[0], 4);
  1956. j = EXTRACT_32BITS(bp);
  1957. bp += sizeof(int32_t);
  1958. for (i = 0; i < j; i++) {
  1959. DESTSERVEROUT();
  1960. if (i != j - 1)
  1961. ND_PRINT((ndo, ","));
  1962. }
  1963. if (j == 0)
  1964. ND_PRINT((ndo, " <none!>"));
  1965. }
  1966. break;
  1967. case 65538: /* Dump version 2 */
  1968. ND_PRINT((ndo, " fromtrans"));
  1969. UINTOUT();
  1970. ND_PRINT((ndo, " fromdate"));
  1971. DATEOUT();
  1972. ND_PRINT((ndo, " flags"));
  1973. UINTOUT();
  1974. break;
  1975. default:
  1976. ;
  1977. }
  1978. return;
  1979. trunc:
  1980. ND_PRINT((ndo, " [|vol]"));
  1981. }
  1982. /*
  1983. * Handle replies to the AFS Volume Service
  1984. */
  1985. static void
  1986. vol_reply_print(netdissect_options *ndo,
  1987. register const u_char *bp, int length, int32_t opcode)
  1988. {
  1989. const struct rx_header *rxh;
  1990. if (length <= (int)sizeof(struct rx_header))
  1991. return;
  1992. rxh = (const struct rx_header *) bp;
  1993. /*
  1994. * Print out the afs call we're invoking. The table used here was
  1995. * gleaned from volser/volint.xg
  1996. */
  1997. ND_PRINT((ndo, " vol reply %s", tok2str(vol_req, "op#%d", opcode)));
  1998. bp += sizeof(struct rx_header);
  1999. /*
  2000. * If it was a data packet, interpret the response.
  2001. */
  2002. if (rxh->type == RX_PACKET_TYPE_DATA) {
  2003. switch (opcode) {
  2004. case 100: /* Create volume */
  2005. ND_PRINT((ndo, " volid"));
  2006. UINTOUT();
  2007. ND_PRINT((ndo, " trans"));
  2008. UINTOUT();
  2009. break;
  2010. case 104: /* End transaction */
  2011. UINTOUT();
  2012. break;
  2013. case 105: /* Clone */
  2014. ND_PRINT((ndo, " newvol"));
  2015. UINTOUT();
  2016. break;
  2017. case 107: /* Get flags */
  2018. UINTOUT();
  2019. break;
  2020. case 108: /* Transaction create */
  2021. ND_PRINT((ndo, " trans"));
  2022. UINTOUT();
  2023. break;
  2024. case 110: /* Get n-th volume */
  2025. ND_PRINT((ndo, " volume"));
  2026. UINTOUT();
  2027. ND_PRINT((ndo, " partition"));
  2028. UINTOUT();
  2029. break;
  2030. case 112: /* Get name */
  2031. STROUT(AFSNAMEMAX);
  2032. break;
  2033. case 113: /* Get status */
  2034. ND_PRINT((ndo, " volid"));
  2035. UINTOUT();
  2036. ND_PRINT((ndo, " nextuniq"));
  2037. UINTOUT();
  2038. ND_PRINT((ndo, " type"));
  2039. UINTOUT();
  2040. ND_PRINT((ndo, " parentid"));
  2041. UINTOUT();
  2042. ND_PRINT((ndo, " clone"));
  2043. UINTOUT();
  2044. ND_PRINT((ndo, " backup"));
  2045. UINTOUT();
  2046. ND_PRINT((ndo, " restore"));
  2047. UINTOUT();
  2048. ND_PRINT((ndo, " maxquota"));
  2049. UINTOUT();
  2050. ND_PRINT((ndo, " minquota"));
  2051. UINTOUT();
  2052. ND_PRINT((ndo, " owner"));
  2053. UINTOUT();
  2054. ND_PRINT((ndo, " create"));
  2055. DATEOUT();
  2056. ND_PRINT((ndo, " access"));
  2057. DATEOUT();
  2058. ND_PRINT((ndo, " update"));
  2059. DATEOUT();
  2060. ND_PRINT((ndo, " expire"));
  2061. DATEOUT();
  2062. ND_PRINT((ndo, " backup"));
  2063. DATEOUT();
  2064. ND_PRINT((ndo, " copy"));
  2065. DATEOUT();
  2066. break;
  2067. case 115: /* Old list partitions */
  2068. break;
  2069. case 116: /* List volumes */
  2070. case 121: /* List one volume */
  2071. {
  2072. unsigned long i, j;
  2073. ND_TCHECK2(bp[0], 4);
  2074. j = EXTRACT_32BITS(bp);
  2075. bp += sizeof(int32_t);
  2076. for (i = 0; i < j; i++) {
  2077. ND_PRINT((ndo, " name"));
  2078. VECOUT(32);
  2079. ND_PRINT((ndo, " volid"));
  2080. UINTOUT();
  2081. ND_PRINT((ndo, " type"));
  2082. bp += sizeof(int32_t) * 21;
  2083. if (i != j - 1)
  2084. ND_PRINT((ndo, ","));
  2085. }
  2086. if (j == 0)
  2087. ND_PRINT((ndo, " <none!>"));
  2088. }
  2089. break;
  2090. default:
  2091. ;
  2092. }
  2093. } else {
  2094. /*
  2095. * Otherwise, just print out the return code
  2096. */
  2097. ND_PRINT((ndo, " errcode"));
  2098. INTOUT();
  2099. }
  2100. return;
  2101. trunc:
  2102. ND_PRINT((ndo, " [|vol]"));
  2103. }
  2104. /*
  2105. * Handle calls to the AFS BOS service
  2106. */
  2107. static void
  2108. bos_print(netdissect_options *ndo,
  2109. register const u_char *bp, int length)
  2110. {
  2111. int bos_op;
  2112. if (length <= (int)sizeof(struct rx_header))
  2113. return;
  2114. if (ndo->ndo_snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
  2115. goto trunc;
  2116. }
  2117. /*
  2118. * Print out the afs call we're invoking. The table used here was
  2119. * gleaned from bozo/bosint.xg
  2120. */
  2121. bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  2122. ND_PRINT((ndo, " bos call %s", tok2str(bos_req, "op#%d", bos_op)));
  2123. /*
  2124. * Decode some of the arguments to the BOS calls
  2125. */
  2126. bp += sizeof(struct rx_header) + 4;
  2127. switch (bos_op) {
  2128. case 80: /* Create B node */
  2129. ND_PRINT((ndo, " type"));
  2130. STROUT(BOSNAMEMAX);
  2131. ND_PRINT((ndo, " instance"));
  2132. STROUT(BOSNAMEMAX);
  2133. break;
  2134. case 81: /* Delete B node */
  2135. case 83: /* Get status */
  2136. case 85: /* Get instance info */
  2137. case 87: /* Add super user */
  2138. case 88: /* Delete super user */
  2139. case 93: /* Set cell name */
  2140. case 96: /* Add cell host */
  2141. case 97: /* Delete cell host */
  2142. case 104: /* Restart */
  2143. case 106: /* Uninstall */
  2144. case 108: /* Exec */
  2145. case 112: /* Getlog */
  2146. case 114: /* Get instance strings */
  2147. STROUT(BOSNAMEMAX);
  2148. break;
  2149. case 82: /* Set status */
  2150. case 98: /* Set T status */
  2151. STROUT(BOSNAMEMAX);
  2152. ND_PRINT((ndo, " status"));
  2153. INTOUT();
  2154. break;
  2155. case 86: /* Get instance parm */
  2156. STROUT(BOSNAMEMAX);
  2157. ND_PRINT((ndo, " num"));
  2158. INTOUT();
  2159. break;
  2160. case 84: /* Enumerate instance */
  2161. case 89: /* List super users */
  2162. case 90: /* List keys */
  2163. case 91: /* Add key */
  2164. case 92: /* Delete key */
  2165. case 95: /* Get cell host */
  2166. INTOUT();
  2167. break;
  2168. case 105: /* Install */
  2169. STROUT(BOSNAMEMAX);
  2170. ND_PRINT((ndo, " size"));
  2171. INTOUT();
  2172. ND_PRINT((ndo, " flags"));
  2173. INTOUT();
  2174. ND_PRINT((ndo, " date"));
  2175. INTOUT();
  2176. break;
  2177. default:
  2178. ;
  2179. }
  2180. return;
  2181. trunc:
  2182. ND_PRINT((ndo, " [|bos]"));
  2183. }
  2184. /*
  2185. * Handle replies to the AFS BOS Service
  2186. */
  2187. static void
  2188. bos_reply_print(netdissect_options *ndo,
  2189. register const u_char *bp, int length, int32_t opcode)
  2190. {
  2191. const struct rx_header *rxh;
  2192. if (length <= (int)sizeof(struct rx_header))
  2193. return;
  2194. rxh = (const struct rx_header *) bp;
  2195. /*
  2196. * Print out the afs call we're invoking. The table used here was
  2197. * gleaned from volser/volint.xg
  2198. */
  2199. ND_PRINT((ndo, " bos reply %s", tok2str(bos_req, "op#%d", opcode)));
  2200. bp += sizeof(struct rx_header);
  2201. /*
  2202. * If it was a data packet, interpret the response.
  2203. */
  2204. if (rxh->type == RX_PACKET_TYPE_DATA)
  2205. /* Well, no, not really. Leave this for later */
  2206. ;
  2207. else {
  2208. /*
  2209. * Otherwise, just print out the return code
  2210. */
  2211. ND_PRINT((ndo, " errcode"));
  2212. INTOUT();
  2213. }
  2214. return;
  2215. trunc:
  2216. ND_PRINT((ndo, " [|bos]"));
  2217. }
  2218. /*
  2219. * Check to see if this is a Ubik opcode.
  2220. */
  2221. static int
  2222. is_ubik(uint32_t opcode)
  2223. {
  2224. if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) ||
  2225. (opcode >= DISK_LOW && opcode <= DISK_HIGH))
  2226. return(1);
  2227. else
  2228. return(0);
  2229. }
  2230. /*
  2231. * Handle Ubik opcodes to any one of the replicated database services
  2232. */
  2233. static void
  2234. ubik_print(netdissect_options *ndo,
  2235. register const u_char *bp)
  2236. {
  2237. int ubik_op;
  2238. int32_t temp;
  2239. /*
  2240. * Print out the afs call we're invoking. The table used here was
  2241. * gleaned from ubik/ubik_int.xg
  2242. */
  2243. /* Every function that calls this function first makes a bounds check
  2244. * for (sizeof(rx_header) + 4) bytes, so long as it remains this way
  2245. * the line below will not over-read.
  2246. */
  2247. ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
  2248. ND_PRINT((ndo, " ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)));
  2249. /*
  2250. * Decode some of the arguments to the Ubik calls
  2251. */
  2252. bp += sizeof(struct rx_header) + 4;
  2253. switch (ubik_op) {
  2254. case 10000: /* Beacon */
  2255. ND_TCHECK2(bp[0], 4);
  2256. temp = EXTRACT_32BITS(bp);
  2257. bp += sizeof(int32_t);
  2258. ND_PRINT((ndo, " syncsite %s", temp ? "yes" : "no"));
  2259. ND_PRINT((ndo, " votestart"));
  2260. DATEOUT();
  2261. ND_PRINT((ndo, " dbversion"));
  2262. UBIK_VERSIONOUT();
  2263. ND_PRINT((ndo, " tid"));
  2264. UBIK_VERSIONOUT();
  2265. break;
  2266. case 10003: /* Get sync site */
  2267. ND_PRINT((ndo, " site"));
  2268. UINTOUT();
  2269. break;
  2270. case 20000: /* Begin */
  2271. case 20001: /* Commit */
  2272. case 20007: /* Abort */
  2273. case 20008: /* Release locks */
  2274. case 20010: /* Writev */
  2275. ND_PRINT((ndo, " tid"));
  2276. UBIK_VERSIONOUT();
  2277. break;
  2278. case 20002: /* Lock */
  2279. ND_PRINT((ndo, " tid"));
  2280. UBIK_VERSIONOUT();
  2281. ND_PRINT((ndo, " file"));
  2282. INTOUT();
  2283. ND_PRINT((ndo, " pos"));
  2284. INTOUT();
  2285. ND_PRINT((ndo, " length"));
  2286. INTOUT();
  2287. ND_TCHECK_32BITS(bp);
  2288. temp = EXTRACT_32BITS(bp);
  2289. bp += sizeof(int32_t);
  2290. tok2str(ubik_lock_types, "type %d", temp);
  2291. break;
  2292. case 20003: /* Write */
  2293. ND_PRINT((ndo, " tid"));
  2294. UBIK_VERSIONOUT();
  2295. ND_PRINT((ndo, " file"));
  2296. INTOUT();
  2297. ND_PRINT((ndo, " pos"));
  2298. INTOUT();
  2299. break;
  2300. case 20005: /* Get file */
  2301. ND_PRINT((ndo, " file"));
  2302. INTOUT();
  2303. break;
  2304. case 20006: /* Send file */
  2305. ND_PRINT((ndo, " file"));
  2306. INTOUT();
  2307. ND_PRINT((ndo, " length"));
  2308. INTOUT();
  2309. ND_PRINT((ndo, " dbversion"));
  2310. UBIK_VERSIONOUT();
  2311. break;
  2312. case 20009: /* Truncate */
  2313. ND_PRINT((ndo, " tid"));
  2314. UBIK_VERSIONOUT();
  2315. ND_PRINT((ndo, " file"));
  2316. INTOUT();
  2317. ND_PRINT((ndo, " length"));
  2318. INTOUT();
  2319. break;
  2320. case 20012: /* Set version */
  2321. ND_PRINT((ndo, " tid"));
  2322. UBIK_VERSIONOUT();
  2323. ND_PRINT((ndo, " oldversion"));
  2324. UBIK_VERSIONOUT();
  2325. ND_PRINT((ndo, " newversion"));
  2326. UBIK_VERSIONOUT();
  2327. break;
  2328. default:
  2329. ;
  2330. }
  2331. return;
  2332. trunc:
  2333. ND_PRINT((ndo, " [|ubik]"));
  2334. }
  2335. /*
  2336. * Handle Ubik replies to any one of the replicated database services
  2337. */
  2338. static void
  2339. ubik_reply_print(netdissect_options *ndo,
  2340. register const u_char *bp, int length, int32_t opcode)
  2341. {
  2342. const struct rx_header *rxh;
  2343. if (length < (int)sizeof(struct rx_header))
  2344. return;
  2345. rxh = (const struct rx_header *) bp;
  2346. /*
  2347. * Print out the ubik call we're invoking. This table was gleaned
  2348. * from ubik/ubik_int.xg
  2349. */
  2350. ND_PRINT((ndo, " ubik reply %s", tok2str(ubik_req, "op#%d", opcode)));
  2351. bp += sizeof(struct rx_header);
  2352. /*
  2353. * If it was a data packet, print out the arguments to the Ubik calls
  2354. */
  2355. if (rxh->type == RX_PACKET_TYPE_DATA)
  2356. switch (opcode) {
  2357. case 10000: /* Beacon */
  2358. ND_PRINT((ndo, " vote no"));
  2359. break;
  2360. case 20004: /* Get version */
  2361. ND_PRINT((ndo, " dbversion"));
  2362. UBIK_VERSIONOUT();
  2363. break;
  2364. default:
  2365. ;
  2366. }
  2367. /*
  2368. * Otherwise, print out "yes" it it was a beacon packet (because
  2369. * that's how yes votes are returned, go figure), otherwise
  2370. * just print out the error code.
  2371. */
  2372. else
  2373. switch (opcode) {
  2374. case 10000: /* Beacon */
  2375. ND_PRINT((ndo, " vote yes until"));
  2376. DATEOUT();
  2377. break;
  2378. default:
  2379. ND_PRINT((ndo, " errcode"));
  2380. INTOUT();
  2381. }
  2382. return;
  2383. trunc:
  2384. ND_PRINT((ndo, " [|ubik]"));
  2385. }
  2386. /*
  2387. * Handle RX ACK packets.
  2388. */
  2389. static void
  2390. rx_ack_print(netdissect_options *ndo,
  2391. register const u_char *bp, int length)
  2392. {
  2393. const struct rx_ackPacket *rxa;
  2394. int i, start, last;
  2395. uint32_t firstPacket;
  2396. if (length < (int)sizeof(struct rx_header))
  2397. return;
  2398. bp += sizeof(struct rx_header);
  2399. /*
  2400. * This may seem a little odd .... the rx_ackPacket structure
  2401. * contains an array of individual packet acknowledgements
  2402. * (used for selective ack/nack), but since it's variable in size,
  2403. * we don't want to truncate based on the size of the whole
  2404. * rx_ackPacket structure.
  2405. */
  2406. ND_TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS);
  2407. rxa = (const struct rx_ackPacket *) bp;
  2408. bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS);
  2409. /*
  2410. * Print out a few useful things from the ack packet structure
  2411. */
  2412. if (ndo->ndo_vflag > 2)
  2413. ND_PRINT((ndo, " bufspace %d maxskew %d",
  2414. (int) EXTRACT_16BITS(&rxa->bufferSpace),
  2415. (int) EXTRACT_16BITS(&rxa->maxSkew)));
  2416. firstPacket = EXTRACT_32BITS(&rxa->firstPacket);
  2417. ND_PRINT((ndo, " first %d serial %d reason %s",
  2418. firstPacket, EXTRACT_32BITS(&rxa->serial),
  2419. tok2str(rx_ack_reasons, "#%d", (int) rxa->reason)));
  2420. /*
  2421. * Okay, now we print out the ack array. The way _this_ works
  2422. * is that we start at "first", and step through the ack array.
  2423. * If we have a contiguous range of acks/nacks, try to
  2424. * collapse them into a range.
  2425. *
  2426. * If you're really clever, you might have noticed that this
  2427. * doesn't seem quite correct. Specifically, due to structure
  2428. * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually
  2429. * yield the start of the ack array (because RX_MAXACKS is 255
  2430. * and the structure will likely get padded to a 2 or 4 byte
  2431. * boundary). However, this is the way it's implemented inside
  2432. * of AFS - the start of the extra fields are at
  2433. * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_
  2434. * the exact start of the ack array. Sigh. That's why we aren't
  2435. * using bp, but instead use rxa->acks[]. But nAcks gets added
  2436. * to bp after this, so bp ends up at the right spot. Go figure.
  2437. */
  2438. if (rxa->nAcks != 0) {
  2439. ND_TCHECK2(bp[0], rxa->nAcks);
  2440. /*
  2441. * Sigh, this is gross, but it seems to work to collapse
  2442. * ranges correctly.
  2443. */
  2444. for (i = 0, start = last = -2; i < rxa->nAcks; i++)
  2445. if (rxa->acks[i] == RX_ACK_TYPE_ACK) {
  2446. /*
  2447. * I figured this deserved _some_ explanation.
  2448. * First, print "acked" and the packet seq
  2449. * number if this is the first time we've
  2450. * seen an acked packet.
  2451. */
  2452. if (last == -2) {
  2453. ND_PRINT((ndo, " acked %d", firstPacket + i));
  2454. start = i;
  2455. }
  2456. /*
  2457. * Otherwise, if there is a skip in
  2458. * the range (such as an nacked packet in
  2459. * the middle of some acked packets),
  2460. * then print the current packet number
  2461. * seperated from the last number by
  2462. * a comma.
  2463. */
  2464. else if (last != i - 1) {
  2465. ND_PRINT((ndo, ",%d", firstPacket + i));
  2466. start = i;
  2467. }
  2468. /*
  2469. * We always set last to the value of
  2470. * the last ack we saw. Conversely, start
  2471. * is set to the value of the first ack
  2472. * we saw in a range.
  2473. */
  2474. last = i;
  2475. /*
  2476. * Okay, this bit a code gets executed when
  2477. * we hit a nack ... in _this_ case we
  2478. * want to print out the range of packets
  2479. * that were acked, so we need to print
  2480. * the _previous_ packet number seperated
  2481. * from the first by a dash (-). Since we
  2482. * already printed the first packet above,
  2483. * just print the final packet. Don't
  2484. * do this if there will be a single-length
  2485. * range.
  2486. */
  2487. } else if (last == i - 1 && start != last)
  2488. ND_PRINT((ndo, "-%d", firstPacket + i - 1));
  2489. /*
  2490. * So, what's going on here? We ran off the end of the
  2491. * ack list, and if we got a range we need to finish it up.
  2492. * So we need to determine if the last packet in the list
  2493. * was an ack (if so, then last will be set to it) and
  2494. * we need to see if the last range didn't start with the
  2495. * last packet (because if it _did_, then that would mean
  2496. * that the packet number has already been printed and
  2497. * we don't need to print it again).
  2498. */
  2499. if (last == i - 1 && start != last)
  2500. ND_PRINT((ndo, "-%d", firstPacket + i - 1));
  2501. /*
  2502. * Same as above, just without comments
  2503. */
  2504. for (i = 0, start = last = -2; i < rxa->nAcks; i++)
  2505. if (rxa->acks[i] == RX_ACK_TYPE_NACK) {
  2506. if (last == -2) {
  2507. ND_PRINT((ndo, " nacked %d", firstPacket + i));
  2508. start = i;
  2509. } else if (last != i - 1) {
  2510. ND_PRINT((ndo, ",%d", firstPacket + i));
  2511. start = i;
  2512. }
  2513. last = i;
  2514. } else if (last == i - 1 && start != last)
  2515. ND_PRINT((ndo, "-%d", firstPacket + i - 1));
  2516. if (last == i - 1 && start != last)
  2517. ND_PRINT((ndo, "-%d", firstPacket + i - 1));
  2518. bp += rxa->nAcks;
  2519. }
  2520. /*
  2521. * These are optional fields; depending on your version of AFS,
  2522. * you may or may not see them
  2523. */
  2524. #define TRUNCRET(n) if (ndo->ndo_snapend - bp + 1 <= n) return;
  2525. if (ndo->ndo_vflag > 1) {
  2526. TRUNCRET(4);
  2527. ND_PRINT((ndo, " ifmtu"));
  2528. INTOUT();
  2529. TRUNCRET(4);
  2530. ND_PRINT((ndo, " maxmtu"));
  2531. INTOUT();
  2532. TRUNCRET(4);
  2533. ND_PRINT((ndo, " rwind"));
  2534. INTOUT();
  2535. TRUNCRET(4);
  2536. ND_PRINT((ndo, " maxpackets"));
  2537. INTOUT();
  2538. }
  2539. return;
  2540. trunc:
  2541. ND_PRINT((ndo, " [|ack]"));
  2542. }
  2543. #undef TRUNCRET