Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
ebpfCAT
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Martin Teichmann
ebpfCAT
Commits
0e57945b
Commit
0e57945b
authored
2 years ago
by
Martin Teichmann
Browse files
Options
Downloads
Patches
Plain Diff
add switch_endian method, and use it
parent
1450e2c4
No related branches found
Branches containing commit
No related tags found
1 merge request
!15
add a PacketVar to XDP
Pipeline
#98711
failed
2 years ago
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ebpfcat/ebpf.py
+62
-31
62 additions, 31 deletions
ebpfcat/ebpf.py
with
62 additions
and
31 deletions
ebpfcat/ebpf.py
+
62
−
31
View file @
0e57945b
...
@@ -546,10 +546,15 @@ class Expression:
...
@@ -546,10 +546,15 @@ class Expression:
__rand__
=
__and__
__rand__
=
__and__
def
__neg__
(
self
):
def
__neg__
(
self
):
return
Negate
(
self
.
ebpf
,
self
)
return
Negate
(
self
)
def
__abs__
(
self
):
def
__abs__
(
self
):
return
Absolute
(
self
.
ebpf
,
self
)
return
Absolute
(
self
)
def
switch_endian
(
self
,
fmt
):
if
isinstance
(
fmt
,
str
)
and
len
(
fmt
)
>
1
:
return
SwitchEndian
(
self
,
fmt
)
return
self
def
__bool__
(
self
):
def
__bool__
(
self
):
raise
AssembleError
(
"
Expression only has a value at execution time
"
)
raise
AssembleError
(
"
Expression only has a value at execution time
"
)
...
@@ -590,7 +595,6 @@ class Expression:
...
@@ -590,7 +595,6 @@ class Expression:
with
self
.
get_address
(
dst
,
long
)
as
(
src
,
fmt
):
with
self
.
get_address
(
dst
,
long
)
as
(
src
,
fmt
):
self
.
ebpf
.
append
(
Opcode
.
LD
+
fmt_to_opcode
(
fmt
),
self
.
ebpf
.
append
(
Opcode
.
LD
+
fmt_to_opcode
(
fmt
),
dst
,
src
,
0
,
0
)
dst
,
src
,
0
,
0
)
self
.
ebpf
.
append_endian
(
fmt
,
dst
)
yield
dst
,
long
yield
dst
,
long
@contextmanager
@contextmanager
...
@@ -656,38 +660,54 @@ class Binary(Expression):
...
@@ -656,38 +660,54 @@ class Binary(Expression):
and
self
.
right
.
contains
(
no
))
and
self
.
right
.
contains
(
no
))
class
Negate
(
Expression
):
class
Unary
(
Expression
):
def
__init__
(
self
,
ebpf
,
arg
):
def
__init__
(
self
,
arg
):
self
.
ebpf
=
ebpf
self
.
arg
=
arg
self
.
arg
=
arg
self
.
signed
=
True
self
.
ebpf
=
arg
.
ebpf
self
.
signed
=
arg
.
signed
self
.
fixed
=
arg
.
fixed
self
.
fixed
=
arg
.
fixed
@contextmanager
@contextmanager
def
calculate
(
self
,
dst
,
long
,
force
=
False
):
def
calculate
(
self
,
dst
,
long
,
force
=
False
):
with
self
.
arg
.
calculate
(
dst
,
long
,
force
)
as
(
dst
,
long
):
with
self
.
arg
.
calculate
(
dst
,
long
,
force
)
as
(
dst
,
long
):
self
.
ebpf
.
append
(
Opcode
.
NEG
+
Opcode
.
LONG
*
long
,
dst
,
0
,
0
,
0
)
self
.
calculate_unary
(
dst
,
long
)
yield
dst
,
long
yield
dst
,
long
def
contains
(
self
,
no
):
def
contains
(
self
,
no
):
return
self
.
arg
.
contains
(
no
)
return
self
.
arg
.
contains
(
no
)
class
Absolute
(
Expression
):
class
Negate
(
Unary
):
def
__init__
(
self
,
ebpf
,
arg
):
def
__init__
(
self
,
arg
):
self
.
ebpf
=
ebpf
super
().
__init__
(
arg
)
self
.
arg
=
arg
self
.
signed
=
True
self
.
fixed
=
arg
.
fixed
@contextmanager
def
calculate_unary
(
self
,
dst
,
long
):
def
calculate
(
self
,
dst
,
long
,
force
=
False
):
self
.
ebpf
.
append
(
Opcode
.
NEG
+
Opcode
.
LONG
*
long
,
dst
,
0
,
0
,
0
)
with
self
.
arg
.
calculate
(
dst
,
long
,
force
)
as
(
dst
,
long
):
with
self
.
ebpf
.
sr
[
dst
]
<
0
:
self
.
ebpf
.
sr
[
dst
]
=
-
self
.
ebpf
.
sr
[
dst
]
yield
dst
,
long
def
contains
(
self
,
no
):
return
self
.
arg
.
contains
(
no
)
class
Absolute
(
Unary
):
def
__init__
(
self
,
arg
):
super
().
__init__
(
arg
)
self
.
signed
=
False
def
calculate_unary
(
self
,
dst
,
long
):
with
self
.
ebpf
.
sr
[
dst
]
<
0
:
self
.
ebpf
.
sr
[
dst
]
=
-
self
.
ebpf
.
sr
[
dst
]
class
SwitchEndian
(
Unary
):
def
__init__
(
self
,
arg
,
fmt
):
super
().
__init__
(
arg
)
self
.
fmt
=
fmt
def
calculate_unary
(
self
,
dst
,
long
):
endian
,
size
=
self
.
fmt
if
endian
==
"
<
"
:
opcode
=
Opcode
.
LE
elif
endian
in
"
>!
"
:
opcode
=
Opcode
.
BE
self
.
ebpf
.
append
(
opcode
,
dst
,
0
,
0
,
calcsize
(
size
)
*
8
)
class
Sum
(
Binary
):
class
Sum
(
Binary
):
...
@@ -796,6 +816,11 @@ class Constant(Expression):
...
@@ -796,6 +816,11 @@ class Constant(Expression):
self
.
ebpf
.
append
(
Opcode
.
W
,
0
,
0
,
0
,
value
>>
32
)
self
.
ebpf
.
append
(
Opcode
.
W
,
0
,
0
,
0
,
value
>>
32
)
yield
dst
,
not
(
-
0x80000000
<=
value
<
0x100000000
)
yield
dst
,
not
(
-
0x80000000
<=
value
<
0x100000000
)
def
switch_endian
(
self
,
fmt
):
if
not
isinstance
(
fmt
,
str
)
or
len
(
fmt
)
==
1
:
return
self
return
Constant
(
self
.
ebpf
,
*
unpack
(
fmt
,
pack
(
fmt
[
-
1
],
self
.
value
)))
class
Register
(
Expression
):
class
Register
(
Expression
):
"""
represent one EBPF register
"""
"""
represent one EBPF register
"""
...
@@ -881,13 +906,17 @@ class Memory(Expression):
...
@@ -881,13 +906,17 @@ class Memory(Expression):
@contextmanager
@contextmanager
def
calculate
(
self
,
dst
,
long
,
force
=
False
):
def
calculate
(
self
,
dst
,
long
,
force
=
False
):
if
self
.
has_endian
():
with
self
.
without_endian
().
switch_endian
(
self
.
fmt
)
\
.
calculate
(
dst
,
long
,
force
)
as
(
dst
,
long
):
yield
dst
,
long
return
with
ExitStack
()
as
exitStack
:
with
ExitStack
()
as
exitStack
:
if
isinstance
(
self
.
address
,
Sum
):
if
isinstance
(
self
.
address
,
Sum
):
dst
=
exitStack
.
enter_context
(
self
.
ebpf
.
get_free_register
(
dst
))
dst
=
exitStack
.
enter_context
(
self
.
ebpf
.
get_free_register
(
dst
))
opcode
=
fmt_to_opcode
(
self
.
fmt
)
opcode
=
fmt_to_opcode
(
self
.
fmt
)
self
.
ebpf
.
append
(
Opcode
.
LD
+
opcode
,
dst
,
self
.
address
.
left
.
no
,
self
.
ebpf
.
append
(
Opcode
.
LD
+
opcode
,
dst
,
self
.
address
.
left
.
no
,
self
.
address
.
right
.
value
,
0
)
self
.
address
.
right
.
value
,
0
)
self
.
ebpf
.
append_endian
(
self
.
fmt
,
dst
)
else
:
else
:
dst
,
_
=
exitStack
.
enter_context
(
dst
,
_
=
exitStack
.
enter_context
(
super
().
calculate
(
dst
,
long
,
force
))
super
().
calculate
(
dst
,
long
,
force
))
...
@@ -897,7 +926,7 @@ class Memory(Expression):
...
@@ -897,7 +926,7 @@ class Memory(Expression):
self
.
ebpf
.
r
[
dst
]
>>=
self
.
fmt
[
0
]
self
.
ebpf
.
r
[
dst
]
>>=
self
.
fmt
[
0
]
yield
dst
,
"
B
"
yield
dst
,
"
B
"
else
:
else
:
yield
dst
,
self
.
fmt
in
"
QqA
"
yield
dst
,
self
.
fmt
[
-
1
]
in
"
QqA
x
"
@contextmanager
@contextmanager
def
get_address
(
self
,
dst
,
long
,
force
=
False
):
def
get_address
(
self
,
dst
,
long
,
force
=
False
):
...
@@ -915,6 +944,14 @@ class Memory(Expression):
...
@@ -915,6 +944,14 @@ class Memory(Expression):
def
fixed
(
self
):
def
fixed
(
self
):
return
isinstance
(
self
.
fmt
,
str
)
and
self
.
fmt
==
"
x
"
return
isinstance
(
self
.
fmt
,
str
)
and
self
.
fmt
==
"
x
"
def
has_endian
(
self
):
return
isinstance
(
self
.
fmt
,
str
)
and
len
(
self
.
fmt
)
>
1
def
without_endian
(
self
):
if
self
.
has_endian
():
return
Memory
(
self
.
ebpf
,
self
.
fmt
[
-
1
],
self
.
address
)
return
self
def
__invert__
(
self
):
def
__invert__
(
self
):
if
not
isinstance
(
self
.
fmt
,
tuple
)
or
self
.
fmt
[
1
]
!=
1
:
if
not
isinstance
(
self
.
fmt
,
tuple
)
or
self
.
fmt
[
1
]
!=
1
:
return
NotImplemented
return
NotImplemented
...
@@ -953,12 +990,7 @@ class Memory(Expression):
...
@@ -953,12 +990,7 @@ class Memory(Expression):
value
=
value
.
value
value
=
value
.
value
opcode
=
Opcode
.
XADD
opcode
=
Opcode
.
XADD
elif
not
isinstance
(
value
,
Expression
):
elif
not
isinstance
(
value
,
Expression
):
if
self
.
fmt
==
"
x
"
:
value
=
Constant
(
self
.
ebpf
,
value
)
value
=
Constant
(
self
.
ebpf
,
value
)
else
:
value
=
Constant
(
self
.
ebpf
,
*
unpack
(
self
.
fmt
,
pack
(
self
.
fmt
[
-
1
],
value
)))
if
self
.
fmt
==
"
x
"
and
not
value
.
fixed
:
if
self
.
fmt
==
"
x
"
and
not
value
.
fixed
:
value
*=
Expression
.
FIXED_BASE
value
*=
Expression
.
FIXED_BASE
elif
self
.
fmt
!=
"
x
"
and
value
.
fixed
:
elif
self
.
fmt
!=
"
x
"
and
value
.
fixed
:
...
@@ -970,6 +1002,7 @@ class Memory(Expression):
...
@@ -970,6 +1002,7 @@ class Memory(Expression):
dst
,
_
=
exitStack
.
enter_context
(
dst
,
_
=
exitStack
.
enter_context
(
self
.
address
.
calculate
(
None
,
True
))
self
.
address
.
calculate
(
None
,
True
))
offset
=
0
offset
=
0
value
=
value
.
switch_endian
(
self
.
fmt
)
if
value
.
small_constant
and
opcode
==
Opcode
.
STX
:
if
value
.
small_constant
and
opcode
==
Opcode
.
STX
:
self
.
ebpf
.
append
(
Opcode
.
ST
+
fmt_to_opcode
(
self
.
fmt
),
dst
,
0
,
self
.
ebpf
.
append
(
Opcode
.
ST
+
fmt_to_opcode
(
self
.
fmt
),
dst
,
0
,
offset
,
int
(
value
.
value
))
offset
,
int
(
value
.
value
))
...
@@ -977,8 +1010,6 @@ class Memory(Expression):
...
@@ -977,8 +1010,6 @@ class Memory(Expression):
src
,
_
=
exitStack
.
enter_context
(
src
,
_
=
exitStack
.
enter_context
(
value
.
calculate
(
None
,
isinstance
(
self
.
fmt
,
str
)
value
.
calculate
(
None
,
isinstance
(
self
.
fmt
,
str
)
and
self
.
fmt
[
-
1
]
in
'
qQx
'
))
and
self
.
fmt
[
-
1
]
in
'
qQx
'
))
if
not
isinstance
(
value
,
Constant
):
self
.
ebpf
.
append_endian
(
self
.
fmt
,
src
)
self
.
ebpf
.
append
(
opcode
+
fmt_to_opcode
(
self
.
fmt
),
self
.
ebpf
.
append
(
opcode
+
fmt_to_opcode
(
self
.
fmt
),
dst
,
src
,
offset
,
0
)
dst
,
src
,
offset
,
0
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment