blob: a5358698273dd227767cb7f8262cc27d941903ff [file] [log] [blame]
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +09001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package core
18
19import (
20 "errors"
21 "github.com/google/gopacket"
22 "github.com/google/gopacket/layers"
23 "github.com/google/gopacket/pcap"
24 "log"
25 "net"
26)
27
28func RecvWorker(io *Ioinfo, handler *pcap.Handle, r chan Packet) {
29 log.Printf("recvWorker runs. handler: %v", *handler)
30 packetSource := gopacket.NewPacketSource(handler, handler.LinkType())
31 for packet := range packetSource.Packets() {
32 log.Printf("recv packet from IF: %v \n", *handler)
33 //log.Println(packet.Dump())
34 pkt := Packet{}
35 pkt.Info = io
36 pkt.Pkt = packet
37 r <- pkt
38 }
39}
40
41func SendUni(handle *pcap.Handle, packet gopacket.Packet) {
42 handle.WritePacketData(packet.Data())
43 log.Printf("send packet to UNI-IF: %v \n", *handle)
44 //log.Println(packet.Dump())
45}
46
47func SendNni(handle *pcap.Handle, packet gopacket.Packet) {
48 handle.WritePacketData(packet.Data())
49 log.Printf("send packet to NNI-IF: %v \n", *handle)
50 //log.Println(packet.Dump())
51}
52
53func PopVLAN(pkt gopacket.Packet) (gopacket.Packet, uint16, error) {
54 if layer := getDot1QLayer(pkt); layer != nil {
55 if eth := getEthernetLayer(pkt); eth != nil {
56 ethernetLayer := &layers.Ethernet{
57 SrcMAC: eth.SrcMAC,
58 DstMAC: eth.DstMAC,
59 EthernetType: layer.Type,
60 }
61 buffer := gopacket.NewSerializeBuffer()
62 gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
63 ethernetLayer,
64 gopacket.Payload(layer.Payload),
65 )
66 retpkt := gopacket.NewPacket(
67 buffer.Bytes(),
68 layers.LayerTypeEthernet,
69 gopacket.Default,
70 )
71 vid := uint16(4095 & layer.VLANIdentifier)
72 log.Printf("Pop the 802.1Q header (VID: %d)", vid)
73 return retpkt, vid, nil
74 }
75 }
76 //return pkt, 1, nil
77 return nil, 0, errors.New("failed to pop vlan")
78}
79
80func PushVLAN(pkt gopacket.Packet, vid uint16) (gopacket.Packet, error) {
81 if eth := getEthernetLayer(pkt); eth != nil {
82 ethernetLayer := &layers.Ethernet{
83 SrcMAC: eth.SrcMAC,
84 DstMAC: eth.DstMAC,
85 EthernetType: 0x8100,
86 }
87 dot1qLayer := &layers.Dot1Q{
88 Type: eth.EthernetType,
89 VLANIdentifier: uint16(vid),
90 }
91
92 buffer := gopacket.NewSerializeBuffer()
93 gopacket.SerializeLayers(
94 buffer,
95 gopacket.SerializeOptions{
96 FixLengths: false,
97 },
98 ethernetLayer,
99 dot1qLayer,
100 gopacket.Payload(eth.Payload),
101 )
102 ret := gopacket.NewPacket(
103 buffer.Bytes(),
104 layers.LayerTypeEthernet,
105 gopacket.Default,
106 )
107 log.Printf("Push the 802.1Q header (VID: %d)", vid)
108 return ret, nil
109 }
110 return nil, errors.New("failed to push vlan")
111}
112
113func getEthernetLayer(pkt gopacket.Packet) *layers.Ethernet {
114 eth := &layers.Ethernet{}
115 if ethLayer := pkt.Layer(layers.LayerTypeEthernet); ethLayer != nil {
116 eth, _ = ethLayer.(*layers.Ethernet)
117 }
118 return eth
119}
120func getDot1QLayer(pkt gopacket.Packet) (dot1q *layers.Dot1Q) {
121 if dot1qLayer := pkt.Layer(layers.LayerTypeDot1Q); dot1qLayer != nil {
122 dot1q = dot1qLayer.(*layers.Dot1Q)
123 }
124 return dot1q
125}
126
127func getMacAddress(ifName string) net.HardwareAddr {
128 var err error
129 var netIf *net.Interface
130 var hwAddr net.HardwareAddr
131 if netIf, err = net.InterfaceByName(ifName); err == nil {
132 hwAddr = netIf.HardwareAddr
133 }
134 return hwAddr
135}