Commit c8f46998 authored by 吴洲洋's avatar 吴洲洋

add upf-n4

parent 5aa2b2a5
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="dataSourceStorageLocal">
<data-source name="n4" uuid="7e4f659a-4bf0-4452-8335-c266af6bc8a1">
<database-info product="SQLite" version="3.31.1" jdbc-version="2.1" driver-name="SQLite JDBC" driver-version="3.31.1" dbms="SQLITE" exact-version="3.31.1" exact-driver-version="3.31">
<identifier-quote-string>&quot;</identifier-quote-string>
</database-info>
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
<secret-storage>master_key</secret-storage>
<auth-provider>no-auth</auth-provider>
<schema-mapping>
<introspection-scope>
<node kind="schema" qname="@" />
</introspection-scope>
</schema-mapping>
</data-source>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="n4" uuid="7e4f659a-4bf0-4452-8335-c266af6bc8a1">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/n4.db</jdbc-url>
</data-source>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<dataSource name="n4">
<database-model serializer="dbm" dbms="SQLITE" family-id="SQLITE" format-version="4.18">
<root id="1">
<ServerVersion>3.31.1</ServerVersion>
</root>
<schema id="2" parent="1" name="main">
<Current>1</Current>
</schema>
<collation id="3" parent="1" name="BINARY"/>
<collation id="4" parent="1" name="NOCASE"/>
<collation id="5" parent="1" name="RTRIM"/>
<table id="6" parent="2" name="association"/>
<table id="7" parent="2" name="sqlite_master">
<System>1</System>
</table>
<table id="8" parent="2" name="sqlite_sequence">
<System>1</System>
</table>
<column id="9" parent="6" name="id">
<Position>1</Position>
<DataType>INTEGER|0s</DataType>
<NotNull>1</NotNull>
<SequenceIdentity>1</SequenceIdentity>
</column>
<column id="10" parent="6" name="i_pv4">
<Position>2</Position>
<DataType>TEXT|0s</DataType>
</column>
<column id="11" parent="6" name="flags">
<Position>3</Position>
<DataType>INTEGER|0s</DataType>
</column>
<column id="12" parent="6" name="version">
<Position>4</Position>
<DataType>INTEGER|0s</DataType>
<DefaultExpression>1</DefaultExpression>
</column>
<index id="13" parent="6" name="UQE_association_i_pv4">
<ColNames>i_pv4</ColNames>
<ColumnCollations></ColumnCollations>
<Unique>1</Unique>
</index>
<key id="14" parent="6">
<ColNames>id</ColNames>
<Primary>1</Primary>
</key>
<column id="15" parent="7" name="type">
<Position>1</Position>
<DataType>text|0s</DataType>
</column>
<column id="16" parent="7" name="name">
<Position>2</Position>
<DataType>text|0s</DataType>
</column>
<column id="17" parent="7" name="tbl_name">
<Position>3</Position>
<DataType>text|0s</DataType>
</column>
<column id="18" parent="7" name="rootpage">
<Position>4</Position>
<DataType>int|0s</DataType>
</column>
<column id="19" parent="7" name="sql">
<Position>5</Position>
<DataType>text|0s</DataType>
</column>
<column id="20" parent="8" name="name">
<Position>1</Position>
</column>
<column id="21" parent="8" name="seq">
<Position>2</Position>
</column>
</database-model>
</dataSource>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/upf-n4.iml" filepath="$PROJECT_DIR$/.idea/upf-n4.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
This diff is collapsed.
# 0.4 UPF-N4
## Test process and results of relevant functions
In UPF version 0.4, the following two processes were tested:
1. Create session - > delete session
![image-20200526132301230](doc/picture/image-20200526132301230.png)
2. Create session - > Modify session - > delete session
![image-20200526132611642](doc/picture/image-20200526132611642.png)
## 0.5 Functions to be improved in the version
UPF version 0.4 does not support the update and release of coupling, storage of session information, processing of multiple nodes and other functions. The above functions will be supported in version 0.5.
Important note: the IE completed above is based on the standard that Wireshark packet capturing can be parsed normally, not that its process can be handled normally in UPF. If you need to replicate the test process, please refer to the pcap package attached to the project for the message content to be encapsulated.
## Use guide
```shell script
cd example/upf/main
go build main.go
sudo ./main --upf upf upf的IP --smf smf的IP
```
\ No newline at end of file
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import "C"
import (
"flag"
"n4/conf"
"n4/pkg/log"
"n4/pkg/upf/client"
"n4/pkg/upf/controller"
"os"
)
//var c conf.Config
var (
add = flag.String("c", "/home/wu/GOPATH/src/n4/conf/conf.yaml", "n4 configure file address")
)
func main() {
flag.Parse()
log.Info("UPF-N4 Start up\n")
end := make(chan bool)
c := conf.Config{}
config := c.GetConf(*add)
exist, err := pathExists("/var/log/upf/5gn4")
if err != nil {
log.Error("Git log file dir error ")
}
if exist {
err := os.Remove("/var/log/upf/5gn4/logrus.log")
if err != nil {
log.Error("Log file remove failed!")
}
err = os.MkdirAll("/var/log/upf/5gn4", os.ModePerm)
if err != nil {
log.Error("Log file created failed")
}
} else {
err = os.MkdirAll("/var/log/upf/5gn4", os.ModePerm)
if err != nil {
log.Error("Log file created failed")
}
}
go controller.UDPServer(config)
go client.UPDClient(config)
<-end
}
func pathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package conf
import (
"gopkg.in/yaml.v2"
"io/ioutil"
"n4/pkg/log"
)
type Config struct {
Host string `yaml:"host"`
Port string `yaml:"port"`
Gnb string `yaml:"gnb"`
Smf string `yaml:"smf"`
Upf string `yaml:"upf"`
LogSize string `yaml:"logSize"`
}
func (c *Config) GetConf(confAddress string) *Config {
yamlFile, err := ioutil.ReadFile(confAddress)
if err != nil {
log.Error(err.Error())
}
err = yaml.Unmarshal(yamlFile, c)
if err != nil {
log.Error(err.Error())
}
return c
}
gnb: 192.168.10.10
smf: 192.168.2.189
upf: 192.168.2.216
logSize: 100
\ No newline at end of file
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
func main() {
db, _ := sql.Open("mysql", "root:123456@/dbname")
defer db.Close()
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"net"
"time"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
//IE required for encapsulation
nodeID := ie.NewNodeID("172.55.55.102", "", "")
acreq, err := message.NewAssociationReleaseRequest(0, 0, 0, nodeID).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(acreq); err != nil {
log.Fatal(err)
}
log.Printf("sent Association Release Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
waiting := true
for waiting {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
acres, ok := msg.(*message.AssociationReleaseResponse)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
waiting = false
nid, err := acres.NodeID.NodeID()
if err != nil {
log.Printf("got Association Release Response with invalid NodeID: %s, from: %s", err, addr)
break
}
log.Printf("got Association Release Response with NodeID: %s, from: %s", nid, addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"n4/pkg/pfcp/ie"
_ "n4/pkg/pfcp/ie"
"go_n4/n4/log"
"n4/pkg/pfcp/message"
"net"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.1:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err.Error())
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err.Error())
}
buf := make([]byte, 1500)
for {
log.Info("waiting for messages to come on: " + laddr.String())
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err.Error())
}
msg, err := message.Parse(buf[:n])
log.Info(msg.MessageTypeName())
acreq, ok := msg.(*message.AssociationReleaseRequest)
if !ok {
log.Info("got unexpected message: s" + msg.MessageTypeName())
continue
}
nid, err := acreq.NodeID.NodeID()
if err != nil {
log.Info("got Association Release Request with invalid NodeID: " + err.Error())
continue
} else {
log.Info("got Association Release Request with NodeID: " + nid)
}
nodeID := ie.NewNodeID("172.55.55.102", "", "")
cause := ie.NewCause(0)
// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
acres, err := message.NewAssociationReleaseResponse(0, 0, 0, nodeID, cause).Marshal()
if err != nil {
log.Fatal(err.Error())
}
if _, err := conn.WriteTo(acres, addr); err != nil {
log.Fatal(err.Error())
}
log.Info("sent Association Release Response to: " + addr.String())
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"net"
"time"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
//IE required for encapsulation
nodeID := ie.NewNodeID("172.55.55.102", "", "")
ts := ie.NewRecoveryTimeStamp(time.Date(2020, 3, 3, 12, 22, 22, 22, time.Local))
up := ie.NewUPFunctionFeatures(0x10, 0x00)
cp := ie.NewCPFunctionFeatures(0x10)
pfcpAssociationReleaseRequest := ie.NewPFCPAssociationReleaseRequest(1, 2)
gracefulReleasePeriod := ie.NewGracefulReleasePeriod(time.Microsecond)
pfcpaureqFlags := ie.NewPFCPAUReqFlags(true)
ipv4 := net.ParseIP("192.168.2.146").To4()
ipv6 := net.ParseIP("2001:db8:130F:0000:0000:09C0:876A:130B").To16()
userPlaneIPResourceInformation1 := ie.NewUserPlaneIpResourceInformation(0, ipv4, ipv6, "111", 10)
userPlaneIPResourceInformation2 := ie.NewUserPlaneIpResourceInformation(0, ipv4, ipv6, "111", 10)
alternativeSMFIPAddress1 := ie.NewAlternativeSMFIPAddress(ipv4, ipv6)
alternativeSMFIPAddress2 := ie.NewAlternativeSMFIPAddress(ipv4, ipv6)
acreq, err := message.NewAssociationUpdateRequest(0, 0, 0, nodeID, ts, up, cp, userPlaneIPResourceInformation1, userPlaneIPResourceInformation2, alternativeSMFIPAddress1, alternativeSMFIPAddress2, pfcpAssociationReleaseRequest, gracefulReleasePeriod, pfcpaureqFlags).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(acreq); err != nil {
log.Fatal(err)
}
log.Printf("sent Association Update Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
waiting := true
for waiting {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
acres, ok := msg.(*message.AssociationSetupResponse)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
waiting = false
nid, err := acres.NodeID.NodeID()
if err != nil {
log.Printf("got Association Update Response with invalid NodeID: %s, from: %s", err, addr)
break
}
log.Printf("got Association Update Response with NodeID: %s, from: %s", nid, addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.1:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
for {
log.Printf("waiting for messages to come on: %s", laddr)
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
acreq, ok := msg.(*message.AssociationUpdateRequest)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
nid, err := acreq.NodeID.NodeID()
if err != nil {
log.Printf("got Association Update Request with invalid NodeID: %s, from: %s", err, addr)
continue
} else {
log.Printf("got Association Update Request with NodeID: %s, from: %s", nid, addr)
}
nodeID := ie.NewNodeID("172.55.55.102", "", "")
cause := ie.NewCause(1)
up := ie.NewUPFunctionFeatures(0x10, 0x00)
cp := ie.NewCPFunctionFeatures(0x10)
// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
acres, err := message.NewAssociationUpdateResponse(0, 0, 0, nodeID, up, cp, cause).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.WriteTo(acres, addr); err != nil {
log.Fatal(err)
}
log.Printf("sent Association Update Response to: %s", addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"net"
"time"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
//IE required for encapsulation
nodeID := ie.NewNodeID("192.168.2.64", "", "")
ts := ie.NewRecoveryTimeStamp(time.Date(2020, 3, 3, 12, 22, 22, 22, time.Local))
up := ie.NewUPFunctionFeatures(0x10, 0x00)
cp := ie.NewUPFunctionFeatures(16, 0x00)
ipv4 := net.ParseIP("192.168.2.146").To4()
ipv6 := net.ParseIP("2001:db8:130F:0000:0000:09C0:876A:130B").To16()
userPlaneIPResourceInformation1 := ie.NewUserPlaneIpResourceInformation(0, ipv4, ipv6, "111", 10)
userPlaneIPResourceInformation2 := ie.NewUserPlaneIpResourceInformation(0, ipv4, ipv6, "111", 10)
alternativeSMFIPAddress1 := ie.NewAlternativeSMFIPAddress(ipv4, ipv6)
alternativeSMFIPAddress2 := ie.NewAlternativeSMFIPAddress(ipv4, ipv6)
acreq, err := message.NewAssociationSetupRequest(0, 0, 0, nodeID, ts, cp, up, userPlaneIPResourceInformation1, userPlaneIPResourceInformation2, alternativeSMFIPAddress1, alternativeSMFIPAddress2).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(acreq); err != nil {
log.Fatal(err)
}
log.Printf("sent AssociationSetup Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
waiting := true
for waiting {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
acres, ok := msg.(*message.AssociationSetupResponse)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
waiting = false
nid, _ := acres.NodeID.NodeID()
cause, _ := acres.Cause.Cause()
ts, _ := acres.RecoveryTimeStamp.RecoveryTimeStamp()
cp, _ := acres.CPFunctionFeatures.CPFunctionFeatures()
log.Printf("got Association Setup Response with NodeID: %s, Cause: %d,RecoveryTimeStamp: %s,CPFunctionFeatures: %d", nid, cause, ts, cp)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
"time"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.1:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
for {
log.Printf("waiting for messages to come on: %s", laddr)
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
acreq, ok := msg.(*message.AssociationSetupRequest)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
nid, _ := acreq.NodeID.NodeID()
ts, _ := acreq.RecoveryTimeStamp.RecoveryTimeStamp()
cp, _ := acreq.CPFunctionFeatures.CPFunctionFeatures()
log.Printf("got Association Setup Request with NodeID: %s,RecoveryTimeStamp: %s , CPFunctionFeatures: %d", nid, ts, cp)
nodeID := ie.NewNodeID("172.55.55.102", "", "")
cause := ie.NewCause(1)
ts_1 := ie.NewRecoveryTimeStamp(time.Date(2020, 3, 3, 12, 22, 22, 22, time.Local))
cp_1 := ie.NewCPFunctionFeatures(0x00)
//// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
acres, err := message.NewAssociationSetupResponse(0, 0, 0, nodeID, ts_1, cp_1, cause).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.WriteTo(acres, addr); err != nil {
log.Fatal(err)
}
log.Printf("sent Association Setup Response to: %s", addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// Command hb-client sends a HeartbeatRequest and checks response.
//
// Heartbeat exchanging feature is planned be included in the go-pfcp package's
// built-in functions in the future.
package main
import (
"flag"
"log"
"net"
"time"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
hbreq, err := message.NewHeartbeatRequest(0, 0, 0, ie.NewRecoveryTimeStamp(time.Now())).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(hbreq); err != nil {
log.Fatal(err)
}
log.Printf("sent Heartbeat Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
waiting := true
for waiting {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
hbres, ok := msg.(*message.HeartbeatResponse)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
waiting = false
ts, err := hbres.RecoveryTimeStamp.RecoveryTimeStamp()
if err != nil {
log.Printf("got Heartbeat Response with invalid TS: %s, from: %s", err, addr)
break
}
log.Printf("got Heartbeat Response with TS: %s, from: %s", ts, addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// Command hb-controller sends a HeartbeatRequest and checks response.
//
// Heartbeat exchanging feature is planned be included in the go-pfcp package's
// built-in functions in the future.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
"time"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.2:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
for {
log.Printf("waiting for messages to come on: %s", laddr)
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
hbreq, ok := msg.(*message.HeartbeatRequest)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
ts, err := hbreq.RecoveryTimeStamp.RecoveryTimeStamp()
if err != nil {
log.Printf("got Heartbeat Request with invalid TS: %s, from: %s", err, addr)
continue
} else {
log.Printf("got Heartbeat Request with TS: %s, from: %s", ts, addr)
}
// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
hbres, err := message.NewHeartbeatResponse(0, 0, 0, ie.NewRecoveryTimeStamp(time.Now())).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.WriteTo(hbres, addr); err != nil {
log.Fatal(err)
}
log.Printf("sent Heartbeat Response to: %s", addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"net"
"time"
"n4/pkg/pfcp/message"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
//IE required for encapsulation
nodeID := ie.NewNodeID("192.168.2.1", "", "")
nodeReportType := ie.NewNodeReportType(1)
dl := ie.NewDestinationInterface(1)
nt := ie.NewNetworkInstance("11")
userPlanePathFailureReport := ie.NewUserPlanePathFailureReport(ie.NewRemoteGTPUPeer("192.168.2.1", "", dl, nt))
acreq, err := message.NewNodeReportRequest(0, 0, 0, nodeID, nodeReportType, userPlanePathFailureReport).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(acreq); err != nil {
log.Fatal(err)
}
log.Printf("sent PFCP Node Report Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
waiting := true
for waiting {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
acres, ok := msg.(*message.NodeReportResponse)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
waiting = false
nid, err := acres.NodeID.NodeID()
if err != nil {
log.Printf("got PFCP Node Report Response with invalid NodeID: %s, from: %s", err, addr)
break
}
log.Printf("got PFCP Node Report Response with NodeID: %s, from: %s", nid, addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.1:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
for {
log.Printf("waiting for messages to come on: %s", laddr)
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
acreq, ok := msg.(*message.NodeReportRequest)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
nid, err := acreq.NodeID.NodeID()
if err != nil {
log.Printf("got PFCP Node Report Request with invalid NodeID: %s, from: %s", err, addr)
continue
} else {
log.Printf("got PFCP Node Report Request with NodeID: %s, from: %s", nid, addr)
}
nodeID := ie.NewNodeID("172.55.55.102", "", "")
cause := ie.NewCause(0)
offendingIE := ie.NewOffendingIE(1)
// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
acres, err := message.NewNodeReportResponse(0, 0, 0, nodeID, cause, offendingIE).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.WriteTo(acres, addr); err != nil {
log.Fatal(err)
}
log.Printf("sent PFCP Node Report Response to: %s", addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"net"
"time"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
//IE required for encapsulation
pfdContents := ie.NewPFDContents("11", "192.168.2.130", "11", "11", "11", []string{"11", "22"}, nil, nil)
pfdContent := ie.NewPFDContext(pfdContents)
applictionID := ie.NewApplicationID("1")
applictionIDsPFDs := ie.NewApplicationIDsPFDs(applictionID, pfdContent)
acreq, err := message.NewPFDManagementRequest(1, 0, 0, applictionIDsPFDs).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(acreq); err != nil {
log.Fatal(err)
}
log.Printf("sent PFCP PFD Management Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.1:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
for {
log.Printf("waiting for messages to come on: %s", laddr)
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
_, ok := msg.(*message.PFDManagementRequest)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
cause := ie.NewCause(1)
offendingIE := ie.NewOffendingIE(1)
// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
acres, err := message.NewPFDManagementResponse(0, 0, 0, cause, offendingIE).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.WriteTo(acres, addr); err != nil {
log.Fatal(err)
}
log.Printf("sent PFD Management Response to: %s", addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
"time"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
f_seid := ie.NewFSEID(0xbebebebebebebebf, net.ParseIP("192.168.2.182"), nil, nil)
hbreq, err := message.NewSessionDeletionRequest(0, 0, 0, f_seid).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(hbreq); err != nil {
log.Fatal(err)
}
log.Printf("sent Session Deletion Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
waiting := true
for waiting {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
resp, ok := msg.(*message.SessionDeletionResponse)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
waiting = false
cause, _ := resp.Cause.Cause()
offendingIE, _ := resp.OffendingIE.OffendingIE()
log.Printf("get message Cause: %d, Offending IE :%d ", cause, offendingIE)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.1:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
for {
log.Printf("waiting for messages to come on: %s", laddr)
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
req, ok := msg.(*message.SessionDeletionRequest)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
fseid, _ := req.CPFSeid.FSEID()
log.Printf("get message F-SEID:%d", fseid.SEID)
cause := ie.NewCause(ie.CauseConditionalIEMissing)
offendingIE := ie.NewOffendingIE(2)
// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
acres, err := message.NewSessionDeletionResponse(0, 0, 0, cause, offendingIE).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.WriteTo(acres, addr); err != nil {
log.Fatal(err)
}
log.Printf("sent PFD Deletion Response to: %s", addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
"time"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
nodeID := ie.NewNodeID("192.168.2.181", "", "")
f_seid := ie.NewFSEID(0xbebebebebebebebf, net.ParseIP("192.168.2.182"), nil, nil)
pdrID := ie.NewPacketDetectionRuleID(1)
precedence := ie.NewPrecedence(0)
sourceInterface := ie.NewSourceInterface(0)
f_teid := ie.NewFTEID(0, nil, nil, nil)
ue_ip_address := ie.NewUEIPAddress("10.0.0.3", "", 0)
pdi := ie.NewPDI(sourceInterface, f_teid, ue_ip_address)
far_id := ie.NewFARID(1)
create_pdr := ie.NewCreatePDR(pdrID, precedence, pdi, far_id)
applyAction := ie.NewApplyAction(0x02)
destinationInterface := ie.NewDestinationInterface(1)
outerHeaderCreation := ie.NewOuterHeaderCreation(ie.CTPUUDPIPv4, 1, "192.168.2.157", "", 0, 0, 0)
forwardingParameters := ie.NewForwardingParameters(0, destinationInterface, outerHeaderCreation)
create_far := ie.NewCreateFAR(far_id, applyAction, forwardingParameters)
hbreq, err := message.NewSessionEstablishmentRequest(0, 0, 0, nodeID, f_seid, create_pdr, create_far).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(hbreq); err != nil {
log.Fatal(err)
}
log.Printf("sent Session Establishment Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
waiting := true
for waiting {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
acres, ok := msg.(*message.SessionEstablishmentResponse)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
waiting = false
nid, _ := acres.NodeID.NodeID()
cause, _ := acres.Cause.Cause()
ipv4, _ := acres.UPFSEID.FSEID()
if err != nil {
log.Printf("got Session Establishment Response with invalid NodeID: %s, from: %s", err, addr)
break
}
log.Printf("got Session Establishment Response with NodeID: %s, cause: %d,ipv4: %s,PDRID: %d,F TEID IPv4: %s", nid, cause, ipv4.IPv4Address)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.1:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
for {
log.Printf("waiting for messages to come on: %s", laddr)
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
req, ok := msg.(*message.SessionEstablishmentRequest)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
nodeID, _ := req.NodeID.NodeID()
fseid, _ := req.CPFSeid.FSEID()
createPDR, _ := req.CreatePDR[0].CreatePDR()
pdrid, _ := createPDR[0].PacketDetectionRuleID()
precedence, _ := createPDR[1].Precedence()
pdiIEs, _ := createPDR[2].PDI()
sourceInterface, _ := pdiIEs[0].SourceInterface()
//fteid, _ := pdiIEs[1].FTEID()
ueipaddress, _ := pdiIEs[2].UEIPAddress()
farid, _ := createPDR[3].FARID()
createFAR, _ := req.CreateFAR[0].CreateFAR()
applyAction, _ := createFAR[1].ApplyAction()
forwardingParameters, _ := createFAR[2].ForwardingParameters()
destinationInterface, _ := forwardingParameters[0].DestinationInterface()
outerHeaderCreation, _ := forwardingParameters[1].OuterHeaderCreation()
log.Printf("get message Node ID: %s,F-SEID:%d,ipv4:%s,PDR ID: %d, Precedence: %d, Source Interface: %d,UE IP Address:%s, FAR ID:%d ", nodeID, fseid.SEID, fseid.IPv4Address, pdrid, precedence, sourceInterface, ueipaddress.IPv4Address, farid)
log.Printf("get message ApplyAction: %x,DestionationInterface:%d,OuterHeaderCreation IPv4:%s", applyAction, destinationInterface, outerHeaderCreation.IPv4Address)
nodeID_2 := ie.NewNodeID("192.168.2.115", "", "")
cause := ie.NewCause(ie.CauseRequestAccepted)
f_seid := ie.NewFSEID(1, net.ParseIP("192.168.2.115"), nil, nil)
pdrid_2 := ie.NewPacketDetectionRuleID(1)
f_teid := ie.NewFTEID(1, net.ParseIP("192.168.2.189"), nil, nil)
createPDR_2 := ie.NewCreatePDR(pdrid_2, f_teid)
// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
acres, err := message.NewSessionEstablishmentResponse(111111111111, 0, 0, nodeID_2, cause, f_seid, createPDR_2).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.WriteTo(acres, addr); err != nil {
log.Fatal(err)
}
log.Printf("sent PFD Management Response to: %s", addr)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
"time"
)
func main() {
var (
server = flag.String("-s", "127.0.0.1:8805", "controller's addr/port")
)
flag.Parse()
raddr, err := net.ResolveUDPAddr("udp", *server)
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, raddr)
if err != nil {
log.Fatal(err)
}
pdr_id := ie.NewPacketDetectionRuleID(1)
far_id := ie.NewFARID(1)
remove_pdr := ie.NewRemovePDR(pdr_id)
remove_far := ie.NewRemoveFAR(far_id)
f_seid := ie.NewFSEID(0xbebebebebebebebf, net.ParseIP("192.168.2.182"), nil, nil)
precedence := ie.NewPrecedence(0)
sourceInterface := ie.NewSourceInterface(0)
f_teid := ie.NewFTEID(0, nil, nil, nil)
ue_ip_address := ie.NewUEIPAddress("10.0.0.3", "", 0)
pdi := ie.NewPDI(sourceInterface, f_teid, ue_ip_address)
create_pdr := ie.NewUpdatePDR(pdr_id, precedence, pdi, far_id)
applyAction := ie.NewApplyAction(0x02)
destinationInterface := ie.NewDestinationInterface(1)
outerHeaderCreation := ie.NewOuterHeaderCreation(ie.CTPUUDPIPv4, 1, "192.168.2.157", "", 0, 0, 0)
forwardingParameters := ie.NewForwardingParameters(0, destinationInterface, outerHeaderCreation)
create_far := ie.NewUpdateFAR(far_id, applyAction, forwardingParameters)
hbreq, err := message.NewSessionModificationRequest(0, 0, 0, f_seid, remove_pdr, remove_far, create_pdr, create_far).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.Write(hbreq); err != nil {
log.Fatal(err)
}
log.Printf("sent Session Modification Request to: %s", raddr)
if err := conn.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
waiting := true
for waiting {
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
resp, ok := msg.(*message.SessionModificationResponse)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
waiting = false
cause, _ := resp.Cause.Cause()
offendingIE, _ := resp.OffendingIE.OffendingIE()
log.Printf("get message Cause: %d, Offending IE :%d ", cause, offendingIE)
}
}
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
import (
"flag"
"log"
"n4/pkg/pfcp/ie"
"n4/pkg/pfcp/message"
"net"
)
func main() {
var (
listen = flag.String("-s", "127.0.0.1:8805", "addr/port to listen on")
)
flag.Parse()
laddr, err := net.ResolveUDPAddr("udp", *listen)
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", laddr)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1500)
for {
log.Printf("waiting for messages to come on: %s", laddr)
n, addr, err := conn.ReadFrom(buf)
if err != nil {
log.Fatal(err)
}
msg, err := message.Parse(buf[:n])
if err != nil {
log.Printf("ignored undecodable message: %x, error: %s", buf[:n], err)
continue
}
req, ok := msg.(*message.SessionModificationRequest)
if !ok {
log.Printf("got unexpected message: %s, from: %s", msg.MessageTypeName(), addr)
continue
}
removePDRList, _ := req.RemovePDR[0].RemovePDR()
removePDR, _ := removePDRList[0].PacketDetectionRuleID()
removeFARList, _ := req.RemoveFAR[0].RemoveFAR()
removeFAR, _ := removeFARList[0].FARID()
fseid, _ := req.CPFSeid.FSEID()
updatePDR, _ := req.UpdatePDR[0].UpdatePDR()
pdrid, _ := updatePDR[0].PacketDetectionRuleID()
precedence, _ := updatePDR[1].Precedence()
pdiIEs, _ := updatePDR[2].PDI()
sourceInterface, _ := pdiIEs[0].SourceInterface()
//fteid, _ := pdiIEs[1].FTEID()
ueipaddress, _ := pdiIEs[2].UEIPAddress()
farid, _ := updatePDR[3].FARID()
updateFAR, _ := req.UpdateFAR[0].UpdateFAR()
applyAction, _ := updateFAR[1].ApplyAction()
forwardingParameters, _ := updateFAR[2].ForwardingParameters()
destinationInterface, _ := forwardingParameters[0].DestinationInterface()
outerHeaderCreation, _ := forwardingParameters[1].OuterHeaderCreation()
log.Printf("get message Remove PDR ID: %d, Remove FAR ID:%d ", removePDR, removeFAR)
log.Printf("get message F-SEID:%d,ipv4:%s,PDR ID: %d, Precedence: %d, Source Interface: %d,UE IP Address:%s, FAR ID:%d ", fseid.SEID, fseid.IPv4Address, pdrid, precedence, sourceInterface, ueipaddress.IPv4Address, farid)
log.Printf("get message ApplyAction: %x,DestionationInterface:%d,OuterHeaderCreation IPv4:%s", applyAction, destinationInterface, outerHeaderCreation.IPv4Address)
cause := ie.NewCause(ie.CauseConditionalIEMissing)
offendingIE := ie.NewOffendingIE(2)
// Timestamp shouldn't be the time message is sent in the real deployment but anyway :D
acres, err := message.NewSessionModificationResponse(0, 0, 0, cause, offendingIE).Marshal()
if err != nil {
log.Fatal(err)
}
if _, err := conn.WriteTo(acres, addr); err != nil {
log.Fatal(err)
}
log.Printf("sent PFD Management Response to: %s", addr)
}
}
This diff is collapsed.
// Code generated by GoVPP's binapi-generator. DO NOT EDIT.
// source: /usr/share/vpp/api/core/af_packet.api.json
/*
Package af_packet is a generated VPP binary API for 'af_packet' module.
It consists of:
8 messages
4 services
*/
package af_packet
import (
bytes "bytes"
context "context"
struc "github.com/lunixbochs/struc"
io "io"
api "n4/pkg/vpp/api"
strconv "strconv"
)
const (
// ModuleName is the name of this module.
ModuleName = "af_packet"
// APIVersion is the API version of this module.
APIVersion = "1.0.0"
// VersionCrc is the CRC of this module.
VersionCrc = 0xfefd69b7
)
// AfPacketCreate represents VPP binary API message 'af_packet_create'.
type AfPacketCreate struct {
HostIfName []byte `struc:"[64]byte"`
HwAddr []byte `struc:"[6]byte"`
UseRandomHwAddr uint8
}
func (*AfPacketCreate) GetMessageName() string {
return "af_packet_create"
}
func (*AfPacketCreate) GetCrcString() string {
return "6d5d30d6"
}
func (*AfPacketCreate) GetMessageType() api.MessageType {
return api.RequestMessage
}
// AfPacketCreateReply represents VPP binary API message 'af_packet_create_reply'.
type AfPacketCreateReply struct {
Retval int32
SwIfIndex uint32
}
func (*AfPacketCreateReply) GetMessageName() string {
return "af_packet_create_reply"
}
func (*AfPacketCreateReply) GetCrcString() string {
return "fda5941f"
}
func (*AfPacketCreateReply) GetMessageType() api.MessageType {
return api.ReplyMessage
}
// AfPacketDelete represents VPP binary API message 'af_packet_delete'.
type AfPacketDelete struct {
HostIfName []byte `struc:"[64]byte"`
}
func (*AfPacketDelete) GetMessageName() string {
return "af_packet_delete"
}
func (*AfPacketDelete) GetCrcString() string {
return "3efceda3"
}
func (*AfPacketDelete) GetMessageType() api.MessageType {
return api.RequestMessage
}
// AfPacketDeleteReply represents VPP binary API message 'af_packet_delete_reply'.
type AfPacketDeleteReply struct {
Retval int32
}
func (*AfPacketDeleteReply) GetMessageName() string {
return "af_packet_delete_reply"
}
func (*AfPacketDeleteReply) GetCrcString() string {
return "e8d4e804"
}
func (*AfPacketDeleteReply) GetMessageType() api.MessageType {
return api.ReplyMessage
}
// AfPacketDetails represents VPP binary API message 'af_packet_details'.
type AfPacketDetails struct {
SwIfIndex uint32
HostIfName []byte `struc:"[64]byte"`
}
func (*AfPacketDetails) GetMessageName() string {
return "af_packet_details"
}
func (*AfPacketDetails) GetCrcString() string {
return "057205fa"
}
func (*AfPacketDetails) GetMessageType() api.MessageType {
return api.ReplyMessage
}
// AfPacketDump represents VPP binary API message 'af_packet_dump'.
type AfPacketDump struct{}
func (*AfPacketDump) GetMessageName() string {
return "af_packet_dump"
}
func (*AfPacketDump) GetCrcString() string {
return "51077d14"
}
func (*AfPacketDump) GetMessageType() api.MessageType {
return api.RequestMessage
}
// AfPacketSetL4CksumOffload represents VPP binary API message 'af_packet_set_l4_cksum_offload'.
type AfPacketSetL4CksumOffload struct {
SwIfIndex uint8
Set uint8
}
func (*AfPacketSetL4CksumOffload) GetMessageName() string {
return "af_packet_set_l4_cksum_offload"
}
func (*AfPacketSetL4CksumOffload) GetCrcString() string {
return "86538585"
}
func (*AfPacketSetL4CksumOffload) GetMessageType() api.MessageType {
return api.RequestMessage
}
// AfPacketSetL4CksumOffloadReply represents VPP binary API message 'af_packet_set_l4_cksum_offload_reply'.
type AfPacketSetL4CksumOffloadReply struct {
Retval int32
}
func (*AfPacketSetL4CksumOffloadReply) GetMessageName() string {
return "af_packet_set_l4_cksum_offload_reply"
}
func (*AfPacketSetL4CksumOffloadReply) GetCrcString() string {
return "e8d4e804"
}
func (*AfPacketSetL4CksumOffloadReply) GetMessageType() api.MessageType {
return api.ReplyMessage
}
func init() {
api.RegisterMessage((*AfPacketCreate)(nil), "af_packet.AfPacketCreate")
api.RegisterMessage((*AfPacketCreateReply)(nil), "af_packet.AfPacketCreateReply")
api.RegisterMessage((*AfPacketDelete)(nil), "af_packet.AfPacketDelete")
api.RegisterMessage((*AfPacketDeleteReply)(nil), "af_packet.AfPacketDeleteReply")
api.RegisterMessage((*AfPacketDetails)(nil), "af_packet.AfPacketDetails")
api.RegisterMessage((*AfPacketDump)(nil), "af_packet.AfPacketDump")
api.RegisterMessage((*AfPacketSetL4CksumOffload)(nil), "af_packet.AfPacketSetL4CksumOffload")
api.RegisterMessage((*AfPacketSetL4CksumOffloadReply)(nil), "af_packet.AfPacketSetL4CksumOffloadReply")
}
// Messages returns list of all messages in this module.
func AllMessages() []api.Message {
return []api.Message{
(*AfPacketCreate)(nil),
(*AfPacketCreateReply)(nil),
(*AfPacketDelete)(nil),
(*AfPacketDeleteReply)(nil),
(*AfPacketDetails)(nil),
(*AfPacketDump)(nil),
(*AfPacketSetL4CksumOffload)(nil),
(*AfPacketSetL4CksumOffloadReply)(nil),
}
}
// RPCService represents RPC service API for af_packet module.
type RPCService interface {
DumpAfPacket(ctx context.Context, in *AfPacketDump) (RPCService_DumpAfPacketClient, error)
AfPacketCreate(ctx context.Context, in *AfPacketCreate) (*AfPacketCreateReply, error)
AfPacketDelete(ctx context.Context, in *AfPacketDelete) (*AfPacketDeleteReply, error)
AfPacketSetL4CksumOffload(ctx context.Context, in *AfPacketSetL4CksumOffload) (*AfPacketSetL4CksumOffloadReply, error)
}
type serviceClient struct {
ch api.Channel
}
func NewServiceClient(ch api.Channel) RPCService {
return &serviceClient{ch}
}
func (c *serviceClient) DumpAfPacket(ctx context.Context, in *AfPacketDump) (RPCService_DumpAfPacketClient, error) {
stream := c.ch.SendMultiRequest(in)
x := &serviceClient_DumpAfPacketClient{stream}
return x, nil
}
type RPCService_DumpAfPacketClient interface {
Recv() (*AfPacketDetails, error)
}
type serviceClient_DumpAfPacketClient struct {
api.MultiRequestCtx
}
func (c *serviceClient_DumpAfPacketClient) Recv() (*AfPacketDetails, error) {
m := new(AfPacketDetails)
stop, err := c.MultiRequestCtx.ReceiveReply(m)
if err != nil {
return nil, err
}
if stop {
return nil, io.EOF
}
return m, nil
}
func (c *serviceClient) AfPacketCreate(ctx context.Context, in *AfPacketCreate) (*AfPacketCreateReply, error) {
out := new(AfPacketCreateReply)
err := c.ch.SendRequest(in).ReceiveReply(out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *serviceClient) AfPacketDelete(ctx context.Context, in *AfPacketDelete) (*AfPacketDeleteReply, error) {
out := new(AfPacketDeleteReply)
err := c.ch.SendRequest(in).ReceiveReply(out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *serviceClient) AfPacketSetL4CksumOffload(ctx context.Context, in *AfPacketSetL4CksumOffload) (*AfPacketSetL4CksumOffloadReply, error) {
out := new(AfPacketSetL4CksumOffloadReply)
err := c.ch.SendRequest(in).ReceiveReply(out)
if err != nil {
return nil, err
}
return out, nil
}
// This is a compile-time assertion to ensure that this generated file
// is compatible with the GoVPP api package it is being compiled against.
// A compilation error at this line likely means your copy of the
// GoVPP api package needs to be updated.
const _ = api.GoVppAPIPackageIsVersion1 // please upgrade the GoVPP api package
// Reference imports to suppress errors if they are not otherwise used.
var _ = api.RegisterMessage
var _ = bytes.NewBuffer
var _ = context.Background
var _ = io.Copy
var _ = strconv.Itoa
var _ = struc.Pack
package binapi
// Generate Go code from the VPP APIs located in the /usr/share/vpp/api directory.
//go:generate -command binapigen binapi-generator --output-dir=. --include-services --continue-onerror
//go:generate binapigen --input-file=/usr/share/vpp/api/core/af_packet.api.json
//go:generate binapigen --input-file=/usr/share/vpp/api/core/interface.api.json
//go:generate binapigen --input-file=/usr/share/vpp/api/core/ip.api.json
//go:generate binapigen --input-file=/usr/share/vpp/api/core/memclnt.api.json
//go:generate binapigen --input-file=/usr/share/vpp/api/core/vpe.api.json
//go:generate binapigen --input-file=/usr/share/vpp/api/plugins/memif.api.json
// VPP version
///go:generate sh -c "dpkg-query -f '$DOLLAR{Version}' -W vpp > VPP_VERSION"
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Code generated by GoVPP's binapi-generator. DO NOT EDIT.
// source: /usr/share/vpp/api/plugins/memif.api.json
/*
Package memif is a generated VPP binary API for 'memif' module.
It consists of:
10 messages
5 services
*/
package memif
import (
bytes "bytes"
context "context"
struc "github.com/lunixbochs/struc"
io "io"
api "n4/pkg/vpp/api"
strconv "strconv"
)
const (
// ModuleName is the name of this module.
ModuleName = "memif"
// APIVersion is the API version of this module.
APIVersion = "2.0.0"
// VersionCrc is the CRC of this module.
VersionCrc = 0x939f78a7
)
// MemifCreate represents VPP binary API message 'memif_create'.
type MemifCreate struct {
Role uint8
Mode uint8
RxQueues uint8
TxQueues uint8
ID uint32
SocketID uint32
Secret []byte `struc:"[24]byte"`
RingSize uint32
BufferSize uint16
HwAddr []byte `struc:"[6]byte"`
}
func (*MemifCreate) GetMessageName() string {
return "memif_create"
}
func (*MemifCreate) GetCrcString() string {
return "6597cdb2"
}
func (*MemifCreate) GetMessageType() api.MessageType {
return api.RequestMessage
}
// MemifCreateReply represents VPP binary API message 'memif_create_reply'.
type MemifCreateReply struct {
Retval int32
SwIfIndex uint32
}
func (*MemifCreateReply) GetMessageName() string {
return "memif_create_reply"
}
func (*MemifCreateReply) GetCrcString() string {
return "fda5941f"
}
func (*MemifCreateReply) GetMessageType() api.MessageType {
return api.ReplyMessage
}
// MemifDelete represents VPP binary API message 'memif_delete'.
type MemifDelete struct {
SwIfIndex uint32
}
func (*MemifDelete) GetMessageName() string {
return "memif_delete"
}
func (*MemifDelete) GetCrcString() string {
return "529cb13f"
}
func (*MemifDelete) GetMessageType() api.MessageType {
return api.RequestMessage
}
// MemifDeleteReply represents VPP binary API message 'memif_delete_reply'.
type MemifDeleteReply struct {
Retval int32
}
func (*MemifDeleteReply) GetMessageName() string {
return "memif_delete_reply"
}
func (*MemifDeleteReply) GetCrcString() string {
return "e8d4e804"
}
func (*MemifDeleteReply) GetMessageType() api.MessageType {
return api.ReplyMessage
}
// MemifDetails represents VPP binary API message 'memif_details'.
type MemifDetails struct {
SwIfIndex uint32
IfName []byte `struc:"[64]byte"`
HwAddr []byte `struc:"[6]byte"`
ID uint32
Role uint8
Mode uint8
SocketID uint32
RingSize uint32
BufferSize uint16
AdminUpDown uint8
LinkUpDown uint8
}
func (*MemifDetails) GetMessageName() string {
return "memif_details"
}
func (*MemifDetails) GetCrcString() string {
return "4f5a3397"
}
func (*MemifDetails) GetMessageType() api.MessageType {
return api.ReplyMessage
}
// MemifDump represents VPP binary API message 'memif_dump'.
type MemifDump struct{}
func (*MemifDump) GetMessageName() string {
return "memif_dump"
}
func (*MemifDump) GetCrcString() string {
return "51077d14"
}
func (*MemifDump) GetMessageType() api.MessageType {
return api.RequestMessage
}
// MemifSocketFilenameAddDel represents VPP binary API message 'memif_socket_filename_add_del'.
type MemifSocketFilenameAddDel struct {
IsAdd uint8
SocketID uint32
SocketFilename []byte `struc:"[128]byte"`
}
func (*MemifSocketFilenameAddDel) GetMessageName() string {
return "memif_socket_filename_add_del"
}
func (*MemifSocketFilenameAddDel) GetCrcString() string {
return "30e3929d"
}
func (*MemifSocketFilenameAddDel) GetMessageType() api.MessageType {
return api.RequestMessage
}
// MemifSocketFilenameAddDelReply represents VPP binary API message 'memif_socket_filename_add_del_reply'.
type MemifSocketFilenameAddDelReply struct {
Retval int32
}
func (*MemifSocketFilenameAddDelReply) GetMessageName() string {
return "memif_socket_filename_add_del_reply"
}
func (*MemifSocketFilenameAddDelReply) GetCrcString() string {
return "e8d4e804"
}
func (*MemifSocketFilenameAddDelReply) GetMessageType() api.MessageType {
return api.ReplyMessage
}
// MemifSocketFilenameDetails represents VPP binary API message 'memif_socket_filename_details'.
type MemifSocketFilenameDetails struct {
SocketID uint32
SocketFilename []byte `struc:"[128]byte"`
}
func (*MemifSocketFilenameDetails) GetMessageName() string {
return "memif_socket_filename_details"
}
func (*MemifSocketFilenameDetails) GetCrcString() string {
return "e347e32f"
}
func (*MemifSocketFilenameDetails) GetMessageType() api.MessageType {
return api.ReplyMessage
}
// MemifSocketFilenameDump represents VPP binary API message 'memif_socket_filename_dump'.
type MemifSocketFilenameDump struct{}
func (*MemifSocketFilenameDump) GetMessageName() string {
return "memif_socket_filename_dump"
}
func (*MemifSocketFilenameDump) GetCrcString() string {
return "51077d14"
}
func (*MemifSocketFilenameDump) GetMessageType() api.MessageType {
return api.RequestMessage
}
func init() {
api.RegisterMessage((*MemifCreate)(nil), "memif.MemifCreate")
api.RegisterMessage((*MemifCreateReply)(nil), "memif.MemifCreateReply")
api.RegisterMessage((*MemifDelete)(nil), "memif.MemifDelete")
api.RegisterMessage((*MemifDeleteReply)(nil), "memif.MemifDeleteReply")
api.RegisterMessage((*MemifDetails)(nil), "memif.MemifDetails")
api.RegisterMessage((*MemifDump)(nil), "memif.MemifDump")
api.RegisterMessage((*MemifSocketFilenameAddDel)(nil), "memif.MemifSocketFilenameAddDel")
api.RegisterMessage((*MemifSocketFilenameAddDelReply)(nil), "memif.MemifSocketFilenameAddDelReply")
api.RegisterMessage((*MemifSocketFilenameDetails)(nil), "memif.MemifSocketFilenameDetails")
api.RegisterMessage((*MemifSocketFilenameDump)(nil), "memif.MemifSocketFilenameDump")
}
// Messages returns list of all messages in this module.
func AllMessages() []api.Message {
return []api.Message{
(*MemifCreate)(nil),
(*MemifCreateReply)(nil),
(*MemifDelete)(nil),
(*MemifDeleteReply)(nil),
(*MemifDetails)(nil),
(*MemifDump)(nil),
(*MemifSocketFilenameAddDel)(nil),
(*MemifSocketFilenameAddDelReply)(nil),
(*MemifSocketFilenameDetails)(nil),
(*MemifSocketFilenameDump)(nil),
}
}
// RPCService represents RPC service API for memif module.
type RPCService interface {
DumpMemif(ctx context.Context, in *MemifDump) (RPCService_DumpMemifClient, error)
DumpMemifSocketFilename(ctx context.Context, in *MemifSocketFilenameDump) (RPCService_DumpMemifSocketFilenameClient, error)
MemifCreate(ctx context.Context, in *MemifCreate) (*MemifCreateReply, error)
MemifDelete(ctx context.Context, in *MemifDelete) (*MemifDeleteReply, error)
MemifSocketFilenameAddDel(ctx context.Context, in *MemifSocketFilenameAddDel) (*MemifSocketFilenameAddDelReply, error)
}
type serviceClient struct {
ch api.Channel
}
func NewServiceClient(ch api.Channel) RPCService {
return &serviceClient{ch}
}
func (c *serviceClient) DumpMemif(ctx context.Context, in *MemifDump) (RPCService_DumpMemifClient, error) {
stream := c.ch.SendMultiRequest(in)
x := &serviceClient_DumpMemifClient{stream}
return x, nil
}
type RPCService_DumpMemifClient interface {
Recv() (*MemifDetails, error)
}
type serviceClient_DumpMemifClient struct {
api.MultiRequestCtx
}
func (c *serviceClient_DumpMemifClient) Recv() (*MemifDetails, error) {
m := new(MemifDetails)
stop, err := c.MultiRequestCtx.ReceiveReply(m)
if err != nil {
return nil, err
}
if stop {
return nil, io.EOF
}
return m, nil
}
func (c *serviceClient) DumpMemifSocketFilename(ctx context.Context, in *MemifSocketFilenameDump) (RPCService_DumpMemifSocketFilenameClient, error) {
stream := c.ch.SendMultiRequest(in)
x := &serviceClient_DumpMemifSocketFilenameClient{stream}
return x, nil
}
type RPCService_DumpMemifSocketFilenameClient interface {
Recv() (*MemifSocketFilenameDetails, error)
}
type serviceClient_DumpMemifSocketFilenameClient struct {
api.MultiRequestCtx
}
func (c *serviceClient_DumpMemifSocketFilenameClient) Recv() (*MemifSocketFilenameDetails, error) {
m := new(MemifSocketFilenameDetails)
stop, err := c.MultiRequestCtx.ReceiveReply(m)
if err != nil {
return nil, err
}
if stop {
return nil, io.EOF
}
return m, nil
}
func (c *serviceClient) MemifCreate(ctx context.Context, in *MemifCreate) (*MemifCreateReply, error) {
out := new(MemifCreateReply)
err := c.ch.SendRequest(in).ReceiveReply(out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *serviceClient) MemifDelete(ctx context.Context, in *MemifDelete) (*MemifDeleteReply, error) {
out := new(MemifDeleteReply)
err := c.ch.SendRequest(in).ReceiveReply(out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *serviceClient) MemifSocketFilenameAddDel(ctx context.Context, in *MemifSocketFilenameAddDel) (*MemifSocketFilenameAddDelReply, error) {
out := new(MemifSocketFilenameAddDelReply)
err := c.ch.SendRequest(in).ReceiveReply(out)
if err != nil {
return nil, err
}
return out, nil
}
// This is a compile-time assertion to ensure that this generated file
// is compatible with the GoVPP api package it is being compiled against.
// A compilation error at this line likely means your copy of the
// GoVPP api package needs to be updated.
const _ = api.GoVppAPIPackageIsVersion1 // please upgrade the GoVPP api package
// Reference imports to suppress errors if they are not otherwise used.
var _ = api.RegisterMessage
var _ = bytes.NewBuffer
var _ = context.Background
var _ = io.Copy
var _ = strconv.Itoa
var _ = struc.Pack
This diff is collapsed.
This diff is collapsed.
// Copyright (c) 2017 Cisco and/or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// service-unixsocket is an example VPP management application that exercises the
// govpp API using generated service unixsocket.
package main
import (
"context"
"flag"
"fmt"
"io"
"log"
"n4/pkg/vpp/examples/binapi/memclnt"
"strings"
"n4/example/vpp/binapi/interfaces"
"n4/pkg/vpp"
"n4/pkg/vpp/adapter/socketclient"
"n4/pkg/vpp/api"
"n4/pkg/vpp/examples/binapi/vpe"
)
var (
sockAddr = flag.String("sock", socketclient.DefaultSocketName, "Path to VPP binary API socket file")
)
func main() {
flag.Parse()
fmt.Println("Starting RPC service example")
// connect to VPP
conn, err := govpp.Connect(*sockAddr)
if err != nil {
log.Fatalln("ERROR: connecting to VPP failed:", err)
}
defer conn.Disconnect()
// create a channel
ch, err := conn.NewAPIChannel()
if err != nil {
log.Fatalln("ERROR: creating channel failed:", err)
}
defer ch.Close()
showVersion(ch)
interfaceDump(ch)
}
// showVersion shows an example of simple request with services.
func showVersion(ch api.Channel) {
c := vpe.NewServiceClient(ch)
version, err := c.ShowVersion(context.Background(), &vpe.ShowVersion{})
if err != nil {
log.Fatalln("ERROR: ShowVersion failed:", err)
}
fmt.Printf("Version: %v\n", version.Version)
}
// interfaceDump shows an example of multi request with services.
func interfaceDump(ch api.Channel) {
c := interfaces.NewServiceClient(ch)
stream, err := c.DumpSwInterface(context.Background(), &interfaces.SwInterfaceDump{})
if err != nil {
log.Fatalln("ERROR: DumpSwInterface failed:", err)
}
fmt.Println("Dumping interfaces")
for {
iface, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
log.Fatalln("ERROR: DumpSwInterface failed:", err)
}
fmt.Printf("- interface: %s\n", strings.Trim(iface.InterfaceName, "\x00"))
}
}
func traces(ch api.Channel) {
c := interfaces.NewServiceClient(ch)
stream, err := c.DumpSwInterface(context.Background(), &memclnt.TracePluginMsgIds{})
if err != nil {
log.Fatalln("ERROR: DumpSwInterface failed:", err)
}
fmt.Println("Dumping interfaces")
for {
iface, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
log.Fatalln("ERROR: DumpSwInterface failed:", err)
}
fmt.Printf("- interface: %s\n", strings.Trim(iface.InterfaceName, "\x00"))
}
}
This diff is collapsed.
// Copyright 2019-2020 UPF-N4 authors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
package main
func main() {
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Wed Aug 12 20:06:08 2020 -0700
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment