-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathtype_checking.ks
More file actions
167 lines (137 loc) · 4.24 KB
/
Copy pathtype_checking.ks
File metadata and controls
167 lines (137 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// This file demonstrates the type checking capabilities
// Type definitions for comprehensive type checking
include "xdp.kh"
type IpAddress = u32
type PacketSize = u16
struct PacketHeader {
src_ip: IpAddress,
dst_ip: IpAddress,
protocol: u8,
length: PacketSize,
}
enum ProtocolType {
TCP = 6,
UDP = 17,
ICMP = 1
}
enum FilterDecision {
Allow = 0,
Block = 1,
Log = 2
}
// Global map for demonstration
pin var connection_stats : hash<IpAddress, u64>(1024)
@helper
fn extract_header(ctx: *xdp_md) -> *PacketHeader {
// Type checker validates context parameter access
var data = ctx->data
var data_end = ctx->data_end
// Type checker ensures arithmetic operations are on numeric types
var packet_len = data_end - data
if (packet_len < 20) {
return null
}
// Type checker validates struct field types
var header: PacketHeader = PacketHeader {
src_ip: 0xC0A80001, // Type checked as u32 (IpAddress)
dst_ip: 0xC0A80002, // Type checked as u32 (IpAddress)
protocol: 6, // Type checked as u8
length: packet_len // Type promoted from arithmetic to u16
}
return &header
}
@helper
fn classify_protocol(proto: u8) -> ProtocolType {
// Type checker validates enum constant access
return match (proto) {
6: TCP,
17: UDP,
1: ICMP,
default: TCP // Default to TCP for unknown protocols
}
}
@helper
fn update_statistics(header: PacketHeader) {
// Type checker validates map operations and key/value types
if (var current_count = connection_stats[header.src_ip]) {
// Type checker ensures arithmetic on compatible types
connection_stats[header.src_ip] = current_count + 1
} else {
// Type checker validates map insert operation
connection_stats[header.src_ip] = 1
}
}
@helper
fn make_decision(header: PacketHeader) -> FilterDecision {
// Type checker validates function call signatures
var proto_type = classify_protocol(header.protocol)
return match (proto_type) {
TCP: {
// Type checker validates field access on struct types
if (header.length > 1500) {
Block
} else {
Allow
}
},
UDP: Allow,
ICMP: Log,
default: Block
}
}
@xdp fn packet_analyzer(ctx: *xdp_md) -> xdp_action {
// Type checker validates context parameter and return type
var packet_header = extract_header(ctx)
if (packet_header == null) {
// Type checker validates return type compatibility
return XDP_DROP
}
// Type checker validates function calls with correct types
update_statistics(*packet_header)
var decision = make_decision(*packet_header)
// Type checker validates match expressions and enum types
return match (decision) {
Allow: XDP_PASS,
Block: XDP_DROP,
Log: {
// Type checker validates built-in function signatures
print("Logging packet", 14)
XDP_PASS
}
}
}
// Additional function demonstrating type inference
fn calculate_bandwidth(packet_count: u64, packet_size: u16) -> u64 {
// Type checker infers result type from operand types
var total_bytes = packet_count * packet_size // u64 * u16 -> u64
var bandwidth = total_bytes * 8 // u64 * literal -> u64
return bandwidth
}
// Function demonstrating error detection
fn type_error_examples() {
// The following would be caught by the type checker:
// 1. Type mismatch in assignment
// var x: u32 = true // ERROR: cannot assign bool to u32
// 2. Invalid field access
// var header: PacketHeader = get_header()
// var invalid = header.nonexistent_field // ERROR: field not found
// 3. Function call with wrong types
// var result = calculate_bandwidth(true, "hello") // ERROR: wrong argument types
// 4. Arithmetic on incompatible types
// var bad_math = 42 + true // ERROR: cannot add u32 and bool
// 5. Missing return in non-void function
// fn missing_return() -> u32 {
// var x = 42
// // ERROR: missing return statement
// }
}
fn main() -> i32 {
var prog = load(packet_analyzer)
attach(prog, "eth0", 0)
print("Type checking demo program attached to eth0")
print("Demonstrating comprehensive type checking capabilities...")
// Show type checking working properly
detach(prog)
print("Type checking demo program detached")
return 0
}