encoder.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. package encoder
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "reflect"
  8. "strconv"
  9. "strings"
  10. )
  11. type BinaryMarshallable interface {
  12. MarshalBinary(*Metadata) ([]byte, error)
  13. UnmarshalBinary([]byte, *Metadata) (interface{}, error)
  14. }
  15. type Metadata struct {
  16. Tags *TagMap
  17. Lens map[string]uint64
  18. Offsets map[string]uint64
  19. Count map[string]uint64
  20. Parent interface{}
  21. ParentBuf []byte
  22. CurrOffset uint64
  23. CurrField string
  24. }
  25. type TagMap struct {
  26. m map[string]interface{}
  27. has map[string]bool
  28. }
  29. func (t Metadata) CurrOffsetMove(move uint64) {
  30. t.CurrOffset += move
  31. }
  32. func (t TagMap) Has(key string) bool {
  33. return t.has[key]
  34. }
  35. func (t TagMap) Set(key string, val interface{}) {
  36. t.m[key] = val
  37. t.has[key] = true
  38. }
  39. func (t TagMap) Get(key string) interface{} {
  40. return t.m[key]
  41. }
  42. func (t TagMap) GetInt(key string) (int, error) {
  43. if !t.Has(key) {
  44. return 0, errors.New("Key does not exist in tag")
  45. }
  46. return t.Get(key).(int), nil
  47. }
  48. func (t TagMap) GetString(key string) (string, error) {
  49. if !t.Has(key) {
  50. return "", errors.New("Key does not exist in tag")
  51. }
  52. return t.Get(key).(string), nil
  53. }
  54. func parseTags(sf reflect.StructField) (*TagMap, error) {
  55. ret := &TagMap{
  56. m: make(map[string]interface{}),
  57. has: make(map[string]bool),
  58. }
  59. tag := sf.Tag.Get("smb")
  60. smbTags := strings.Split(tag, ",")
  61. for _, smbTag := range smbTags {
  62. tokens := strings.Split(smbTag, ":")
  63. switch tokens[0] {
  64. case "len", "offset", "count":
  65. if len(tokens) != 2 {
  66. return nil, errors.New("Missing required tag data. Expecting key:val")
  67. }
  68. ret.Set(tokens[0], tokens[1])
  69. case "fixed":
  70. if len(tokens) != 2 {
  71. return nil, errors.New("Missing required tag data. Expecting key:val")
  72. }
  73. i, err := strconv.Atoi(tokens[1])
  74. if err != nil {
  75. return nil, err
  76. }
  77. ret.Set(tokens[0], i)
  78. case "asn1":
  79. ret.Set(tokens[0], true)
  80. }
  81. }
  82. return ret, nil
  83. }
  84. func getOffsetByFieldName(fieldName string, meta *Metadata) (uint64, error) {
  85. if meta == nil || meta.Tags == nil || meta.Parent == nil || meta.Lens == nil {
  86. return 0, errors.New("Cannot determine field offset. Missing required metadata")
  87. }
  88. var ret uint64
  89. var found bool
  90. parentvf := reflect.Indirect(reflect.ValueOf(meta.Parent))
  91. // To determine offset, we loop through all fields of the struct, summing lengths of previous elements
  92. // until we reach our field
  93. for i := 0; i < parentvf.NumField(); i++ {
  94. tf := parentvf.Type().Field(i)
  95. if tf.Name == fieldName {
  96. found = true
  97. break
  98. }
  99. if l, ok := meta.Lens[tf.Name]; ok {
  100. // Length of field is in cache
  101. ret += l
  102. } else {
  103. tags, err := parseTags(tf)
  104. if err != nil {
  105. return 0, err
  106. }
  107. if tags.Has("fixed") {
  108. length, err := tags.GetInt("fixed")
  109. if err != nil {
  110. return 0, err
  111. }
  112. meta.Lens[tf.Name] = uint64(length)
  113. } else {
  114. // Not in cache. Must marshal field to determine length. Add to cache after
  115. buf, err := Marshal(parentvf.Field(i).Interface())
  116. if err != nil {
  117. return 0, err
  118. }
  119. l := uint64(len(buf))
  120. meta.Lens[tf.Name] = l
  121. ret += l
  122. }
  123. }
  124. }
  125. if !found {
  126. return 0, errors.New("Cannot find field name within struct: " + fieldName)
  127. }
  128. return ret, nil
  129. }
  130. func getFieldLengthByName(fieldName string, meta *Metadata) (uint64, error) {
  131. var ret uint64
  132. if meta == nil || meta.Tags == nil || meta.Parent == nil || meta.Lens == nil {
  133. return 0, errors.New("Cannot determine field length. Missing required metadata")
  134. }
  135. // Check if length is stored in field length cache
  136. if val, ok := meta.Lens[fieldName]; ok {
  137. return uint64(val), nil
  138. }
  139. parentvf := reflect.Indirect(reflect.ValueOf(meta.Parent))
  140. field := parentvf.FieldByName(fieldName)
  141. if !field.IsValid() {
  142. return 0, errors.New("Invalid field. Cannot determine length.")
  143. }
  144. bm, ok := field.Interface().(BinaryMarshallable)
  145. if ok {
  146. // Custom marshallable interface found.
  147. buf, err := bm.(BinaryMarshallable).MarshalBinary(meta)
  148. if err != nil {
  149. return 0, err
  150. }
  151. return uint64(len(buf)), nil
  152. }
  153. if field.Kind() == reflect.Ptr {
  154. field = field.Elem()
  155. }
  156. switch field.Kind() {
  157. case reflect.Struct:
  158. buf, err := Marshal(field.Interface())
  159. if err != nil {
  160. return 0, err
  161. }
  162. ret = uint64(len(buf))
  163. case reflect.Interface:
  164. return 0, errors.New("Interface length calculation not implemented")
  165. case reflect.Slice, reflect.Array:
  166. switch field.Type().Elem().Kind() {
  167. case reflect.Uint8:
  168. ret = uint64(len(field.Interface().([]byte)))
  169. default:
  170. return 0, errors.New("Cannot calculate the length of unknown slice type for " + fieldName)
  171. }
  172. case reflect.Uint8:
  173. ret = uint64(binary.Size(field.Interface().(uint8)))
  174. case reflect.Uint16:
  175. ret = uint64(binary.Size(field.Interface().(uint16)))
  176. case reflect.Uint32:
  177. ret = uint64(binary.Size(field.Interface().(uint32)))
  178. case reflect.Uint64:
  179. ret = uint64(binary.Size(field.Interface().(uint64)))
  180. default:
  181. return 0, errors.New("Cannot calculate the length of unknown kind for field " + fieldName)
  182. }
  183. meta.Lens[fieldName] = ret
  184. return ret, nil
  185. }
  186. func Marshal(v interface{}) ([]byte, error) {
  187. m := &Metadata{
  188. Tags: &TagMap{},
  189. Lens: make(map[string]uint64),
  190. Parent: v,
  191. }
  192. return marshal(v, m)
  193. }
  194. func marshal(v interface{}, meta *Metadata) ([]byte, error) {
  195. var ret []byte
  196. typev := reflect.TypeOf(v)
  197. valuev := reflect.ValueOf(v)
  198. bm, ok := v.(BinaryMarshallable)
  199. if ok {
  200. // Custom marshallable interface found.
  201. buf, err := bm.MarshalBinary(meta)
  202. if err != nil {
  203. return nil, err
  204. }
  205. return buf, nil
  206. }
  207. if typev.Kind() == reflect.Ptr {
  208. valuev = reflect.Indirect(reflect.ValueOf(v))
  209. typev = valuev.Type()
  210. }
  211. lenOffset := func(data uint64) (uint64, error) {
  212. if meta != nil && meta.Tags.Has("len") {
  213. fieldName, err := meta.Tags.GetString("len")
  214. if err != nil {
  215. return 0, err
  216. }
  217. l, err := getFieldLengthByName(fieldName, meta)
  218. if err != nil {
  219. return 0, err
  220. }
  221. return uint64(l), nil
  222. }
  223. if meta != nil && meta.Tags.Has("offset") {
  224. fieldName, err := meta.Tags.GetString("offset")
  225. if err != nil {
  226. return 0, err
  227. }
  228. l, err := getOffsetByFieldName(fieldName, meta)
  229. if err != nil {
  230. return 0, err
  231. }
  232. return uint64(l), nil
  233. }
  234. return data, nil
  235. }
  236. w := bytes.NewBuffer(ret)
  237. switch typev.Kind() {
  238. case reflect.Struct:
  239. m := &Metadata{
  240. Tags: &TagMap{},
  241. Lens: make(map[string]uint64),
  242. Parent: v,
  243. }
  244. for j := 0; j < valuev.NumField(); j++ {
  245. tags, err := parseTags(typev.Field(j))
  246. name := typev.Field(j).Name
  247. if err != nil {
  248. return nil, err
  249. }
  250. m.Tags = tags
  251. buf, err := marshal(valuev.Field(j).Interface(), m)
  252. if err != nil {
  253. return nil, err
  254. }
  255. m.Lens[name] = uint64(len(buf))
  256. if err := binary.Write(w, binary.LittleEndian, buf); err != nil {
  257. return nil, err
  258. }
  259. }
  260. case reflect.Slice, reflect.Array:
  261. switch typev.Elem().Kind() {
  262. case reflect.Uint8:
  263. if meta.Tags.Has("fixed") {
  264. length, err := meta.Tags.GetInt("fixed")
  265. if err != nil {
  266. return nil, err
  267. }
  268. v8 := v.([]uint8)
  269. if len(v8) != length {
  270. vv := make([]uint8, length)
  271. copy(vv, v8)
  272. v = vv
  273. }
  274. }
  275. if err := binary.Write(w, binary.LittleEndian, v.([]uint8)); err != nil {
  276. return nil, err
  277. }
  278. case reflect.Uint16:
  279. if err := binary.Write(w, binary.LittleEndian, v.([]uint16)); err != nil {
  280. return nil, err
  281. }
  282. }
  283. case reflect.Uint8:
  284. if err := binary.Write(w, binary.LittleEndian, valuev.Interface().(uint8)); err != nil {
  285. return nil, err
  286. }
  287. case reflect.Uint16:
  288. data := valuev.Interface().(uint16)
  289. if data2, err := lenOffset(uint64(data)); err != nil {
  290. return nil, err
  291. } else {
  292. data = uint16(data2)
  293. }
  294. // if meta != nil && meta.Tags.Has("len") {
  295. // fieldName, err := meta.Tags.GetString("len")
  296. // if err != nil {
  297. // return nil, err
  298. // }
  299. // l, err := getFieldLengthByName(fieldName, meta)
  300. // if err != nil {
  301. // return nil, err
  302. // }
  303. // data = uint16(l)
  304. // }
  305. // if meta != nil && meta.Tags.Has("offset") {
  306. // fieldName, err := meta.Tags.GetString("offset")
  307. // if err != nil {
  308. // return nil, err
  309. // }
  310. // l, err := getOffsetByFieldName(fieldName, meta)
  311. // if err != nil {
  312. // return nil, err
  313. // }
  314. // data = uint16(l)
  315. // }
  316. if err := binary.Write(w, binary.LittleEndian, data); err != nil {
  317. return nil, err
  318. }
  319. case reflect.Uint32:
  320. data := valuev.Interface().(uint32)
  321. if data2, err := lenOffset(uint64(data)); err != nil {
  322. return nil, err
  323. } else {
  324. data = uint32(data2)
  325. }
  326. // if meta != nil && meta.Tags.Has("len") {
  327. // fieldName, err := meta.Tags.GetString("len")
  328. // if err != nil {
  329. // return nil, err
  330. // }
  331. // l, err := getFieldLengthByName(fieldName, meta)
  332. // if err != nil {
  333. // return nil, err
  334. // }
  335. // data = uint32(l)
  336. // }
  337. // if meta != nil && meta.Tags.Has("offset") {
  338. // fieldName, err := meta.Tags.GetString("offset")
  339. // if err != nil {
  340. // return nil, err
  341. // }
  342. // l, err := getOffsetByFieldName(fieldName, meta)
  343. // if err != nil {
  344. // return nil, err
  345. // }
  346. // data = uint32(l)
  347. // }
  348. if err := binary.Write(w, binary.LittleEndian, data); err != nil {
  349. return nil, err
  350. }
  351. case reflect.Uint64:
  352. if err := binary.Write(w, binary.LittleEndian, valuev.Interface().(uint64)); err != nil {
  353. return nil, err
  354. }
  355. default:
  356. return nil, errors.New(fmt.Sprintf("Marshal not implemented for kind: %s", typev.Kind()))
  357. }
  358. return w.Bytes(), nil
  359. }
  360. func unmarshal(buf []byte, v interface{}, meta *Metadata) (interface{}, error) {
  361. typev := reflect.TypeOf(v)
  362. valuev := reflect.ValueOf(v)
  363. if meta == nil {
  364. meta = &Metadata{
  365. Tags: &TagMap{},
  366. Lens: make(map[string]uint64),
  367. Parent: v,
  368. ParentBuf: buf,
  369. Offsets: make(map[string]uint64),
  370. Count: make(map[string]uint64),
  371. CurrOffset: 0,
  372. }
  373. }
  374. bm, ok := v.(BinaryMarshallable)
  375. if ok {
  376. // Custom marshallable interface found.
  377. newbm, err := bm.UnmarshalBinary(buf, meta)
  378. if err != nil {
  379. return nil, err
  380. }
  381. if newbm != nil {
  382. return newbm, nil
  383. }
  384. return bm, nil
  385. }
  386. if typev.Kind() == reflect.Ptr {
  387. valuev = reflect.ValueOf(v).Elem()
  388. typev = valuev.Type()
  389. }
  390. offsetLen := func(ret uint64) error {
  391. if meta.Tags.Has("len") {
  392. ref, err := meta.Tags.GetString("len")
  393. if err != nil {
  394. return err
  395. }
  396. meta.Lens[ref] = ret
  397. }
  398. if meta.Tags.Has("offset") {
  399. ref, err := meta.Tags.GetString("offset")
  400. if err != nil {
  401. return err
  402. }
  403. meta.Offsets[ref] = ret
  404. }
  405. if meta.Tags.Has("count") {
  406. ref, err := meta.Tags.GetString("count")
  407. if err != nil {
  408. return err
  409. }
  410. meta.Count[ref] = ret
  411. }
  412. return nil
  413. }
  414. r := bytes.NewBuffer(buf)
  415. switch typev.Kind() {
  416. case reflect.Struct:
  417. m := &Metadata{
  418. Tags: &TagMap{},
  419. Lens: make(map[string]uint64),
  420. Parent: v,
  421. ParentBuf: buf,
  422. Offsets: make(map[string]uint64),
  423. Count: make(map[string]uint64),
  424. CurrOffset: 0,
  425. }
  426. for i := 0; i < typev.NumField(); i++ {
  427. m.CurrField = typev.Field(i).Name
  428. tags, err := parseTags(typev.Field(i))
  429. if err != nil {
  430. return nil, err
  431. }
  432. m.Tags = tags
  433. var data interface{}
  434. k := typev.Field(i).Type.Kind()
  435. switch k {
  436. case reflect.Struct:
  437. data, err = unmarshal(buf[m.CurrOffset:], valuev.Field(i).Addr().Interface(), m)
  438. default:
  439. data, err = unmarshal(buf[m.CurrOffset:], valuev.Field(i).Interface(), m)
  440. }
  441. if err != nil {
  442. return nil, err
  443. }
  444. // logx.Printf("name: %v, offset: %v", m.CurrField, m.CurrOffset)
  445. valuev.Field(i).Set(reflect.ValueOf(data))
  446. }
  447. v = reflect.Indirect(reflect.ValueOf(v)).Interface()
  448. meta.CurrOffset += m.CurrOffset
  449. return v, nil
  450. case reflect.Uint8:
  451. var ret uint8
  452. if err := binary.Read(r, binary.LittleEndian, &ret); err != nil {
  453. return nil, err
  454. }
  455. meta.CurrOffset += uint64(binary.Size(ret))
  456. return ret, nil
  457. case reflect.Uint16:
  458. var ret uint16
  459. if err := binary.Read(r, binary.LittleEndian, &ret); err != nil {
  460. return nil, err
  461. }
  462. if err := offsetLen(uint64(ret)); err != nil {
  463. return nil, err
  464. }
  465. meta.CurrOffset += uint64(binary.Size(ret))
  466. return ret, nil
  467. case reflect.Uint32:
  468. var ret uint32
  469. if err := binary.Read(r, binary.LittleEndian, &ret); err != nil {
  470. return nil, err
  471. }
  472. if err := offsetLen(uint64(ret)); err != nil {
  473. return nil, err
  474. }
  475. meta.CurrOffset += uint64(binary.Size(ret))
  476. return ret, nil
  477. case reflect.Uint64:
  478. var ret uint64
  479. if err := binary.Read(r, binary.LittleEndian, &ret); err != nil {
  480. return nil, err
  481. }
  482. meta.CurrOffset += uint64(binary.Size(ret))
  483. return ret, nil
  484. case reflect.Slice, reflect.Array:
  485. switch typev.Elem().Kind() {
  486. case reflect.Uint8:
  487. var length, offset int
  488. var err error
  489. if meta.Tags.Has("fixed") {
  490. if length, err = meta.Tags.GetInt("fixed"); err != nil {
  491. return nil, err
  492. }
  493. // Fixed length fields advance current offset
  494. meta.CurrOffset += uint64(length)
  495. } else {
  496. if val, ok := meta.Lens[meta.CurrField]; ok {
  497. length = int(val)
  498. } else {
  499. return nil, errors.New("Variable length field missing length reference in struct: " + meta.CurrField)
  500. }
  501. if val, ok := meta.Offsets[meta.CurrField]; ok {
  502. offset = int(val)
  503. } else {
  504. // No offset found in map. Use current offset
  505. offset = int(meta.CurrOffset)
  506. }
  507. // Variable length data is relative to parent/outer struct. Reset reader to point to beginning of data
  508. r = bytes.NewBuffer(meta.ParentBuf[offset : offset+length])
  509. // Variable length data fields do NOT advance current offset.
  510. meta.CurrOffset += uint64(length)
  511. }
  512. data := make([]byte, length)
  513. if err := binary.Read(r, binary.LittleEndian, &data); err != nil {
  514. return nil, err
  515. }
  516. // meta.CurrOffset += uint64(length)
  517. return data, nil
  518. case reflect.Uint16:
  519. length := len(buf) / 2
  520. if val, ok := meta.Count[meta.CurrField]; ok {
  521. length = int(val)
  522. }
  523. data := make([]uint16, length)
  524. if err := binary.Read(r, binary.LittleEndian, &data); err != nil {
  525. return nil, err
  526. }
  527. meta.CurrOffset += uint64(length * 2)
  528. return data, nil
  529. }
  530. default:
  531. return errors.New("Unmarshal not implemented for kind:" + typev.Kind().String()), nil
  532. }
  533. return nil, nil
  534. }
  535. func Unmarshal(buf []byte, v interface{}) error {
  536. _, err := Unmarshal2(buf, v)
  537. return err
  538. }
  539. func Unmarshal2(buf []byte, v interface{}) ([]byte, error) {
  540. meta := &Metadata{
  541. Tags: &TagMap{},
  542. Lens: make(map[string]uint64),
  543. Parent: v,
  544. ParentBuf: buf,
  545. Offsets: make(map[string]uint64),
  546. Count: make(map[string]uint64),
  547. CurrOffset: 0,
  548. }
  549. _, err := unmarshal(buf, v, meta)
  550. return buf[meta.CurrOffset:], err
  551. }