Berkeley Packet Filter (BPF) assembler.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.1KB

  1. // Copyright (c) 2019 Wijnand Modderman-Lenstra. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package bpf
  5. import (
  6. "log"
  7. "math"
  8. "strconv"
  9. "strings"
  10. "golang.org/x/net/bpf"
  11. "maze.io/x/bpf/internal/parser"
  12. )
  13. type dst uint8
  14. const (
  15. regA dst = iota
  16. regX
  17. reg2
  18. reg4
  19. invalid dst = 0xff
  20. )
  21. func parseNumber(text string) uint32 {
  22. switch {
  23. case strings.HasPrefix(text, "0x"):
  24. value, err := strconv.ParseUint(text[2:], 16, 32)
  25. if err != nil {
  26. log.Fatalln(err)
  27. }
  28. return uint32(value)
  29. case strings.HasPrefix(text, "0b"):
  30. value, err := strconv.ParseUint(text[2:], 2, 32)
  31. if err != nil {
  32. log.Fatalln(err)
  33. }
  34. return uint32(value)
  35. case strings.HasPrefix(text, "0o"):
  36. value, err := strconv.ParseUint(text[1:], 8, 32)
  37. if err != nil {
  38. log.Fatalln(err)
  39. }
  40. return uint32(value)
  41. default:
  42. value, err := strconv.Atoi(text)
  43. if err != nil {
  44. log.Fatalln(err)
  45. }
  46. return uint32(value)
  47. }
  48. }
  49. func parseAluOpcode(ctx *parser.AluOperatorContext) bpf.ALUOp {
  50. switch {
  51. case ctx.ADD() != nil:
  52. return bpf.ALUOpAdd
  53. case ctx.SUB() != nil:
  54. return bpf.ALUOpSub
  55. case ctx.MUL() != nil:
  56. return bpf.ALUOpMul
  57. case ctx.DIV() != nil:
  58. return bpf.ALUOpDiv
  59. case ctx.MOD() != nil:
  60. return bpf.ALUOpMod
  61. case ctx.AND() != nil:
  62. return bpf.ALUOpAnd
  63. case ctx.OR() != nil:
  64. return bpf.ALUOpOr
  65. case ctx.XOR() != nil:
  66. return bpf.ALUOpXor
  67. case ctx.LSH() != nil:
  68. return bpf.ALUOpShiftLeft
  69. case ctx.RSH() != nil:
  70. return bpf.ALUOpShiftRight
  71. default:
  72. return bpf.ALUOp(0)
  73. }
  74. }
  75. func parseJumpCondition(ctx *parser.JumpConditionalOperatorContext) bpf.JumpTest {
  76. switch {
  77. case ctx.JEQ() != nil:
  78. return bpf.JumpEqual
  79. case ctx.JNE() != nil:
  80. return bpf.JumpNotEqual
  81. case ctx.JGT() != nil:
  82. return bpf.JumpGreaterThan
  83. case ctx.JLT() != nil:
  84. return bpf.JumpLessThan
  85. case ctx.JGE() != nil:
  86. return bpf.JumpGreaterOrEqual
  87. case ctx.JLE() != nil:
  88. return bpf.JumpLessOrEqual
  89. case ctx.JSE() != nil:
  90. return bpf.JumpBitsSet
  91. default:
  92. return math.MaxUint16
  93. }
  94. }
  95. func parseExtension(ext string) bpf.Extension {
  96. switch ext {
  97. case "len": // skb->len
  98. return bpf.ExtLen
  99. case "proto": // skb->protocol
  100. return bpf.ExtProto
  101. case "type": // skb->pkt_type
  102. return bpf.ExtType
  103. case "poff": // Payload start offset
  104. return bpf.ExtPayloadOffset
  105. case "ifidx": // skb->dev->ifindex
  106. return bpf.ExtInterfaceIndex
  107. case "nla": // Netlink attribute of type X with offset A
  108. return bpf.ExtNetlinkAttr
  109. case "nlan": // Nested Netlink attribute of type X with offset A
  110. return bpf.ExtNetlinkAttrNested
  111. case "mark": // skb->mark
  112. return bpf.ExtMark
  113. case "queue": // skb->queue_mapping
  114. return bpf.ExtQueue
  115. case "hatype": // skb->dev->type
  116. return bpf.ExtLinkLayerType
  117. case "rxhash": // skb->hash
  118. return bpf.ExtRXHash
  119. case "cpu": // raw_smp_processor_id()
  120. return bpf.ExtCPUID
  121. case "vlan_tci": // skb_vlan_tag_get(skb)
  122. return bpf.ExtVLANTag
  123. case "vlan_avail": // skb_vlan_tag_present(skb)
  124. return bpf.ExtVLANTagPresent
  125. case "vlan_tpid": // skb->vlan_proto
  126. return bpf.ExtVLANProto
  127. case "rand": // prandom_u32()
  128. return bpf.ExtRand
  129. default:
  130. return 0
  131. }
  132. }