blob: cc4eb940e3bce4ff0148fa99b67f3e439c7a3fbe [file] [log] [blame]
Brian O'Connor6a37ea92017-08-03 22:45:59 -07001// Copyright 2016 Open Networking Foundation
David K. Bainbridgedf9df632016-07-07 18:47:46 -07002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
David K. Bainbridge97ee8052016-06-14 00:52:07 -070014package main
15
16import (
17 "encoding/json"
David K. Bainbridge97ee8052016-06-14 00:52:07 -070018 "net/http"
David K. Bainbridgea9c2e0a2016-07-01 18:33:50 -070019 "strings"
David K. Bainbridge97ee8052016-06-14 00:52:07 -070020)
21
22type Vendors interface {
23 Switchq(mac string) (bool, error)
24}
25
26type VendorRec struct {
27 Prefix string `json:"prefix"`
28 Vendor string `json:"vendor"`
29 Provision bool `json:"provision"`
30}
31
32type VendorsData struct {
33 Vendors map[string]VendorRec
34}
35
36func NewVendors(spec string) (Vendors, error) {
37 v := VendorsData{}
38 v.Vendors = make(map[string]VendorRec)
39
40 t := &http.Transport{}
41 t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
42 c := &http.Client{Transport: t}
43 res, err := c.Get(spec)
44 if err != nil {
45 return nil, err
46 }
47 defer res.Body.Close()
48
49 data := make([]VendorRec, 0)
50 decoder := json.NewDecoder(res.Body)
51 err = decoder.Decode(&data)
52 if err != nil {
53 return nil, err
54 }
55 for _, rec := range data {
56 v.Vendors[rec.Prefix] = rec
57 }
David K. Bainbridgea9c2e0a2016-07-01 18:33:50 -070058 log.Debugf("known vendors %+v", v.Vendors)
David K. Bainbridge97ee8052016-06-14 00:52:07 -070059
60 return &v, nil
61}
62
63func (v *VendorsData) Switchq(mac string) (bool, error) {
Luca Prete57e76272017-12-11 14:15:08 -080064 // If there is a "full" MAC then attempt to see if that can
65 // be matched. If matched, accept that result and look no
66 // further
67 if len(mac) == 17 {
68 if rec, ok := v.Vendors[strings.ToUpper(mac)]; ok {
69 return rec.Provision, nil
70 }
David K. Bainbridge97ee8052016-06-14 00:52:07 -070071 }
72
Luca Prete57e76272017-12-11 14:15:08 -080073 // If we have at least a OUI, look to see if that can be
74 // be matched. If matched, accept that result and look no
75 // further.
76 if len(mac) >= 8 {
77 if rec, ok := v.Vendors[strings.ToUpper(mac[0:8])]; ok {
78 return rec.Provision, nil
79 }
80 }
81
82 // No match found, so assume false.
83 return false, nil
David K. Bainbridge97ee8052016-06-14 00:52:07 -070084}