├── afl └── testcase │ ├── b40a88e1e4a0e0044936b2e61de5364d48b16e8c.csv │ ├── 39c99f32ec43d6ee12857a64e031114ae7cf23cd.csv │ ├── b2eeafbc752b681e5d68332192c8097ef43ab687.csv │ ├── 6184436113637747407bf86315ebd987300b8799 │ ├── 657af263aa78ee4d6b755df9e00a159d5c88dc2a.csv │ ├── 7e1e393db35bd119ab38a395829ff5deadd9501a │ ├── 9062ca40d53bbf790d9338ed79b5215ca76178d2.csv │ ├── fb0082d5df4c4f237f65ac2c2717ae46408c17b8.csv │ ├── 554ff10f0a6f35849db7e44176aa94c6dc232872.csv │ ├── eebceb65beacbe25d0db149e5c37198ee5be1912.csv │ ├── 617ce3a43c7dbb1ba99a422ce455c1b55d2260b4.csv │ ├── 9c3040be62f1785b6387524185ae7508966a8fca │ ├── fcc19a8cc98ada27c4b6a605adca5bb497ad618e │ ├── f007593acbf7f63773efa1b65ef61da7fcefbb34 │ ├── log_sense_fb4080b69b8ca7d50d16f424305467a18d8eded9.csv │ ├── 9da9f3b23df2a728a486968d9e4f4a87aff34bf6.csv │ ├── id:000008,src:001208,op:flip1,pos:89 │ ├── id:000005,sig:11,src:005234,op:havoc,rep:2 │ ├── id:000013,sig:11,src:005882,op:havoc,rep:2 │ ├── log_sense_d192aef3ac66f84b8996edeb95ef1e7e9d6660cb.csv │ ├── log_sense_c52c16bd44de5cf72ba1a55c0b6258349a74e5d6.csv │ ├── 801bc5987bfe420b04e07eb1cd5ae0462a0b750c │ ├── 961ce3b94d711105a238b82068012e5b765b4027 │ ├── e71ac2a14ce3dd789a00eae0c656b36e2c07186a │ ├── ee66ad0b8b05525c54c4538059714a92646c39fb │ ├── fec38c54692c2fcff269370fc1bbb9e598b821a7 │ ├── 1b5fac8682806d6e823c301159d6da81e30f421a │ ├── 7eeaad7ca0a2197d1283c87d441a15f6c8d5e6f6 │ ├── a6b72fc2c30cf1d9ff74a2d5054bcb5dca317c15 │ ├── f40e3999c3fe73cd2e50083874537ec000697cb7 │ ├── ff82315f17a9d582afd6aba974c222e00d14af15 │ ├── ff5f50f7b5d36b765da768ef583a8b289be09a7e.csv │ ├── 86f870fdeb8e99954869aaf1b58e456109e2e6c8 │ ├── ffefa3f6034cc5680792a8cae855bc7a2d9f9019 │ ├── f7faaa230cdb97e1aec1e5ca75f89b7ea8b78726 │ ├── fc52fecd84a8f8a478b99b4965333a7f9dfa002c │ ├── ffb313726fc6fa8b68381e5df22e960cb623b62c.csv │ ├── id:000003,src:000314,op:flip1,pos:19 │ ├── id:000005,src:000445,op:flip1,pos:132 │ ├── ff0232f5144d65579feeccb6b65687c5056501a7 │ ├── ff3242c96b948a6ded16dd8ae51b1e61c40c5a66 │ ├── id:000001,src:000141,op:arith8,pos:118,val:-34 │ ├── log_sense_ac03383386fa3d77d3d460480a52e0b99a1c580e.csv │ ├── ffe9cd6ca4dbbdd2b2429c8d8023183b84c2962f │ ├── a750591769e551117e3144c8927a05d96fdfb362 │ ├── id:000019,src:001231,op:flip1,pos:72 │ ├── 2b34251f3421af9a5c53a41f7e27f1cc3e8a13b0 │ ├── log_sense_f2ca65053fcb0a0b0a479e181fa8b497beb40d9c.csv │ ├── log_sense_dc08fbd86ddd3f34a56532faf9b46f0ae135e644.csv │ ├── 5b7d04cbfbe29ec8f91526131c87e7cc8e9ea10e │ ├── id:000015,src:001216,op:flip1,pos:229 │ ├── 4941885df82498d8ca26375728606d41be818e27 │ ├── f3492a44323a0bf7bea4e59b536feaf7620b8e8b │ ├── log_sense_fc58600bcf8dc103f911bb2a6a867ab2c8e42fe2.csv │ ├── id:000001,sig:11,src:005156,op:ext_AO,pos:34 │ ├── id:000007,sig:11,src:005483,op:flip2,pos:43 │ ├── log_sense_ffee0af0b99b68b9d287e6f65ad08a4e11967daa.csv │ ├── log_sense_ffe62c433d9a885d2a5670ff890f5b00089739aa.csv │ ├── ebc80a44e5ef0a66fddb29c48373701b2eeb5227 │ ├── fff9db19407d43fdb18735c075071a866a5f0795 │ ├── fec50c6c3f5486958b33beada06857deeff177dd.csv │ ├── log_sense_9bd3419f85d952cf54a38196fc0775a2bfa4c6ff.csv │ ├── f5272bcea41574f9cd663f33334c530abcca01d7 │ ├── fedb716d47c930bafffff38b6c274ce9202187ac │ ├── fffa5f13587a7e46023238c9e7db91fd61414105 │ ├── 745f69394ad87d7d234e796b1a54a31f970e2510.csv │ ├── ce03e25003a16fc03abb3d4f337a39e622962c60 │ ├── d2f9abc5e26020e42b45a32fcf3777cc61ea711c │ ├── fcd8ce757f7d3f54ab0ee3d01007e0a6d70fa288 │ ├── ff5a0c3111af229b7f4ec8c4a38d82ccf7e553a2 │ ├── ef22fafdd3041dc08043fe2bb908e96dffa34ff5 │ ├── 28eeac63bfcf7ad2126d2eddcdc04019270075ec │ ├── ff980b7b6e39f929b8ddb08e419a2904abd44b33 │ ├── a4005cb54f820f0dc3889aab343ea1698b1dd5f4.csv │ ├── id:000002,src:000200,op:ext_AO,pos:571 │ ├── id:000018,src:001179,op:ext_AO,pos:826 │ ├── febd83d39f830202ca6081514960b4242e536df7 │ ├── 7c597125d72d146425d1899f6512b82df99b59c1 │ ├── a051877bf52e199210ffd96778f7698e3dc6978e.csv │ ├── f7db47bebdfb5888fae0fbe826b37df33a450292 │ ├── 8329e3313860bfd6b8dd1252b4a4542d4c791f13.csv │ ├── c144c7638bb08162db1ae53954e6cd20e66474f7 │ ├── fbc7b5cc87f1afa84d70c82f152761258a3b0ca6 │ ├── ca52cd17cb1a061767830cb4e49867be9b637e56 │ ├── 90548a1ef4bae0b9b7382497097a01691333fb4f │ ├── id:000018,sig:11,src:001807,op:flip1,pos:93 │ ├── id:000019,sig:11,src:001807,op:flip1,pos:670 │ ├── id:000020,sig:11,src:001807,op:flip1,pos:2325 │ ├── id:000021,sig:11,src:001807,op:flip2,pos:238 │ ├── 186704e9f39832c4c7b4f2ab71c52762017bd728 │ └── a3a3b5b0ea540bc579228dfe70b21f40d9c0df96 ├── src ├── CMakeLists.txt ├── parse.c ├── smartdb │ ├── smartdb.c │ ├── smartdb_gen.c │ ├── smartdb_gen_c.py │ └── smartdb.xml ├── log_sense.c ├── str_map.c ├── parse_read_cap.c ├── parse_inquiry.c ├── ata_smart.c ├── ata.c └── cdb.c ├── test ├── sense_dump.h ├── main.h ├── samples │ ├── parse_file.py │ └── breakout.py ├── ata_check_power_mode.c ├── ata_identify.c ├── scsi_read_capacity_10.c ├── sense_decode.c ├── ata_smart_return_status.c ├── CMakeLists.txt ├── scsi_read_capacity_16.c ├── scsi_receive_diagnostics.c ├── scsi_mode_sense.c ├── main.c ├── scsi_log_sense.c ├── sense_dump.c ├── ata_smart_read_data.c └── scsi_inquiry.c ├── regen.sh ├── structs ├── update-asc-num ├── ata_struct_2_h_dump.py ├── asc-num-to-list ├── ata_struct_2_c_dump.py ├── ata_struct_2_h.py └── ata_identify.yaml ├── .gitignore ├── CMakeLists.txt ├── include ├── ata_smart.h ├── smartdb.h ├── sense_key_list.h ├── scsicmd_utils.h ├── parse_extended_inquiry.h ├── parse_receive_diagnostics.h ├── parse_log_sense.h ├── parse_read_defect_data.h └── parse_mode_sense.h └── README.md /afl/testcase/b40a88e1e4a0e0044936b2e61de5364d48b16e8c.csv: -------------------------------------------------------------------------------- 1 | ,1a 00 7f ff ff 00,, 2 | -------------------------------------------------------------------------------- /afl/testcase/39c99f32ec43d6ee12857a64e031114ae7cf23cd.csv: -------------------------------------------------------------------------------- 1 | ,25 00 00 00 00 00 00 00 00 00,, 2 | -------------------------------------------------------------------------------- /afl/testcase/b2eeafbc752b681e5d68332192c8097ef43ab687.csv: -------------------------------------------------------------------------------- 1 | ,37 00 08 00 00 00 00 00 08 00,, 2 | -------------------------------------------------------------------------------- /afl/testcase/6184436113637747407bf86315ebd987300b8799: -------------------------------------------------------------------------------- 1 | ,37 00 0a 00 00 00 00 02 00 00,,00 0a 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/657af263aa78ee4d6b755df9e00a159d5c88dc2a.csv: -------------------------------------------------------------------------------- 1 | ,1c 01 00 40 00 00,,00 00 00 02 00 3f 2 | -------------------------------------------------------------------------------- /afl/testcase/7e1e393db35bd119ab38a395829ff5deadd9501a: -------------------------------------------------------------------------------- 1 | ,1c 01 1b 40 00 00,,1b 00 00 04 00 01 00 03 2 | -------------------------------------------------------------------------------- /afl/testcase/9062ca40d53bbf790d9338ed79b5215ca76178d2.csv: -------------------------------------------------------------------------------- 1 | ,1c 01 00 40 00 00,,00 00 00 03 00 3f 82 2 | -------------------------------------------------------------------------------- /afl/testcase/fb0082d5df4c4f237f65ac2c2717ae46408c17b8.csv: -------------------------------------------------------------------------------- 1 | ,1c 01 00 40 00 00,,00 00 00 04 00 3f 40 82 2 | -------------------------------------------------------------------------------- /afl/testcase/554ff10f0a6f35849db7e44176aa94c6dc232872.csv: -------------------------------------------------------------------------------- 1 | ,9e 10 00 00 00 00 00 00 00 00 00 00 02 00 00 00,, 2 | -------------------------------------------------------------------------------- /afl/testcase/eebceb65beacbe25d0db149e5c37198ee5be1912.csv: -------------------------------------------------------------------------------- 1 | ,25 00 00 00 00 00 00 00 00 00,,00 0e 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/617ce3a43c7dbb1ba99a422ce455c1b55d2260b4.csv: -------------------------------------------------------------------------------- 1 | ,1c 01 00 40 00 00,,00 00 00 0a 00 01 02 04 05 07 0d 0e 0f 1d 2 | -------------------------------------------------------------------------------- /afl/testcase/9c3040be62f1785b6387524185ae7508966a8fca: -------------------------------------------------------------------------------- 1 | ,4d 00 40 ff 00 00 00 40 00 00,,40 ff 00 04 00 ff 34 ff 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/fcc19a8cc98ada27c4b6a605adca5bb497ad618e: -------------------------------------------------------------------------------- 1 | ,4d 00 4d 00 00 00 00 40 00 00,,0d 00 00 0c 00 00 43 02 00 17 00 01 43 02 00 46 2 | -------------------------------------------------------------------------------- /afl/testcase/f007593acbf7f63773efa1b65ef61da7fcefbb34: -------------------------------------------------------------------------------- 1 | ,25 00 00 00 00 00 00 00 00 00,70 00 06 00 00 00 00 0a 00 00 00 00 29 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_fb4080b69b8ca7d50d16f424305467a18d8eded9.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 46 00 00 00 00 40 00 00,,06 00 00 08 00 00 02 04 00 00 02 44 2 | -------------------------------------------------------------------------------- /afl/testcase/9da9f3b23df2a728a486968d9e4f4a87aff34bf6.csv: -------------------------------------------------------------------------------- 1 | ,1c 01 00 40 00 00,,00 00 00 11 00 01 02 04 05 0a 0e 10 11 80 81 82 83 90 91 f0 f1 2 | -------------------------------------------------------------------------------- /afl/testcase/id:000008,src:001208,op:flip1,pos:89: -------------------------------------------------------------------------------- 1 | ,1a 08 300,,23 00 10 00 08 12 1F 00 ff ff 00 00 ff ff ff ff 00 ff 00 00 00 00 00fffffffffdffffffffffff00 00 -------------------------------------------------------------------------------- /afl/testcase/id:000005,sig:11,src:005234,op:havoc,rep:2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baruch/libscsicmd/HEAD/afl/testcase/id:000005,sig:11,src:005234,op:havoc,rep:2 -------------------------------------------------------------------------------- /afl/testcase/id:000013,sig:11,src:005882,op:havoc,rep:2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baruch/libscsicmd/HEAD/afl/testcase/id:000013,sig:11,src:005882,op:havoc,rep:2 -------------------------------------------------------------------------------- /afl/testcase/log_sense_d192aef3ac66f84b8996edeb95ef1e7e9d6660cb.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 40 00 00 00 00 40 00 00,,00 00 00 0f 00 02 03 05 06 0d 0e 0f 10 11 15 18 1a 2f 31 2 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_c52c16bd44de5cf72ba1a55c0b6258349a74e5d6.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 40 00 00 00 00 40 00 00,,00 00 00 11 00 02 03 05 06 0d 0e 0f 10 11 15 18 1a 2f 30 31 37 2 | -------------------------------------------------------------------------------- /afl/testcase/801bc5987bfe420b04e07eb1cd5ae0462a0b750c: -------------------------------------------------------------------------------- 1 | ,37 00 0e 00 00 00 00 00 08 00,70 00 01 00 00 00 00 10 00 00 00 00 1c 00 00 80 00 00 00 21 1c 00 00 00,00 0c 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/961ce3b94d711105a238b82068012e5b765b4027: -------------------------------------------------------------------------------- 1 | ,1c 01 00 40 00 00,70 00 02 00 00 00 00 18 00 00 00 00 31 01 00 00 00 00 00 00 f5 07 00 00 00 00 00 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/e71ac2a14ce3dd789a00eae0c656b36e2c07186a: -------------------------------------------------------------------------------- 1 | ,1a 08 3f ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 01 00 00 00 00 00 00 f5 02 00 00 00 00 00 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/ee66ad0b8b05525c54c4538059714a92646c39fb: -------------------------------------------------------------------------------- 1 | ,1c 01 80 40 00 00,,80 00 00 1c 56 45 4e 44 4f 52 20 20 03 01 41 30 35 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/fec38c54692c2fcff269370fc1bbb9e598b821a7: -------------------------------------------------------------------------------- 1 | ,1a 00 7f ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 04 00 80 30 9e 00 00 f5 04 00 00 00 00 00 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/1b5fac8682806d6e823c301159d6da81e30f421a: -------------------------------------------------------------------------------- 1 | ,4d 00 40 03 00 00 00 40 00 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 03 00 00 f8 23 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/7eeaad7ca0a2197d1283c87d441a15f6c8d5e6f6: -------------------------------------------------------------------------------- 1 | ,25 00 00 00 00 00 00 00 00 00,70 00 04 00 00 00 00 18 00 00 00 00 29 07 00 00 00 00 00 00 f5 19 00 00 00 00 00 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/a6b72fc2c30cf1d9ff74a2d5054bcb5dca317c15: -------------------------------------------------------------------------------- 1 | ,25 00 00 00 00 00 00 00 00 00,70 00 06 00 00 00 00 18 00 00 00 00 3f 01 00 00 00 00 00 00 f5 22 00 00 00 00 00 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/f40e3999c3fe73cd2e50083874537ec000697cb7: -------------------------------------------------------------------------------- 1 | ,25 00 00 00 00 00 00 00 00 00,71 00 04 00 00 00 00 18 00 00 00 00 44 a2 00 00 00 00 00 00 f6 22 00 00 00 00 00 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/ff82315f17a9d582afd6aba974c222e00d14af15: -------------------------------------------------------------------------------- 1 | ,4d 00 5f d2 00 00 00 40 00 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 cd 00 02 00 00 f8 23 00 00 00 00 00 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/ff5f50f7b5d36b765da768ef583a8b289be09a7e.csv: -------------------------------------------------------------------------------- 1 | ,1a 08 3f ff ff 00,,23 00 10 00 08 12 10 00 ff ff 00 00 ff ff ff ff 00 ff 00 00 00 00 00 00 1c 0a 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(scsicmd STATIC ata.c ata_smart.c cdb.c parse_inquiry.c parse_read_cap.c parse_sense.c log_sense.c parse.c str_map.c smartdb/smartdb.c smartdb/smartdb_gen.c) 2 | -------------------------------------------------------------------------------- /afl/testcase/86f870fdeb8e99954869aaf1b58e456109e2e6c8: -------------------------------------------------------------------------------- 1 | ,37 00 0a 00 00 00 00 00 08 00,70 00 01 00 00 00 00 18 00 00 00 00 1c 02 00 c0 00 02 00 00 17 48 00 00 00 00 00 00 00 00 00 00,00 0e 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/ffefa3f6034cc5680792a8cae855bc7a2d9f9019: -------------------------------------------------------------------------------- 1 | ,12 01 c0 02 00 00,,0d c0 00 24 01 00 00 00 24 00 00 00 66 2f e0 06 0d 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 23 4a 88 75 2 | -------------------------------------------------------------------------------- /afl/testcase/f7faaa230cdb97e1aec1e5ca75f89b7ea8b78726: -------------------------------------------------------------------------------- 1 | ,25 00 00 00 00 00 00 00 00 00,70 00 03 00 00 00 00 18 00 00 00 00 31 00 03 00 00 00 00 00 03 31 00 03 ff ff ff ff ff ff 00 00,00 83 00 48 01 03 00 08 2 | -------------------------------------------------------------------------------- /afl/testcase/fc52fecd84a8f8a478b99b4965333a7f9dfa002c: -------------------------------------------------------------------------------- 1 | ,37 00 11 00 00 00 00 00 08 00,70 00 01 00 00 00 00 18 00 00 00 00 1c 01 00 c0 00 02 00 00 17 47 00 00 00 00 00 00 00 00 00 00,00 16 04 50 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/ffb313726fc6fa8b68381e5df22e960cb623b62c.csv: -------------------------------------------------------------------------------- 1 | ,9e 10 00 00 00 00 00 00 00 00 00 00 02 00 00 00,,00 00 00 00 00 e7 bf ff 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/id:000003,src:000314,op:flip1,pos:19: -------------------------------------------------------------------------------- 1 | ,5a 10 3f ff00,,00 0e 40 10 01 00 00 10 00 00 00 00 00 e7 bf ff 00 00 00 00 00 00 d2 00 08 00 ff ff ff ff ff ffff 0000 ff 00 00 ff ff 00 ff 00 00 00 00 00 00 1 -------------------------------------------------------------------------------- /afl/testcase/id:000005,src:000445,op:flip1,pos:132: -------------------------------------------------------------------------------- 1 | ,5a 10 3f ff00,,00 2e 00 10 01 00 00 10 00 00 00 00 00 e7 bd ff 00 00 00 00 00 00 08 12 10 09 ff ff 00 02 00 0810 00 ff ff ff ff fd 00 ff 00 00 0000 00 1c 0a -------------------------------------------------------------------------------- /afl/testcase/ff0232f5144d65579feeccb6b65687c5056501a7: -------------------------------------------------------------------------------- 1 | ,4d 00 77 00 00 00 00 40 00 00,,37 00 00 28 00 00 02 04 4a 92 79 ba 00 01 02 04 71 dd 1f cd 00 02 02 04 6d 2c da 32 00 03 02 04 01 87 03 91 00 04 02 04 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/ff3242c96b948a6ded16dd8ae51b1e61c40c5a66: -------------------------------------------------------------------------------- 1 | ,1a 00 bf ff ff 00,70 00 05 00 00 00 00 28 00 00 00 00 24 00 00 c0 00 04 00 1a 13 01 01 00 00 00 00 00 00 00 78 00 00 1d 31 1a 18 00 00 00 00 00 14 00 00 00 00 00, 2 | -------------------------------------------------------------------------------- /afl/testcase/id:000001,src:000141,op:arith8,pos:118,val:-34: -------------------------------------------------------------------------------- 1 | ,5a 10 300,,00 2e 00 10 01 00 00 18 00 00 00 00 00 e7 bf ff 00 00 00 00 00 00 02 00 08 12 10 00 ff ff 00 00 ff ff ff fD 00 ff 00 00 00 00 00 00 1c 0a 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_ac03383386fa3d77d3d460480a52e0b99a1c580e.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 7e 00 00 00 00 40 00 00,,3e 00 00 24 00 00 02 04 00 10 c8 20 00 08 02 04 00 00 00 10 00 09 02 04 00 00 00 3c 00 0e 02 08 00 00 3c 04 24 09 8b 7d 2 | -------------------------------------------------------------------------------- /afl/testcase/ffe9cd6ca4dbbdd2b2429c8d8023183b84c2962f: -------------------------------------------------------------------------------- 1 | ,12 01 88 02 00 00,,00 88 00 30 00 00 00 01 00 00 00 00 00 00 00 0c 61 93 00 08 50 00 c5 00 67 b9 53 ad 00 00 00 02 00 00 00 00 00 00 00 0c 61 93 00 08 50 00 c5 00 67 b9 53 ae 2 | -------------------------------------------------------------------------------- /test/sense_dump.h: -------------------------------------------------------------------------------- 1 | #ifndef _SENSE_DUMP_H 2 | #define _SENSE_DUMP_H 3 | 4 | void sense_dump(unsigned char *sense, int sense_len); 5 | void response_dump(unsigned char *buf, int buf_len); 6 | void cdb_dump(unsigned char *cdb, int cdb_len); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /afl/testcase/a750591769e551117e3144c8927a05d96fdfb362: -------------------------------------------------------------------------------- 1 | ,4d 00 42 00 00 00 00 40 00 00,,02 00 00 36 00 00 00 04 00 00 00 00 00 01 00 04 00 00 00 00 00 02 00 04 00 00 00 00 00 03 00 04 00 00 00 00 00 05 00 0a 00 00 00 00 00 00 00 01 80 00 00 06 00 04 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/id:000019,src:001231,op:flip1,pos:72: -------------------------------------------------------------------------------- 1 | ,5a 00,,00 59 00 00 00 00 00 0B 02 0e 00 00 00 00 00 00 00 00 00 FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -------------------------------------------------------------------------------- /afl/testcase/2b34251f3421af9a5c53a41f7e27f1cc3e8a13b0: -------------------------------------------------------------------------------- 1 | ,5a 00 3f ff 00 00 00 10 00 00,,00 3a 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 27 10 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 00 00 18 06 06 00 00 00 00 00 19 0e 46 00 07 d0 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_f2ca65053fcb0a0b0a479e181fa8b497beb40d9c.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 4e 00 00 00 00 40 00 00,,0e 00 00 34 00 01 01 06 32 30 31 33 34 37 00 02 01 06 32 30 31 33 34 37 00 03 03 04 00 00 27 10 00 04 03 04 00 00 05 53 00 05 03 04 00 04 93 e0 00 06 03 04 00 00 05 53 2 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_dc08fbd86ddd3f34a56532faf9b46f0ae135e644.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 6f 00 00 00 00 40 00 00,,2f 00 00 3c 00 00 03 08 00 00 19 55 21 00 00 00 00 01 03 04 5d 53 00 00 00 02 03 04 5d 54 00 00 00 03 03 04 5d 28 00 00 00 04 03 04 0b 06 00 00 00 05 03 04 5d 55 00 00 00 06 03 04 5d 56 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/5b7d04cbfbe29ec8f91526131c87e7cc8e9ea10e: -------------------------------------------------------------------------------- 1 | ,4d 00 40 ff 00 00 00 40 00 00,,40 ff 00 44 00 00 00 ff 02 00 02 ff 03 00 03 ff 05 00 05 ff 06 00 06 ff 0d 00 0d ff 0e 00 0e ff 0f 00 0f ff 10 00 10 ff 11 00 11 ff 15 00 15 ff 18 00 18 ff 1a 00 1a ff 2f 00 2f ff 30 00 30 ff 31 00 31 ff 37 00 37 ff 2 | -------------------------------------------------------------------------------- /afl/testcase/id:000015,src:001216,op:flip1,pos:229: -------------------------------------------------------------------------------- 1 | ,5a 20 3f ff00 00 10 00 00,,00 52 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 40 00 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffff0 00 18 06fffffffffffff -------------------------------------------------------------------------------- /regen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Regenerate generated files" 4 | 5 | src/smartdb/smartdb_gen_c.py src/smartdb/smartdb.xml > src/smartdb/smartdb_gen.c 6 | git add src/smartdb/smartdb_gen.c 7 | 8 | structs/ata_struct_2_h.py structs/ata_identify.yaml > include/ata_parse.h 9 | git add include/ata_parse.h 10 | -------------------------------------------------------------------------------- /afl/testcase/4941885df82498d8ca26375728606d41be818e27: -------------------------------------------------------------------------------- 1 | ,4d 00 40 ff 00 00 00 40 00 00,,00 00 00 4c 00 00 00 ff 02 00 02 ff 03 00 03 ff 05 00 05 ff 06 00 06 ff 0c 00 0c ff 0d 00 0d ff 0e 00 0e ff 0f 00 0f ff 10 00 10 ff 11 00 11 ff 15 00 15 ff 18 00 18 ff 19 00 19 ff 1a 00 1a ff 2f 00 2f ff 30 00 30 ff 31 00 31 ff 38 00 38 ff 2 | -------------------------------------------------------------------------------- /afl/testcase/f3492a44323a0bf7bea4e59b536feaf7620b8e8b: -------------------------------------------------------------------------------- 1 | ,5a 00 3f ff 00 00 00 10 00 00,,00 52 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 00 00 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 00 00 18 06 06 00 00 00 00 00 19 06 16 00 00 0a 00 00 a0 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_fc58600bcf8dc103f911bb2a6a867ab2c8e42fe2.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 6f 00 00 00 00 40 00 00,,2f 00 00 4c 00 00 03 08 00 00 1c 46 26 00 00 00 00 01 03 04 5d 53 00 00 00 02 03 04 5d 54 00 00 00 03 03 04 5d 57 00 00 00 04 03 04 5d 28 00 00 00 05 03 04 0b 06 01 00 00 06 03 04 5d 56 38 00 00 07 03 04 5d 55 00 00 00 08 03 04 5d 20 00 00 2 | -------------------------------------------------------------------------------- /structs/update-asc-num: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | if [ -d structs ]; then 5 | cd structs 6 | fi 7 | curl 'http://www.t10.org/lists/asc-num.txt' > asc-num.txt.tmp 8 | mv asc-num.txt.tmp asc-num.txt 9 | dos2unix asc-num.txt 10 | ./asc-num-to-list < asc-num.txt > asc-num.h 11 | mv asc-num.h ../include/asc_num_list.h 12 | -------------------------------------------------------------------------------- /afl/testcase/id:000001,sig:11,src:005156,op:ext_AO,pos:34: -------------------------------------------------------------------------------- 1 | ,1C 00 43 00 00 00 00 40 00 00,,01 aa 00 54 00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00B00030 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 00 73 e0 f6 d9 46 00 00 06 00 08 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/id:000007,sig:11,src:005483,op:flip2,pos:43: -------------------------------------------------------------------------------- 1 | ,12 01 43 00 00 00 00 40 00 00,,03 40 00 54,00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00B00030 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 00 73 e0 f6 d9 46 00 00 06 00 08 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_ffee0af0b99b68b9d287e6f65ad08a4e11967daa.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 43 00 00 00 00 40 00 00,,03 00 00 54 00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00 00 00 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 01 69 53 90 5e 44 00 00 06 00 08 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_ffe62c433d9a885d2a5670ff890f5b00089739aa.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 59 00 00 00 00 40 00 00,,19 00 00 5c 00 01 02 40 00 00 00 05 1d 74 16 f0 00 00 00 04 62 22 c5 8d 00 00 00 43 98 00 04 2c 00 00 00 53 be 7d 55 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 08 00 00 00 00 01 b4 c1 aa 00 03 03 08 00 00 00 02 00 00 00 05 2 | -------------------------------------------------------------------------------- /afl/testcase/ebc80a44e5ef0a66fddb29c48373701b2eeb5227: -------------------------------------------------------------------------------- 1 | ,4d 00 71 00 00 00 00 40 00 00,,31 00 00 68 80 00 03 08 00 00 00 00 00 00 01 bd 80 01 03 08 00 00 00 00 00 00 01 bd 80 02 03 08 00 00 00 00 00 00 01 97 80 03 03 08 00 00 00 00 00 00 01 a6 8f fa 03 08 00 00 00 00 00 00 01 97 8f fb 03 08 00 00 00 00 00 00 01 a6 8f fc 03 04 00 00 00 63 8f fd 03 04 00 00 00 00 8f fe 03 04 00 00 10 70 8f ff 03 04 00 00 74 04 2 | -------------------------------------------------------------------------------- /afl/testcase/fff9db19407d43fdb18735c075071a866a5f0795: -------------------------------------------------------------------------------- 1 | ,1c 01 82 40 00 00,,82 00 00 6e 48 49 54 41 43 48 49 20 43 32 36 30 00 01 00 00 00 00 00 00 0b 08 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 0e 00 01 00 01 00 00 00 5f 00 02 00 00 00 00 00 0b 00 02 00 01 00 00 00 11 00 03 00 00 00 00 00 00 00 03 00 01 00 00 00 00 00 04 00 00 00 00 00 00 00 04 00 01 00 00 00 00 00 05 00 00 00 00 00 0e 00 05 00 01 00 00 00 50 2 | -------------------------------------------------------------------------------- /src/parse.c: -------------------------------------------------------------------------------- 1 | #include "parse_read_defect_data.h" 2 | 3 | static const char *defect_data_format_str[] = { 4 | "Short", 5 | "Reserved (1)", 6 | "Reserved (2)", 7 | "Long", 8 | "Index", 9 | "Physical", 10 | "Vendor", 11 | "Reserved (7)", 12 | }; 13 | 14 | const char *read_defect_data_format_to_str(uint8_t fmt) 15 | { 16 | if (fmt > 7) 17 | return "Unknown"; 18 | return defect_data_format_str[fmt]; 19 | } 20 | -------------------------------------------------------------------------------- /afl/testcase/fec50c6c3f5486958b33beada06857deeff177dd.csv: -------------------------------------------------------------------------------- 1 | ,12 00 00 02 00 00,,0d 00 06 12 83 00 d0 02 45 4d 43 20 20 20 20 20 45 53 45 53 20 45 6e 63 6c 6f 73 75 72 65 20 20 30 30 30 31 50 4d 43 53 49 45 52 41 80 05 02 00 00 00 00 00 00 00 00 00 00 00 00 75 0c 00 03 01 03 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 00 00 00 01 41 50 4d 30 30 31 34 30 37 32 34 32 36 38 00 00 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | .*.d 3 | .gdb_history 4 | tags 5 | libscsicmd.a 6 | ata_identify 7 | test/ata_identify_dump.[ch] 8 | ata_smart_return_status 9 | ata_smart_read_data 10 | ata_check_power_mode 11 | sense_decode 12 | scsi_read_capacity_10 13 | scsi_read_capacity_16 14 | scsi_inquiry 15 | scsi_log_sense 16 | scsi_mode_sense 17 | scsi_receive_diagnostics 18 | parse_scsi 19 | collect_raw_data 20 | test/libtestlib.a 21 | 22 | CMakeCache.txt 23 | CMakeFiles 24 | Makefile 25 | cmake_install.cmake 26 | -------------------------------------------------------------------------------- /afl/testcase/log_sense_9bd3419f85d952cf54a38196fc0775a2bfa4c6ff.csv: -------------------------------------------------------------------------------- 1 | ,4d 00 55 00 00 00 00 40 00 00,,95 00 00 88 00 00 03 0c 00 0f 17 2b 00 08 02 5d 00 00 02 5d 00 01 03 14 00 03 7f bf 51 18 01 50 5b 54 03 48 00 00 00 00 11 57 80 1b 00 02 03 14 00 0c 68 1c 13 11 00 20 44 4c 03 9d 00 00 00 00 0b 8f 13 7a 00 03 03 14 00 0c 6c da 51 17 01 20 9d ef 05 26 00 00 00 00 1a 25 64 00 00 04 03 14 00 0c f2 ec 51 17 01 21 f2 bd 04 4a 00 00 00 00 4a cf 77 f7 00 05 03 14 00 0d ab 1d 51 17 01 21 89 2a 03 75 00 00 00 00 3c f7 ac 00 2 | -------------------------------------------------------------------------------- /src/smartdb/smartdb.c: -------------------------------------------------------------------------------- 1 | #include "smartdb.h" 2 | #include 3 | 4 | const smart_attr_t *smart_attr_for_id(const smart_table_t *table, uint8_t id) 5 | { 6 | int i; 7 | 8 | for (i = 0; i < table->num_attrs; i++) { 9 | if (table->attrs[i].id == id) 10 | return &table->attrs[i]; 11 | } 12 | 13 | return NULL; 14 | } 15 | 16 | const smart_attr_t *smart_attr_for_type(const smart_table_t *table, smart_attr_type_e attr_type) 17 | { 18 | int i; 19 | 20 | for (i = 0; i < table->num_attrs; i++) { 21 | if (table->attrs[i].type == attr_type) 22 | return &table->attrs[i]; 23 | } 24 | 25 | return NULL; 26 | } 27 | -------------------------------------------------------------------------------- /test/main.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBSCSICMD_TEST_H 2 | #define LIBSCSICMD_TEST_H 3 | 4 | #include 5 | 6 | extern int debug; 7 | 8 | /** Do the command that we want to test on the open disk interface. */ 9 | void do_command(int fd); 10 | bool submit_cmd(int fd, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_len, int dxfer_dir); 11 | bool read_response_buf(int fd, unsigned char **sense, unsigned *sense_len, unsigned *buf_read); 12 | 13 | static inline bool read_response(int fd, unsigned char **sense, unsigned *sense_len) 14 | { 15 | return read_response_buf(fd, sense, sense_len, NULL); 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /structs/ata_struct_2_h_dump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import yaml 5 | 6 | def emit_header(structs): 7 | for name, struct in list(structs.items()): 8 | print('void dump_%s(const unsigned char *buf);' % name) 9 | 10 | def emit_prefix(): 11 | print('#ifndef _DUMP_H_') 12 | print('#define _DUMP_H_') 13 | 14 | def emit_suffix(): 15 | print('#endif') 16 | 17 | def convert_def(filename): 18 | f = file(filename) 19 | structs = yaml.load(f) 20 | f.close() 21 | emit_header(structs) 22 | 23 | if __name__ == '__main__': 24 | emit_prefix() 25 | filenames = sys.argv[1:] 26 | for filename in filenames: 27 | convert_def(filename) 28 | emit_suffix() 29 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(libscsicmd) 3 | 4 | export(PACKAGE libscsicmd) 5 | 6 | include_directories("include") 7 | add_compile_options(-Wall -Wextra -Wshadow -Wmissing-prototypes -Winit-self -g) 8 | add_definitions(-D_GNU_SOURCE -D_FORTIFY_SOURCE=2) 9 | 10 | set(CMAKE_C_FLAGS_DEBUG "-Werror -O0 ${CMAKE_C_FLAGS_DEBUG}") 11 | set(CMAKE_C_FLAGS_RELEASE "-Wall -O3 ${CMAKE_C_FLAGS_RELEASE}") 12 | 13 | add_subdirectory(src) 14 | 15 | if (${CMAKE_PROJECT_NAME} STREQUAL "libscsicmd") 16 | add_subdirectory(test) 17 | MESSAGE(STATUS "top level project, compiling tests") 18 | else() 19 | MESSAGE(STATUS "tests will not be compiled") 20 | endif() 21 | -------------------------------------------------------------------------------- /afl/testcase/f5272bcea41574f9cd663f33334c530abcca01d7: -------------------------------------------------------------------------------- 1 | ,1c 01 01 40 00 00,,01 00 00 d8 00 00 00 00 22 00 06 58 50 01 63 60 01 b6 34 3e 51 55 41 4e 54 41 00 00 4a 42 45 20 49 53 49 4d 37 20 20 20 00 00 00 00 30 31 30 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 12 00 10 04 12 00 10 07 01 00 10 0e 01 00 10 18 01 00 10 19 12 00 10 41 72 72 61 79 20 44 65 76 69 63 65 20 20 20 20 54 65 6d 70 65 72 61 74 75 72 65 20 20 20 20 20 45 4d 4d 20 20 20 20 20 20 20 20 20 20 20 20 20 45 6e 63 6c 6f 73 75 72 65 20 20 20 20 20 20 20 45 78 70 61 6e 64 65 72 20 20 20 20 20 20 20 20 43 6f 6e 6e 65 63 74 6f 72 20 20 20 20 20 20 20 2 | -------------------------------------------------------------------------------- /src/log_sense.c: -------------------------------------------------------------------------------- 1 | #include "parse_log_sense.h" 2 | 3 | bool log_sense_page_informational_exceptions(uint8_t *page, unsigned page_len, uint8_t *asc, uint8_t *ascq, uint8_t *temperature) 4 | { 5 | if (!log_sense_is_valid(page, page_len)) 6 | return false; 7 | if (log_sense_page_code(page) != 0x2F) 8 | return false; 9 | if (log_sense_subpage_format(page) && log_sense_subpage_code(page) != 0) 10 | return false; 11 | 12 | uint8_t *param; 13 | for_all_log_sense_params(page, page_len, param) { 14 | if (log_sense_param_code(param) == 0) { 15 | uint8_t *param_data = log_sense_param_data(param); 16 | *asc = param_data[0]; 17 | *ascq = param_data[1]; 18 | *temperature = param_data[2]; 19 | return true; 20 | } 21 | } 22 | 23 | return false; 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /afl/testcase/fedb716d47c930bafffff38b6c274ce9202187ac: -------------------------------------------------------------------------------- 1 | ,1a 08 bf ff ff 00,,00 0e 00 00 00 00 00 00 00 00 00 03 00 00 00 2c 00 00 00 00 00 00 00 5a 00 00 00 01 00 00 00 5a 00 00 00 02 00 00 00 5a 00 00 00 03 00 00 00 5a 00 00 00 04 00 00 00 5a 00 00 00 06 00 00 00 5a 00 00 00 07 00 00 00 5a 00 00 00 08 00 00 00 5a 00 00 00 09 00 00 00 5a 00 00 00 0a 00 00 00 5a 00 00 00 0b 00 00 00 5a 00 00 00 12 00 00 00 5a 00 00 00 0c 00 00 00 5a 00 00 00 0d 00 00 00 5a 00 00 00 0e 00 00 00 5a 00 00 00 0f 00 00 00 5a 00 00 00 10 00 00 00 5a 00 00 00 05 00 00 00 5a 00 00 00 11 00 00 00 5a 00 00 00 13 00 00 00 5a 00 00 00 1e 00 00 00 5a 00 00 00 14 00 00 00 5a 00 00 00 15 00 00 00 5a 00 00 00 16 00 00 00 5a 00 00 00 17 00 00 00 5a 00 00 00 1f 00 00 00 5a 00 00 00 20 00 00 00 5a 00 00 00 21 00 00 00 5a 00 00 00 22 00 00 00 5a 00 00 00 23 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/fffa5f13587a7e46023238c9e7db91fd61414105: -------------------------------------------------------------------------------- 1 | ,1a 00 bf ff ff 00,,bf 00 10 08 2e 90 ed d0 00 00 02 00 81 0a 04 01 00 00 00 00 00 00 0c 00 82 0e 00 00 00 00 00 00 01 f4 00 00 00 00 00 00 03 16 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 40 00 00 00 04 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 04 01 00 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 8a 0a 00 10 00 00 00 00 00 00 00 06 ca 01 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 98 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 d9 01 00 64 00 06 02 02 00 00 00 00 21 0a 02 02 50 00 cc a0 13 07 16 b1 50 06 04 80 d8 12 41 bf 18 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 21 0a 02 02 50 00 cc 2 | -------------------------------------------------------------------------------- /afl/testcase/745f69394ad87d7d234e796b1a54a31f970e2510.csv: -------------------------------------------------------------------------------- 1 | ,1a 00 3f ff ff 00,,37 00 00 08 00 00 00 00 00 00 02 00 01 0a 80 00 00 00 00 00 00 00 00 00 08 12 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a 0a 02 00 00 00 00 00 ff ff 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/ce03e25003a16fc03abb3d4f337a39e622962c60: -------------------------------------------------------------------------------- 1 | ,1c 01 02 40 00 00,,02 00 01 00 00 00 00 00 00 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 00 00 00 00 01 00 2f 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 31 00 01 00 33 00 01 00 34 00 01 00 37 00 01 00 34 00 01 00 34 00 01 00 31 00 01 00 31 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 2e 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 2 | -------------------------------------------------------------------------------- /include/ata_smart.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBSCSICMD_ATA_SMART_H 2 | #define LIBSCSICMD_ATA_SMART_H 3 | 4 | #include "smartdb.h" 5 | #include "ata.h" 6 | 7 | /* These functions are for common information that may show up differently in different drives (or unsupported) */ 8 | int ata_smart_get_temperature(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, int *min_temp, int *max_temp); 9 | int ata_smart_get_power_on_hours(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, int *pminutes); 10 | int ata_smart_get_num_reallocations(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table); 11 | int ata_smart_get_num_pending_reallocations(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table); 12 | int ata_smart_get_num_crc_errors(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /afl/testcase/d2f9abc5e26020e42b45a32fcf3777cc61ea711c: -------------------------------------------------------------------------------- 1 | ,1a 08 ff ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 03 00 00 00 00 00 00 02 04 03 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 68 59 9c bd 50 01 e6 78 7a c0 e0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 68 59 9c be 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/fcd8ce757f7d3f54ab0ee3d01007e0a6d70fa288: -------------------------------------------------------------------------------- 1 | ,1a 08 bf ff ff 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 04 00 00 05 24 00 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a c4 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 00 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 14 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 54 97 b0 31 50 01 e6 75 96 b7 10 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 54 97 b0 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/ff5a0c3111af229b7f4ec8c4a38d82ccf7e553a2: -------------------------------------------------------------------------------- 1 | ,1a 08 3f ff ff 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 04 00 00 05 24 00 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 00 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 14 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 70 c8 b6 d5 50 01 e6 78 ea fa c0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 70 c8 b6 d6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/ef22fafdd3041dc08043fe2bb908e96dffa34ff5: -------------------------------------------------------------------------------- 1 | ,37 00 0b 00 00 00 00 02 00 00,,00 0e 01 18 00 00 00 12 00 00 07 75 00 00 00 12 00 00 00 c1 00 00 00 12 00 00 07 4f 00 00 00 12 00 00 01 3d 00 00 00 12 00 00 05 eb 00 00 00 12 00 00 05 bd 00 00 00 12 00 00 07 33 00 00 00 12 00 00 05 23 00 00 00 12 00 00 04 35 00 00 00 12 00 00 06 ed 00 00 00 12 00 00 01 97 00 00 00 12 00 00 02 07 00 00 00 12 00 00 02 2b 00 00 00 12 00 00 03 f5 00 00 00 12 00 00 04 f7 00 00 00 12 00 00 06 cf 00 00 00 12 00 00 04 17 00 00 00 12 00 00 01 0b 00 00 00 12 00 00 02 73 00 00 00 12 00 00 02 35 00 00 00 12 00 00 02 3d 00 00 00 12 00 00 01 31 00 00 00 12 00 00 03 37 00 00 00 12 00 00 06 07 00 00 00 12 00 00 00 5d 00 00 00 12 00 00 06 af 00 00 00 12 00 00 03 dd 00 00 00 12 00 00 00 6f 00 00 00 12 00 00 06 0d 00 00 00 12 00 00 05 9d 00 00 00 12 00 00 04 49 00 00 00 12 00 00 01 f5 00 00 00 12 00 00 06 a1 00 00 00 12 00 00 03 f3 00 00 00 12 00 00 03 55 2 | -------------------------------------------------------------------------------- /afl/testcase/28eeac63bfcf7ad2126d2eddcdc04019270075ec: -------------------------------------------------------------------------------- 1 | ,1c 01 05 40 00 00,,05 00 01 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 46 41 14 0f 76 73 14 0f 76 73 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 00 00 00 00 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /structs/asc-num-to-list: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | def nn_str(name): 6 | return name.replace('NN', '%u') 7 | 8 | # Skip the header 9 | for line in sys.stdin: 10 | if line[0] == '-': 11 | break 12 | 13 | # Read the raw data 14 | print('#ifndef LIBSCSICMD_ASC_NUM_LIST_H') 15 | print('#define LIBSCSICMD_ASC_NUM_LIST_H') 16 | print('#define ASC_NUM_LIST \\') 17 | for line in sys.stdin: 18 | line = line.strip() 19 | asc = int(line[0:2], 16) 20 | ascq_str = line[4:6] 21 | if ascq_str == 'NN': 22 | ascq = 'NN' 23 | else: 24 | ascq = int(ascq_str, 16) 25 | name = line[24:] 26 | if name == '': 27 | continue 28 | 29 | if ascq == 'NN': 30 | name_nn = nn_str(name) 31 | print('SENSE_CODE_KEYED(0x%x, "%s") \\' % (asc, name_nn)) 32 | else: 33 | print('SENSE_CODE(0x%x, 0x%x, "%s") \\' % (asc, ascq, name)) 34 | print() 35 | print('#endif') 36 | -------------------------------------------------------------------------------- /afl/testcase/ff980b7b6e39f929b8ddb08e419a2904abd44b33: -------------------------------------------------------------------------------- 1 | ,1c 01 04 40 00 00,,04 00 01 4d 32 34 3a 31 35 3a 31 31 3a 31 37 3a 30 30 30 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 32 34 3a 31 35 3a 31 31 3a 31 37 3a 32 30 33 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 31 20 64 61 74 61 3a 20 30 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 61 34 0a 32 34 3a 31 35 3a 31 31 3a 32 35 3a 31 38 30 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 32 34 3a 31 35 3a 31 31 3a 32 35 3a 31 38 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 2 | -------------------------------------------------------------------------------- /test/samples/parse_file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import csv 5 | import os 6 | 7 | def parse_file(f): 8 | c = csv.reader(f) 9 | for line in c: 10 | msg = line[0] 11 | if msg != '': continue 12 | if len(line) != 4: continue 13 | 14 | cdb = line[1] 15 | sense = line[2] 16 | data = line[3] 17 | 18 | print('Parsing CDB: %s' % cdb) 19 | print('Parsing Sense: %s' % sense) 20 | print('Parsing Data: %s' % data) 21 | sys.stdout.flush() 22 | sys.stderr.flush() 23 | os.system('../parse_scsi "%s" "%s" "%s"' % (cdb, sense, data)) 24 | sys.stdout.flush() 25 | sys.stderr.flush() 26 | print('=========================================================================\n') 27 | 28 | if len(sys.argv) > 1: 29 | for filename in sys.argv[1:]: 30 | print('Parsing file %s' % filename) 31 | f = file(filename, 'r') 32 | parse_file(f) 33 | print('Done') 34 | print('') 35 | else: 36 | parse_file(sys.stdin) 37 | -------------------------------------------------------------------------------- /src/str_map.c: -------------------------------------------------------------------------------- 1 | #include "scsicmd.h" 2 | 3 | #include 4 | 5 | const char *sense_key_to_name(enum sense_key_e sense_key) 6 | { 7 | #undef SENSE_KEY_MAP 8 | 9 | switch (sense_key) { 10 | #define SENSE_KEY_MAP(_name_, _val_) \ 11 | case _val_: return #_name_ ; 12 | SENSE_KEY_LIST 13 | } 14 | #undef SENSE_KEY_MAP 15 | 16 | return "Unknown sense key"; 17 | } 18 | 19 | const char *asc_num_to_name(uint8_t asc, uint8_t ascq) 20 | { 21 | static char msg[64]; 22 | 23 | uint16_t asc_full = asc<<8 | ascq; 24 | 25 | switch (asc_full) { 26 | #define SENSE_CODE_KEYED(_asc_, _fmt_) 27 | #define SENSE_CODE(_asc_, _ascq_, _msg_) case _asc_<<8 | _ascq_: return _msg_; 28 | ASC_NUM_LIST 29 | #undef SENSE_CODE 30 | #undef SENSE_CODE_KEYED 31 | } 32 | 33 | #define SENSE_CODE_KEYED(_asc_, _fmt_) if (asc == _asc_) { snprintf(msg, sizeof(msg), _fmt_, ascq); return msg; } 34 | #define SENSE_CODE(_asc_, _ascq_, _msg_) 35 | ASC_NUM_LIST 36 | #undef SENSE_CODE 37 | #undef SENSE_CODE_KEYED 38 | 39 | snprintf(msg, sizeof(msg), "UNKNOWN ASC/ASCQ (%02Xh/%02Xh)", asc, ascq); 40 | return msg; 41 | } 42 | -------------------------------------------------------------------------------- /test/samples/breakout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import subprocess 5 | 6 | files = { 7 | ',4d ' : 'log_sense', 8 | ',25 ' : 'read_cap_10', 9 | ',9e ' : 'read_cap_16', 10 | ',12 ' : 'inquiry', 11 | ',5a ' : 'mode_sense_10', 12 | ',1a ' : 'mode_sense_6', 13 | ',37 ' : 'read_defect_data_10', 14 | ',b7 ' : 'read_defect_data_12', 15 | ',1c ' : 'receive_diagnostics', 16 | } 17 | 18 | for key in files.keys(): 19 | filename = files[key] + '.csv.bz2' 20 | f = subprocess.Popen(['/bin/bzip2', '-z', '-c', '-9'], stdin=subprocess.PIPE, stdout=file(filename, 'w')) 21 | if f is None: 22 | print 'Failed to create process for', filename 23 | files[key] = f 24 | 25 | for line in sys.stdin: 26 | prefix = line[0:4] 27 | f = files.get(prefix, None) 28 | if f is None: 29 | print '"%s"' % prefix 30 | continue 31 | f.stdin.write(line) 32 | 33 | for key in files.keys(): 34 | print 'Closing', key 35 | files[key].stdin.close() 36 | files[key].wait() 37 | print 'Done' 38 | -------------------------------------------------------------------------------- /include/smartdb.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBSCSICMD_SMARTDB_H 2 | #define LIBSCSICMD_SMARTDB_H 3 | 4 | #include 5 | 6 | typedef struct smart_table smart_table_t; 7 | typedef struct smart_attr smart_attr_t; 8 | 9 | typedef enum smart_attr_type { 10 | SMART_ATTR_TYPE_NONE, 11 | SMART_ATTR_TYPE_POH, 12 | SMART_ATTR_TYPE_TEMP, 13 | SMART_ATTR_TYPE_REALLOC, 14 | SMART_ATTR_TYPE_REALLOC_PENDING, 15 | SMART_ATTR_TYPE_CRC_ERRORS, 16 | } smart_attr_type_e; 17 | 18 | typedef enum smart_attr_raw { 19 | SMART_ATTR_RAW_HEX48, 20 | SMART_ATTR_RAW_DEC48, 21 | } smart_attr_raw_e; 22 | 23 | struct smart_attr { 24 | uint8_t id; 25 | smart_attr_type_e type; 26 | smart_attr_raw_e raw; 27 | int offset; 28 | const char *name; 29 | }; 30 | 31 | struct smart_table { 32 | int num_attrs; 33 | smart_attr_t attrs[30]; 34 | }; 35 | 36 | const smart_table_t *smart_table_for_disk(const char *vendor, const char *model, const char *firmware); 37 | const smart_attr_t *smart_attr_for_id(const smart_table_t *table, uint8_t id); 38 | const smart_attr_t *smart_attr_for_type(const smart_table_t *table, smart_attr_type_e attr_type); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libscsicmd 2 | 3 | A library to create SCSI commands (CDBs) and parse the results, also for ATA commands and results. 4 | 5 | This library doesn't deal with actually submitting the CDBs or getting the results from the storage device, only with 6 | the commands themselves. The actual sending of the command is different between the different OSes and this library 7 | tries to be OS agnostic. 8 | 9 | ## Build 10 | 11 | The build system is using cmake, you need to get it before you can build. 12 | 13 | To build, run: 14 | 15 | cmake . && make 16 | 17 | For a developer debug build use: 18 | 19 | cmake -DCMAKE_BUILD_TYPE=Debug . 20 | 21 | To build for American Fuzzy Lop instrumentation: 22 | 23 | cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=/usr/bin/afl-gcc -DCMAKE_C_FLAGS=-DAFL_HARDEN=1 . 24 | 25 | ## Testing 26 | 27 | Testing is either done manually with some raw data collected from SCSI devices 28 | with test/collect\_raw\_data or with American Fuzzy Lop (AFL) for parsing 29 | problems. 30 | 31 | Using AFL: 32 | 33 | afl-fuzz -t 200 -i afl/testcase -o afl/finding test/parse_scsi 34 | 35 | ## Author 36 | 37 | Baruch Even 38 | -------------------------------------------------------------------------------- /afl/testcase/a4005cb54f820f0dc3889aab343ea1698b1dd5f4.csv: -------------------------------------------------------------------------------- 1 | ,b7 0d 00 00 00 00 00 00 02 00 00 00,,00 0e 00 00 00 00 01 98 00 00 00 00 00 00 00 b6 00 00 00 00 00 00 04 62 00 00 00 00 00 00 00 70 00 00 00 00 00 00 00 98 00 00 00 00 00 00 02 ce 00 00 00 00 00 00 02 14 00 00 00 00 00 00 06 64 00 00 00 00 00 00 05 4a 00 00 00 00 00 00 07 02 00 00 00 00 00 00 04 bc 00 00 00 00 00 00 04 08 00 00 00 00 00 00 04 54 00 00 00 00 00 00 03 98 00 00 00 00 00 00 06 6e 00 00 00 00 00 00 00 9e 00 00 00 00 00 00 03 c0 00 00 00 00 00 00 01 12 00 00 00 00 00 00 02 92 00 00 00 00 00 00 02 a8 00 00 00 00 00 00 02 8c 00 00 00 00 00 00 04 de 00 00 00 00 00 00 03 a2 00 00 00 00 00 00 07 36 00 00 00 00 00 00 07 3e 00 00 00 00 00 00 04 40 00 00 00 00 00 00 05 0e 00 00 00 00 00 00 01 52 00 00 00 00 00 00 02 34 00 00 00 00 00 00 00 36 00 00 00 00 00 00 00 8c 00 00 00 00 00 00 05 b4 00 00 00 00 00 00 01 82 00 00 00 00 00 00 05 36 00 00 00 00 00 00 02 16 00 00 00 00 00 00 06 f2 00 00 00 00 00 00 04 ea 00 00 00 00 00 00 02 86 00 00 00 00 00 00 03 b8 00 00 00 00 00 00 01 60 00 00 00 00 00 00 05 cc 00 00 00 00 00 00 07 56 00 00 00 00 00 00 01 dc 00 00 00 00 00 00 01 3a 00 00 00 00 00 00 05 a0 00 00 00 00 00 00 05 08 00 00 00 00 00 00 01 a6 00 00 00 00 00 00 06 c0 00 00 00 00 00 00 05 d4 00 00 00 00 00 00 05 aa 00 00 00 00 00 00 00 e8 00 00 00 00 00 00 04 24 2 | -------------------------------------------------------------------------------- /afl/testcase/id:000002,src:000200,op:ext_AO,pos:571: -------------------------------------------------------------------------------- 1 | ,5a 00 bf ff 00 00 00 10 00 00,,01 a2 00 10 00 00 00 08 68 cb 9e 30 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 0B 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 ff fd f2 f1 50 01 e6 77 5a 4d b0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 5f 0d f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 02 00 0c 00 06 03 e8 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 00 02 00 00 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 09 00 00 01 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 00 00 9a 26 00 00 00 00 00 0a 00 00 8c a0 00 00 17 70 00 00 46 50 00 00 46 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 00 04 00 00 00 00 00 00 00 01 dc 01 00 0c 01 00 00 48 00 18 01 f4 00 00 00 00 80 16 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/id:000018,src:001179,op:ext_AO,pos:826: -------------------------------------------------------------------------------- 1 | ,5a 00 bf ff 00 00 00 10 00 00,,01 a2 00 10 00 00 00 08 68 cb 9e 30 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 65 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 5f 0d f2 f1 50 01 e6 77 5a 4d b0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 5f 0d f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 ff ff fd 00 06 03 e8 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 00 02 00 00 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 09 00 00 01 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 00 00 9a 26 00 00 00 00 00 0a 00 00 8c a0 00 00 17 70 00 00 46 50 00 00 46 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 00 04 00 00 00 00 00 00 00 01 dc 01 00 0c 01 00 00 48 00 18 01 f4 00 00 00 00 80 16 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/febd83d39f830202ca6081514960b4242e536df7: -------------------------------------------------------------------------------- 1 | ,5a 08 ff ff 00 00 00 10 00 00,,01 f6 00 00 00 00 00 00 81 0a c8 ff ff 00 00 00 ff 00 13 88 82 0e 00 00 00 0a 00 00 00 00 01 00 00 00 00 00 83 16 00 80 00 00 00 00 00 00 00 80 02 00 00 01 00 00 00 00 40 00 00 00 84 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 08 ff ff 00 00 00 00 00 13 88 88 12 14 00 ff ff 00 00 00 00 ff ff 00 08 00 00 00 00 00 00 8a 0a 00 00 00 00 00 00 00 00 07 08 ca 01 00 1c 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 98 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 d9 01 00 64 00 06 01 02 00 00 00 00 21 1a 02 02 50 00 03 96 9c 89 bf e2 50 06 04 80 78 0f c3 3f 0e 00 00 00 00 00 00 00 88 bb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 21 1a 02 02 50 00 03 96 9c 89 bf e3 50 06 04 80 78 0e dc bf 20 00 00 00 00 00 00 00 88 bb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d9 02 00 0c 00 06 00 00 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 01 02 00 00 00 10 80 ab 00 00 80 af 00 01 c0 a8 00 01 00 00 0a 00 00 01 00 10 80 ab 00 00 80 af 00 01 c0 a8 00 01 00 00 0a 00 9a 26 00 02 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 da 01 00 0c 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 08 00 00 00 00 00 00 00 00 01 a4 0e 00 00 40 37 0f 13 00 00 00 00 00 00 00 00 e4 01 00 0c 00 00 00 00 00 00 00 00 00 00 00 00 c0 01 00 30 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/7c597125d72d146425d1899f6512b82df99b59c1: -------------------------------------------------------------------------------- 1 | ,b7 14 00 00 00 00 00 00 02 00 00 00,,00 16 00 00 00 00 17 f8 00 00 00 72 00 00 00 33 00 00 00 0f 00 00 00 70 00 00 00 17 00 00 00 cc 00 00 00 17 00 00 00 d0 00 00 00 61 00 00 01 85 00 00 00 0f 00 00 02 00 00 00 00 00 00 00 02 02 00 00 00 00 00 00 02 03 00 00 00 01 00 00 02 02 00 00 00 01 00 00 02 03 00 00 00 02 00 00 02 02 00 00 00 02 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 0 2 | -------------------------------------------------------------------------------- /include/sense_key_list.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #ifndef LIBSCSICMD_SENSE_KEY_LIST_H 18 | #define LIBSCSICMD_SENSE_KEY_LIST_H 19 | 20 | #define SENSE_KEY_LIST \ 21 | SENSE_KEY_MAP(NO_SENSE, 0x0) \ 22 | SENSE_KEY_MAP(RECOVERED_ERROR, 0x1) \ 23 | SENSE_KEY_MAP(NOT_READY, 0x2) \ 24 | SENSE_KEY_MAP(MEDIUM_ERROR, 0x3) \ 25 | SENSE_KEY_MAP(HARDWARE_ERROR, 0x4) \ 26 | SENSE_KEY_MAP(ILLEGAL_REQUEST, 0x5) \ 27 | SENSE_KEY_MAP(UNIT_ATTENTION, 0x6) \ 28 | SENSE_KEY_MAP(DATA_PROTECT, 0x7) \ 29 | SENSE_KEY_MAP(BLANK_CHECK, 0x8) \ 30 | SENSE_KEY_MAP(VENDOR_SPECIFIC, 0x9) \ 31 | SENSE_KEY_MAP(COPY_ABORTED, 0xA) \ 32 | SENSE_KEY_MAP(ABORTED_COMMAND, 0xB) \ 33 | SENSE_KEY_MAP(RESERVED_C, 0xC) \ 34 | SENSE_KEY_MAP(VOLUME_OVERFLOW, 0xD) \ 35 | SENSE_KEY_MAP(MISCOMPARE, 0xE) \ 36 | SENSE_KEY_MAP(COMPLETED, 0xF) 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /afl/testcase/a051877bf52e199210ffd96778f7698e3dc6978e.csv: -------------------------------------------------------------------------------- 1 | ,1c 01 04 40 00 00,,04 00 01 fa 30 37 3a 30 32 3a 31 31 3a 35 34 3a 35 33 37 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 34 38 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 72 65 61 64 79 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 35 31 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 6c 69 6e 6b 20 72 65 61 64 79 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 35 38 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 72 61 74 65 20 75 6e 6b 6e 6f 77 6e 2d 3e 36 47 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 36 32 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 66 66 2d 3e 30 78 30 30 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 38 37 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 31 20 64 61 74 61 3a 20 30 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 61 34 0a 30 37 3a 30 32 3a 31 31 3a 35 36 3a 37 37 35 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 37 3a 30 32 3a 31 31 3a 35 36 3a 37 38 34 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 2 | -------------------------------------------------------------------------------- /afl/testcase/f7db47bebdfb5888fae0fbe826b37df33a450292: -------------------------------------------------------------------------------- 1 | ,37 00 08 00 00 00 00 00 08 00,,00 0e 00 00 00 00 00 00 00 00 00 0c 00 00 00 70 00 00 00 0c 00 00 00 8e 00 00 00 0c 00 00 01 06 00 00 00 00 00 00 02 02 00 00 00 00 00 00 02 03 00 00 00 01 00 00 02 02 00 00 00 01 00 00 02 03 00 00 00 02 00 00 02 02 00 00 00 02 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 03 00 00 00 1c 00 00 02 02 00 00 00 1c 00 00 02 03 00 00 00 1d 00 00 02 02 00 00 00 1d 00 00 02 03 2 | -------------------------------------------------------------------------------- /afl/testcase/8329e3313860bfd6b8dd1252b4a4542d4c791f13.csv: -------------------------------------------------------------------------------- 1 | ,37 00 08 00 00 00 00 00 08 00,,00 00 00 05 00 3f 45 46 82 27 21 60 00 00 02 00 81 0a c4 01 00 00 00 00 00 00 0c 00 82 0e 00 00 00 00 00 00 01 f4 00 00 00 00 00 00 03 16 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 40 00 00 00 04 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 04 01 00 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 8a 0a 00 10 00 00 00 00 00 00 00 06 ca 01 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ca 02 01 8c 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2 | -------------------------------------------------------------------------------- /afl/testcase/c144c7638bb08162db1ae53954e6cd20e66474f7: -------------------------------------------------------------------------------- 1 | ,b7 0a 00 00 00 00 00 00 02 00 00 00,,00 83 00 48 01 03 00 08 50 00 cc a0 2b 03 e0 b0 61 93 00 08 50 00 cc a0 2b 03 e0 b2 61 94 00 04 00 00 00 02 61 a3 00 08 50 00 cc a0 2b 03 e0 b3 63 a8 00 18 6e 61 61 2e 35 30 30 30 43 43 41 30 32 42 30 33 45 30 42 33 00 00 00 00 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 03 00 00 00 1c 00 00 02 02 00 00 00 1c 00 00 02 03 00 00 00 1d 00 00 02 02 00 00 00 1d 00 00 02 03 2 | -------------------------------------------------------------------------------- /afl/testcase/fbc7b5cc87f1afa84d70c82f152761258a3b0ca6: -------------------------------------------------------------------------------- 1 | ,b7 0d 00 00 00 00 00 00 00 08 00 00,,00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 5a 00 00 00 01 00 00 00 5a 00 00 00 02 00 00 00 5a 00 00 00 03 00 00 00 5a 00 00 00 04 00 00 00 5a 00 00 00 06 00 00 00 5a 00 00 00 07 00 00 00 5a 00 00 00 08 00 00 00 5a 00 00 00 09 00 00 00 5a 00 00 00 0a 00 00 00 5a 00 00 00 0b 00 00 00 5a 00 00 00 12 00 00 00 5a 00 00 00 0c 00 00 00 5a 00 00 00 0d 00 00 00 5a 00 00 00 0e 00 00 00 5a 00 00 00 0f 00 00 00 5a 00 00 00 10 00 00 00 5a 00 00 00 05 00 00 00 5a 00 00 00 11 00 00 00 5a 00 00 00 13 00 00 00 5a 00 00 00 1e 00 00 00 5a 00 00 00 14 00 00 00 5a 00 00 00 15 00 00 00 5a 00 00 00 16 00 00 00 5a 00 00 00 17 00 00 00 5a 00 00 00 1f 00 00 00 5a 00 00 00 20 00 00 00 5a 00 00 00 21 00 00 00 5a 00 00 00 22 00 00 00 5a 00 00 00 23 00 00 00 5a 00 00 00 18 00 00 00 5a 00 00 00 19 00 00 00 5a 00 00 00 1a 00 00 00 5a 00 00 00 1b 00 00 00 5a 00 00 00 1c 00 00 00 5a 00 00 00 1d 00 00 00 5a 00 00 00 24 00 00 00 5a 00 00 00 25 00 00 00 5a 00 00 00 26 00 00 00 5a 00 00 00 27 00 00 00 5a 00 00 00 28 00 00 00 5a 00 00 00 29 00 00 00 5a 00 00 00 2a 00 00 00 5a 00 00 00 2d 00 00 00 5a 00 00 00 2e 00 00 00 5a 00 00 00 2f 00 00 00 5a 00 00 00 30 00 00 00 5a 00 00 00 31 00 00 00 5a 00 00 00 32 00 00 00 5a 00 00 00 33 00 00 00 5a 00 00 00 34 00 00 00 5a 00 00 00 35 00 00 00 5a 00 00 00 2b 00 00 00 5a 00 00 00 2c 00 00 00 5a 00 00 00 06 00 00 00 5b 00 00 00 00 00 00 00 5b 00 00 00 01 00 00 00 5b 00 00 00 04 00 00 00 5b 00 00 00 02 00 00 00 5b 00 00 00 03 00 00 00 5b 00 00 00 05 00 00 00 5b 00 00 00 07 00 00 00 5b 00 00 00 38 00 00 00 5a 2 | -------------------------------------------------------------------------------- /test/ata_check_power_mode.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "ata.h" 18 | #include "ata_parse.h" 19 | #include "main.h" 20 | #include 21 | #include 22 | #include 23 | 24 | void do_command(int fd) 25 | { 26 | unsigned char cdb[12]; 27 | unsigned char buf[512] ; 28 | int cdb_len = cdb_ata_check_power_mode(cdb); 29 | 30 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 31 | if (!ret) { 32 | fprintf(stderr, "Failed to submit command\n"); 33 | return; 34 | } 35 | 36 | unsigned char *sense; 37 | unsigned sense_len; 38 | ret = read_response(fd, &sense, &sense_len); 39 | if (!ret) { 40 | fprintf(stderr, "Error reading scsi response\n"); 41 | return; 42 | } 43 | 44 | ata_status_t status; 45 | if (sense && ata_status_from_scsi_sense(sense, sense_len, &status)) { 46 | printf("extend: %d\n", status.extend); 47 | printf("error: %02x\n", status.error); 48 | printf("lba: %08"PRIx64"\n", status.lba); 49 | printf("device: %02x\n", status.device); 50 | printf("status: %02x\n", status.status); 51 | printf("count: %02x\n", status.sector_count); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/ata_identify.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "ata.h" 18 | #include "ata_parse.h" 19 | #include "ata_identify_dump.h" 20 | #include "main.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | void do_command(int fd) 32 | { 33 | unsigned char cdb[32]; 34 | unsigned char buf[512] ; 35 | unsigned cdb_len = cdb_ata_identify(cdb); 36 | 37 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 38 | if (!ret) { 39 | fprintf(stderr, "Failed to submit command\n"); 40 | return; 41 | } 42 | 43 | unsigned char *sense = NULL; 44 | unsigned sense_len = 0; 45 | ret = read_response(fd, &sense, &sense_len); 46 | 47 | ata_status_t status; 48 | if (sense && ata_status_from_scsi_sense(sense, sense_len, &status)) { 49 | printf("extend: %d\n", status.extend); 50 | printf("error: %02x\n", status.error); 51 | printf("lba: %08"PRIx64"\n", status.lba); 52 | printf("device: %02x\n", status.device); 53 | printf("status: %02x\n", status.status); 54 | } 55 | 56 | if (!sense) 57 | dump_ata_identify(buf); 58 | else 59 | printf("error while reading ATA IDENTIFY, nothing to show\n"); 60 | } 61 | -------------------------------------------------------------------------------- /test/scsi_read_capacity_10.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | #include "main.h" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | void do_command(int fd) 30 | { 31 | unsigned char cdb[32]; 32 | unsigned char buf[512] ; 33 | unsigned cdb_len = cdb_read_capacity_10(cdb); 34 | 35 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 36 | if (!ret) { 37 | fprintf(stderr, "Failed to submit command\n"); 38 | return; 39 | } 40 | 41 | unsigned char *sense = NULL; 42 | unsigned sense_len = 0; 43 | unsigned buf_len = 0; 44 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 45 | 46 | if (sense) { 47 | printf("error while reading response buffer, nothing to show\n"); 48 | return; 49 | } 50 | 51 | printf("Read %u bytes\n", buf_len); 52 | 53 | uint32_t max_lba; 54 | uint32_t block_size; 55 | bool parsed = parse_read_capacity_10(buf, buf_len, &max_lba, &block_size); 56 | if (!parsed) { 57 | printf("Failed to parse read capacity buffer\n"); 58 | return; 59 | } 60 | 61 | printf("Max LBA: %u\nBlock size: %u\n", max_lba, block_size); 62 | return; 63 | } 64 | -------------------------------------------------------------------------------- /test/sense_decode.c: -------------------------------------------------------------------------------- 1 | #include "sense_dump.h" 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | unsigned char sense[256]; 8 | int sense_len = 0; 9 | 10 | printf("Reading sense from args to buffer...\n"); 11 | int i; 12 | bool is_top_nibble = true; 13 | for (i = 1; i < argc; i++) { 14 | char *ch; 15 | 16 | for (ch = argv[i]; *ch != 0; ch++) { 17 | unsigned char val; 18 | if (*ch >= '0' && *ch <= '9') 19 | val = (*ch) - '0'; 20 | else if (*ch >= 'a' && *ch <= 'f') 21 | val = (*ch) - 'a' + 0xa; 22 | else if (*ch >= 'A' && *ch <= 'F') 23 | val = (*ch) - 'A' + 0xA; 24 | else if (*ch == ' ' || *ch == '+' || *ch == '\t') { 25 | continue; 26 | } else { 27 | fprintf(stderr, "\n\nInvalid character '%c' (%d) in sequence\n", *ch, *ch); 28 | return 1; 29 | } 30 | 31 | if (is_top_nibble) { 32 | sense[sense_len] = val<<4; 33 | is_top_nibble = false; 34 | } else { 35 | sense[sense_len] |= val; 36 | is_top_nibble = true; 37 | sense_len++; 38 | } 39 | } 40 | } 41 | 42 | if (!is_top_nibble) { 43 | fprintf(stderr, "Missing a nibble!\n"); 44 | return 2; 45 | } 46 | 47 | printf("Decoding sense...\n"); 48 | sense_dump(sense, sense_len); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /test/ata_smart_return_status.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "ata.h" 18 | #include "ata_parse.h" 19 | #include "main.h" 20 | #include 21 | #include 22 | #include 23 | 24 | void do_command(int fd) 25 | { 26 | unsigned char cdb[12]; 27 | unsigned char buf[512] ; 28 | int cdb_len = cdb_ata_smart_return_status(cdb); 29 | 30 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 31 | if (!ret) { 32 | fprintf(stderr, "Failed to submit command\n"); 33 | return; 34 | } 35 | 36 | unsigned char *sense; 37 | unsigned sense_len; 38 | ret = read_response(fd, &sense, &sense_len); 39 | if (!ret) { 40 | fprintf(stderr, "Error reading scsi response\n"); 41 | return; 42 | } 43 | printf("\n"); 44 | 45 | ata_status_t status; 46 | if (ata_status_from_scsi_sense(sense, sense_len, &status)) { 47 | printf("extend: %d\n", status.extend); 48 | printf("error: %02x\n", status.error); 49 | printf("lba: %08" PRIx64 "\n", status.lba); 50 | printf("device: %02x\n", status.device); 51 | printf("status: %02x\n", status.status); 52 | } 53 | printf("\n"); 54 | 55 | bool smart_ok; 56 | if (ata_smart_return_status_result(sense, sense_len, &smart_ok)) 57 | printf("smart result: %s\n", smart_ok ? "ok" : "failed"); 58 | else 59 | printf("smart parsing failed\n"); 60 | } 61 | -------------------------------------------------------------------------------- /include/scsicmd_utils.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #ifndef LIBSCSICMD_UTILS_H 18 | #define LIBSCSICMD_UTILS_H 19 | 20 | #include 21 | 22 | static inline uint16_t get_uint16(unsigned char *buf, int start) 23 | { 24 | return (uint16_t)buf[start] << 8 | 25 | (uint16_t)buf[start+1]; 26 | } 27 | 28 | static inline uint32_t get_uint24(unsigned char *buf, int start) 29 | { 30 | return (uint32_t)buf[start] << 16 | 31 | (uint32_t)buf[start+1] << 8 | 32 | (uint32_t)buf[start+2]; 33 | } 34 | 35 | static inline uint32_t get_uint32(unsigned char *buf, int start) 36 | { 37 | return (uint32_t)buf[start] << 24 | 38 | (uint32_t)buf[start+1] << 16 | 39 | (uint32_t)buf[start+2] << 8 | 40 | (uint32_t)buf[start+3]; 41 | } 42 | 43 | static inline uint64_t get_uint64(unsigned char *buf, int start) 44 | { 45 | return (uint64_t)buf[start] << 56 | 46 | (uint64_t)buf[start+1] << 48 | 47 | (uint64_t)buf[start+2] << 40 | 48 | (uint64_t)buf[start+3] << 32 | 49 | (uint64_t)buf[start+4] << 24 | 50 | (uint64_t)buf[start+5] << 16 | 51 | (uint64_t)buf[start+6] << 8 | 52 | (uint64_t)buf[start+7]; 53 | } 54 | 55 | static inline unsigned safe_len(uint8_t *start, unsigned len, uint8_t *subbuf, unsigned subbuf_len) 56 | { 57 | const int start_offset = subbuf - start; 58 | 59 | if (start_offset < 0 || (unsigned)start_offset > len) 60 | return 0; 61 | 62 | if (subbuf_len + start_offset > len) 63 | return len - start_offset; 64 | else 65 | return subbuf_len; 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/parse_read_cap.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | #include "scsicmd_utils.h" 19 | 20 | #include 21 | #include 22 | 23 | bool parse_read_capacity_10(unsigned char *buf, unsigned buf_len, uint32_t *max_lba, uint32_t *block_size) 24 | { 25 | if (buf_len < 8) 26 | return false; 27 | 28 | if (max_lba) 29 | *max_lba = get_uint32(buf, 0); 30 | if (block_size) 31 | *block_size = get_uint32(buf, 4); 32 | return true; 33 | } 34 | 35 | bool parse_read_capacity_16(unsigned char *buf, unsigned buf_len, uint64_t *max_lba, uint32_t *block_size, bool *prot_enable, 36 | unsigned *p_type, unsigned *p_i_exponent, unsigned *logical_blocks_per_physical_block_exponent, 37 | bool *thin_provisioning_enabled, bool *thin_provisioning_zero, unsigned *lowest_aligned_lba) 38 | { 39 | if (buf_len < 16) 40 | return false; 41 | 42 | if (max_lba) 43 | *max_lba = get_uint64(buf, 0); 44 | if (block_size) 45 | *block_size = get_uint32(buf, 8); 46 | if (prot_enable) 47 | *prot_enable = buf[12] & 1; 48 | if (p_type) 49 | *p_type = (buf[12] & 0xe) >> 1; 50 | if (p_i_exponent) 51 | *p_i_exponent = (buf[13] & 0xf0) >> 4; 52 | if (logical_blocks_per_physical_block_exponent) 53 | *logical_blocks_per_physical_block_exponent = buf[13] & 0xf; 54 | if (thin_provisioning_enabled) 55 | *thin_provisioning_enabled = buf[14] & 0x80; 56 | if (thin_provisioning_zero) 57 | *thin_provisioning_zero = buf[14] & 0x40; 58 | if (*lowest_aligned_lba) 59 | *lowest_aligned_lba = (buf[14] & 0x3f) << 8 | buf[15]; 60 | return true; 61 | } 62 | -------------------------------------------------------------------------------- /src/parse_inquiry.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | 19 | #include 20 | #include 21 | 22 | bool parse_inquiry(unsigned char *buf, unsigned buf_len, int *device_type, scsi_vendor_t vendor, scsi_model_t model, 23 | scsi_fw_revision_t revision, scsi_serial_t serial) 24 | { 25 | *device_type = -1; 26 | vendor[0] = 0; 27 | model[0] = 0; 28 | revision[0] = 0; 29 | serial[0] = 0; 30 | 31 | if (buf_len < 32) 32 | return false; 33 | 34 | unsigned char fmt = buf[3] & 0xf; 35 | 36 | int valid_len = buf[4] + 4; 37 | 38 | *device_type = buf[0] & 0x1f; 39 | 40 | if (valid_len >= 8 + SCSI_VENDOR_LEN) { 41 | strncpy(vendor, (char*)buf+8, SCSI_VENDOR_LEN); 42 | vendor[SCSI_VENDOR_LEN] = 0; 43 | } 44 | 45 | if (valid_len >= 16 + SCSI_MODEL_LEN) { 46 | strncpy(model, (char*)buf+16, SCSI_MODEL_LEN); 47 | model[SCSI_MODEL_LEN] = 0; 48 | } 49 | 50 | if (valid_len >= 32 + SCSI_FW_REVISION_LEN) { 51 | strncpy(revision, (char*)buf+32, SCSI_FW_REVISION_LEN); 52 | revision[SCSI_FW_REVISION_LEN] = 0; 53 | } 54 | 55 | if (valid_len >= 44 && fmt == 2) { 56 | strncpy(serial, (char*)buf+36, SCSI_SERIAL_LEN); 57 | serial[SCSI_SERIAL_LEN] = 0; 58 | } 59 | 60 | return true; 61 | } 62 | 63 | #define STRINGIFY(name) # name 64 | 65 | const char *scsi_device_type_name(scsi_device_type_e dev_type) 66 | { 67 | #define X(name) case SCSI_DEV_TYPE_##name: return STRINGIFY(name); 68 | switch (dev_type) { 69 | SCSI_DEVICE_TYPE_LIST 70 | #undef X 71 | } 72 | 73 | return "Unknown device type"; 74 | } 75 | -------------------------------------------------------------------------------- /include/parse_extended_inquiry.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #ifndef LIBSCSICMD_EXTENDED_INQUIRY_H 18 | #define LIBSCSICMD_EXTENDED_INQUIRY_H 19 | 20 | #include 21 | 22 | #define EVPD_MIN_LEN 4 23 | 24 | static inline uint8_t evpd_peripheral_qualifier(uint8_t *data) 25 | { 26 | return data[0] >> 5; 27 | } 28 | 29 | static inline uint8_t evpd_peripheral_device_type(uint8_t *data) 30 | { 31 | return data[0] & 0x1F; 32 | } 33 | 34 | static inline uint8_t evpd_page_code(uint8_t *data) 35 | { 36 | return data[1]; 37 | } 38 | 39 | static inline uint16_t evpd_page_len(uint8_t *data) 40 | { 41 | return (data[2] << 8) | data[3]; 42 | } 43 | 44 | static inline uint8_t *evpd_page_data(uint8_t *data) 45 | { 46 | return data + EVPD_MIN_LEN; 47 | } 48 | 49 | static inline bool evpd_is_ascii_page(uint8_t page_code) 50 | { 51 | return 0x01 <= page_code && page_code <= 0x7F; 52 | } 53 | 54 | /* This should be called with the body of the EVPD data and not the full (i.e. with the output of evpd_page_data()) */ 55 | static inline uint16_t evpd_ascii_len(uint8_t *evpd_body) 56 | { 57 | return (evpd_body[0] << 8) | evpd_body[1]; 58 | } 59 | 60 | static inline uint8_t *evpd_ascii_data(uint8_t *evpd_body) 61 | { 62 | return evpd_body + 2; 63 | } 64 | 65 | static inline uint8_t *evpd_ascii_post_data(uint8_t *evpd_body) 66 | { 67 | return evpd_body + 2 + evpd_ascii_len(evpd_body); 68 | } 69 | 70 | static inline unsigned evpd_ascii_post_data_len(uint8_t *evpd_body, unsigned full_data_len) 71 | { 72 | return full_data_len - EVPD_MIN_LEN - 2 - evpd_ascii_len(evpd_body); 73 | } 74 | 75 | static inline bool evpd_is_valid(uint8_t *data, unsigned data_len) 76 | { 77 | if (data_len < EVPD_MIN_LEN) 78 | return false; 79 | 80 | if (evpd_page_len(data) > data_len) 81 | return false; 82 | 83 | return true; 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(testlib STATIC main.c sense_dump.c) 2 | 3 | add_executable(ata_check_power_mode ata_check_power_mode.c) 4 | target_link_libraries(ata_check_power_mode testlib scsicmd) 5 | 6 | add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/ata_identify_dump.h 7 | COMMAND ${PROJECT_SOURCE_DIR}/structs/ata_struct_2_h_dump.py ${PROJECT_SOURCE_DIR}/structs/ata_identify.yaml > ${CMAKE_CURRENT_SOURCE_DIR}/ata_identify_dump.h 8 | DEPENDS ${PROJECT_SOURCE_DIR}/structs/ata_struct_2_h_dump.py ${PROJECT_SOURCE_DIR}/structs/ata_identify.yaml) 9 | add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/ata_identify_dump.c 10 | COMMAND ${PROJECT_SOURCE_DIR}/structs/ata_struct_2_c_dump.py ${PROJECT_SOURCE_DIR}/structs/ata_identify.yaml > ${CMAKE_CURRENT_SOURCE_DIR}/ata_identify_dump.c 11 | DEPENDS ${PROJECT_SOURCE_DIR}/structs/ata_struct_2_c_dump.py ${PROJECT_SOURCE_DIR}/structs/ata_identify.yaml) 12 | add_executable(ata_identify ata_identify.c ata_identify_dump.c ata_identify_dump.h) 13 | target_link_libraries(ata_identify testlib scsicmd) 14 | 15 | add_executable(ata_smart_read_data ata_smart_read_data.c) 16 | target_link_libraries(ata_smart_read_data testlib scsicmd) 17 | 18 | add_executable(ata_smart_return_status ata_smart_return_status.c) 19 | target_link_libraries(ata_smart_return_status testlib scsicmd) 20 | 21 | add_executable(scsi_inquiry scsi_inquiry.c) 22 | target_link_libraries(scsi_inquiry testlib scsicmd) 23 | 24 | add_executable(scsi_log_sense scsi_log_sense.c) 25 | target_link_libraries(scsi_log_sense testlib scsicmd) 26 | 27 | add_executable(parse_scsi parse_scsi.c) 28 | target_link_libraries(parse_scsi testlib scsicmd) 29 | 30 | add_executable(scsi_mode_sense scsi_mode_sense.c) 31 | target_link_libraries(scsi_mode_sense testlib scsicmd) 32 | 33 | add_executable(scsi_receive_diagnostics scsi_receive_diagnostics.c) 34 | target_link_libraries(scsi_receive_diagnostics testlib scsicmd) 35 | 36 | add_executable(scsi_read_capacity_10 scsi_read_capacity_10.c) 37 | target_link_libraries(scsi_read_capacity_10 testlib scsicmd) 38 | 39 | add_executable(scsi_read_capacity_16 scsi_read_capacity_16.c) 40 | target_link_libraries(scsi_read_capacity_16 testlib scsicmd) 41 | 42 | add_executable(sense_decode sense_decode.c) 43 | target_link_libraries(sense_decode testlib scsicmd) 44 | 45 | add_executable(collect_raw_data collect_raw_data.c) 46 | target_link_libraries(collect_raw_data testlib scsicmd) 47 | -------------------------------------------------------------------------------- /structs/ata_struct_2_c_dump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import yaml 5 | 6 | def emit_func_bit(name, field, params): 7 | bit_params = dict(name=name, field=field, word=int(params[0]), bit=int(params[1])) 8 | print('printf("%%-40s: %%s\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf) ? "true" : "false");' % bit_params) 9 | 10 | def emit_func_string(name, field, params): 11 | bit_params = dict(name=name, field=field, word_start=int(params[0]), word_end=int(params[1])) 12 | print('{') 13 | print('char outbuf[1024];') 14 | print('ata_get_%(name)s_%(field)s(buf, outbuf);' % bit_params) 15 | print('printf("%%-40s: %%s\\n", "%(field)s", outbuf);' % bit_params) 16 | print('}') 17 | 18 | def emit_func_bits(name, field, params): 19 | bit_params = dict(name=name, field=field, word_start=int(params[0])) 20 | print('printf("%%-40s: %%u\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) 21 | 22 | def emit_func_longword(name, field, params): 23 | bit_params = dict(name=name, field=field, word_start=int(params)) 24 | print('printf("%%-40s: %%u\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) 25 | 26 | def emit_func_qword(name, field, params): 27 | bit_params = dict(name=name, field=field, word_start=int(params)) 28 | print('printf("%%-40s: %%"PRIu64"\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) 29 | 30 | kinds = { 31 | 'bit': emit_func_bit, 32 | 'bits': emit_func_bits, 33 | 'string': emit_func_string, 34 | 'longword': emit_func_longword, 35 | 'qword': emit_func_qword, 36 | } 37 | 38 | def emit_header_single(name, struct): 39 | field_names = list(struct.keys()) 40 | field_names.sort() 41 | 42 | for field in field_names: 43 | info = struct[field] 44 | keys = list(info.keys()) 45 | assert(len(keys) == 1) 46 | kind = keys[0] 47 | params = info[kind] 48 | 49 | kinds[kind](name, field, params) 50 | 51 | def emit_header(structs): 52 | for name, struct in list(structs.items()): 53 | print('void dump_%s(const unsigned char *buf)' % name) 54 | print('{') 55 | emit_header_single(name, struct) 56 | print('}') 57 | 58 | def emit_prefix(): 59 | print('#include "ata.h"') 60 | print('#include "ata_parse.h"') 61 | print('#include "ata_identify_dump.h"') 62 | print('#include ') 63 | print('#include ') 64 | 65 | def emit_suffix(): 66 | print('') 67 | 68 | def convert_def(filename): 69 | f = file(filename) 70 | structs = yaml.load(f) 71 | f.close() 72 | emit_header(structs) 73 | 74 | if __name__ == '__main__': 75 | emit_prefix() 76 | filenames = sys.argv[1:] 77 | for filename in filenames: 78 | convert_def(filename) 79 | emit_suffix() 80 | -------------------------------------------------------------------------------- /src/ata_smart.c: -------------------------------------------------------------------------------- 1 | #include "ata_smart.h" 2 | #include 3 | 4 | 5 | static const smart_attr_t *ata_smart_get(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, const ata_smart_attr_t **pattr, smart_attr_type_e attr_type) 6 | { 7 | const smart_attr_t *attr_info; 8 | int i; 9 | 10 | attr_info = smart_attr_for_type(table, attr_type); 11 | if (attr_info == NULL) 12 | return NULL; 13 | 14 | for (i = 0; i < num_attrs; i++) { 15 | if (attrs[i].id == attr_info->id) { 16 | *pattr = &attrs[i]; 17 | return attr_info; 18 | } 19 | } 20 | 21 | // Attribute not found in disk smart data 22 | return NULL; 23 | } 24 | 25 | static int ata_smart_get_simple(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, smart_attr_type_e attr_type) 26 | { 27 | const smart_attr_t *attr_info; 28 | const ata_smart_attr_t *smart_attr; 29 | 30 | attr_info = ata_smart_get(attrs, num_attrs, table, &smart_attr, attr_type); 31 | if (attr_info == NULL) 32 | return -1; 33 | 34 | return smart_attr->raw; 35 | } 36 | 37 | int ata_smart_get_temperature(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, int *pmin_temp, int *pmax_temp) 38 | { 39 | const smart_attr_t *attr_info; 40 | const ata_smart_attr_t *smart_attr; 41 | 42 | attr_info = ata_smart_get(attrs, num_attrs, table, &smart_attr, SMART_ATTR_TYPE_TEMP); 43 | if (attr_info == NULL) 44 | return -1; 45 | 46 | // Temperature is some offset minus the current value, usually 47 | int temp = attr_info->offset - smart_attr->value; 48 | *pmin_temp = *pmax_temp = -1; 49 | 50 | if (smart_attr->raw) { 51 | int min_temp = (smart_attr->raw >> 16) & 0xFFFF; 52 | int max_temp = (smart_attr->raw >> 32) & 0xFFFF; 53 | 54 | temp = smart_attr->raw & 0xFFFF; 55 | 56 | if (max_temp >= temp && min_temp <= temp) { 57 | *pmin_temp = min_temp; 58 | *pmax_temp = max_temp; 59 | } 60 | } 61 | return temp; 62 | } 63 | 64 | int ata_smart_get_power_on_hours(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, int *pminutes) 65 | { 66 | *pminutes = -1; 67 | return ata_smart_get_simple(attrs, num_attrs, table, SMART_ATTR_TYPE_POH); 68 | } 69 | 70 | int ata_smart_get_num_reallocations(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table) 71 | { 72 | return ata_smart_get_simple(attrs, num_attrs, table, SMART_ATTR_TYPE_REALLOC); 73 | } 74 | 75 | int ata_smart_get_num_pending_reallocations(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table) 76 | { 77 | return ata_smart_get_simple(attrs, num_attrs, table, SMART_ATTR_TYPE_REALLOC_PENDING); 78 | } 79 | 80 | int ata_smart_get_num_crc_errors(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table) 81 | { 82 | return ata_smart_get_simple(attrs, num_attrs, table, SMART_ATTR_TYPE_CRC_ERRORS); 83 | } 84 | -------------------------------------------------------------------------------- /structs/ata_struct_2_h.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import yaml 5 | 6 | def emit_func_bit(name, field, params): 7 | bit_params = dict(name=name, field=field, word=int(params[0]), bit=int(params[1])) 8 | print("""static inline bool ata_get_%(name)s_%(field)s(const unsigned char *buf) { 9 | ata_word_t val = ata_get_word(buf, %(word)d); 10 | return val & (1 << %(bit)d); 11 | } 12 | """ % bit_params) 13 | 14 | def emit_func_bits(name, field, params): 15 | bit_params = dict(name=name, field=field, word=int(params[0]), start_bit=int(params[1]), end_bit=int(params[2])) 16 | print("""static inline unsigned ata_get_%(name)s_%(field)s(const unsigned char *buf) { 17 | ata_word_t val = ata_get_word(buf, %(word)d); 18 | return (val >> %(start_bit)d) & ((1<<(%(end_bit)d - %(start_bit)d + 1)) - 1); 19 | } 20 | """ % bit_params) 21 | 22 | def emit_func_string(name, field, params): 23 | bit_params = dict(name=name, field=field, word_start=int(params[0]), word_end=int(params[1])) 24 | print("""static inline void ata_get_%(name)s_%(field)s(const unsigned char *buf, char *out) { 25 | ata_get_string(buf, %(word_start)d, %(word_end)d, out); 26 | } 27 | """ % bit_params) 28 | 29 | def emit_func_longword(name, field, params): 30 | bit_params = dict(name=name, field=field, word_start=int(params)) 31 | print("""static inline ata_longword_t ata_get_%(name)s_%(field)s(const unsigned char *buf) { 32 | return ata_get_longword(buf, %(word_start)d); 33 | } 34 | """ % bit_params) 35 | 36 | def emit_func_qword(name, field, params): 37 | bit_params = dict(name=name, field=field, word_start=int(params)) 38 | print("""static inline ata_qword_t ata_get_%(name)s_%(field)s(const unsigned char *buf) { 39 | return ata_get_qword(buf, %(word_start)d); 40 | } 41 | """ % bit_params) 42 | 43 | kinds = { 44 | 'bit': emit_func_bit, 45 | 'bits': emit_func_bits, 46 | 'string': emit_func_string, 47 | 'longword': emit_func_longword, 48 | 'qword': emit_func_qword, 49 | } 50 | 51 | def emit_header_single(name, struct): 52 | for field, info in list(struct.items()): 53 | keys = list(info.keys()) 54 | assert(len(keys) == 1) 55 | kind = keys[0] 56 | params = info[kind] 57 | 58 | kinds[kind](name, field, params) 59 | 60 | def emit_header(structs): 61 | for name, struct in list(structs.items()): 62 | emit_header_single(name, struct) 63 | 64 | def emit_prefix(): 65 | print('/* Generated file, do not edit */') 66 | print('#ifndef ATA_PARSE_H') 67 | print('#define ATA_PARSE_H') 68 | print('#include "ata.h"') 69 | 70 | def emit_suffix(): 71 | print('#endif') 72 | 73 | def convert_def(filename): 74 | f = file(filename) 75 | structs = yaml.load(f) 76 | f.close() 77 | emit_header(structs) 78 | 79 | if __name__ == '__main__': 80 | emit_prefix() 81 | filenames = sys.argv[1:] 82 | for filename in filenames: 83 | convert_def(filename) 84 | emit_suffix() 85 | -------------------------------------------------------------------------------- /test/scsi_read_capacity_16.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | #include "main.h" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | void do_command(int fd) 30 | { 31 | unsigned char cdb[32]; 32 | unsigned char buf[512] ; 33 | unsigned cdb_len = cdb_read_capacity_16(cdb, sizeof(buf)); 34 | 35 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 36 | if (!ret) { 37 | fprintf(stderr, "Failed to submit command\n"); 38 | return; 39 | } 40 | 41 | unsigned char *sense = NULL; 42 | unsigned sense_len = 0; 43 | unsigned buf_len = 0; 44 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 45 | 46 | if (sense) { 47 | printf("error while reading response buffer, nothing to show\n"); 48 | return; 49 | } 50 | 51 | printf("Read %u bytes\n", buf_len); 52 | 53 | uint64_t max_lba; 54 | uint32_t block_size; 55 | bool prot_enable; 56 | unsigned p_type; 57 | unsigned p_i_exponent; 58 | unsigned logical_blocks_per_physical_block_exponent; 59 | bool thin_provisioning_enabled; 60 | bool thin_provisioning_zero; 61 | unsigned lowest_aligned_lba; 62 | bool parsed = parse_read_capacity_16(buf, buf_len, &max_lba, &block_size, &prot_enable, 63 | &p_type, &p_i_exponent, &logical_blocks_per_physical_block_exponent, 64 | &thin_provisioning_enabled, &thin_provisioning_zero, &lowest_aligned_lba); 65 | if (!parsed) { 66 | printf("Failed to parse read capacity buffer\n"); 67 | return; 68 | } 69 | 70 | printf("Max LBA: %"PRIu64"\nBlock size: %u\n", max_lba, block_size); 71 | printf("Protection enabled: %s\n", prot_enable ? "true" : "false"); 72 | printf("Protection type: %u\n", p_type); 73 | printf("Protection exponent: %u\n", p_i_exponent); 74 | printf("LBAs per block exponent: %u\n", logical_blocks_per_physical_block_exponent); 75 | printf("Thin provisioning enabled: %s\n", thin_provisioning_enabled ? "true" : "false"); 76 | printf("Thin provisoning zeroes: %s\n", thin_provisioning_zero ? "true" : "false"); 77 | printf("Lowest aligned LBA: %u\n", lowest_aligned_lba); 78 | return; 79 | } 80 | -------------------------------------------------------------------------------- /test/scsi_receive_diagnostics.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2014 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | #include "parse_receive_diagnostics.h" 19 | #include "main.h" 20 | #include "sense_dump.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | static void dump_page(int fd, uint8_t page) 33 | { 34 | unsigned char cdb[32]; 35 | unsigned char buf[16*1024]; 36 | unsigned cdb_len = cdb_receive_diagnostics(cdb, true, page, sizeof(buf)); 37 | 38 | printf("List page %02X\n", page); 39 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 40 | if (!ret) { 41 | fprintf(stderr, "Failed to submit command\n"); 42 | return; 43 | } 44 | 45 | unsigned char *sense = NULL; 46 | unsigned sense_len = 0; 47 | unsigned buf_len = 0; 48 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 49 | 50 | if (sense) { 51 | printf("error while reading response buffer, nothing to show\n"); 52 | return; 53 | } 54 | 55 | printf("Read %u bytes\n", buf_len); 56 | response_dump(buf, buf_len); 57 | printf("\n"); 58 | } 59 | 60 | void do_command(int fd) 61 | { 62 | unsigned char cdb[32]; 63 | unsigned char buf[16*1024]; 64 | unsigned cdb_len = cdb_receive_diagnostics(cdb, true, 0, sizeof(buf)); 65 | 66 | printf("List all supported pages\n"); 67 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 68 | if (!ret) { 69 | fprintf(stderr, "Failed to submit command\n"); 70 | return; 71 | } 72 | 73 | unsigned char *sense = NULL; 74 | unsigned sense_len = 0; 75 | unsigned buf_len = 0; 76 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 77 | 78 | if (sense) { 79 | printf("error while reading response buffer, nothing to show\n"); 80 | return; 81 | } 82 | 83 | printf("Read %u bytes\n", buf_len); 84 | response_dump(buf, buf_len); 85 | 86 | if (buf_len < RECV_DIAG_MIN_LEN) { 87 | printf("receive diagnostics list must have at least 4 bytes\n"); 88 | return; 89 | } 90 | 91 | if (recv_diag_get_page_code(buf) != 0) { 92 | printf("expected to receive receive diagnostics page 0\n"); 93 | return; 94 | } 95 | 96 | uint16_t num_pages = recv_diag_get_len(buf); 97 | uint16_t i; 98 | for (i = 0; i < num_pages; i++) { 99 | dump_page(fd, buf[4 + i]); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/smartdb/smartdb_gen.c: -------------------------------------------------------------------------------- 1 | #include "smartdb.h" 2 | static const smart_table_t defaults = { 3 | .num_attrs = 26, 4 | .attrs = { 5 | {.id=1, .type=SMART_ATTR_TYPE_NONE, .name="Raw Read Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 6 | {.id=2, .type=SMART_ATTR_TYPE_NONE, .name="Throughput Performance", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 7 | {.id=3, .type=SMART_ATTR_TYPE_NONE, .name="Spin Up Time", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 8 | {.id=4, .type=SMART_ATTR_TYPE_NONE, .name="Start/Stop Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 9 | {.id=5, .type=SMART_ATTR_TYPE_REALLOC, .name="Reallocated Sectors Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 10 | {.id=7, .type=SMART_ATTR_TYPE_NONE, .name="Seek Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 11 | {.id=8, .type=SMART_ATTR_TYPE_NONE, .name="Seek Time Performance", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 12 | {.id=9, .type=SMART_ATTR_TYPE_POH, .name="Power On Hours", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 13 | {.id=10, .type=SMART_ATTR_TYPE_NONE, .name="Spin Retry Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 14 | {.id=11, .type=SMART_ATTR_TYPE_NONE, .name="Drive Calibration Retry Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 15 | {.id=12, .type=SMART_ATTR_TYPE_NONE, .name="Device Power Cycle Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 16 | {.id=13, .type=SMART_ATTR_TYPE_NONE, .name="Read Soft Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 17 | {.id=191, .type=SMART_ATTR_TYPE_NONE, .name="G Sense Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 18 | {.id=192, .type=SMART_ATTR_TYPE_NONE, .name="Power Off Retract Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 19 | {.id=193, .type=SMART_ATTR_TYPE_NONE, .name="Load/Unload Cycle Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 20 | {.id=194, .type=SMART_ATTR_TYPE_TEMP, .name="Temperature", .raw=SMART_ATTR_RAW_DEC48, .offset=150}, 21 | {.id=195, .type=SMART_ATTR_TYPE_NONE, .name="Hardware ECC Recovered", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 22 | {.id=196, .type=SMART_ATTR_TYPE_NONE, .name="Reallocation Event Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 23 | {.id=197, .type=SMART_ATTR_TYPE_REALLOC_PENDING, .name="Pending Sector Reallocation Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 24 | {.id=198, .type=SMART_ATTR_TYPE_NONE, .name="Off-Line Scan Uncorrecable Sector Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 25 | {.id=199, .type=SMART_ATTR_TYPE_CRC_ERRORS, .name="CRC Error Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 26 | {.id=200, .type=SMART_ATTR_TYPE_NONE, .name="Multi-zone Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 27 | {.id=240, .type=SMART_ATTR_TYPE_NONE, .name="Head Flying Hours", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 28 | {.id=241, .type=SMART_ATTR_TYPE_NONE, .name="Total LBAs Written", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 29 | {.id=242, .type=SMART_ATTR_TYPE_NONE, .name="Total LBAs Read", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 30 | {.id=254, .type=SMART_ATTR_TYPE_NONE, .name="Free Fall Sensor", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, 31 | } 32 | }; 33 | const smart_table_t * smart_table_for_disk(const char *vendor, const char *model, const char *firmware) 34 | { 35 | (void)vendor; 36 | (void)model; 37 | (void)firmware; 38 | return &defaults; 39 | } 40 | -------------------------------------------------------------------------------- /afl/testcase/ca52cd17cb1a061767830cb4e49867be9b637e56: -------------------------------------------------------------------------------- 1 | ,1c 01 04 40 00 00,,04 00 04 5f 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 30 39 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 31 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 32 39 20 64 65 76 2f 70 68 79 2e 30 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 34 31 20 64 65 76 2f 70 68 79 2e 31 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 35 33 20 64 65 76 2f 70 68 79 2e 32 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 36 32 20 64 65 76 2f 70 68 79 2e 33 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 36 37 20 64 65 76 2f 70 68 79 2e 30 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 37 32 20 64 65 76 2f 70 68 79 2e 30 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 38 33 20 64 65 76 2f 70 68 79 2e 30 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 38 39 20 64 65 76 2f 70 68 79 2e 30 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 34 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 30 31 20 64 65 76 2f 70 68 79 2e 31 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 30 36 20 64 65 76 2f 70 68 79 2e 31 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 31 30 20 64 65 76 2f 70 68 79 2e 31 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 31 35 20 64 65 76 2f 70 68 79 2e 31 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 35 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 32 37 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 32 38 20 64 65 76 2f 70 68 79 2e 32 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 34 34 20 64 65 76 2f 70 68 79 2e 32 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 34 38 20 64 65 76 2f 70 68 79 2e 32 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 35 32 20 64 65 76 2f 70 68 79 2e 32 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 36 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 36 34 20 64 65 76 2f 70 68 79 2e 33 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 36 38 20 64 65 76 2f 70 68 79 2e 33 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 37 33 20 64 65 76 2f 70 68 79 2e 33 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 37 38 20 64 65 76 2f 70 68 79 2e 33 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 37 2d 3e 30 78 66 66 0a 2 | -------------------------------------------------------------------------------- /test/scsi_mode_sense.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2014 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | #include "main.h" 19 | #include "sense_dump.h" 20 | #include "parse_mode_sense.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | void do_command(int fd) 32 | { 33 | unsigned char cdb[32]; 34 | unsigned char buf[4096]; 35 | unsigned cdb_len = cdb_mode_sense_10(cdb, true, false, PAGE_CONTROL_CURRENT, 0x3F, 0xFF, sizeof(buf)); 36 | 37 | memset(buf, 0, sizeof(buf)); 38 | printf("List all supported pages\n"); 39 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 40 | if (!ret) { 41 | fprintf(stderr, "Failed to submit command\n"); 42 | return; 43 | } 44 | 45 | unsigned char *sense = NULL; 46 | unsigned sense_len = 0; 47 | unsigned buf_len = 0; 48 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 49 | 50 | if (sense) { 51 | printf("error while reading response buffer, nothing to show\n"); 52 | return; 53 | } 54 | 55 | printf("Read %u bytes\n", buf_len); 56 | response_dump(buf, buf_len); 57 | 58 | if (buf_len < MODE_SENSE_10_MIN_LEN) { 59 | printf("Returned data is too short, expected a minimum of %u bytes and got only %u\n", MODE_SENSE_10_MIN_LEN, buf_len); 60 | return; 61 | } 62 | 63 | printf("Mode data len: %u\n", mode_sense_10_data_len(buf)); 64 | printf("Medium Type: %u\n", mode_sense_10_medium_type(buf)); 65 | printf("Device specific param: %u\n", mode_sense_10_device_specific_param(buf)); 66 | printf("Long LBA: %s\n", mode_sense_10_long_lba(buf) ? "yes" : "no"); 67 | printf("Block Descriptor length: %u\n", mode_sense_10_block_descriptor_length(buf)); 68 | 69 | if (buf_len < MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(buf)) 70 | { 71 | printf("Not enough data for the block descriptor length\n"); 72 | return; 73 | } 74 | 75 | if (mode_sense_10_long_lba(buf)) { 76 | printf("Don't know how to parse the block descriptor for a long lba yet\n"); 77 | } else { 78 | uint8_t *bdb = mode_sense_10_block_descriptor_data(buf); 79 | 80 | putchar('\n'); 81 | printf("Density code: %u\n", block_descriptor_density_code(bdb)); 82 | printf("Num blocks: %u\n", block_descriptor_num_blocks(bdb)); 83 | printf("Block length: %u\n", block_descriptor_block_length(bdb)); 84 | } 85 | 86 | if (buf_len < MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(buf) + mode_sense_10_data_len(buf)) 87 | { 88 | printf("Not enough data for the mode data length\n"); 89 | return; 90 | } 91 | 92 | putchar('\n'); 93 | //uint8_t *mode_data = mode_sense_10_mode_data(buf); 94 | 95 | } 96 | -------------------------------------------------------------------------------- /afl/testcase/90548a1ef4bae0b9b7382497097a01691333fb4f: -------------------------------------------------------------------------------- 1 | ,1c 01 01 40 00 00,,01 04 04 68 00 00 00 08 11 00 0a ea 50 06 04 80 a0 1c 19 3e 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 4c 43 43 20 20 20 30 42 33 30 07 81 42 02 00 01 02 55 53 31 44 30 31 31 30 35 30 30 30 35 39 00 00 05 40 a6 20 31 35 31 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 20 20 33 31 34 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 21 20 32 32 32 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 22 20 32 31 36 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 23 20 30 32 31 20 43 44 45 46 00 00 00 00 00 00 00 00 00 10 02 80 00 01 03 00 02 01 04 80 02 00 05 01 40 00 06 03 40 00 07 85 00 00 08 86 00 00 09 02 00 00 0a 02 01 00 0b 02 02 00 0c 02 03 00 0d 02 04 00 0e 02 05 00 0f 02 06 00 10 02 07 00 11 04 00 00 02 c0 c1 05 4c 43 43 20 42 11 01 06 b5 50 06 04 80 d8 21 42 be 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 4c 43 43 20 20 20 30 42 33 30 07 80 41 02 01 00 01 4a 57 58 45 4c 31 33 30 35 30 30 35 35 31 00 00 05 5a 06 20 31 35 31 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 00 20 33 31 34 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 01 20 32 32 32 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 02 20 32 31 36 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 03 20 30 32 31 20 43 44 45 46 00 00 00 00 00 00 00 00 00 03 12 00 03 01 13 80 03 00 14 03 5a 00 01 c2 05 4c 43 43 20 41 11 02 04 4f 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 45 6e 63 6c 20 20 30 30 31 31 0e 1f 4d 02 02 02 00 43 4b 4d 30 30 31 33 31 38 30 31 37 35 38 00 00 00 02 00 00 01 01 01 80 01 00 01 c3 07 43 68 61 73 73 69 73 11 03 03 6a 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 30 30 30 42 30 30 31 39 00 00 00 00 00 00 00 00 32 41 31 30 02 81 42 02 00 04 33 41 43 37 42 30 31 33 30 32 31 37 38 31 39 20 20 01 86 a4 20 35 2e 33 33 53 58 50 33 36 78 36 47 00 00 00 00 00 02 15 00 04 01 16 80 04 00 01 c4 0e 50 6f 77 65 72 20 53 75 70 70 6c 79 20 42 11 04 03 56 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 45 4d 43 20 44 45 52 52 49 4e 47 45 52 20 50 53 43 30 33 30 02 80 41 02 01 03 32 41 43 37 42 30 31 33 30 32 31 37 35 31 38 20 20 00 02 17 00 05 01 18 80 05 00 01 c5 0e 50 6f 77 65 72 20 53 75 70 70 6c 79 20 41 17 19 00 0c 04 01 00 0e 0e 01 00 05 81 25 00 0c 18 01 00 0a 07 01 00 0c 19 0a 00 0f 0c 02 00 0d 0c 01 00 0c 10 01 00 08 04 01 01 0e 0e 01 01 05 81 08 01 0c 18 01 01 0a 07 01 01 0c 19 0a 01 0f 0e 01 02 09 03 00 02 0d 04 01 02 0e 19 1a 02 0f 03 02 03 0d 04 02 03 0e 02 01 03 0e 03 02 04 0d 04 02 04 0e 02 01 04 0e 41 72 72 61 79 20 44 65 76 69 63 65 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 42 4c 43 43 20 42 45 78 70 61 6e 64 65 72 20 50 68 79 45 78 70 61 6e 64 65 72 20 42 43 6f 6e 74 72 6f 6c 6c 65 72 20 42 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 42 44 69 73 70 6c 61 79 20 47 72 65 65 6e 44 69 73 70 6c 61 79 20 42 6c 75 65 4c 61 6e 67 75 61 67 65 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 41 4c 43 43 20 41 45 78 70 61 6e 64 65 72 20 50 68 79 45 78 70 61 6e 64 65 72 20 41 43 6f 6e 74 72 6f 6c 6c 65 72 20 41 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 41 45 6e 63 6c 6f 73 75 72 65 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 4d 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 4d 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 4d 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 42 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 42 50 6f 77 65 72 20 53 75 70 70 6c 79 20 42 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 41 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 41 50 6f 77 65 72 20 53 75 70 70 6c 79 20 41 2 | -------------------------------------------------------------------------------- /test/main.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "ata.h" 18 | #include "ata_parse.h" 19 | #include "main.h" 20 | #include "sense_dump.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | static unsigned char sense[128]; 31 | 32 | int debug = 1; 33 | 34 | bool submit_cmd(int fd, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_len, int dxfer_dir) 35 | { 36 | sg_io_hdr_t hdr; 37 | 38 | if (debug) 39 | cdb_dump(cdb, cdb_len); 40 | 41 | memset(&hdr, 0, sizeof(hdr)); 42 | 43 | hdr.interface_id = 'S'; 44 | hdr.dxfer_direction = dxfer_dir; 45 | hdr.cmd_len = cdb_len; 46 | hdr.mx_sb_len = sizeof(sense); 47 | hdr.dxfer_len = buf_len; 48 | hdr.dxferp = buf; 49 | hdr.cmdp = cdb; 50 | hdr.sbp = sense; 51 | hdr.timeout = 30*1000; 52 | hdr.flags = SG_FLAG_LUN_INHIBIT; 53 | hdr.pack_id = 0; 54 | hdr.usr_ptr = 0; 55 | 56 | ssize_t ret = write(fd, &hdr, sizeof(hdr)); 57 | return ret == sizeof(hdr); 58 | } 59 | 60 | bool read_response_buf(int fd, unsigned char **sensep, unsigned *sense_len, unsigned *buf_read) 61 | { 62 | *sensep = NULL; 63 | *sense_len = 0; 64 | 65 | sg_io_hdr_t hdr; 66 | int ret = read(fd, &hdr, sizeof(hdr)); 67 | if (ret != sizeof(hdr)) { 68 | fprintf(stderr, "Error reading scsi response, ret=%d, expected=%d, %m\n", ret, (int)sizeof(hdr)); 69 | return false; 70 | } 71 | 72 | printf("status: %d\n", hdr.status); 73 | printf("masked status: %d\n", hdr.masked_status); 74 | printf("driver status: %d\n", hdr.driver_status); 75 | printf("msg status: %d\n", hdr.msg_status); 76 | printf("host status: %d\n", hdr.host_status); 77 | printf("sense len: %d\n", hdr.sb_len_wr); 78 | 79 | if (hdr.sb_len_wr) { 80 | *sensep = sense; 81 | *sense_len = hdr.sb_len_wr; 82 | 83 | if (debug) { 84 | printf("sense data:\n"); 85 | sense_dump(sense, hdr.sb_len_wr); 86 | } 87 | } 88 | if (buf_read) 89 | *buf_read = hdr.dxfer_len - hdr.resid; 90 | return true; 91 | } 92 | 93 | static void test(const char *devname) 94 | { 95 | int fd = open(devname, O_RDWR); 96 | if (fd < 0) { 97 | fprintf(stderr, "Error opening device '%s': %m\n", devname); 98 | return; 99 | } 100 | 101 | do_command(fd); 102 | 103 | close(fd); 104 | } 105 | 106 | static int usage(char *name) 107 | { 108 | fprintf(stderr, "Usage:\n"); 109 | fprintf(stderr, "\t%s disk_device\n", name); 110 | return 1; 111 | } 112 | 113 | int main(int argc, char **argv) 114 | { 115 | if (argc != 2 || strstr(argv[1], "/sd") != NULL) 116 | return usage(argv[0]); 117 | 118 | test(argv[1]); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /src/smartdb/smartdb_gen_c.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import xml.etree.ElementTree as ET 5 | 6 | tree = ET.parse(sys.argv[1]) 7 | root = tree.getroot() 8 | 9 | assert root.tag == 'smartdb' 10 | 11 | names = {} 12 | defaults = {} 13 | 14 | raw_types = { 15 | 'hex48': 'SMART_ATTR_RAW_HEX48', 16 | 'dec48': 'SMART_ATTR_RAW_DEC48', 17 | } 18 | raw_type_default = 'dec48' 19 | def raw_type_to_enum(raw): 20 | return raw_types.get(raw) 21 | 22 | attr_code = { 23 | 'none': 'SMART_ATTR_TYPE_NONE', 24 | 'poh': 'SMART_ATTR_TYPE_POH', 25 | 'temperature': 'SMART_ATTR_TYPE_TEMP', 26 | 'reallocations': 'SMART_ATTR_TYPE_REALLOC', 27 | 'pending_reallocations': 'SMART_ATTR_TYPE_REALLOC_PENDING', 28 | 'crc_count': 'SMART_ATTR_TYPE_CRC_ERRORS', 29 | } 30 | attr_code_default = 'none' 31 | def attr_code_to_enum(code): 32 | try: 33 | return attr_code[code] 34 | except KeyError: 35 | sys.stderr.write('Cannot find key "%s" in the known attribute code list: %s\n' % (code, attr_code.keys())) 36 | raise 37 | 38 | def validate_name(c, root): 39 | assert root.tag == 'name' 40 | name = root.text.strip() 41 | assert len(name) > 0 42 | for child in root: 43 | assert False, 'node cant have a child' 44 | assert name not in names 45 | names[name] = root.get('type', attr_code_default) 46 | 47 | def validate_attr(d, root): 48 | assert root.tag == 'attr' 49 | aid = None 50 | name = None 51 | tempoffset = -1 52 | raw = raw_type_default 53 | code = attr_code_default 54 | for child in root: 55 | assert child.tag in ('id', 'name', 'raw', 'tempoffset') 56 | if child.tag == 'id': 57 | val = int(child.text) 58 | assert val > 0 59 | assert val <= 255 60 | aid = val 61 | elif child.tag == 'name': 62 | val = child.text.strip() 63 | assert val in names 64 | name = val 65 | code = names.get(name) 66 | elif child.tag == 'raw': 67 | val = child.text.strip() 68 | assert val in list(raw_types.keys()) 69 | raw = val 70 | elif child.tag == 'tempoffset': 71 | val = int(child.text) 72 | assert val > 0 and val < 255 73 | tempoffset = val 74 | d[aid] = (aid, name, raw, code, tempoffset) 75 | 76 | nodes = { 77 | 'names': validate_name, 78 | 'default': validate_attr, 79 | } 80 | 81 | for child in root: 82 | if child.tag not in list(nodes.keys()): 83 | raise 'tag %s is unknown at smartdb level' % child.tag 84 | vfunc = nodes.get(child.tag) 85 | for subchild in child: 86 | vfunc(defaults, subchild) 87 | 88 | print('#include "smartdb.h"') 89 | 90 | print('static const smart_table_t defaults = {') 91 | print('.num_attrs = %d,' % len(defaults)) 92 | print('.attrs = {') 93 | keys = list(defaults.keys()) 94 | keys.sort() 95 | for aid in keys: 96 | attr = defaults[aid] 97 | name = attr[1] 98 | raw = raw_type_to_enum(attr[2]) 99 | atype = attr_code_to_enum(attr[3]) 100 | tempoffset = attr[4] 101 | print('{.id=%d, .type=%s, .name="%s", .raw=%s, .offset=%d},' % (aid, atype, name, raw, tempoffset)) 102 | print('}') 103 | print('};') 104 | 105 | print('const smart_table_t * smart_table_for_disk(const char *vendor, const char *model, const char *firmware)') 106 | print('{') 107 | print('(void)vendor;') 108 | print('(void)model;') 109 | print('(void)firmware;') 110 | print('return &defaults;') 111 | print('}') 112 | -------------------------------------------------------------------------------- /src/smartdb/smartdb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Raw Read Error Rate 4 | Throughput Performance 5 | Spin Up Time 6 | Start/Stop Count 7 | Reallocated Sectors Count 8 | Seek Error Rate 9 | Seek Time Performance 10 | Power On Hours 11 | Spin Retry Count 12 | Device Power Cycle Count 13 | G Sense Error Rate 14 | Power Off Retract Count 15 | Load/Unload Cycle Count 16 | Temperature 17 | Reallocation Event Count 18 | Pending Sector Reallocation Count 19 | Off-Line Scan Uncorrecable Sector Count 20 | CRC Error Count 21 | Total LBAs Written 22 | Multi-zone Error Rate 23 | Drive Calibration Retry Count 24 | Free Fall Sensor 25 | Total LBAs Read 26 | Head Flying Hours 27 | Hardware ECC Recovered 28 | Read Soft Error Rate 29 | 30 | 31 | 32 | 33 | 1 34 | Raw Read Error Rate 35 | dec48 36 | 37 | 38 | 2 39 | Throughput Performance 40 | 41 | 42 | 3 43 | Spin Up Time 44 | 45 | 46 | 4 47 | Start/Stop Count 48 | 49 | 50 | 5 51 | Reallocated Sectors Count 52 | 53 | 54 | 7 55 | Seek Error Rate 56 | 57 | 58 | 8 59 | Seek Time Performance 60 | 61 | 62 | 9 63 | Power On Hours 64 | 65 | 66 | 10 67 | Spin Retry Count 68 | 69 | 70 | 11 71 | Drive Calibration Retry Count 72 | 73 | 74 | 12 75 | Device Power Cycle Count 76 | 77 | 78 | 13 79 | Read Soft Error Rate 80 | 81 | 82 | 191 83 | G Sense Error Rate 84 | 85 | 86 | 192 87 | Power Off Retract Count 88 | 89 | 90 | 193 91 | Load/Unload Cycle Count 92 | 93 | 94 | 194 95 | Temperature 96 | 150 97 | 98 | 99 | 195 100 | Hardware ECC Recovered 101 | 102 | 103 | 196 104 | Reallocation Event Count 105 | 106 | 107 | 197 108 | Pending Sector Reallocation Count 109 | 110 | 111 | 198 112 | Off-Line Scan Uncorrecable Sector Count 113 | 114 | 115 | 199 116 | CRC Error Count 117 | 118 | 119 | 200 120 | Multi-zone Error Rate 121 | 122 | 123 | 240 124 | Head Flying Hours 125 | 126 | 127 | 241 128 | Total LBAs Written 129 | 130 | 131 | 242 132 | Total LBAs Read 133 | 134 | 135 | 254 136 | Free Fall Sensor 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /test/scsi_log_sense.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2014 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | #include "scsicmd_utils.h" 19 | 20 | #include "main.h" 21 | #include "sense_dump.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | static void dump_page(int fd, uint8_t page, uint8_t subpage) 33 | { 34 | unsigned char cdb[32]; 35 | unsigned char buf[16*1024]; 36 | unsigned cdb_len = cdb_log_sense(cdb, page, subpage, sizeof(buf)); 37 | 38 | printf("List page %02X subpage %02X\n", page, subpage); 39 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 40 | if (!ret) { 41 | fprintf(stderr, "Failed to submit command\n"); 42 | return; 43 | } 44 | 45 | unsigned char *sense = NULL; 46 | unsigned sense_len = 0; 47 | unsigned buf_len = 0; 48 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 49 | 50 | if (sense) { 51 | printf("error while reading response buffer, nothing to show\n"); 52 | return; 53 | } 54 | 55 | printf("Read %u bytes\n", buf_len); 56 | response_dump(buf, buf_len); 57 | printf("\n"); 58 | } 59 | 60 | void do_command(int fd) 61 | { 62 | unsigned char cdb[32]; 63 | unsigned char buf[16*1024]; 64 | unsigned cdb_len = cdb_log_sense(cdb, 0, 0, sizeof(buf)); 65 | 66 | printf("List all supported pages\n"); 67 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 68 | if (!ret) { 69 | fprintf(stderr, "Failed to submit command\n"); 70 | return; 71 | } 72 | 73 | unsigned char *sense = NULL; 74 | unsigned sense_len = 0; 75 | unsigned buf_len = 0; 76 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 77 | 78 | if (sense) { 79 | printf("error while reading response buffer, nothing to show\n"); 80 | return; 81 | } 82 | 83 | printf("Read %u bytes\n", buf_len); 84 | response_dump(buf, buf_len); 85 | 86 | if (buf_len < 4) { 87 | printf("log sense list must have at least 4 bytes\n"); 88 | return; 89 | } 90 | 91 | if (buf[0] != 0 || buf[1] != 0) { 92 | printf("expected to receive log page 0 subpage 0\n"); 93 | return; 94 | } 95 | 96 | uint16_t num_pages = get_uint16(buf, 2); 97 | uint16_t i; 98 | for (i = 0; i < num_pages; i++) { 99 | dump_page(fd, buf[4 + i], 0); 100 | } 101 | 102 | printf("List all pages and subpages\n"); 103 | cdb_len = cdb_log_sense(cdb, 0, 0xff, sizeof(buf)); 104 | 105 | ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 106 | if (!ret) { 107 | fprintf(stderr, "Failed to submit command\n"); 108 | return; 109 | } 110 | 111 | sense = NULL; 112 | sense_len = 0; 113 | buf_len = 0; 114 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 115 | 116 | if (sense) { 117 | printf("error while reading response buffer, nothing to show\n"); 118 | return; 119 | } 120 | 121 | printf("Read %u bytes\n", buf_len); 122 | 123 | response_dump(buf, buf_len); 124 | 125 | if (buf_len < 4) { 126 | printf("log sense list must have at least 4 bytes\n"); 127 | return; 128 | } 129 | 130 | if (buf[0] != 0x40 || buf[1] != 0xFF) { 131 | printf("expected to receive log page 0 (spf=1) subpage 0xFF\n"); 132 | return; 133 | } 134 | 135 | num_pages = get_uint16(buf, 2); 136 | for (i = 0; i < num_pages; i++) { 137 | uint8_t page = buf[4 + i*2] & 0x3F; 138 | uint8_t subpage = buf[4 + i*2 + 1]; 139 | if (subpage == 0) { 140 | printf("Skipping page %02X subpage %02X since subpage is 00 it was already retrieved above\n", page, subpage); 141 | continue; 142 | } 143 | dump_page(fd, page, subpage); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/ata.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "ata.h" 18 | #include 19 | #include 20 | 21 | 22 | bool ata_inquiry_checksum_verify(const unsigned char *buf, int buf_len) 23 | { 24 | if (buf_len != 512) 25 | return false; 26 | 27 | if (buf[511] != 0xA5) { 28 | // Checksum isn't claimed to be valid, nothing to check here 29 | return true; 30 | } 31 | 32 | return ata_checksum_verify(buf); 33 | } 34 | 35 | bool ata_status_from_scsi_sense(unsigned char *sense, int sense_len, ata_status_t *status) 36 | { 37 | sense_info_t sense_info; 38 | 39 | assert(status); 40 | 41 | bool parsed = scsi_parse_sense(sense, sense_len, &sense_info); 42 | 43 | if (parsed && sense_info.ata_status_valid) { 44 | *status = sense_info.ata_status; 45 | return true; 46 | } 47 | if (sense_info.is_fixed) { 48 | // Fixed format parsing for ATA passthrough can't be known automatically 49 | memset(status, 0, sizeof(*status)); 50 | status->error = sense_info.information & 0xFF; 51 | status->status = (sense_info.information >> 8) & 0xFF; 52 | status->device = (sense_info.information >> 16) & 0xFF; 53 | 54 | status->sector_count = (sense_info.information >> 24) & 0xFF; 55 | 56 | status->extend = sense_info.cmd_specific & 0x80; 57 | uint32_t lba_high = (sense_info.cmd_specific >> 8) & 0xFF; 58 | uint32_t lba_mid = (sense_info.cmd_specific >> 16) & 0xFF; 59 | uint32_t lba_low = (sense_info.cmd_specific >> 24) & 0xFF; 60 | status->lba = (lba_high << 16) | (lba_mid << 8) | lba_low; 61 | 62 | // TODO: sector_count_upper_non_zero: sense_info.cmd_specific & 0x40 63 | // TODO: lba upper non zero: sense_info.cmd_specific & 0x20 64 | // TODO: log index: sense_info.cmd_specific & 0x07 65 | } 66 | 67 | return false; 68 | } 69 | 70 | /* ATA SMART READ DATA */ 71 | 72 | uint16_t ata_get_ata_smart_read_data_version(const unsigned char *buf) 73 | { 74 | return ata_get_word(buf, 0); 75 | } 76 | 77 | int ata_parse_ata_smart_read_data(const unsigned char *buf, ata_smart_attr_t *attrs, int max_attrs) 78 | { 79 | if (!ata_check_ata_smart_read_data_checksum(buf)) 80 | return -1; 81 | 82 | if (ata_get_ata_smart_read_data_version(buf) != 0x0010) 83 | return -1; 84 | 85 | int i, j; 86 | 87 | for (i = 0, j = 0; i < MAX_SMART_ATTRS && i < max_attrs; i++) { 88 | const unsigned char *raw_attr = buf + 2 + 12*i; 89 | ata_smart_attr_t *attr = &attrs[j]; 90 | 91 | attr->id = raw_attr[0]; 92 | if (attr->id == 0) // Skip an invalid attribute 93 | continue; 94 | attr->status = raw_attr[1] | raw_attr[2]<<8; 95 | attr->value = raw_attr[3]; 96 | attr->min = raw_attr[4]; 97 | attr->raw = (raw_attr[5]) | 98 | (raw_attr[6] << 8) | 99 | (raw_attr[7] << 16) | 100 | (raw_attr[8] << 24) | 101 | ((uint64_t)raw_attr[9] << 32) | 102 | ((uint64_t)raw_attr[10] << 40); 103 | 104 | j++; 105 | } 106 | 107 | return j; 108 | } 109 | 110 | int ata_parse_ata_smart_read_thresh(const unsigned char *buf, ata_smart_thresh_t *attrs, int max_attrs) 111 | { 112 | if (!ata_check_ata_smart_read_data_checksum(buf)) 113 | return -1; 114 | 115 | if (ata_get_ata_smart_read_data_version(buf) != 0x0010) 116 | return -1; 117 | 118 | int i, j; 119 | 120 | for (i = 0, j = 0; i < MAX_SMART_ATTRS && i < max_attrs; i++) { 121 | const unsigned char *raw_attr = buf + 2 + 12*i; 122 | ata_smart_thresh_t *attr = &attrs[j]; 123 | 124 | attr->id = raw_attr[0]; 125 | if (attr->id == 0) // Skip an invalid attribute 126 | continue; 127 | attr->threshold = raw_attr[1]; 128 | 129 | j++; 130 | } 131 | 132 | return j; 133 | } 134 | -------------------------------------------------------------------------------- /include/parse_receive_diagnostics.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #ifndef LIBSCSICMD_RECEIVE_DIAGNOSTICS_H 18 | #define LIBSCSICMD_RECEIVE_DIAGNOSTICS_H 19 | 20 | #include "scsicmd_utils.h" 21 | #include 22 | #include 23 | 24 | #define RECV_DIAG_MIN_LEN 4 25 | 26 | static inline uint8_t recv_diag_get_page_code(uint8_t *data) 27 | { 28 | return data[0]; 29 | } 30 | 31 | static inline uint8_t recv_diag_get_page_code_specific(uint8_t *data) 32 | { 33 | return data[1]; 34 | } 35 | 36 | static inline uint16_t recv_diag_get_len(uint8_t *data) 37 | { 38 | return (data[2] << 8) | data[3]; 39 | } 40 | 41 | static inline uint8_t *recv_diag_data(uint8_t *data) 42 | { 43 | return data + RECV_DIAG_MIN_LEN; 44 | } 45 | 46 | static inline bool recv_diag_is_valid(uint8_t *data, unsigned data_len) 47 | { 48 | if (data_len < RECV_DIAG_MIN_LEN) 49 | return false; 50 | if ((unsigned)recv_diag_get_len(data) + RECV_DIAG_MIN_LEN > data_len) 51 | return false; 52 | return true; 53 | } 54 | 55 | /* SES Page 1 Configuration */ 56 | 57 | static inline bool ses_config_is_valid(uint8_t *data, unsigned data_len) 58 | { 59 | if (data_len < 8) 60 | return false; 61 | if (recv_diag_get_len(data) < 4) 62 | return false; 63 | return true; 64 | } 65 | 66 | static inline uint8_t ses_config_num_sub_enclosures(uint8_t *data) 67 | { 68 | return data[1] + 1; // +1 for primary 69 | } 70 | 71 | static inline uint32_t ses_config_generation(uint8_t *data) 72 | { 73 | return get_uint32(data, 4); 74 | } 75 | 76 | static inline uint8_t *ses_config_sub_enclosure(uint8_t *data) 77 | { 78 | return data + 8; 79 | } 80 | 81 | /* Enclosure Descriptor */ 82 | static inline uint8_t ses_config_enclosure_descriptor_process_identifier(uint8_t *data) 83 | { 84 | return (data[0] >> 4) & 0x7; 85 | } 86 | 87 | static inline uint8_t ses_config_enclosure_descriptor_num_processes(uint8_t *data) 88 | { 89 | return data[0] & 0x7; 90 | } 91 | 92 | static inline uint8_t ses_config_enclosure_descriptor_subenclosure_identifier(uint8_t *data) 93 | { 94 | return data[1]; 95 | } 96 | 97 | static inline uint8_t ses_config_enclosure_descriptor_num_type_descriptors(uint8_t *data) 98 | { 99 | return data[2]; 100 | } 101 | 102 | static inline uint8_t ses_config_enclosure_descriptor_len(uint8_t *data) 103 | { 104 | return data[3]; 105 | } 106 | 107 | static inline uint64_t ses_config_enclosure_descriptor_logical_identifier(uint8_t *data) 108 | { 109 | return get_uint64(data, 4); 110 | } 111 | 112 | static inline bool ses_config_enclosure_descriptor_is_valid(uint8_t *data, unsigned data_len) 113 | { 114 | if (data_len < 12) 115 | return false; 116 | if (ses_config_enclosure_descriptor_len(data) < 36 || 117 | ses_config_enclosure_descriptor_len(data) > 252 || 118 | ses_config_enclosure_descriptor_len(data) > data_len) 119 | { 120 | return false; 121 | } 122 | return true; 123 | } 124 | 125 | static inline void _ses_str_cpy(uint8_t *src, unsigned src_len, char *s, unsigned slen) 126 | { 127 | if (slen > src_len) 128 | slen = src_len; 129 | else 130 | slen--; 131 | 132 | memcpy(s, src, slen); 133 | s[slen] = 0; 134 | } 135 | 136 | static inline void ses_config_enclosure_descriptor_vendor_identifier(uint8_t *data, char *s, unsigned slen) 137 | { 138 | _ses_str_cpy(data+12, 8, s, slen); 139 | } 140 | 141 | static inline void ses_config_enclosure_descriptor_product_identifier(uint8_t *data, char *s, unsigned slen) 142 | { 143 | _ses_str_cpy(data+20, 16, s, slen); 144 | } 145 | 146 | static inline void ses_config_enclosure_descriptor_revision_level(uint8_t *data, char *s, unsigned slen) 147 | { 148 | _ses_str_cpy(data+36, 4, s, slen); 149 | } 150 | 151 | static inline uint8_t *ses_config_enclosure_descriptor_vendor_info(uint8_t *data) 152 | { 153 | return data + 40; 154 | } 155 | 156 | static inline uint8_t ses_config_enclosure_descriptor_vendor_len(uint8_t *data) 157 | { 158 | return ses_config_enclosure_descriptor_len(data) + 4 - 40; 159 | } 160 | 161 | #endif 162 | -------------------------------------------------------------------------------- /include/parse_log_sense.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #ifndef LIBSCSICMD_LOG_SENSE_H 18 | #define LIBSCSICMD_LOG_SENSE_H 19 | 20 | #include "scsicmd_utils.h" 21 | #include 22 | #include 23 | 24 | /* Log Sense Header decode */ 25 | 26 | #define LOG_SENSE_MIN_LEN 4 27 | 28 | static inline uint8_t log_sense_page_code(uint8_t *data) 29 | { 30 | return data[0] & 0x3F; 31 | } 32 | 33 | static inline bool log_sense_subpage_format(uint8_t *data) 34 | { 35 | return data[0] & 0x40; 36 | } 37 | 38 | static inline bool log_sense_data_saved(uint8_t *data) 39 | { 40 | return data[0] & 0x80; 41 | } 42 | 43 | static inline uint8_t log_sense_subpage_code(uint8_t *data) 44 | { 45 | return data[1]; 46 | } 47 | 48 | static inline unsigned log_sense_data_len(uint8_t *data) 49 | { 50 | return get_uint16(data, 2); 51 | } 52 | 53 | static inline uint8_t *log_sense_data(uint8_t *data) 54 | { 55 | return data + LOG_SENSE_MIN_LEN; 56 | } 57 | 58 | static inline uint8_t *log_sense_data_end(uint8_t *data, unsigned data_len) 59 | { 60 | return data + safe_len(data, data_len, log_sense_data(data), log_sense_data_len(data)); 61 | } 62 | 63 | static inline bool log_sense_is_valid(uint8_t *data, unsigned data_len) 64 | { 65 | if (data_len < LOG_SENSE_MIN_LEN) 66 | return false; 67 | if (!log_sense_subpage_format(data) && log_sense_subpage_code(data) != 0) 68 | return false; 69 | if (log_sense_data_len(data) + LOG_SENSE_MIN_LEN < data_len) 70 | return false; 71 | return true; 72 | } 73 | 74 | /* Log Sense Parameter decode */ 75 | #define LOG_SENSE_MIN_PARAM_LEN 4 76 | 77 | #define LOG_PARAM_FLAG_DU 0x80 78 | #define LOG_PARAM_FLAG_TSD 0x20 79 | #define LOG_PARAM_FLAG_ETC 0x10 80 | #define LOG_PARAM_FLAG_TMC_MASK 0x0C 81 | #define LOG_PARAM_FLAG_FMT_MASK 0x03 82 | 83 | #define LOG_PARAM_TMC_EVERY_UPDATE 0 84 | #define LOG_PARAM_TMC_EQUAL 1 85 | #define LOG_PARAM_TMC_NOT_EQUAL 2 86 | #define LOG_PARAM_TMC_GREATER 3 87 | 88 | #define LOG_PARAM_FMT_COUNTER_STOP 0 89 | #define LOG_PARAM_FMT_ASCII 1 90 | #define LOG_PARAM_FMT_COUNTER_ROLLOVER 2 91 | #define LOG_PARAM_FMT_BINARY 2 92 | 93 | static inline uint16_t log_sense_param_code(uint8_t *param) 94 | { 95 | return get_uint16(param, 0); 96 | } 97 | 98 | inline static uint8_t log_sense_param_flags(uint8_t *param) 99 | { 100 | return param[2]; 101 | } 102 | 103 | inline static uint8_t log_sense_param_tmc(uint8_t *param) 104 | { 105 | return (log_sense_param_flags(param) & LOG_PARAM_FLAG_TMC_MASK) >> 2; 106 | } 107 | 108 | inline static uint8_t log_sense_param_fmt(uint8_t *param) 109 | { 110 | return log_sense_param_flags(param) & LOG_PARAM_FLAG_FMT_MASK; 111 | } 112 | 113 | static inline unsigned log_sense_param_len(uint8_t *param) 114 | { 115 | return param[3]; 116 | } 117 | 118 | static inline uint8_t *log_sense_param_data(uint8_t *param) 119 | { 120 | return param + LOG_SENSE_MIN_PARAM_LEN; 121 | } 122 | 123 | static inline bool log_sense_param_is_valid(uint8_t *data, unsigned data_len, uint8_t *param) 124 | { 125 | if (param < data) 126 | return false; 127 | 128 | const unsigned param_offset = param - data; 129 | if (param_offset > data_len) 130 | return false; 131 | 132 | if (param_offset + LOG_SENSE_MIN_PARAM_LEN > data_len) 133 | return false; 134 | 135 | if (param_offset + LOG_SENSE_MIN_PARAM_LEN + log_sense_param_len(param) > data_len) 136 | return false; 137 | 138 | return true; 139 | } 140 | 141 | #define for_all_log_sense_params(data, data_len, param) \ 142 | for (param = log_sense_data(data); \ 143 | log_sense_param_is_valid(data, data_len, param); \ 144 | param = param + LOG_SENSE_MIN_PARAM_LEN + log_sense_param_len(param)) 145 | 146 | #define for_all_log_sense_pg_0_supported_pages(data, data_len, supported_page) \ 147 | uint8_t *__tmp; \ 148 | for (__tmp = log_sense_data(data), supported_page = __tmp[0]; __tmp < log_sense_data_end(data, data_len); __tmp++, supported_page = __tmp[0]) 149 | 150 | #define for_all_log_sense_pg_0_supported_subpages(data, data_len, supported_page, supported_subpage) \ 151 | uint8_t *__tmp; \ 152 | for (__tmp = log_sense_data(data), supported_page = __tmp[0], supported_subpage = __tmp[1]; __tmp + 1 < log_sense_data_end(data, data_len); __tmp+=2, supported_page = __tmp[0], supported_subpage = __tmp[1]) 153 | 154 | bool log_sense_page_informational_exceptions(uint8_t *page, unsigned page_len, uint8_t *asc, uint8_t *ascq, uint8_t *temperature); 155 | 156 | #endif 157 | -------------------------------------------------------------------------------- /test/sense_dump.c: -------------------------------------------------------------------------------- 1 | #include "sense_dump.h" 2 | #include "scsicmd.h" 3 | #include 4 | #include 5 | 6 | void cdb_dump(unsigned char *cdb, int cdb_len) 7 | { 8 | int i; 9 | 10 | printf("CDB: "); 11 | for (i = 0; i < cdb_len; i++) { 12 | printf("%02x ", cdb[i]); 13 | } 14 | printf("\n"); 15 | } 16 | 17 | void response_dump(unsigned char *buf, int buf_len) 18 | { 19 | int i; 20 | for (i = 0; i < buf_len; i++) { 21 | if (i % 16 == 0) 22 | printf("\n%02x ", i); 23 | printf("%02x ", buf[i]); 24 | } 25 | printf("\n"); 26 | } 27 | 28 | static bool print_bool(const char *name, bool val) 29 | { 30 | printf("%s: %s\n", name, val ? "yes" : "no"); 31 | return val; 32 | } 33 | 34 | static bool print_code(const char *name, bool val, const char *true_code, const char *false_code) 35 | { 36 | printf("%s: %s\n", name, val ? true_code : false_code); 37 | return val; 38 | } 39 | 40 | static void sense_dump_sense_info(sense_info_t *si) 41 | { 42 | print_code("Type", si->is_fixed, "Fixed", "Descriptor"); 43 | print_code("Time", si->is_current, "Current", "Deferred"); 44 | printf("Code: %x/%02x/%02x\n", si->sense_key, si->asc, si->ascq); 45 | printf("Code: %s/%s\n", sense_key_to_name(si->sense_key), asc_num_to_name(si->asc, si->ascq)); 46 | printf("Vendor Unique: 0x%04x\n", si->vendor_unique_error); 47 | if (si->information_valid) 48 | printf("Information: %"PRIx64"\n", si->information); 49 | if (si->cmd_specific_valid) 50 | printf("Command specific: %"PRIx64"\n", si->cmd_specific); 51 | if (si->sense_key_specific_valid) { 52 | 53 | switch (si->sense_key) { 54 | case SENSE_KEY_ILLEGAL_REQUEST: 55 | print_code("Illegal Request Type", si->sense_key_specific.illegal_request.command_error, "CDB", "Data"); 56 | if (si->sense_key_specific.illegal_request.bit_pointer_valid) 57 | printf("Illegal Request Bit: %d\n", si->sense_key_specific.illegal_request.bit_pointer); 58 | printf("Illegal Request Field: %d\n", si->sense_key_specific.illegal_request.field_pointer); 59 | break; 60 | case SENSE_KEY_HARDWARE_ERROR: 61 | case SENSE_KEY_MEDIUM_ERROR: 62 | case SENSE_KEY_RECOVERED_ERROR: 63 | printf("Actual Retry Count: %d\n", si->sense_key_specific.hardware_medium_recovered_error.actual_retry_count); 64 | break; 65 | case SENSE_KEY_NOT_READY: 66 | case SENSE_KEY_NO_SENSE: 67 | printf("Progress: %g%%\n", si->sense_key_specific.not_ready.progress); 68 | break; 69 | case SENSE_KEY_COPY_ABORTED: 70 | print_code("Copy Aborted Type", si->sense_key_specific.copy_aborted.segment_descriptor, "Segment", "Descriptor"); 71 | if (si->sense_key_specific.copy_aborted.bit_pointer_valid) 72 | printf("Copy Aborted Bit: %d\n", si->sense_key_specific.copy_aborted.bit_pointer); 73 | printf("Copy Aborted Field: %d\n", si->sense_key_specific.copy_aborted.field_pointer); 74 | break; 75 | case SENSE_KEY_UNIT_ATTENTION: 76 | print_bool("Unit Attention Overflow", si->sense_key_specific.unit_attention.overflow); 77 | break; 78 | } 79 | } 80 | 81 | if (si->fru_code_valid) 82 | printf("FRU Code: %02x\n", si->fru_code); 83 | 84 | if (si->ata_status_valid) { 85 | printf("ATA Status valid\n"); /*TODO: more details */ 86 | printf("ATA\n"); 87 | printf(" Extend: %02x\n", si->ata_status.extend); 88 | printf(" Error: %02x\n", si->ata_status.error); 89 | printf(" Device: %02x\n", si->ata_status.device); 90 | printf(" Status: %02x\n", si->ata_status.status); 91 | printf(" Sector Count: %u\n", si->ata_status.sector_count); 92 | printf(" LBA: %"PRIu64" / %"PRIx64"\n", si->ata_status.lba, si->ata_status.lba); 93 | } 94 | 95 | print_bool("Incorrect Length Indicator", si->incorrect_len_indicator); 96 | } 97 | 98 | void sense_dump(unsigned char *sense, int sense_len) 99 | { 100 | printf("Raw sense buffer:\n"); 101 | response_dump(sense, sense_len); 102 | printf("\n"); 103 | 104 | sense_info_t si; 105 | bool success = scsi_parse_sense(sense, sense_len, &si); 106 | printf("Parsing succeeded: %s\n", success ? "yes" : "no"); 107 | sense_dump_sense_info(&si); 108 | } 109 | -------------------------------------------------------------------------------- /test/ata_smart_read_data.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "ata.h" 18 | #include "ata_parse.h" 19 | #include "ata_smart.h" 20 | #include "sense_dump.h" 21 | #include "main.h" 22 | #include "smartdb.h" 23 | #include 24 | #include 25 | #include 26 | 27 | static bool read_data(int fd, unsigned char *buf, int buf_len) 28 | { 29 | unsigned char cdb[12]; 30 | 31 | int cdb_len = cdb_ata_smart_read_data(cdb); 32 | 33 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, buf_len, SG_DXFER_FROM_DEV); 34 | if (!ret) { 35 | fprintf(stderr, "Failed to submit command\n"); 36 | return false; 37 | } 38 | 39 | unsigned char *sense; 40 | unsigned sense_len; 41 | ret = read_response(fd, &sense, &sense_len); 42 | if (!ret) { 43 | fprintf(stderr, "Error reading scsi response\n"); 44 | return false; 45 | } 46 | 47 | printf("Response Dump:\n"); 48 | response_dump(buf, sizeof(buf)); 49 | 50 | printf("Page checksum read: %02X\n", ata_get_ata_smart_read_data_checksum(buf)); 51 | printf("Page checksum calc: %02X\n", ata_calc_checksum(buf)); 52 | printf("Page checksum matches: %s\n", ata_check_ata_smart_read_data_checksum(buf) ? "true" : "false"); 53 | printf("Page version: %04Xh\n", ata_get_ata_smart_read_data_version(buf)); 54 | if (ata_get_ata_smart_read_data_version(buf) != 0x10) { 55 | printf("Unknown page version, only known version is 10h\n"); 56 | return false; 57 | } 58 | 59 | return true; 60 | } 61 | 62 | static bool read_threshold(int fd, unsigned char *buf, int buf_len) 63 | { 64 | unsigned char cdb[12]; 65 | 66 | int cdb_len = cdb_ata_smart_read_threshold(cdb); 67 | 68 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, buf_len, SG_DXFER_FROM_DEV); 69 | if (!ret) { 70 | fprintf(stderr, "Failed to submit command\n"); 71 | return false; 72 | } 73 | 74 | unsigned char *sense; 75 | unsigned sense_len; 76 | ret = read_response(fd, &sense, &sense_len); 77 | if (!ret) { 78 | fprintf(stderr, "Error reading scsi response\n"); 79 | return false; 80 | } 81 | 82 | printf("Response Dump:\n"); 83 | response_dump(buf, sizeof(buf)); 84 | 85 | printf("Page checksum read: %02X\n", ata_get_ata_smart_read_data_checksum(buf)); 86 | printf("Page checksum calc: %02X\n", ata_calc_checksum(buf)); 87 | printf("Page checksum matches: %s\n", ata_check_ata_smart_read_data_checksum(buf) ? "true" : "false"); 88 | printf("Page version: %04Xh\n", ata_get_ata_smart_read_data_version(buf)); 89 | if (ata_get_ata_smart_read_data_version(buf) != 0x10) { 90 | printf("Unknown page version, only known version is 10h\n"); 91 | return false; 92 | } 93 | return true; 94 | } 95 | 96 | void do_command(int fd) 97 | { 98 | unsigned char buf_thresh[512]; 99 | unsigned char buf_data[512]; 100 | 101 | if (!read_data(fd, buf_data, sizeof(buf_data))) 102 | return; 103 | 104 | if (!read_threshold(fd, buf_thresh, sizeof(buf_thresh))) 105 | return; 106 | 107 | const smart_table_t *table = smart_table_for_disk(NULL, NULL, NULL); 108 | 109 | ata_smart_attr_t attrs[MAX_SMART_ATTRS]; 110 | int num_attrs1 = ata_parse_ata_smart_read_data(buf_data, attrs, MAX_SMART_ATTRS); 111 | 112 | ata_smart_thresh_t thresholds[MAX_SMART_ATTRS]; 113 | int num_attrs2 = ata_parse_ata_smart_read_thresh(buf_thresh, thresholds, MAX_SMART_ATTRS); 114 | 115 | 116 | if (num_attrs1 != num_attrs2) { 117 | printf("Number of attributes in data (%d) and thresholds (%d) do not match\n", num_attrs1, num_attrs2); 118 | return; 119 | } 120 | 121 | printf("num attributes %d\n", num_attrs1); 122 | int i; 123 | for (i = 0; i < num_attrs1; i++) { 124 | const ata_smart_attr_t *attr = &attrs[i]; 125 | const ata_smart_thresh_t *thresh = &thresholds[i]; 126 | const smart_attr_t *attr_type = smart_attr_for_id(table, attr->id); 127 | printf("Attribute #%2d: id %3u %-40s status %04X val %3u min %3u thresh %3u raw %"PRIu64"\n", i, attr->id, attr_type ? attr_type->name : "Unknown", attr->status, attr->value, attr->min, thresh->threshold, attr->raw); 128 | } 129 | 130 | 131 | printf("\nKey attributes:\n"); 132 | { 133 | int min_temp, max_temp, cur_temp; 134 | cur_temp = ata_smart_get_temperature(attrs, num_attrs1, table, &min_temp, &max_temp); 135 | printf(" Temperature: %d (min=%d max=%d)\n", cur_temp, min_temp, max_temp); 136 | } 137 | { 138 | int minutes = -1; 139 | int hours; 140 | hours = ata_smart_get_power_on_hours(attrs, num_attrs1, table, &minutes); 141 | printf(" POH: %d (minutes: %d)\n", hours, minutes); 142 | } 143 | printf(" # Reallocations: %d\n", ata_smart_get_num_reallocations(attrs, num_attrs1, table)); 144 | printf(" # Pending Reallocations: %d\n", ata_smart_get_num_pending_reallocations(attrs, num_attrs1, table)); 145 | printf(" # CRC Errors: %d\n", ata_smart_get_num_crc_errors(attrs, num_attrs1, table)); 146 | } 147 | -------------------------------------------------------------------------------- /afl/testcase/id:000018,sig:11,src:001807,op:flip1,pos:93: -------------------------------------------------------------------------------- 1 | ,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 94 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 -------------------------------------------------------------------------------- /afl/testcase/id:000019,sig:11,src:001807,op:flip1,pos:670: -------------------------------------------------------------------------------- 1 | ,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 16 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 -------------------------------------------------------------------------------- /afl/testcase/id:000020,sig:11,src:001807,op:flip1,pos:2325: -------------------------------------------------------------------------------- 1 | ,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 94 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 -------------------------------------------------------------------------------- /afl/testcase/id:000021,sig:11,src:001807,op:flip2,pos:238: -------------------------------------------------------------------------------- 1 | ,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 12 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 -------------------------------------------------------------------------------- /test/scsi_inquiry.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | #include "main.h" 19 | #include "sense_dump.h" 20 | #include "parse_extended_inquiry.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | static void dump_evpd_ascii(unsigned char *data, uint16_t data_len) 33 | { 34 | const uint16_t ascii_len = (data[0] << 8) | data[1]; 35 | bool not_in_string = true; 36 | uint16_t i; 37 | 38 | printf("ASCII len: %u\n", ascii_len); 39 | printf("ASCII data: \""); 40 | for (i = 2; i < ascii_len + 2; i++) 41 | putchar(data[i]); 42 | printf("\"\n"); 43 | 44 | for (; i < data_len; i++) { 45 | if (isprint(data[i])) { 46 | if (not_in_string) { 47 | printf("Vendor string: \""); 48 | not_in_string = false; 49 | } 50 | putchar(data[i]); 51 | } else { 52 | if (!not_in_string) { 53 | printf("\"\n"); 54 | not_in_string = true; 55 | } 56 | } 57 | } 58 | if (!not_in_string) 59 | printf("\"\n"); 60 | } 61 | 62 | static void dump_evpd(int fd, uint8_t page) 63 | { 64 | unsigned char cdb[32]; 65 | unsigned char buf[512] ; 66 | unsigned cdb_len = cdb_inquiry(cdb, true, page, sizeof(buf)); 67 | 68 | printf("\n\nExtended Inquiry Page %u (%02x):\n", page, page); 69 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 70 | if (!ret) { 71 | fprintf(stderr, "Failed to submit command\n"); 72 | return; 73 | } 74 | 75 | unsigned char *sense = NULL; 76 | unsigned sense_len = 0; 77 | unsigned buf_len = 0; 78 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 79 | 80 | if (sense) { 81 | printf("error while reading response buffer, nothing to show\n"); 82 | return; 83 | } 84 | 85 | printf("Read %u bytes\n", buf_len); 86 | 87 | response_dump(buf, buf_len); 88 | 89 | if (buf_len < EVPD_MIN_LEN) { 90 | printf("Buffer returned is too small, got %d expected minimum of %d", buf_len, EVPD_MIN_LEN); 91 | return; 92 | } 93 | 94 | if (page >= 0x01 && page <= 0x7F) { 95 | dump_evpd_ascii(evpd_page_data(buf), evpd_page_len(buf)); 96 | } 97 | } 98 | 99 | static void do_extended_inquiry(int fd) 100 | { 101 | unsigned char cdb[32]; 102 | unsigned char buf[512] ; 103 | unsigned cdb_len = cdb_inquiry(cdb, true, 0, sizeof(buf)); 104 | 105 | printf("\n\nExtended Inquiry:\n"); 106 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 107 | if (!ret) { 108 | fprintf(stderr, "Failed to submit command\n"); 109 | return; 110 | } 111 | 112 | unsigned char *sense = NULL; 113 | unsigned sense_len = 0; 114 | unsigned buf_len = 0; 115 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 116 | 117 | if (sense) { 118 | printf("error while reading response buffer, nothing to show\n"); 119 | return; 120 | } 121 | 122 | printf("Read %u bytes\n", buf_len); 123 | 124 | response_dump(buf, buf_len); 125 | 126 | if (buf_len < EVPD_MIN_LEN) { 127 | printf("Buffer returned is too small, got %d expected minimum of %d", buf_len, EVPD_MIN_LEN); 128 | return; 129 | } 130 | 131 | printf("Peripheral Qualifier: %u\n", evpd_peripheral_qualifier(buf)); 132 | printf("Peripheral Device Type: %u\n", evpd_peripheral_device_type(buf)); 133 | 134 | uint16_t max_page_idx = evpd_page_len(buf) + 4; 135 | uint16_t i; 136 | for (i = 4; i < max_page_idx; i++) 137 | dump_evpd(fd, buf[i]); 138 | } 139 | 140 | static void do_simple_inquiry(int fd) 141 | { 142 | unsigned char cdb[32]; 143 | unsigned char buf[512] ; 144 | unsigned cdb_len = cdb_inquiry_simple(cdb, 96); 145 | 146 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); 147 | if (!ret) { 148 | fprintf(stderr, "Failed to submit command\n"); 149 | return; 150 | } 151 | 152 | unsigned char *sense = NULL; 153 | unsigned sense_len = 0; 154 | unsigned buf_len = 0; 155 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); 156 | 157 | if (sense) { 158 | printf("error while reading response buffer, nothing to show\n"); 159 | return; 160 | } 161 | 162 | printf("Read %u bytes\n", buf_len); 163 | response_dump(buf, buf_len); 164 | 165 | int device_type; 166 | scsi_vendor_t vendor; 167 | scsi_model_t model; 168 | scsi_fw_revision_t rev; 169 | scsi_serial_t serial; 170 | bool parsed = parse_inquiry(buf, buf_len, &device_type, vendor, model, rev, serial); 171 | if (!parsed) { 172 | printf("Failed to parse INQUIRY buffer\n"); 173 | return; 174 | } 175 | 176 | printf("Device Type: %d - %s\n", device_type, scsi_device_type_name(device_type)); 177 | printf("Vendor: %s\n", vendor); 178 | printf("Model: %s\n", model); 179 | printf("Rev: %s\n", rev); 180 | printf("Serial: %s\n", serial); 181 | } 182 | 183 | void do_command(int fd) 184 | { 185 | do_simple_inquiry(fd); 186 | do_extended_inquiry(fd); 187 | } 188 | -------------------------------------------------------------------------------- /include/parse_read_defect_data.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #ifndef LIBSCSICMD_READ_DEFECT_DATA_H 18 | #define LIBSCSICMD_READ_DEFECT_DATA_H 19 | 20 | #include "scsicmd_utils.h" 21 | #include "scsicmd.h" 22 | #include 23 | #include 24 | 25 | const char *read_defect_data_format_to_str(uint8_t fmt); 26 | 27 | /* READ DEFECT DATA 10 */ 28 | 29 | #define READ_DEFECT_DATA_10_MIN_LEN 4 30 | 31 | static inline bool read_defect_data_10_is_plist_valid(uint8_t *data) 32 | { 33 | return data[1] & 0x10; 34 | } 35 | 36 | static inline bool read_defect_data_10_is_glist_valid(uint8_t *data) 37 | { 38 | return data[1] & 0x08; 39 | } 40 | 41 | static inline uint8_t read_defect_data_10_list_format(uint8_t *data) 42 | { 43 | return data[1] & 0x07; 44 | } 45 | 46 | static inline uint16_t read_defect_data_10_len(uint8_t *data) 47 | { 48 | return get_uint16(data, 2); 49 | } 50 | 51 | /* For READ DEFECT DATA 10 the user may ask for only the header and the data is never really transfered, allow for this seperation in the checks. */ 52 | static inline bool read_defect_data_10_hdr_is_valid(uint8_t *data, unsigned data_len) 53 | { 54 | if (data_len < READ_DEFECT_DATA_10_MIN_LEN) 55 | return false; 56 | if ((read_defect_data_10_len(data) % 4) != 0) 57 | return false; 58 | return true; 59 | } 60 | 61 | static inline bool read_defect_data_10_is_valid(uint8_t *data, unsigned data_len) 62 | { 63 | if (!read_defect_data_10_hdr_is_valid(data, data_len)) 64 | return false; 65 | if ((unsigned)read_defect_data_10_len(data) + READ_DEFECT_DATA_10_MIN_LEN < data_len) 66 | return false; 67 | return true; 68 | } 69 | 70 | static inline uint8_t *read_defect_data_10_data(uint8_t *data) 71 | { 72 | return data + READ_DEFECT_DATA_10_MIN_LEN; 73 | } 74 | 75 | /* READ DEFECT DATA 10 */ 76 | 77 | #define READ_DEFECT_DATA_12_MIN_LEN 8 78 | 79 | static inline bool read_defect_data_12_is_plist_valid(uint8_t *data) 80 | { 81 | return data[1] & 0x10; 82 | } 83 | 84 | static inline bool read_defect_data_12_is_glist_valid(uint8_t *data) 85 | { 86 | return data[1] & 0x08; 87 | } 88 | 89 | static inline uint8_t read_defect_data_12_list_format(uint8_t *data) 90 | { 91 | return data[1] & 0x07; 92 | } 93 | 94 | static inline uint32_t read_defect_data_12_len(uint8_t *data) 95 | { 96 | return get_uint32(data, 4); 97 | } 98 | 99 | /* For READ DEFECT DATA 10 the user may ask for only the header and the data is never really transfered, allow for this seperation in the checks. */ 100 | static inline bool read_defect_data_12_hdr_is_valid(uint8_t *data, unsigned data_len) 101 | { 102 | if (data_len < READ_DEFECT_DATA_12_MIN_LEN) 103 | return false; 104 | if ((read_defect_data_12_len(data) % 4) != 0) 105 | return false; 106 | return true; 107 | } 108 | 109 | static inline bool read_defect_data_12_is_valid(uint8_t *data, unsigned data_len) 110 | { 111 | if (!read_defect_data_12_hdr_is_valid(data, data_len)) 112 | return false; 113 | if (read_defect_data_12_len(data) + READ_DEFECT_DATA_12_MIN_LEN < data_len) 114 | return false; 115 | return true; 116 | } 117 | 118 | static inline uint8_t *read_defect_data_12_data(uint8_t *data) 119 | { 120 | return data + READ_DEFECT_DATA_12_MIN_LEN; 121 | } 122 | 123 | /* Formats */ 124 | 125 | /* Short format */ 126 | #define FORMAT_ADDRESS_SHORT_LEN 4 127 | static inline uint32_t format_address_short_lba(uint8_t *data) 128 | { 129 | return get_uint32(data, 0); 130 | } 131 | 132 | /* Long format */ 133 | #define FORMAT_ADDRESS_LONG_LEN 8 134 | static inline uint32_t format_address_long_lba(uint8_t *data) 135 | { 136 | return get_uint64(data, 0); 137 | } 138 | 139 | /* Byte from index */ 140 | #define FORMAT_ADDRESS_BYTE_FROM_INDEX_LEN 8 141 | static inline uint32_t format_address_byte_from_index_cylinder(uint8_t *data) 142 | { 143 | return get_uint24(data, 0); 144 | } 145 | 146 | static inline uint8_t format_address_byte_from_index_head(uint8_t *data) 147 | { 148 | return data[3]; 149 | } 150 | 151 | static inline uint32_t format_address_byte_from_index_bytes(uint8_t *data) 152 | { 153 | return get_uint32(data, 4); 154 | } 155 | #define FORMAT_ADDRESS_BYTE_FROM_INDEX_ALL_TRACK 0xFFFFFFFF 156 | 157 | /* Physical sector format */ 158 | #define FORMAT_ADDRESS_PHYSICAL_LEN 8 159 | static inline uint32_t format_address_physical_cylinder(uint8_t *data) 160 | { 161 | return get_uint24(data, 0); 162 | } 163 | 164 | static inline uint8_t format_address_physical_head(uint8_t *data) 165 | { 166 | return data[3]; 167 | } 168 | 169 | static inline uint32_t format_address_physical_sector(uint8_t *data) 170 | { 171 | return get_uint32(data, 4); 172 | } 173 | #define FORMAT_ADDRESS_PHYSICAL_ALL_TRACK 0xFFFFFFFF 174 | 175 | static inline unsigned read_defect_data_fmt_len(address_desc_format_e fmt) 176 | { 177 | switch (fmt) { 178 | case ADDRESS_FORMAT_SHORT: return FORMAT_ADDRESS_SHORT_LEN; 179 | case ADDRESS_FORMAT_LONG: return FORMAT_ADDRESS_LONG_LEN; 180 | case ADDRESS_FORMAT_INDEX_OFFSET: return FORMAT_ADDRESS_BYTE_FROM_INDEX_LEN; 181 | case ADDRESS_FORMAT_PHYSICAL: return FORMAT_ADDRESS_PHYSICAL_LEN; 182 | case ADDRESS_FORMAT_VENDOR: return 4; 183 | default: return 0; 184 | } 185 | } 186 | 187 | #endif 188 | -------------------------------------------------------------------------------- /afl/testcase/186704e9f39832c4c7b4f2ab71c52762017bd728: -------------------------------------------------------------------------------- 1 | ,4d 00 55 00 00 00 00 40 00 00,,95 00 08 20 00 00 03 0c 00 10 9a 5e 00 08 02 32 00 00 02 32 00 01 03 14 00 00 16 c7 51 17 01 20 3b 37 06 46 00 00 00 00 0a 3b 31 ae 00 02 03 14 00 00 1e bc 51 17 01 20 45 0e 05 59 00 00 00 00 0b ef ff f5 00 03 03 14 00 00 29 a5 51 17 01 20 30 f7 01 4a 00 00 00 00 08 7d ea bc 00 04 03 14 00 00 31 95 51 17 01 20 30 f7 01 4e 00 00 00 00 08 7d ea c0 00 05 03 14 00 00 59 54 51 17 01 20 45 39 00 b7 00 00 00 00 0b f1 22 f3 00 06 03 14 00 02 10 4d 51 17 01 20 00 e1 01 a7 00 00 00 00 00 3c e8 11 00 07 03 14 00 02 8b 87 51 17 01 20 1d d9 07 13 00 00 00 00 05 4e 51 89 00 08 03 14 00 02 ad a8 51 17 01 20 55 1a 06 06 00 00 00 00 0e ad 67 8d 00 09 03 14 00 03 4a 6b 51 17 01 20 99 22 05 2c 00 00 00 00 19 c7 58 b0 00 0a 03 14 00 03 68 e6 51 17 01 20 88 b8 02 de 00 00 00 00 17 26 3a 94 00 0b 03 14 00 03 69 5f 51 17 01 40 17 58 04 d2 00 00 00 00 04 2f dc f6 00 0c 03 14 00 03 ac 6d 51 17 01 20 15 b2 02 54 00 00 00 00 03 d7 af b1 00 0d 03 14 00 03 de b4 51 17 01 20 00 e1 01 a3 00 00 00 00 00 3c e8 0d 00 0e 03 14 00 03 de b7 51 17 01 20 10 47 02 79 00 00 00 00 02 d9 5c d5 00 0f 03 14 00 03 de d5 51 17 01 20 ab a0 02 c8 00 00 00 00 1c c6 eb 8a 00 10 03 14 00 05 a8 fc 51 17 01 20 15 b2 02 51 00 00 00 00 03 d7 af ae 00 11 03 14 00 06 26 4e 51 17 01 20 15 b2 02 43 00 00 00 00 03 d7 af a0 00 12 03 14 00 06 33 f7 51 17 01 20 29 da 06 1f 00 00 00 00 07 53 23 4b 00 13 03 14 00 06 34 b2 51 17 01 20 17 38 01 ee 00 00 00 00 04 21 d7 6e 00 14 03 14 00 06 35 bc 51 17 01 20 01 d5 03 8f 00 00 00 00 00 57 bd 11 00 15 03 14 00 06 35 c5 51 17 01 20 1c 58 04 53 00 00 00 00 05 04 4a 6e 00 16 03 14 00 06 35 d0 51 17 01 20 3a c6 03 6b 00 00 00 00 0a 38 17 d3 00 17 03 14 00 06 36 cb 51 17 01 20 01 d5 03 8e 00 00 00 00 00 57 bd 10 00 18 03 14 00 06 3c ba 51 17 01 20 49 43 05 2e 00 00 00 00 0c ae da 39 00 19 03 14 00 06 6e 21 51 17 01 20 1d f8 02 78 00 00 00 00 05 4f 2a c6 00 1a 03 14 00 06 96 52 51 17 01 20 9d 87 04 b7 00 00 00 00 1a 71 05 cf 00 1b 03 14 00 06 97 30 51 17 01 20 2a a3 02 72 00 00 00 00 07 81 d5 26 00 1c 03 14 00 06 cb 8a 51 17 01 20 3e 2d 01 d2 00 00 00 00 0a cc 67 e2 00 1d 03 14 00 07 22 0b 51 17 01 20 1c 07 06 77 00 00 00 00 04 e4 bf 7b 00 1e 03 14 00 07 40 c7 51 17 01 20 86 3c 05 8d 00 00 00 00 16 c5 84 e5 00 1f 03 14 00 07 9d ea 51 17 01 20 19 70 02 06 00 00 00 00 04 70 f9 79 00 20 03 14 00 08 21 6f 51 17 01 20 01 8e 07 1f 00 00 00 00 00 39 4f e2 00 21 03 14 00 08 26 28 51 17 01 20 00 72 00 2c 00 00 00 00 00 0f c6 34 00 22 03 14 00 08 26 29 51 17 01 20 01 8e 07 12 00 00 00 00 00 39 4f d5 00 23 03 14 00 08 26 29 51 17 01 20 01 8e 07 13 00 00 00 00 00 39 4f d6 00 24 03 14 00 08 27 8c 51 17 01 20 00 72 00 27 00 00 00 00 00 0f c6 2f 00 25 03 14 00 08 3c d8 51 17 01 20 00 72 00 28 00 00 00 00 00 0f c6 30 00 26 03 14 00 08 3c ef 51 17 01 20 49 55 03 96 00 00 00 00 0c ae 5c e1 00 27 03 14 00 08 e6 f0 51 17 01 20 00 72 00 30 00 00 00 00 00 0f c6 38 00 28 03 14 00 09 9f eb 51 17 01 20 1c ce 02 64 00 00 00 00 05 07 94 ef 00 29 03 14 00 0a 4b aa 51 17 01 20 31 d6 06 4f 00 00 00 00 08 a7 65 49 00 2a 03 14 00 0a 4b af 51 17 01 20 3f 3d 00 16 00 00 00 00 0a f9 70 ad 00 2b 03 14 00 0b 70 fb 51 17 01 20 e9 d6 04 fc 00 00 00 00 26 72 2e ad 00 2c 03 14 00 0b 7d 35 51 17 01 20 3f 49 05 ee 00 00 00 00 0a f9 22 85 00 2d 03 14 00 0b 89 09 51 17 01 20 3c 2d 03 dd 00 00 00 00 0a 62 eb cd 00 2e 03 14 00 0b 8c 1f 51 17 01 20 00 ea 02 ce 00 00 00 00 00 3c a8 e7 00 2f 03 14 00 0b 94 3b 51 17 01 20 1d 18 04 a1 00 00 00 00 05 34 11 af 00 30 03 14 00 0b 9e fd 51 17 01 20 1e 6f 02 cf 00 00 00 00 05 52 7e b5 00 31 03 14 00 0b 9f 0a 51 17 01 20 44 26 02 43 00 00 00 00 0b d3 cd c3 00 32 03 14 00 0b a2 ce 51 17 01 20 01 69 05 7e 00 00 00 00 00 3a 55 bb 00 33 03 14 00 0b a7 5a 51 17 01 20 24 e8 00 97 00 00 00 00 06 77 04 e1 00 34 03 14 00 0b a8 b0 51 17 01 20 24 e8 00 9a 00 00 00 00 06 77 04 e4 00 35 03 14 00 0b f1 4c 51 17 01 21 2e 62 05 23 00 00 00 00 30 be 48 20 00 36 03 14 00 0c 09 56 51 17 01 20 35 88 01 66 00 00 00 00 09 58 a2 d3 00 37 03 14 00 0c 21 c0 51 17 01 21 2e 62 05 25 00 00 00 00 30 be 48 22 00 38 03 14 00 0c 2d f8 51 17 01 20 24 e8 00 ae 00 00 00 00 06 77 04 f8 00 39 03 14 00 0c 36 fe 51 17 01 20 9e 49 05 6c 00 00 00 00 1a 97 f7 b3 00 3a 03 14 00 0c 4d ef 51 17 01 20 24 e8 00 a9 00 00 00 00 06 77 04 f3 00 3b 03 14 00 0c 4f 52 51 17 01 20 4f 03 02 9e 00 00 00 00 0d a4 fe 0e 00 3c 03 14 00 0c 5b 5b 51 17 01 20 24 e8 00 9b 00 00 00 00 06 77 04 e5 00 3d 03 14 00 0c 81 ec 51 17 01 20 24 e8 00 aa 00 00 00 00 06 77 04 f4 00 3e 03 14 00 0c 81 ec 51 17 01 20 24 e8 00 ab 00 00 00 00 06 77 04 f5 00 3f 03 14 00 0c 88 98 51 17 01 21 2e 62 05 26 00 00 00 00 30 be 48 23 00 40 03 14 00 0c ab 23 51 17 01 20 00 03 02 0a 00 00 00 00 00 0c ae 1a 00 41 03 14 00 0c d8 7f 51 17 01 20 9e 49 05 70 00 00 00 00 1a 97 f7 b7 00 42 03 14 00 0c e0 ab 51 17 01 20 ed 32 00 6a 00 00 00 00 26 f5 c6 52 00 43 03 14 00 0c ef 0e 51 17 01 20 68 a7 03 a1 00 00 00 00 11 e1 48 c4 00 44 03 14 00 0d 00 1c 51 17 01 20 1e 6f 02 ce 00 00 00 00 05 52 7e b4 00 45 03 14 00 0d 06 3b 51 17 01 20 93 c6 06 5f 00 00 00 00 18 fa 98 dd 00 46 03 14 00 0d 0b ff 51 17 01 20 24 e8 00 99 00 00 00 00 06 77 04 e3 00 47 03 14 00 0d 6b 5f 51 17 01 20 05 9e 04 3a 00 00 00 00 00 f1 53 b6 00 48 03 14 00 0d 7b 58 51 17 01 20 24 e8 00 8f 00 00 00 00 06 77 04 d9 00 49 03 14 00 0d 86 9c 51 17 01 21 2e 62 05 27 00 00 00 00 30 be 48 24 00 4a 03 14 00 0d da 5b 51 17 01 20 29 b2 00 d2 00 00 00 00 07 52 05 fe 00 4b 03 14 00 0d da 81 51 17 01 20 9e 49 05 74 00 00 00 00 1a 97 f7 bb 00 4c 03 14 00 0e 1f 48 51 17 01 40 2d e3 06 44 00 00 00 00 08 09 eb 8e 00 4d 03 14 00 0e 4b 21 51 17 01 20 4f 03 02 9a 00 00 00 00 0d a4 fe 0a 00 4e 03 14 00 0e 5e 54 51 17 01 20 24 e8 00 9f 00 00 00 00 06 77 04 e9 00 4f 03 14 00 0e 71 d2 51 17 01 20 24 e8 00 9e 00 00 00 00 06 77 04 e8 00 50 03 14 00 0e 99 b1 51 17 01 20 29 b2 00 ce 00 00 00 00 07 52 05 fa 00 51 03 14 00 0f 10 6f 51 17 01 20 05 9e 04 3b 00 00 00 00 00 f1 53 b7 00 52 03 14 00 0f 13 48 51 17 01 21 87 1b 01 8e 00 00 00 00 3d 55 25 d6 00 53 03 14 00 0f 29 da 51 17 01 20 7f 65 00 1d 00 00 00 00 15 ac 02 e4 00 54 03 14 00 0f 71 11 51 17 01 20 1d 18 04 a0 00 00 00 00 05 34 11 ae 00 55 03 14 00 0f c7 1a 51 17 01 20 c2 04 05 15 00 00 00 00 20 3f 7a 16 00 56 03 14 00 0f ce ab 51 17 01 20 29 b2 00 d1 00 00 00 00 07 52 05 fd 2 | -------------------------------------------------------------------------------- /structs/ata_identify.yaml: -------------------------------------------------------------------------------- 1 | ata_identify: 2 | not_ata_device: 3 | bit: [0, 15] 4 | response_incomplete: 5 | bit: [0, 2] 6 | 7 | serial_number: 8 | string: [10, 19] 9 | 10 | fw_rev: 11 | string: [23, 26] 12 | 13 | model: 14 | string: [27, 46] 15 | 16 | # max_num_sectors_transfer_per_drq_multiple: 17 | # byte: [40, 1] 18 | 19 | trusted_computing_supported: 20 | bit: [48, 0] 21 | 22 | standby_timer_values_settable: 23 | bit: [49, 13] 24 | iordy_supported: 25 | bit: [49, 11] 26 | iordy_disable_supported: 27 | bit: [49, 10] 28 | dma_supported: 29 | bit: [49, 8] 30 | # alignment_error_reporting_field: 31 | # bits: [49, 0, 1] 32 | 33 | # free_fall_sensitivity: 34 | # bits: [53, 8, 15] 35 | fields_valid_word_88: 36 | bit: [53, 2] 37 | fields_valid_words_64_70: 38 | bit: [53, 1] 39 | 40 | block_erase_supported: 41 | bit: [59, 15] 42 | overwrite_supported: 43 | bit: [59, 14] 44 | crypto_scramble_supported: 45 | bit: [59, 13] 46 | sanitize_supported: 47 | bit: [59, 12] 48 | 49 | total_addressable_sectors_28bit: 50 | longword: 60 51 | 52 | cfast_supported: 53 | bit: [69, 15] 54 | drat_supported: 55 | bit: [69, 14] 56 | lps_misalignment_reporting_supported: 57 | bit: [69, 13] 58 | read_buffer_dma_supported: 59 | bit: [69, 11] 60 | write_buffer_dma_supported: 61 | bit: [69, 10] 62 | set_max_set_password_dma_and_set_max_unlock_dma_supported: 63 | bit: [69, 9] 64 | download_microcode_dma_supported: 65 | bit: [69, 8] 66 | address_28bit_supported: 67 | bit: [69, 6] 68 | rzat_supported: 69 | bit: [69, 5] 70 | encrypt_all_supported: 71 | bit: [69, 4] 72 | extended_number_of_user_addressable_sectors: 73 | bit: [69, 3] 74 | non_volatile_cache: 75 | bit: [69, 2] 76 | 77 | queue_depth: 78 | bits: [75, 0, 4] 79 | 80 | supports_read_log_dma_ext_as_read_log_dma: 81 | bit: [76, 15] 82 | supports_dev_automatic_partial_to_slumber: 83 | bit: [76, 14] 84 | supports_host_automatic_partial_to_slumber: 85 | bit: [76, 13] 86 | supports_ncq_priority: 87 | bit: [76, 12] 88 | supports_unload_while_ncq_outstanding: 89 | bit: [76, 11] 90 | supports_sata_phy_event_counters_log: 91 | bit: [76, 10] 92 | supports_receipt_of_host_initiated_power_management_requests: 93 | bit: [76, 9] 94 | supports_ncq: 95 | bit: [76, 8] 96 | supports_sata_gen3_6gbps: 97 | bit: [76, 3] 98 | supports_sata_gen2_3gbps: 99 | bit: [76, 2] 100 | supports_sata_gen1_1_5gbps: 101 | bit: [76, 1] 102 | 103 | supports_receive_fpdma_queued: 104 | bit: [77, 6] 105 | supports_ncq_queue_management_commands: 106 | bit: [77, 5] 107 | supports_ncq_streaming: 108 | bit: [77, 4] 109 | current_negotiated_link_speed: 110 | bits: [77, 1, 3] 111 | 112 | sata_automatic_partial_to_slumber_transitions_enabled: 113 | bit: [79, 7] 114 | sata_software_settings_preservation_enabled: 115 | bit: [79, 6] 116 | sata_hardware_feature_control_enabled: 117 | bit: [79, 5] 118 | sata_in_order_data_delivery_enabled: 119 | bit: [79, 4] 120 | sata_device_initiated_power_management_enabled: 121 | bit: [79, 3] 122 | sata_dma_setup_auto_activation_enabled: 123 | bit: [79, 2] 124 | sata_non_zero_buffer_offsets_enabled: 125 | bit: [79, 1] 126 | 127 | major_version_acs_2: 128 | bit: [80, 9] 129 | major_version_ata_8_acs: 130 | bit: [80, 8] 131 | major_version_ata_atapi_7: 132 | bit: [80, 7] 133 | major_version_ata_atapi_6: 134 | bit: [80, 6] 135 | major_version_ata_atapi_5: 136 | bit: [80, 5] 137 | 138 | # minor_version: 139 | # word: 81 140 | 141 | nop_supported: 142 | bit: [82, 14] 143 | read_buffer_supported: 144 | bit: [82, 13] 145 | write_buffer_supported: 146 | bit: [82, 12] 147 | read_look_ahead_supported: 148 | bit: [82, 6] 149 | volatile_write_cache_supported: 150 | bit: [82, 5] 151 | packet_feature_set_supported: 152 | bit: [82, 4] 153 | mandatory_power_management_supported: 154 | bit: [82, 3] 155 | security_feature_set_supported: 156 | bit: [82, 1] 157 | smart_supported: 158 | bit: [82, 0] 159 | 160 | address_48bit_supported: 161 | bit: [83, 10] 162 | spin_up_supported: 163 | bit: [83, 6] 164 | puis_supported: 165 | bit: [83, 5] 166 | apm_supported: 167 | bit: [83, 3] 168 | cfa_supported: 169 | bit: [83, 2] 170 | download_microcode_supported: 171 | bit: [83, 0] 172 | 173 | wwn_64bit_supported: 174 | bit: [84, 8] 175 | gpl_supported: 176 | bit: [84, 5] 177 | streaming_supported: 178 | bit: [84, 4] 179 | smart_self_test_supported: 180 | bit: [84, 1] 181 | smart_error_logging_supported: 182 | bit: [84, 0] 183 | 184 | smart_enabled: 185 | bit: [85, 0] 186 | 187 | sense_data_supported: 188 | bit: [119, 6] 189 | 190 | write_uncorrectable_supported: 191 | bit: [119, 2] 192 | 193 | sense_data_enabled: 194 | bit: [120, 6] 195 | 196 | write_uncorrectable_enabled: 197 | bit: [120, 2] 198 | 199 | 200 | sct_data_tables_supported: 201 | bit: [206, 5] 202 | sct_feature_control_supported: 203 | bit: [206, 4] 204 | sct_error_recovery_control_supported: 205 | bit: [206, 3] 206 | sct_write_same_supported: 207 | bit: [206, 2] 208 | sct_command_transport_supported: 209 | bit: [206, 0] 210 | 211 | rotational_rate: 212 | bits: [216, 0, 15] 213 | 214 | wwn_high: 215 | longword: 108 216 | wwn_low: 217 | longword: 110 218 | 219 | additional_product_identifier: 220 | string: [170, 173] 221 | current_media_serial: 222 | string: [176, 205] 223 | 224 | extended_num_user_addressable_sectors: 225 | qword: 230 226 | 227 | # vim:set et ts=4 sw=4: 228 | -------------------------------------------------------------------------------- /src/cdb.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #include "scsicmd.h" 18 | 19 | #include 20 | 21 | static inline void set_uint16(unsigned char *cdb, int start, uint16_t val) 22 | { 23 | cdb[start] = (val >> 8) & 0xFF; 24 | cdb[start+1] = val & 0xFF; 25 | } 26 | 27 | static inline void set_uint32(unsigned char *cdb, int start, uint32_t val) 28 | { 29 | cdb[start] = (val >> 24) & 0xFF; 30 | cdb[start+1] = (val >> 16) & 0xFF; 31 | cdb[start+2] = (val >> 8) & 0xFF; 32 | cdb[start+3] = val & 0xFF; 33 | } 34 | 35 | static inline void set_uint64(unsigned char *cdb, int start, uint64_t val) 36 | { 37 | cdb[start] = (val >> 56) & 0xFF; 38 | cdb[start+1] = (val >> 48) & 0xFF; 39 | cdb[start+2] = (val >> 40) & 0xFF; 40 | cdb[start+3] = (val >> 32) & 0xFF; 41 | cdb[start+4] = (val >> 24) & 0xFF; 42 | cdb[start+5] = (val >> 16) & 0xFF; 43 | cdb[start+6] = (val >> 8) & 0xFF; 44 | cdb[start+7] = val & 0xFF; 45 | } 46 | 47 | int cdb_tur(unsigned char *cdb) 48 | { 49 | const int TUR_LEN = 6; 50 | memset(cdb, 0, TUR_LEN); 51 | return TUR_LEN; 52 | } 53 | 54 | int cdb_inquiry(unsigned char *cdb, bool evpd, char page_code, uint16_t alloc_len) 55 | { 56 | const int INQUIRY_LEN = 6; 57 | 58 | cdb[0] = 0x12; 59 | cdb[1] = evpd ? 1 : 0; 60 | cdb[2] = page_code; 61 | set_uint16(cdb, 3, alloc_len); 62 | cdb[5] = 0; 63 | 64 | return INQUIRY_LEN; 65 | } 66 | 67 | int cdb_read_capacity_10(unsigned char *cdb) 68 | { 69 | const int LEN = 10; 70 | cdb[0] = 0x25; 71 | memset(cdb+1, 0, LEN-1); 72 | return LEN; 73 | } 74 | 75 | int cdb_read_capacity_16(unsigned char *cdb, uint32_t alloc_len) 76 | { 77 | const int LEN = 16; 78 | cdb[0] = 0x9E; 79 | cdb[1] = 0x10; 80 | memset(cdb+2, 0, LEN-2); 81 | set_uint32(cdb, 10, alloc_len); 82 | return LEN; 83 | } 84 | 85 | int cdb_read_10(unsigned char *cdb, bool fua, uint64_t lba, uint16_t transfer_length_blocks) 86 | { 87 | const int LEN = 10; 88 | cdb[0] = 0x28; 89 | cdb[1] = fua << 3; 90 | set_uint32(cdb, 2, lba); 91 | cdb[6] = 0; 92 | set_uint16(cdb, 7, transfer_length_blocks); 93 | cdb[9] = 0; 94 | return LEN; 95 | } 96 | 97 | int cdb_write_10(unsigned char *cdb, bool fua, uint64_t lba, uint16_t transfer_length_blocks) 98 | { 99 | const int LEN = 10; 100 | cdb[0] = 0x2A; 101 | cdb[1] = fua << 3; 102 | set_uint32(cdb, 2, lba); 103 | cdb[6] = 0; 104 | set_uint16(cdb, 7, transfer_length_blocks); 105 | cdb[9] = 0; 106 | return LEN; 107 | } 108 | 109 | int cdb_read_16(unsigned char *cdb, bool fua, bool fua_nv, bool dpo, uint64_t lba, uint32_t transfer_length_blocks) 110 | { 111 | const int LEN = 16; 112 | cdb[0] = 0x88; 113 | cdb[1] = (dpo<<4) | (fua<<3) | (fua_nv<<1); 114 | set_uint64(cdb, 2, lba); 115 | set_uint32(cdb, 10, transfer_length_blocks); 116 | cdb[14] = 0; 117 | cdb[15] = 0; 118 | return LEN; 119 | } 120 | 121 | int cdb_write_16(unsigned char *cdb, bool dpo, bool fua, bool fua_nv, uint64_t lba, uint32_t transfer_length_blocks) 122 | { 123 | const int LEN = 16; 124 | cdb[0] = 0x8A; 125 | cdb[1] = (dpo<<4) | (fua<<3) | (fua_nv<<1); 126 | set_uint64(cdb, 2, lba); 127 | set_uint32(cdb, 10, transfer_length_blocks); 128 | cdb[14] = 0; 129 | cdb[15] = 0; 130 | return LEN; 131 | } 132 | 133 | int cdb_log_sense(unsigned char *cdb, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len) 134 | { 135 | const int LEN = 10; 136 | memset(cdb, 0, LEN); 137 | cdb[0] = 0x4D; 138 | cdb[2] = (1 << 6) | (page_code & 0x3F); // The pc is always set to 1 for Cumulative values 139 | cdb[3] = subpage_code; 140 | set_uint16(cdb, 7, alloc_len); 141 | return LEN; 142 | } 143 | 144 | int cdb_receive_diagnostics(unsigned char *cdb, bool page_code_valid, uint8_t page_code, uint16_t alloc_len) 145 | { 146 | const int LEN = 6; 147 | cdb[0] = 0x1C; 148 | cdb[1] = page_code_valid ? 1 : 0; 149 | cdb[2] = page_code; 150 | set_uint16(cdb, 3, alloc_len); 151 | cdb[5] = 0; 152 | return LEN; 153 | } 154 | 155 | int cdb_send_diagnostics(unsigned char *cdb, self_test_code_e self_test, uint16_t param_len) 156 | { 157 | const int LEN = 6; 158 | cdb[0] = 0x1D; 159 | cdb[1] = self_test << 5; 160 | cdb[2] = 0; 161 | set_uint16(cdb, 3, param_len); 162 | cdb[5] = 0; 163 | return LEN; 164 | } 165 | 166 | int cdb_mode_sense_6(unsigned char *cdb, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint8_t alloc_len) 167 | { 168 | const int LEN = 6; 169 | cdb[0] = 0x1A; 170 | cdb[1] = disable_block_descriptor ? (1<<3) : 0; 171 | cdb[2] = (page_control << 6) | page_code; 172 | cdb[3] = subpage_code; 173 | cdb[4] = alloc_len; 174 | cdb[5] = 0; 175 | return LEN; 176 | } 177 | 178 | int cdb_mode_sense_10(unsigned char *cdb, bool long_lba_accepted, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len) 179 | { 180 | const int LEN = 10; 181 | cdb[0] = 0x5A; 182 | cdb[1] = (long_lba_accepted ? 1<<4 : 0) | (disable_block_descriptor ? 1<<3 : 0); 183 | cdb[2] = (page_control << 6) | page_code; 184 | cdb[3] = subpage_code; 185 | cdb[4] = 0; 186 | cdb[5] = 0; 187 | cdb[6] = 0; 188 | set_uint16(cdb, 7, alloc_len); 189 | cdb[9] = 0; 190 | return LEN; 191 | } 192 | 193 | int cdb_read_defect_data_10(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint16_t alloc_len) 194 | { 195 | const int LEN = 10; 196 | cdb[0] = 0x37; 197 | cdb[1] = 0; 198 | cdb[2] = (plist ? 0x10 : 0) | (glist ? 0x08 : 0) | format; 199 | cdb[3] = cdb[4] = cdb[5] = cdb[6] = 0; 200 | set_uint16(cdb, 7, alloc_len); 201 | cdb[9] = 0; 202 | return LEN; 203 | } 204 | 205 | int cdb_read_defect_data_12(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint32_t alloc_len) 206 | { 207 | const int LEN = 12; 208 | cdb[0] = 0xB7; 209 | cdb[1] = (plist ? 0x10 : 0) | (glist ? 0x08 : 0) | format; 210 | cdb[2] = cdb[3] = cdb[4] = cdb[5] = 0; 211 | set_uint32(cdb, 6, alloc_len); 212 | cdb[10] = 0; 213 | cdb[11] = 0; 214 | return LEN; 215 | } 216 | -------------------------------------------------------------------------------- /include/parse_mode_sense.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Baruch Even 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * 15 | */ 16 | 17 | #ifndef LIBSCSICMD_MODE_SENSE_H 18 | #define LIBSCSICMD_MODE_SENSE_H 19 | 20 | #include "scsicmd_utils.h" 21 | 22 | /* Mode parameter header for the MODE SENSE 6 */ 23 | #define MODE_SENSE_6_MIN_LEN 4u 24 | 25 | static inline unsigned mode_sense_6_data_len(uint8_t *data) 26 | { 27 | return data[0]; 28 | } 29 | 30 | static inline uint8_t mode_sense_6_medium_type(uint8_t *data) 31 | { 32 | return data[1]; 33 | } 34 | 35 | static inline uint8_t mode_sense_6_device_specific_param(uint8_t *data) 36 | { 37 | return data[2]; 38 | } 39 | 40 | static inline uint8_t mode_sense_6_block_descriptor_length(uint8_t *data) 41 | { 42 | return data[3]; 43 | } 44 | 45 | static inline uint8_t *mode_sense_6_block_descriptor_data(uint8_t *data) 46 | { 47 | return data + MODE_SENSE_6_MIN_LEN; 48 | } 49 | 50 | static inline uint8_t *mode_sense_6_mode_data(uint8_t *data) 51 | { 52 | return data + MODE_SENSE_6_MIN_LEN + mode_sense_6_block_descriptor_length(data); 53 | } 54 | 55 | static inline unsigned mode_sense_6_expected_length(uint8_t *data) 56 | { 57 | return 1 + mode_sense_6_data_len(data); // Add the first byte that is not part of the mode data length 58 | } 59 | 60 | static inline unsigned mode_sense_6_mode_data_len(uint8_t *data) 61 | { 62 | return mode_sense_6_expected_length(data) - MODE_SENSE_6_MIN_LEN - mode_sense_6_block_descriptor_length(data); 63 | } 64 | 65 | static inline bool mode_sense_6_is_valid_header(uint8_t *data, unsigned data_len) 66 | { 67 | if (mode_sense_6_data_len(data) < MODE_SENSE_6_MIN_LEN-1) 68 | return false; 69 | if (data_len < (unsigned)(mode_sense_6_data_len(data)) + 1) 70 | return false; 71 | if (mode_sense_6_block_descriptor_length(data) != 0 && 72 | mode_sense_6_block_descriptor_length(data) != 8) 73 | { 74 | return false; 75 | } 76 | if (mode_sense_6_data_len(data) < mode_sense_6_block_descriptor_length(data)) 77 | return false; 78 | return true; 79 | } 80 | 81 | /* Mode parameter header for the MODE SENSE 10 */ 82 | #define MODE_SENSE_10_MIN_LEN 8u 83 | 84 | static inline unsigned mode_sense_10_data_len(uint8_t *data) 85 | { 86 | return get_uint16(data, 0); 87 | } 88 | 89 | static inline uint8_t mode_sense_10_medium_type(uint8_t *data) 90 | { 91 | return data[2]; 92 | } 93 | 94 | static inline uint8_t mode_sense_10_device_specific_param(uint8_t *data) 95 | { 96 | return data[3]; 97 | } 98 | 99 | static inline bool mode_sense_10_long_lba(uint8_t *data) 100 | { 101 | return data[4] & 1; 102 | } 103 | 104 | /* SPC4 says length is times 8 without long lba and times 16 with it but it seems the value is taken verbatim */ 105 | static inline unsigned mode_sense_10_block_descriptor_length(uint8_t *data) 106 | { 107 | return get_uint16(data, 6); 108 | } 109 | 110 | static inline uint8_t *mode_sense_10_block_descriptor_data(uint8_t *data) 111 | { 112 | if (mode_sense_10_block_descriptor_length(data) > 0) 113 | return data + MODE_SENSE_10_MIN_LEN; 114 | else 115 | return NULL; 116 | } 117 | 118 | static inline uint8_t *mode_sense_10_mode_data(uint8_t *data) 119 | { 120 | return data + MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(data); 121 | } 122 | 123 | static inline unsigned mode_sense_10_expected_length(uint8_t *data) 124 | { 125 | return 2 + mode_sense_10_data_len(data); // Add the first two bytes that are not part of the mode data length 126 | } 127 | 128 | static inline unsigned mode_sense_10_mode_data_len(uint8_t *data) 129 | { 130 | return mode_sense_10_expected_length(data) - MODE_SENSE_10_MIN_LEN - mode_sense_10_block_descriptor_length(data); 131 | } 132 | 133 | static inline bool mode_sense_10_is_valid_header(uint8_t *data, unsigned data_len) 134 | { 135 | if (mode_sense_10_data_len(data) < MODE_SENSE_10_MIN_LEN-2) 136 | return false; 137 | if (data_len < (unsigned)(mode_sense_10_data_len(data)) + 2) 138 | return false; 139 | if (mode_sense_10_block_descriptor_length(data) != 0 && 140 | mode_sense_10_block_descriptor_length(data) != 8) 141 | { 142 | return false; 143 | } 144 | return true; 145 | } 146 | 147 | /* Regular block descriptor (as opposed to long) */ 148 | #define BLOCK_DESCRIPTOR_LENGTH 8 149 | #define BLOCK_DESCRIPTOR_NUM_BLOCKS_OVERFLOW 0xFFFFFF 150 | 151 | static inline uint8_t block_descriptor_density_code(uint8_t *data) 152 | { 153 | return data[0]; 154 | } 155 | 156 | static inline uint32_t block_descriptor_num_blocks(uint8_t *data) 157 | { 158 | return get_uint24(data, 1); 159 | } 160 | 161 | static inline uint32_t block_descriptor_block_length(uint8_t *data) 162 | { 163 | return get_uint24(data, 5); 164 | } 165 | 166 | /* Mode Sense page data */ 167 | static inline uint8_t mode_sense_data_page_code(uint8_t *data) 168 | { 169 | return data[0] & 0x3F; 170 | } 171 | 172 | static inline bool mode_sense_data_subpage_format(uint8_t *data) 173 | { 174 | return data[0] & 0x40; 175 | } 176 | 177 | static inline bool mode_sense_data_parameter_saveable(uint8_t *data) 178 | { 179 | return data[0] & 0x80; 180 | } 181 | 182 | /* Caller is required to know if this is a subpage format page or not */ 183 | static inline uint8_t mode_sense_data_subpage_code(uint8_t *data) 184 | { 185 | return data[1]; 186 | } 187 | 188 | static inline unsigned mode_sense_data_page_len(uint8_t *data) 189 | { 190 | return mode_sense_data_subpage_format(data) ? 3 + (unsigned)(get_uint16(data, 2)) : 2 + (unsigned)(data[1]); 191 | } 192 | 193 | static inline unsigned mode_sense_data_param_len(uint8_t *data) 194 | { 195 | return mode_sense_data_subpage_format(data) ? get_uint16(data, 2) : data[1]; 196 | } 197 | 198 | static inline uint8_t *mode_sense_data_param(uint8_t *data) 199 | { 200 | return mode_sense_data_subpage_format(data) ? data + 4 : data + 2; 201 | } 202 | 203 | static inline bool mode_sense_data_param_is_valid(uint8_t *data, unsigned data_len) 204 | { 205 | if (data_len < 2) 206 | return false; 207 | if (mode_sense_data_page_code(data) == 0) 208 | return false; 209 | if (mode_sense_data_subpage_format(data) && data_len < 4) 210 | return false; 211 | if (data_len < mode_sense_data_page_len(data)) 212 | return false; 213 | return true; 214 | } 215 | 216 | 217 | #define for_all_mode_sense_pages(data, data_len, mode_data, mode_data_len, page, remaining_len) \ 218 | for (remaining_len = mode_data - data + safe_len(data, data_len, mode_data, mode_data_len), page = mode_data; \ 219 | remaining_len >= 3 && mode_sense_data_param_is_valid(page, remaining_len); \ 220 | remaining_len += mode_sense_data_param_len(page), page += mode_sense_data_page_len(page)) 221 | 222 | #define for_all_mode_sense_6_pages(data, data_len, page, remaining_len) \ 223 | for_all_mode_sense_pages(data, data_len, mode_sense_6_mode_data(data), mode_sense_6_mode_data_len(data), page, remaining_len) 224 | 225 | #define for_all_mode_sense_10_pages(data, data_len, page, remaining_len) \ 226 | for_all_mode_sense_pages(data, data_len, mode_sense_10_mode_data(data), mode_sense_10_mode_data_len(data), page, remaining_len) 227 | 228 | #endif 229 | -------------------------------------------------------------------------------- /afl/testcase/a3a3b5b0ea540bc579228dfe70b21f40d9c0df96: -------------------------------------------------------------------------------- 1 | ,1c 01 04 40 00 00,,04 00 0a a9 30 35 3a 31 37 3a 33 36 3a 35 38 3a 33 38 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 32 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 33 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 34 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 35 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 38 32 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 38 36 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 39 36 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 36 30 35 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 30 37 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 31 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 32 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 33 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 35 38 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 35 39 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 36 30 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 36 31 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 33 34 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 33 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 34 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 35 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 35 30 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 35 34 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 36 34 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 37 33 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 34 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 35 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 36 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 37 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 35 38 38 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 35 39 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 36 30 33 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 36 31 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 33 38 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 34 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 35 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 36 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 36 34 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 36 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 38 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 38 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 32 32 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 32 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 33 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 34 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 39 32 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 39 33 35 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 30 33 3a 38 34 32 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 35 3a 31 37 3a 34 37 3a 30 34 3a 30 35 32 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 30 20 64 61 74 61 3a 20 31 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 65 34 0a 30 35 3a 31 37 3a 34 37 3a 34 39 3a 34 34 34 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 34 39 3a 34 35 33 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 2 | --------------------------------------------------------------------------------