1
0

check_snmp_printer 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. #!/bin/bash
  2. #########################################################
  3. # #
  4. # SNMP Printer Check #
  5. # #
  6. # check_snmp_printer #
  7. # Version 3.141592 (December 12, 2011) #
  8. # #
  9. # Authored by Jason Leonard #
  10. # E-mail: jason_leonard@yahoo.com #
  11. # #
  12. # Overview #
  13. # ----------------------------------------------------- #
  14. # This plugin is a rewrite of the SNMP printer #
  15. # check provided by Monitoring Solutions. In operating #
  16. # the plugin at our environment, I noticed the output #
  17. # was combined as one long paragraph when using the #
  18. # CONSUM ALL option (definitely a favorite of mine). #
  19. # While this is in accordance with Nagios plugin dev. #
  20. # guidelines, for devices with numerous consumables #
  21. # (like copiers), this makes it difficult to quickly #
  22. # find the empty consumable when an alert came in. So I #
  23. # set out to spruce up the output of the plugin - using #
  24. # one consumable per line. #
  25. # #
  26. # In the process, I also realized the original #
  27. # plugin was more if/then statements than I had seen #
  28. # since my programming class in college. So I made the #
  29. # code a bit cleaner for faster execution. I also had #
  30. # add SNMP pre-flight checks, as the original would #
  31. # return OK status to Nagios even if SNMP was broken. #
  32. # #
  33. # Lastly, I decided to rewrite the options and #
  34. # add other pre-flight checks that are present in my #
  35. # other plugins. I like to be thorough in making sure #
  36. # the program won't return output if the input is just #
  37. # garbage! #
  38. # #
  39. # NOTE: #
  40. # Because CONSUM ALL uses a multi-line output, #
  41. # you will need to use the $LONGSERVICEOUTPUT$ macro #
  42. # in your service notification commands! #
  43. # #
  44. # This plugin is distributed under the GNU GPL license. #
  45. # You may re-destribute only according to the terms of #
  46. # the GNU GPL v2. #
  47. # #
  48. #########################################################
  49. #########################################################
  50. ## GLOBAL VARIABLES ##
  51. #########################################################
  52. APPNAME=$(basename $0)
  53. VERSION="3.14159"
  54. COMMUNITY="public"
  55. EXIT_CODE=0
  56. EXIT_STRING=""
  57. STRING_TYPE=""
  58. PERFDAT=""
  59. CHECK=""
  60. PARAMETER=""
  61. # Set a warning at 20% of consumable, if not passed
  62. WARNING=20
  63. # Set a critical at 5% of consumable, if not passed. The standard of 10
  64. # seems to be high for most consumables, which move very slowly.
  65. CRITICAL=5
  66. # Change this to modify the script's handling of how it separates
  67. # each consumable/tray when multiple checks are output.
  68. # SEPARATOR="\n"
  69. SEPARATOR=" "
  70. # This is the character that tokenizes multiple arguments
  71. # to the TRAY and CONSUM checks. I have this here
  72. # so it's easy to change if I find the current character
  73. # I have is buggy or a bad choice
  74. ARG_TOKEN=","
  75. #########################################################
  76. ## print_help Function ##
  77. #########################################################
  78. # Prints out user help and gives examples of proper #
  79. # plugin usage #
  80. #########################################################
  81. function print_help {
  82. echo 'SNMP Printer Check for Nagios'
  83. echo ''
  84. echo 'This plugin is not developped by the Nagios Plugin group.'
  85. echo 'Please do not e-mail them for support on this plugin.'
  86. echo ''
  87. echo 'For contact info, please read the plugin script file.'
  88. echo ''
  89. echo "Usage of $APPNAME"
  90. echo " $APPNAME -H <host/IP> -C <community> -x <check> [-w] [-c] [-S] | -h | -V "
  91. echo '---------------------------------------------------------------------'
  92. echo 'Usable Options:'
  93. echo ''
  94. echo ' -C <community>'
  95. echo ' The SNMP Community variable - use the name of your SNMP community with read privileges'
  96. echo ' By default, the community is assumed to be public'
  97. echo ' -H <hostname>'
  98. echo ' (required option)'
  99. echo ' The IP address or hostname of the system to check'
  100. echo ' -S <text string>'
  101. echo ' assign a particular string as the separator for consumables.'
  102. echo ' Default is " " to conform to Nagios plugin development guidelines'
  103. echo ' -w <warn>'
  104. echo ' warning threshold (% of consumable remaining)'
  105. echo ' -c <crit>'
  106. echo ' critical threshold (% of consumable remaining)'
  107. echo ' -h'
  108. echo ' show this help screen'
  109. echo ' -V'
  110. echo ' show the current version of the plugin'
  111. echo ' -x <check>'
  112. echo ' (required option)'
  113. echo ' The check you want to perform for the printer. Choose from the following:'
  114. echo ''
  115. echo ' CONSUM {<string> | TEST | ALL}'
  116. echo ' <string> will give you all consumables matching the string '
  117. echo " For example, 'CONSUM Toner' will only show toner levels"
  118. echo ' TEST will give you the exact names of available consumables'
  119. echo ' For example,'
  120. echo ' Black Toner Cartridge HP C4191A'
  121. echo ' To monitor a consumable, call the function as follows:'
  122. echo " $APPNAME -H <hostname> -C <community> -x \"CONSUM Black\" "
  123. echo ' ALL gives you all consumable output at once.'
  124. echo ''
  125. echo ' CONSUMX <string>'
  126. echo ' this gives you results only for the ***EXACT*** consumable specified by <string>'
  127. echo ' For example, '
  128. echo ' CONSUMX "Black Toner Cartridge" '
  129. echo ' will only give you the usage for a consumable named "Black Toner Cartridge". '
  130. echo ' It will not give you results for "Black Toner Cartridge 1" or "Black Toner". '
  131. echo ' DISPLAY'
  132. echo ' Report contents of printer display'
  133. echo ''
  134. echo ' DEVICES'
  135. echo ' Status of hardware modules'
  136. echo ''
  137. echo ' MESSAGES'
  138. echo ' Event logs reported by the printer'
  139. echo ''
  140. echo ' MODEL'
  141. echo ' ALL will give you all tray output at once.'
  142. echo ''
  143. echo ' PAGECOUNT'
  144. echo ' How many pages this printer has processed (culmulative)'
  145. echo ''
  146. echo ' STATUS'
  147. echo ' Overall status of the printer'
  148. echo ''
  149. echo ' TRAY {<number> | TEST | ALL}'
  150. echo ' <number> will give you output for the specified tray. A comma-separated list of values is possible as well.'
  151. echo " TEST will give you the #'s of all trays available "
  152. echo ' ALL will give you all tray output at once.'
  153. echo ''
  154. echo 'Examples:'
  155. echo " $APPNAME -H 10.0.1.10 -C public -x \"CONSUM ALL\" -w 25 -c 10 "
  156. echo " $APPNAME -H 10.0.1.10 -C public -x \"CONSUMX Punch Dust Box\" "
  157. echo " $APPNAME -H 10.0.1.10 -C public -x MODEL "
  158. echo " $APPNAME -H 10.0.1.10 -C public -x \"TRAY 2,3\" "
  159. echo " $APPNAME -V"
  160. echo ''
  161. echo '---------------------------------------------------------------------'
  162. return 3
  163. }
  164. #########################################################
  165. ## check_model function ##
  166. #########################################################
  167. # Returns printer model and serial. Always returns OK #
  168. #########################################################
  169. function check_model(){
  170. # Vendor specific items to code here!
  171. # possibly serial #
  172. MODEL=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.25.3.2.1.3.1 2>/dev/null)
  173. SERIAL=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.5.1.1.17 2>/dev/null | tr -d "\"")
  174. EXIT_STRING="$MODEL, Serial # $SERIAL"
  175. return 0
  176. }
  177. #########################################################
  178. ## check_messages function ##
  179. #########################################################
  180. # Shows messages on the printer display. The OID is not #
  181. # commonly used in all printers #
  182. #########################################################
  183. function check_messages(){
  184. MESSAGES=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.18.1.1.8 2>/dev/null | tr -d "\"" | tr "\n" "\!")
  185. if [ -z "$MESSAGES" ]; then
  186. EXIT_STRING="UNKNOWN: Can't determine messages. Device does not support this OID.\n"
  187. EXIT_CODE=3
  188. else
  189. EXIT_STRING="$MESSAGES"
  190. fi
  191. return $EXIT_CODE
  192. }
  193. #########################################################
  194. ## check_page_count function ##
  195. #########################################################
  196. # Returns pretty-formatted page count for the printer. #
  197. # Awesome for tracking historical page usage. #
  198. #########################################################
  199. function check_page_count(){
  200. PAGE_COUNT=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.10.2.1.4.1.1 2>/dev/null | sed -e :x -e 's/\([0-9][0-9]*\)\([0-9][0-9][0-9]\)/\1,\2/' -e 'tx')
  201. EXIT_STRING="Pagecount is $PAGE_COUNT"
  202. PERFDAT="Pages=$PAGE_COUNT;"
  203. return 0
  204. }
  205. #########################################################
  206. ## check_display function ##
  207. #########################################################
  208. # #
  209. #########################################################
  210. function check_display(){
  211. DISPLAY=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.16.5.1.2.1 2>/dev/null | tr -d "\"" )
  212. # if display is null, we need to let the user know
  213. if [ $? -eq 0 ]; then
  214. # Let's make sure we eliminate any extra new lines, or at least replace them with our
  215. # specified SEPARATOR (which could be a new line)
  216. EXIT_STRING=$(echo "$DISPLAY" | tr "\n" "$SEPARATOR")
  217. return 0
  218. else
  219. # Something happened or this OID isn't available
  220. EXIT_STRING="UNKNOWN - printer does not appear to support using this OID."
  221. return 3
  222. fi
  223. }
  224. #########################################################
  225. ## check_printer_status function ##
  226. #########################################################
  227. # #
  228. #########################################################
  229. function check_printer_status(){
  230. STATUS_EXIT_CODE=0
  231. PRINTER_STATUS=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.25.3.5.1.1.1 2>/dev/null)
  232. case "$PRINTER_STATUS" in
  233. "other(1)"|"other"|"1")
  234. EXIT_STRING="OK: Printer status is $PRINTER_STATUS"
  235. STATUS_EXIT_CODE=0
  236. ;;
  237. "idle(3)"|"idle"|"3")
  238. EXIT_STRING="OK: Printer status is $PRINTER_STATUS"
  239. ;;
  240. "printing(4)"|"printing"|"4")
  241. EXIT_STRING="OK: Printer status is $PRINTER_STATUS"
  242. ;;
  243. "warmup(5)"|"warmup"|"5")
  244. EXIT_STRING="OK: Printer status is $PRINTER_STATUS"
  245. ;;
  246. *)
  247. EXIT_STRING="WARNING: Printer status is $PRINTER_STATUS"
  248. STATUS_EXIT_CODE=1
  249. ;;
  250. esac
  251. return $STATUS_EXIT_CODE
  252. }
  253. #########################################################
  254. ## check_device_status function ##
  255. #########################################################
  256. # #
  257. #########################################################
  258. function check_device_status(){
  259. CURRENT_EXIT_CODE=0
  260. CURRENT_STATUS=0
  261. DEVICE_STATUS=""
  262. DEVICE_NAME=""
  263. DEVICE_IDS=$(snmpwalk -v1 -On -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.25.3.2.1.1 2>/dev/null)
  264. # create this around a for loop on id's, which come from .1.3.6.1.2.1.25.3.2.1.1.x
  265. for ID in $(echo $DEVICE_IDS | egrep -oe '[[:digit:]]+\ =' | cut -d " " -f1)
  266. do
  267. DEVICE_NAME=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.25.3.2.1.3.$ID 2>/dev/null)
  268. EXIT_STRING="$EXIT_STRING$DEVICE_NAME status is "
  269. DEVICE_STATUS=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.25.3.2.1.5.$ID 2>/dev/null)
  270. case "$DEVICE_STATUS" in
  271. "unknown(1)")
  272. EXIT_STRING="$EXIT_STRING$DEVICE_STATUS - WARNING!$SEPARATOR"
  273. CURRENT_STATUS=1
  274. ;;
  275. "running(2)")
  276. EXIT_STRING="$EXIT_STRING$DEVICE_STATUS - OK!$SEPARATOR"
  277. ;;
  278. "warning(3)")
  279. EXIT_STRING="$EXIT_STRING$DEVICE_STATUS - WARNING!$SEPARATOR"
  280. CURRENT_STATUS=1
  281. ;;
  282. "testing(4)")
  283. EXIT_STRING="$EXIT_STRING$DEVICE_STATUS - OK!$SEPARATOR"
  284. ;;
  285. "down(5)")
  286. EXIT_STRING="$EXIT_STRING$DEVICE_STATUS - CRITICAL!$SEPARATOR"
  287. CURRENT_STATUS=2
  288. ;;
  289. *)
  290. EXIT_STRING="$EXIT_STRING$DEVICE_STATUS - WARNING!$SEPARATOR"
  291. CURRENT_STATUS=1
  292. ;;
  293. esac
  294. if [ "$CURRENT_STATUS" -gt "$CURRENT_EXIT_CODE" ]; then
  295. CURRENT_EXIT_CODE="$CURRENT_STATUS"
  296. fi
  297. done
  298. return $CURRENT_EXIT_CODE
  299. }
  300. #########################################################
  301. ## check_one_consumable function ##
  302. #########################################################
  303. # Given the marker's ID (1, 2, 3, etc.), this function #
  304. # grabs the consmable string for that ID, converts it #
  305. # to a name and determines capacity and status code for #
  306. # it. #
  307. # #
  308. # Only status code is returned. Global string variables #
  309. # are used for printing and other functionality. #
  310. #########################################################
  311. function check_one_consumable () {
  312. local CONSUM_EXIT_CODE=0
  313. CURRENT_CAPACITY=0
  314. MAX_CAPACITY=0
  315. MARKER_NAME=""
  316. MARKER_COLOR=""
  317. MARKER_STRING=$(snmpget -v1 -On -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.6.1.$1 2>/dev/null)
  318. # We'll be parsing our name differently depending on whether we have Hex-String or not
  319. if [ "$STRING_TYPE" == "Hex-STRING:" ]; then
  320. MARKER_NAME=$(echo "$MARKER_STRING" | cut -d ":" -f2- | tr -d "\n" | xxd -r -p)
  321. else
  322. MARKER_NAME=$(echo "$MARKER_STRING" | cut -d " " -f4- | tr -d "\"")
  323. fi
  324. # Some manufacturers don't put the actual cartridge color in the above OID text for
  325. # MARKER_STRING. Instead, each entry just says "toner". The OID used here is
  326. # a place where an associated color string must be stored. We are going to get this
  327. # info. and use it if not already available in the MARKER_NAME we've parsed.
  328. # --- Thanks to Martin Љoltis for letting me know about this problem on some copiers.
  329. GETCOLOR=$(snmpget -v1 -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.12.1.1.4.1.$1 2>/dev/null)
  330. MARKER_COLOR=$(echo $GETCOLOR | cut -d " " -f4- | tr -d "\"")
  331. # We're just checking here to see if the consumable already has this color in its text description
  332. if [ $(echo "$MARKER_NAME" | grep -vqi "$MARKER_COLOR") ]; then
  333. # It doesn't, so we're going to add it
  334. MARKER_NAME="$MARKER_COLOR $MARKER_NAME"
  335. fi
  336. # As usual, if the results are an empty set, something went wrong or didn't match up
  337. if [ -z "$MARKER_NAME" ]; then
  338. EXIT_STRING="UNKNOWN - OID not found! Your printer may not support checking this consumable."
  339. EXIT_STRING="$EXIT_STRING Use the CONSUM TEST option to determine which consumables may be monitored."
  340. PERFDAT=""
  341. CONSUM_EXIT_CODE=3
  342. else
  343. # Determine capacities for the current marker
  344. CURRENT_CAPACITY=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.9.1.$1 2>/dev/null)
  345. MAX_CAPACITY=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.8.1.$1 2>/dev/null)
  346. if [ "$MAX_CAPACITY" -lt 0 ]; then
  347. MAX_CAPACITY=0
  348. fi
  349. # the component does not have a measurable status indication
  350. case "$CURRENT_CAPACITY" in
  351. "-3") # A value of (-3) means that the printer knows that there is some supply/remaining space
  352. EXIT_STRING="$EXIT_STRING$MARKER_NAME is OK!$SEPARATOR"
  353. ;;
  354. "-2") # The value (-2) means unknown
  355. EXIT_STRING="$EXIT_STRING$MARKER_NAME is at WARNING level!$SEPARATOR"
  356. if [ "$CONSUM_EXIT_CODE" -lt 1 ]; then
  357. CONSUM_EXIT_CODE=1
  358. fi
  359. ;;
  360. "0") # Something is empty!
  361. EXIT_STRING="$EXIT_STRING$MARKER_NAME is at CRITICAL level!$SEPARATOR"
  362. CONSUM_EXIT_CODE=2
  363. ;;
  364. *) # A positive value means this is a measurable component - let's report it's status code and let user know the % usage
  365. let "CURRENT_CAPACITY=$CURRENT_CAPACITY * 100 / $MAX_CAPACITY"
  366. if [ "$CURRENT_CAPACITY" -gt "$WARNING" ]; then
  367. EXIT_STRING="$EXIT_STRING$MARKER_NAME is at $CURRENT_CAPACITY%% - OK!$SEPARATOR"
  368. else
  369. if [ "$CURRENT_CAPACITY" -le "$WARNING" ] && [ "$CURRENT_CAPACITY" -gt "$CRITICAL" ]; then
  370. EXIT_STRING="$EXIT_STRING$MARKER_NAME is at $CURRENT_CAPACITY%% - WARNING!$SEPARATOR"
  371. if [ "$CONSUM_EXIT_CODE" -lt 1 ]; then
  372. CONSUM_EXIT_CODE=1
  373. fi
  374. else
  375. if [ "$CURRENT_CAPACITY" -le "$CRITICAL" ]; then
  376. EXIT_STRING="$EXIT_STRING$MARKER_NAME is at $CURRENT_CAPACITY%% - CRITICAL!$SEPARATOR"
  377. CONSUM_EXIT_CODE=2
  378. fi
  379. fi
  380. fi
  381. ;;
  382. esac
  383. PERFDAT="$PERFDAT $MARKER_NAME=$CURRENT_CAPACITY;$WARNING;$CRITICAL;"
  384. fi
  385. return $CONSUM_EXIT_CODE
  386. }
  387. #########################################################
  388. ## check_exact_consumable function ##
  389. #########################################################
  390. # Loops through all consumables and compares the string #
  391. # passed to the consumable string. If a match is found, #
  392. # we calculate and output capacity and status. If a #
  393. # match is not found, let the user know. #
  394. # #
  395. # Global string variables are used for printing status #
  396. # and perf data. #
  397. #########################################################
  398. function check_exact_consumable(){
  399. local CONSUMX_EXIT_CODE=0
  400. FOUND=false
  401. FOUND_MARKER=0
  402. # Now we can loop through everything that matched
  403. for MARKER_ID in $(echo "$ALL_MARKERS" | egrep -oe '[[:digit:]]+\ =' | cut -d " " -f1)
  404. do
  405. MARKER_STRING=$(snmpget -v1 -On -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.6.1.$MARKER_ID 2>/dev/null)
  406. # We'll be parsing our name differently depending on whether we have Hex-String or not
  407. if [ "$STRING_TYPE" == "Hex-STRING:" ]; then
  408. MARKER_NAME=$(echo "$MARKER_STRING" | cut -d ":" -f2- | tr -d "\n" | xxd -r -p)
  409. else
  410. MARKER_NAME=$(echo "$MARKER_STRING" | cut -d " " -f4- | tr -d "\"")
  411. fi
  412. # Update our boolean if we find a match!
  413. if [ "$1" == "$MARKER_NAME" ]; then
  414. FOUND=true
  415. FOUND_MARKER="$MARKER_ID"
  416. fi
  417. done
  418. if $FOUND; then
  419. # Determine capacities for the marker of the matching consumable
  420. X_CURRENT_CAPACITY=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.9.1.$FOUND_MARKER 2>/dev/null)
  421. MAX_CAPACITY=$(snmpget -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.8.1.$FOUND_MARKER 2>/dev/null)
  422. if [ "$MAX_CAPACITY" -lt 0 ]; then
  423. MAX_CAPACITY=0
  424. fi
  425. # the component does not have a measurable status indication
  426. case "$X_CURRENT_CAPACITY" in
  427. "-3") # A value of (-3) means that the printer knows that there is some supply/remaining space
  428. EXIT_STRING="$EXIT_STRING$1 is OK!\n"
  429. ;;
  430. "-2") # The value (-2) means unknown
  431. EXIT_STRING="$EXIT_STRING$1 is at WARNING level!$SEPARATOR"
  432. if [ "$CONSUMX_EXIT_CODE" -lt 1 ]; then
  433. CONSUMX_EXIT_CODE=1
  434. fi
  435. ;;
  436. "0") # Something is empty!
  437. EXIT_STRING="$EXIT_STRING$1 is at CRITICAL level!$SEPARATOR"
  438. CONSUMX_EXIT_CODE=2
  439. ;;
  440. *) # A positive value means this is a measurable component - let's report it's status code and let user know the % usage
  441. let "X_CURRENT_CAPACITY=$X_CURRENT_CAPACITY * 100 / $MAX_CAPACITY"
  442. if [ "$X_CURRENT_CAPACITY" -gt "$WARNING" ]; then
  443. EXIT_STRING="$EXIT_STRING$1 is at $X_CURRENT_CAPACITY%% - OK!$SEPARATOR"
  444. else
  445. if [ "$X_CURRENT_CAPACITY" -le "$WARNING" ] && [ "$X_CURRENT_CAPACITY" -gt "$CRITICAL" ]; then
  446. EXIT_STRING="$EXIT_STRING$1 is at $X_CURRENT_CAPACITY%% - WARNING!$SEPARATOR"
  447. if [ "$CONSUMX_EXIT_CODE" -lt 1 ]; then
  448. CONSUMX_EXIT_CODE=1
  449. fi
  450. else
  451. if [ "$X_CURRENT_CAPACITY" -le "$CRITICAL" ]; then
  452. EXIT_STRING="$EXIT_STRING$1 is at $X_CURRENT_CAPACITY%% - CRITICAL!$SEPARATOR"
  453. CONSUMX_EXIT_CODE=2
  454. fi
  455. fi
  456. fi
  457. ;;
  458. esac
  459. PERFDAT="$PERFDAT $1=$X_CURRENT_CAPACITY;$WARNING;$CRITICAL;"
  460. else
  461. # Let the user know we didn't find anything, and report back the string they sent. Also prompt them to run the TEST option to double-check their string
  462. EXIT_STRING="UNKNOWN - No match found for '$1'! Use the CONSUM TEST option to determine which consumables may be monitored.\n"
  463. CONSUMX_EXIT_CODE=3
  464. fi
  465. return $CONSUMX_EXIT_CODE
  466. }
  467. #########################################################
  468. ## check_consumables function ##
  469. #########################################################
  470. # Determines which consumables to check and then pass #
  471. # them all off to check_one_consumable #
  472. # #
  473. # Global string variables are used for printing status #
  474. # and perf data. #
  475. #########################################################
  476. function check_consumables(){
  477. local CONSUMS_EXIT_CODE=0
  478. HEX_ID=0
  479. CURRENT_STATUS=0
  480. HEX_MARKER=""
  481. ASCII_MARKER=""
  482. MARKERS_MATCHED=""
  483. case "$1" in
  484. "TEST") # User passed "TEST" parameter - output what consumables are available
  485. printf "Consumables you may monitor:\n"
  486. if [ "$STRING_TYPE" == "Hex-STRING:" ]; then
  487. for HEX_ID in $(echo "$ALL_MARKERS" | egrep -oe '[[:digit:]]+\ =' | cut -d " " -f1)
  488. do
  489. HEX_MARKER=$(snmpget -v1 -On -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.6.1.$HEX_ID 2>/dev/null)
  490. ASCII_MARKER=$(echo "$HEX_MARKER" | cut -d ":" -f2 | tr -d "\n" | xxd -r -p)
  491. EXIT_STRING="$EXIT_STRING$ASCII_MARKER\n"
  492. done
  493. else
  494. EXIT_STRING=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.6.1 2>/dev/null)
  495. fi
  496. CONSUMS_EXIT_CODE=3
  497. ;;
  498. "ALL") # User passed ALL parameter - check everything!
  499. # Let's loop through all consumables available
  500. for MARKER_ID in $(echo "$ALL_MARKERS" | egrep -oe '[[:digit:]]+\ =' | cut -d " " -f1)
  501. do
  502. check_one_consumable "$MARKER_ID"
  503. CURRENT_STATUS=$?
  504. if [ "$CURRENT_STATUS" -gt "$CONSUMS_EXIT_CODE" ]; then
  505. CONSUMS_EXIT_CODE="$CURRENT_STATUS"
  506. fi
  507. done
  508. ;;
  509. *) # A string was passed, on which we will match to available consumable strings
  510. if [ "$STRING_TYPE" == "Hex-STRING:" ]; then
  511. # If our printer uses Hex-STRING fields, we need to convert our user's string to hex first
  512. HEX_STRING=$(echo "$1" | tr -d "\n" | xxd -p -u)
  513. # Now that we have a hex string for the user string, we need look for it in output that is formatted similarly
  514. # XXD -p doesn't output spaces, but the Hex-STRING fields do use spaces between each byte
  515. MARKERS_MATCHED=$(echo "$ALL_MARKERS" | tr -d " " | egrep -i "$HEX_STRING")
  516. else
  517. MARKERS_MATCHED=$(echo "$ALL_MARKERS" | egrep -i "$1")
  518. fi
  519. if [ -z "$MARKERS_MATCHED" ]; then
  520. EXIT_STRING="UNKNOWN - OID not found! Your printer may not support checking this consumable."
  521. EXIT_STRING="$EXIT_STRING Use the CONSUM TEST option to determine which consumables may be monitored."
  522. PERFDAT=""
  523. EXIT_CODE=3
  524. else
  525. # Now we can loop through everything that matched
  526. for MARKER_ID in $(echo "$MARKERS_MATCHED" | cut -d "=" -f1 | cut -d "." -f14)
  527. do
  528. check_one_consumable "$MARKER_ID"
  529. CURRENT_STATUS=$?
  530. if [ "$CURRENT_STATUS" -gt "$CONSUMS_EXIT_CODE" ]; then
  531. CONSUMS_EXIT_CODE="$CURRENT_STATUS"
  532. fi
  533. done
  534. fi
  535. ;;
  536. esac
  537. return $CONSUMS_EXIT_CODE
  538. }
  539. #########################################################
  540. ## check_one_tray Function ##
  541. #########################################################
  542. # Checks the tray #, as passed by parameter. If found, #
  543. # it returns the status and capacity. #
  544. # #
  545. # Only status code is returned. Global string variables #
  546. # are used for printing and other functionality. #
  547. #########################################################
  548. function check_one_tray (){
  549. TRAY_EXIT_CODE=0
  550. TRAY_CAPACITY=0
  551. TRAY_MAX_CAPACITY=0
  552. TRAY_FEED_DIMENSION=0
  553. TRAY_XFEED_DIMENSION=0
  554. TRAY_DIMENSION_UNITS=0
  555. TRAY_CAPACITY=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.10.1.$1 2>/dev/null)
  556. if [ -z "$TRAY_CAPACITY" ]; then
  557. EXIT_STRING="$EXIT_STRING UNKNOWN - Tray $1 not found. Use the TRAY TEST option to determine which trays may be monitored.\n"
  558. TRAY_EXIT_CODE=3
  559. else
  560. # Determine information about the tray
  561. TRAY_NAME=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.13.1.$1 2>/dev/null)
  562. # Some manufacturers do not set the tray name OID, so we'll assume a generic name depending on the # passed to the function
  563. if [ "$TRAY_NAME"=="" ]; then
  564. TRAY_NAME="Tray $1"
  565. fi
  566. case "$TRAY_CAPACITY" in
  567. "-3") # The value (-3) means that the printer knows that at least one unit remains.
  568. EXIT_STRING="$EXIT_STRING$TRAY_NAME is OK!$SEPARATOR"
  569. ;;
  570. "-2") # The value (-2) means unknown
  571. EXIT_STRING="$EXIT_STRING$TRAY_NAME status is UNKNOWN!$SEPARATOR"
  572. TRAY_EXIT_CODE=3
  573. ;;
  574. "0") # 0 means there is no paper left! This is our only critical value.
  575. # Determine paper size of current tray
  576. TRAY_FEED_DIMENSION=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.4.1.$1 2>/dev/null)
  577. TRAY_XFEED_DIMENSION=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.5.1.$1 2>/dev/null)
  578. TRAY_DIMENSION_UNITS=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.3.1.$1 2>/dev/null)
  579. if [ "$TRAY_FEED_DIMENSION" -lt 0 ] && [ "$TRAY_XFEED_DIMENSION" -lt 0 ]; then
  580. # If either dimension was negative, then we really don't know much about the dimension
  581. TRAY_DIMENSION_STRING="paper."
  582. else
  583. case "$TRAY_DIMENSION_UNITS" in
  584. "3") # convert ten thousandths of an inch to inches
  585. TRAY_FEED_DIMENSION=$(echo "scale=1;$TRAY_FEED_DIMENSION/10000" | bc)
  586. TRAY_XFEED_DIMENSION=$(echo "scale=1;$TRAY_XFEED_DIMENSION/10000" | bc)
  587. ;;
  588. "4") # convert micrometers to inches, and get the int portion
  589. TRAY_FEED_DIMENSION=$(echo "scale=1;$TRAY_FEED_DIMENSION*0.0000393700787" | bc)
  590. TRAY_FEED_DIMENSION=$(echo "scale=1;$TRAY_FEED_DIMENSION+0.5" | bc)
  591. TRAY_FEED_DIMENSION=$(echo "scale=1;$TRAY_FEED_DIMENSION/1" | bc)
  592. TRAY_XFEED_DIMENSION=$(echo "scale=1;$TRAY_XFEED_DIMENSION*0.0000393700787" | bc)
  593. TRAY_XFEED_DIMENSION=$(echo "scale=1;$TRAY_XFEED_DIMENSION+0.5" | bc)
  594. TRAY_XFEED_DIMENSION=$(echo "scale=1;$TRAY_XFEED_DIMENSION/1" | bc)
  595. ;;
  596. esac
  597. TRAY_DIMENSION_STRING="$TRAY_XFEED_DIMENSION x $TRAY_FEED_DIMENSION paper."
  598. fi
  599. EXIT_STRING="$EXIT_STRING$TRAY_NAME is at CRITICAL level - please refill with more $TRAY_DIMENSION_STRING$SEPARATOR"
  600. TRAY_EXIT_CODE=2
  601. ;;
  602. *) # A positive number indicates how many pages are left. We'll calculate what % of capacity this is and determine status
  603. TRAY_MAX_CAPACITY=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.9.1.$1 2>/dev/null )
  604. let "TRAY_CAPACITY = $TRAY_CAPACITY * 100 / $TRAY_MAX_CAPACITY"
  605. if [ "$TRAY_CAPACITY" -gt "$CRITICAL" ]; then
  606. EXIT_STRING="$EXIT_STRING$TRAY_NAME is at $TRAY_CAPACITY%% - OK!$SEPARATOR"
  607. else
  608. if [ "$TRAY_CAPACITY" -le "$WARNING" ]; then
  609. # Determine paper size of current tray
  610. TRAY_FEED_DIMENSION=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.4.1.$1 2>/dev/null )
  611. TRAY_XFEED_DIMENSION=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.5.1.$1 2>/dev/null )
  612. TRAY_DIMENSION_UNITS=$(snmpwalk -v1 -Ovq -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.3.1.$1 2>/dev/null )
  613. if [ "$TRAY_FEED_DIMENSION" -lt 0 ] && [ "$TRAY_XFEED_DIMENSION" -lt 0 ]; then
  614. # If either dimension was negative, then we really don't know much about the dimension
  615. TRAY_DIMENSION_STRING="paper."
  616. else
  617. case "$TRAY_DIMENSION_UNITS" in
  618. "3") # convert ten thousandths of an inch to inches
  619. TRAY_FEED_DIMENSION=$(echo "scale=1;$TRAY_FEED_DIMENSION/10000" | bc)
  620. TRAY_XFEED_DIMENSION=$(echo "scale=1;$TRAY_XFEED_DIMENSION/10000" | bc)
  621. ;;
  622. "4") # convert micrometers to inches, and get the int portion
  623. TRAY_FEED_DIMENSION=$(echo "scale=1;$TRAY_FEED_DIMENSION*0.0000393700787" | bc)
  624. TRAY_FEED_DIMENSION=$(echo "scale=1;$TRAY_FEED_DIMENSION+0.5" | bc)
  625. TRAY_FEED_DIMENSION=$(echo "scale=1;$TRAY_FEED_DIMENSION/1" | bc)
  626. TRAY_XFEED_DIMENSION=$(echo "scale=1;$TRAY_XFEED_DIMENSION*0.0000393700787" | bc)
  627. TRAY_XFEED_DIMENSION=$(echo "scale=1;$TRAY_XFEED_DIMENSION+0.5" | bc)
  628. TRAY_XFEED_DIMENSION=$(echo "scale=1;$TRAY_XFEED_DIMENSION/1" | bc)
  629. ;;
  630. esac
  631. TRAY_DIMENSION_STRING="$TRAY_XFEED_DIMENSION x $TRAY_FEED_DIMENSION paper."
  632. fi
  633. if [ "$TRAY_CAPACITY" -le "$CRITICAL" ]; then
  634. # we have a critical: we already know the value is less than warning
  635. EXIT_STRING="$EXIT_STRING$TRAY_NAME is at $TRAY_CAPACITY%% - CRITICAL! Please refill with more $TRAY_DIMENSION_STRING$SEPARATOR"
  636. TRAY_EXIT_CODE=2
  637. else
  638. # we are only below warning, but not yet below critical
  639. EXIT_STRING="$EXIT_STRING$TRAY_NAME is at $TRAY_CAPACITY%% - WARNING! Please refill with more $TRAY_DIMENSION_STRING$SEPARATOR"
  640. if [ "$TRAY_EXIT_CODE" -lt 1 ]; then
  641. TRAY_EXIT_CODE=1
  642. fi
  643. fi
  644. fi
  645. fi
  646. PERFDAT="$PERFDAT $TRAY_NAME=$TRAY_CAPACITY;$WARNING;$CRITICAL;"
  647. ;;
  648. esac
  649. fi
  650. return $TRAY_EXIT_CODE
  651. }
  652. #########################################################
  653. ## check_paper_trays Function ##
  654. #########################################################
  655. # Determines which trays to check and passes each check #
  656. # off to check_one_tray. #
  657. # #
  658. # Global string variables are used for printing status #
  659. # and perf data. #
  660. #########################################################
  661. function check_paper_trays (){
  662. TRAYS_EXIT_CODE=0
  663. ALL_TRAYS=$(snmpwalk -v1 -On -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.8.2.1.10.1 2>/dev/null)
  664. CURRENT_TRAY_STATUS=0
  665. case "$1" in
  666. "TEST")
  667. echo "Trays you may monitor:"
  668. echo "$(echo "$ALL_TRAYS" | egrep -oe '[[:digit:]]+\ =' | cut -d " " -f1)"
  669. TRAYS_EXIT_CODE=3
  670. ;;
  671. "ALL") # let's check all trays!
  672. for TRAY_ID in $(echo "$ALL_TRAYS" | egrep -oe '[[:digit:]]+\ =' | cut -d " " -f1)
  673. do
  674. check_one_tray "$TRAY_ID"
  675. CURRENT_TRAY_STATUS=$?
  676. if [ "$CURRENT_TRAY_STATUS" -gt "$TRAYS_EXIT_CODE" ]; then
  677. TRAYS_EXIT_CODE="$CURRENT_TRAY_STATUS"
  678. fi
  679. done
  680. ;;
  681. *)
  682. for TRAY_ID in $(echo "$1" | tr "$ARG_TOKEN" "\n")
  683. do
  684. check_one_tray "$TRAY_ID"
  685. CURRENT_TRAY_STATUS=$?
  686. if [ "$CURRENT_TRAY_STATUS" -gt "$TRAYS_EXIT_CODE" ]; then
  687. TRAYS_EXIT_CODE="$CURRENT_TRAY_STATUS"
  688. fi
  689. done
  690. ;;
  691. esac
  692. return $TRAYS_EXIT_CODE
  693. }
  694. #########################################################
  695. ## MAIN CODE ##
  696. #########################################################
  697. # Check that all required binaries for the script are available
  698. # EXIT with an UNKNOWN status if not
  699. binaries="snmpwalk snmpget bc egrep xxd"
  700. for required_binary in $binaries;
  701. do
  702. which $required_binary > /dev/null
  703. if [ "$?" != '0' ];then
  704. printf "UNKNOWN: $APPNAME: No usable '$required_binary' binary in '$PATH'\n"
  705. exit 3
  706. fi
  707. done
  708. # Parse our options as passed, and make sure things are peachy
  709. while getopts "C:H:c:w:x:S:hV" OPTION;
  710. do
  711. case $OPTION in
  712. "C") # Assign community
  713. COMMUNITY="$OPTARG"
  714. ;;
  715. "H") # Assign hostname
  716. HOST_NAME="$OPTARG"
  717. ;;
  718. "c") # Assign CRITICAL threshold
  719. CRITICAL="$OPTARG"
  720. ;;
  721. "w") # Assign WARNING threshold
  722. WARNING="$OPTARG"
  723. ;;
  724. "x") # Assign check to perform
  725. CHECK=$(echo "$OPTARG" | cut -d " " -f1)
  726. PARAMETER=$(echo "$OPTARG" | cut -d " " -f2-)
  727. ;;
  728. "S") # Assign separator
  729. SEPARATOR="$OPTARG"
  730. ;;
  731. "h") # Print application help
  732. print_help
  733. exit $?
  734. ;;
  735. "V") # Print application version
  736. printf "$APPNAME - version $VERSION\n"
  737. exit $EXIT_CODE
  738. ;;
  739. esac
  740. done
  741. # Make sure all necessary arguments were given; EXIT with an UNKNOWN status if not
  742. if [ -z "$COMMUNITY" ] || [ -z "$HOST_NAME" ];then
  743. # we need these parameters to continue
  744. EXIT_STRING="UNKNOWN: Hostname and/or Community variables have not been set!\n"
  745. EXIT_CODE=3
  746. else
  747. ALL_MARKERS=$(snmpwalk -v1 -On -c $COMMUNITY $HOST_NAME 1.3.6.1.2.1.43.11.1.1.6.1 2>/dev/null)
  748. if [ $? -ne 0 ]; then
  749. #Check for server response - is SNMP even setup okay?
  750. EXIT_STRING="WARNING: No SNMP response from $HOST_NAME! Make sure host is up and SNMP is configured properly.\n"
  751. EXIT_CODE=1
  752. else
  753. STRING_TYPE=$(echo "$ALL_MARKERS" | tr -d "\n" | cut -d " " -f3)
  754. case "$CHECK" in
  755. "MESSAGES")
  756. check_messages
  757. ;;
  758. "MODEL")
  759. check_model
  760. ;;
  761. "CONSUM")
  762. check_consumables "$PARAMETER"
  763. ;;
  764. "CONSUMX")
  765. check_exact_consumable "$PARAMETER"
  766. ;;
  767. "TRAY")
  768. check_paper_trays "$PARAMETER"
  769. ;;
  770. "PAGECOUNT")
  771. check_page_count
  772. ;;
  773. "DEVICES")
  774. check_device_status
  775. ;;
  776. "STATUS")
  777. check_printer_status
  778. ;;
  779. "DISPLAY")
  780. check_display
  781. ;;
  782. *) # no parameters were passed, or a parameter was incorrect (wrong spelling, etc.)
  783. echo 'Invalid check specified by -x parameter.'
  784. echo ''
  785. print_help
  786. ;;
  787. esac
  788. EXIT_CODE=$?
  789. fi
  790. fi
  791. # If the program hasn't exited already, then a check was run okay and we can quit.
  792. if [ "$PERFDAT" == "" ]; then
  793. printf "$EXIT_STRING\n"
  794. else
  795. printf "$EXIT_STRING|$PERFDAT\n"
  796. fi
  797. exit $EXIT_CODE