hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/samples/pktgen/functions.sh
....@@ -167,3 +167,168 @@
167167
168168 echo $node_cpu_list
169169 }
170
+
171
+# Check $1 is in between $2, $3 ($2 <= $1 <= $3)
172
+function in_between() { [[ ($1 -ge $2) && ($1 -le $3) ]] ; }
173
+
174
+# Extend shrunken IPv6 address.
175
+# fe80::42:bcff:fe84:e10a => fe80:0:0:0:42:bcff:fe84:e10a
176
+function extend_addr6()
177
+{
178
+ local addr=$1
179
+ local sep=: sep2=::
180
+ local sep_cnt=$(tr -cd $sep <<< $1 | wc -c)
181
+ local shrink
182
+
183
+ # separator count should be (2 <= $sep_cnt <= 7)
184
+ if ! (in_between $sep_cnt 2 7); then
185
+ err 5 "Invalid IP6 address: $1"
186
+ fi
187
+
188
+ # if shrink '::' occurs multiple, it's malformed.
189
+ shrink=( $(egrep -o "$sep{2,}" <<< $addr) )
190
+ if [[ ${#shrink[@]} -ne 0 ]]; then
191
+ if [[ ${#shrink[@]} -gt 1 || ( ${shrink[0]} != $sep2 ) ]]; then
192
+ err 5 "Invalid IP6 address: $1"
193
+ fi
194
+ fi
195
+
196
+ # add 0 at begin & end, and extend addr by adding :0
197
+ [[ ${addr:0:1} == $sep ]] && addr=0${addr}
198
+ [[ ${addr: -1} == $sep ]] && addr=${addr}0
199
+ echo "${addr/$sep2/$(printf ':0%.s' $(seq $[8-sep_cnt])):}"
200
+}
201
+
202
+# Given a single IP(v4/v6) address, whether it is valid.
203
+function validate_addr()
204
+{
205
+ # check function is called with (funcname)6
206
+ [[ ${FUNCNAME[1]: -1} == 6 ]] && local IP6=6
207
+ local bitlen=$[ IP6 ? 128 : 32 ]
208
+ local len=$[ IP6 ? 8 : 4 ]
209
+ local max=$[ 2**(len*2)-1 ]
210
+ local net prefix
211
+ local addr sep
212
+
213
+ IFS='/' read net prefix <<< $1
214
+ [[ $IP6 ]] && net=$(extend_addr6 $net)
215
+
216
+ # if prefix exists, check (0 <= $prefix <= $bitlen)
217
+ if [[ -n $prefix ]]; then
218
+ if ! (in_between $prefix 0 $bitlen); then
219
+ err 5 "Invalid prefix: /$prefix"
220
+ fi
221
+ fi
222
+
223
+ # set separator for each IP(v4/v6)
224
+ [[ $IP6 ]] && sep=: || sep=.
225
+ IFS=$sep read -a addr <<< $net
226
+
227
+ # array length
228
+ if [[ ${#addr[@]} != $len ]]; then
229
+ err 5 "Invalid IP$IP6 address: $1"
230
+ fi
231
+
232
+ # check each digit (0 <= $digit <= $max)
233
+ for digit in "${addr[@]}"; do
234
+ [[ $IP6 ]] && digit=$[ 16#$digit ]
235
+ if ! (in_between $digit 0 $max); then
236
+ err 5 "Invalid IP$IP6 address: $1"
237
+ fi
238
+ done
239
+
240
+ return 0
241
+}
242
+
243
+function validate_addr6() { validate_addr $@ ; }
244
+
245
+# Given a single IP(v4/v6) or CIDR, return minimum and maximum IP addr.
246
+function parse_addr()
247
+{
248
+ # check function is called with (funcname)6
249
+ [[ ${FUNCNAME[1]: -1} == 6 ]] && local IP6=6
250
+ local net prefix
251
+ local min_ip max_ip
252
+
253
+ IFS='/' read net prefix <<< $1
254
+ [[ $IP6 ]] && net=$(extend_addr6 $net)
255
+
256
+ if [[ -z $prefix ]]; then
257
+ min_ip=$net
258
+ max_ip=$net
259
+ else
260
+ # defining array for converting Decimal 2 Binary
261
+ # 00000000 00000001 00000010 00000011 00000100 ...
262
+ local d2b='{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}'
263
+ [[ $IP6 ]] && d2b+=$d2b
264
+ eval local D2B=($d2b)
265
+
266
+ local bitlen=$[ IP6 ? 128 : 32 ]
267
+ local remain=$[ bitlen-prefix ]
268
+ local octet=$[ IP6 ? 16 : 8 ]
269
+ local min_mask max_mask
270
+ local min max
271
+ local ip_bit
272
+ local ip sep
273
+
274
+ # set separator for each IP(v4/v6)
275
+ [[ $IP6 ]] && sep=: || sep=.
276
+ IFS=$sep read -ra ip <<< $net
277
+
278
+ min_mask="$(printf '1%.s' $(seq $prefix))$(printf '0%.s' $(seq $remain))"
279
+ max_mask="$(printf '0%.s' $(seq $prefix))$(printf '1%.s' $(seq $remain))"
280
+
281
+ # calculate min/max ip with &,| operator
282
+ for i in "${!ip[@]}"; do
283
+ digit=$[ IP6 ? 16#${ip[$i]} : ${ip[$i]} ]
284
+ ip_bit=${D2B[$digit]}
285
+
286
+ idx=$[ octet*i ]
287
+ min[$i]=$[ 2#$ip_bit & 2#${min_mask:$idx:$octet} ]
288
+ max[$i]=$[ 2#$ip_bit | 2#${max_mask:$idx:$octet} ]
289
+ [[ $IP6 ]] && { min[$i]=$(printf '%X' ${min[$i]});
290
+ max[$i]=$(printf '%X' ${max[$i]}); }
291
+ done
292
+
293
+ min_ip=$(IFS=$sep; echo "${min[*]}")
294
+ max_ip=$(IFS=$sep; echo "${max[*]}")
295
+ fi
296
+
297
+ echo $min_ip $max_ip
298
+}
299
+
300
+function parse_addr6() { parse_addr $@ ; }
301
+
302
+# Given a single or range of port(s), return minimum and maximum port number.
303
+function parse_ports()
304
+{
305
+ local port_str=$1
306
+ local port_list
307
+ local min_port
308
+ local max_port
309
+
310
+ IFS="-" read -ra port_list <<< $port_str
311
+
312
+ min_port=${port_list[0]}
313
+ max_port=${port_list[1]:-$min_port}
314
+
315
+ echo $min_port $max_port
316
+}
317
+
318
+# Given a minimum and maximum port, verify port number.
319
+function validate_ports()
320
+{
321
+ local min_port=$1
322
+ local max_port=$2
323
+
324
+ # 1 <= port <= 65535
325
+ if (in_between $min_port 1 65535); then
326
+ if (in_between $max_port 1 65535); then
327
+ if [[ $min_port -le $max_port ]]; then
328
+ return 0
329
+ fi
330
+ fi
331
+ fi
332
+
333
+ err 5 "Invalid port(s): $min_port-$max_port"
334
+}