@@ -28,6 +28,8 @@ func (p *Parser) parseMatch(ms *[]Match) (state, error) {
28
28
s , err = p .parseUdp (& m .Flags )
29
29
case "statistic" :
30
30
s , err = p .parseStatistic (& m .Flags )
31
+ case "multiport" :
32
+ s , err = p .parseMultiport (& m .Flags )
31
33
default :
32
34
if _ , ok := matchModules [lit ]; ok {
33
35
return sError , fmt .Errorf ("match modules %q is not implemented" , lit )
@@ -385,6 +387,78 @@ func (p *Parser) parseTcp(f *map[string]Flag) (state, error) {
385
387
return sStart , nil
386
388
}
387
389
390
+ func (p * Parser ) parseMultiport (f * map [string ]Flag ) (state , error ) {
391
+ s := sStart
392
+ for tok , lit := p .scanIgnoreWhitespace (); tok != EOF ; tok , lit = p .scanIgnoreWhitespace () {
393
+ for nextValue := false ; ! nextValue ; {
394
+ nextValue = true
395
+ switch s {
396
+ case sStart :
397
+ switch tok {
398
+ case NOT :
399
+ s = sINotF
400
+ case FLAG :
401
+ s = sIF
402
+ nextValue = false
403
+ default :
404
+ return sError , fmt .Errorf ("unexpected token %q, expected flag, or \" !\" " , lit )
405
+ }
406
+ case sINotF :
407
+ switch {
408
+ case lit == "--dports" || lit == "--destination-ports" :
409
+ (* f )["destination-ports" ] = Flag {
410
+ Not : true ,
411
+ Values : p .parsePorts (),
412
+ }
413
+ s = sStart
414
+ case lit == "--sports" || lit == "--source-ports" :
415
+ (* f )["source-ports" ] = Flag {
416
+ Not : true ,
417
+ Values : p .parsePorts (),
418
+ }
419
+ s = sStart
420
+ case lit == "--ports" :
421
+ (* f )["ports" ] = Flag {
422
+ Not : true ,
423
+ Values : p .parsePorts (),
424
+ }
425
+ s = sStart
426
+ default :
427
+ p .unscan (1 )
428
+ return sNot , nil
429
+ }
430
+ case sIF :
431
+ switch {
432
+ case lit == "--dports" || lit == "--destination-ports" :
433
+ (* f )["destination-ports" ] = Flag {
434
+ Values : p .parsePorts (),
435
+ }
436
+ s = sStart
437
+ case lit == "--sports" || lit == "--source-ports" :
438
+ (* f )["source-ports" ] = Flag {
439
+ Values : p .parsePorts (),
440
+ }
441
+ s = sStart
442
+ case lit == "--ports" :
443
+ (* f )["ports" ] = Flag {
444
+ Not : true ,
445
+ Values : p .parsePorts (),
446
+ }
447
+ s = sStart
448
+ default :
449
+ // The end of the match statement is reached.
450
+ p .unscan (1 )
451
+ return sStart , nil
452
+ }
453
+
454
+ default :
455
+ return sStart , errors .New ("unexpected error parsing match extension" )
456
+ }
457
+ }
458
+ }
459
+ return sStart , nil
460
+ }
461
+
388
462
func (p * Parser ) parsePort () string {
389
463
_ , l := p .scanIgnoreWhitespace ()
390
464
if t , _ := p .scanIgnoreWhitespace (); t == COLON {
@@ -396,6 +470,22 @@ func (p *Parser) parsePort() string {
396
470
return l
397
471
}
398
472
473
+ func (p * Parser ) parsePorts () []string {
474
+ var ports []string
475
+ _ , l := p .scanIgnoreWhitespace ()
476
+ ports = append (ports , l )
477
+ for {
478
+ if t , _ := p .scanIgnoreWhitespace (); t == COMMA {
479
+ _ , c := p .scan ()
480
+ ports = append (ports , c )
481
+ } else {
482
+ p .unscan (1 )
483
+ break
484
+ }
485
+ }
486
+ return ports
487
+ }
488
+
399
489
func (p * Parser ) parseList () (strs []string ) {
400
490
const (
401
491
sC state = iota * 2 + 1
0 commit comments