Skip to content

Commit

Permalink
lang: funcs: Validates mac address strings
Browse files Browse the repository at this point in the history
  • Loading branch information
S-ign committed Mar 22, 2021
1 parent 48fa796 commit 65e5271
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 0 deletions.
31 changes: 31 additions & 0 deletions examples/lang/mac.mcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import "fmt"
import "net"



$good_mac = "0a:1b:2c:3d:4f:56"
$bad_mac = "0a::9b:2z:3d:4f:56"
print "print0" {
msg => fmt.printf("%s: %t", $good_mac, net.is_macaddress($good_mac)),
}
print "print1" {
msg => fmt.printf("%s: %t", $bad_mac, net.is_macaddress($bad_mac)),
}

$good_mac1 = "0a-1b-2c-3d-4f-56"
$bad_mac1 = "0a-9b-2z-3d-4f-56"
print "print2" {
msg => fmt.printf("%s: %t", $good_mac1, net.is_macaddress($good_mac1)),
}
print "print3" {
msg => fmt.printf("%s: %t", $bad_mac1, net.is_macaddress($bad_mac1)),
}

$good_mac2 = "0a.1b.2c.3d.4f.56"
$bad_mac2 = "0a.9b.2z.3d.4f.56"
print "print4" {
msg => fmt.printf("%s: %t", $good_mac2, net.is_macaddress($good_mac2)),
}
print "print5" {
msg => fmt.printf("%s: %t", $bad_mac2, net.is_macaddress($bad_mac2)),
}
94 changes: 94 additions & 0 deletions lang/funcs/core/net/is_macaddress_func.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Mgmt
// Copyright (C) 2013-2021+ James Shubin and the project contributors
// Written by James Shubin <james@shubin.ca> and the project contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package corenet

import (
"strings"

"github.com/purpleidea/mgmt/lang/funcs/simple"
"github.com/purpleidea/mgmt/lang/types"
)

func init() {
simple.ModuleRegister(ModuleName, "is_macaddress", &types.FuncValue{
T: types.NewType("func(a str) bool"),
V: IsMacAddress,
})
}

// IsMacAddress validates mac address in string format that contains one of the
// accepted delimiter [":","-","."]
func IsMacAddress(input []types.Value) (types.Value, error) {
mac := input[0].Str()
if len(mac) != len("00:00:00:00:00:00") {
return &types.BoolValue{V: false}, nil
}
delimiter := strings.Split(mac, "")[2]
return &types.BoolValue{V: validate(mac, delimiter)}, nil
}

func validate(mac, delimiter string) bool {
// valid delimiters
delims := map[string]bool{
":": true,
"-": true,
".": true,
}
_, exists := delims[delimiter]
if !exists {
return false
}

// valid chars
chars := map[string]bool{
"0": true,
"1": true,
"2": true,
"3": true,
"4": true,
"5": true,
"6": true,
"7": true,
"8": true,
"9": true,
"a": true,
"b": true,
"c": true,
"d": true,
"e": true,
"f": true,
}

macSlice := strings.Split(mac, delimiter)
// validates that each split has 2 chars
for _, v := range macSlice {
if len(v) != 2 {
return false
}
v = strings.ToLower(v)
vs := strings.Split(v, "")
// validate that each char is in the valid chars slice
for _, c := range vs {
_, exists = chars[c]
if !exists {
return false
}
}
}
return true
}
67 changes: 67 additions & 0 deletions lang/funcs/core/net/is_macaddress_func_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Mgmt
// Copyright (C) 2013-2021+ James Shubin and the project contributors
// Written by James Shubin <james@shubin.ca> and the project contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package corenet

import (
"testing"

"github.com/purpleidea/mgmt/lang/types"
)

func TestIsMacAddress(t *testing.T) {
macAddressTests := []struct {
name string
mac string
expected bool
err error
}{
{"valid mac with :", "0a:1b:2c:3d:4f:56", true, nil},
{"valid mac with -", "0a-1b-2c-3d-4f-56", true, nil},
{"valid mac with .", "0a.1b.2c.3d.4f.56", true, nil},
{"valid mac with UPPERCASE", "0A:1B:2C:3D:4F:56", true, nil},
{"valid mac with UPPERCASE", "0A-1B-2C-3D-4F-56", true, nil},
{"valid mac with UPPERCASE", "0A.1B.2C.3D.4F.56", true, nil},
{"invalid mac invalid chars", "0x:1j:2c:3d:4m:56", false, nil},
{"invalid mac invalid chars", "0x-1j-2c-3d-4m-56", false, nil},
{"invalid mac invalid delimiter", "0a*1b*2c*3d*4f*56", false, nil},
{"invalid mac invalid delimiter", "0a=1b=2c=3d=4f=56", false, nil},
{"invalid mac invalid delimiter", "0a/1b/2c/3d/4f/56", false, nil},
{"invalid mac invalid delimiter", "0a;1b;2c;3d;4f;56", false, nil},
{"invalid mac mixed delimiters", "0a:1b:2c-3d:4f:56", false, nil},
{"invalid mac invalid delimiter position", "0a::1b2:c3d:4f:56", false, nil},
{"invalid mac invalid delimiter position", "0a--1b2-c3d-4f-56", false, nil},
}

for _, test := range macAddressTests {
t.Run(test.name, func(t *testing.T) {
test := test
// err will always return nil
output, _ := IsMacAddress([]types.Value{
&types.StrValue{V: test.mac},
})
expectedBool := &types.BoolValue{V: test.expected}

if err1 := output.Cmp(expectedBool); err1 != nil {
t.Errorf("mac: %v, expected: %v, got: %v", test.mac, expectedBool, output)
return
}

})
}

}

0 comments on commit 65e5271

Please sign in to comment.