mirror of
https://github.com/netbirdio/netbird.git
synced 2025-03-14 06:38:42 +01:00
Client-side forward handling Co-authored-by: Viktor Liu <17948409+lixmal@users.noreply.github.com> --------- Co-authored-by: Viktor Liu <17948409+lixmal@users.noreply.github.com>
99 lines
2.6 KiB
Go
99 lines
2.6 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
|
|
"github.com/spf13/cobra"
|
|
"google.golang.org/grpc/status"
|
|
|
|
"github.com/netbirdio/netbird/client/proto"
|
|
)
|
|
|
|
var forwardingRulesCmd = &cobra.Command{
|
|
Use: "forwarding",
|
|
Short: "List forwarding rules",
|
|
Long: `Commands to list forwarding rules.`,
|
|
}
|
|
|
|
var forwardingRulesListCmd = &cobra.Command{
|
|
Use: "list",
|
|
Aliases: []string{"ls"},
|
|
Short: "List forwarding rules",
|
|
Example: " netbird forwarding list",
|
|
Long: "Commands to list forwarding rules.",
|
|
RunE: listForwardingRules,
|
|
}
|
|
|
|
func listForwardingRules(cmd *cobra.Command, _ []string) error {
|
|
conn, err := getClient(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer conn.Close()
|
|
|
|
client := proto.NewDaemonServiceClient(conn)
|
|
resp, err := client.ForwardingRules(cmd.Context(), &proto.EmptyRequest{})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to list network: %v", status.Convert(err).Message())
|
|
}
|
|
|
|
if len(resp.GetRules()) == 0 {
|
|
cmd.Println("No forwarding rules available.")
|
|
return nil
|
|
}
|
|
|
|
printForwardingRules(cmd, resp.GetRules())
|
|
return nil
|
|
}
|
|
|
|
func printForwardingRules(cmd *cobra.Command, rules []*proto.ForwardingRule) {
|
|
cmd.Println("Available forwarding rules:")
|
|
|
|
// Sort rules by translated address
|
|
sort.Slice(rules, func(i, j int) bool {
|
|
if rules[i].GetTranslatedAddress() != rules[j].GetTranslatedAddress() {
|
|
return rules[i].GetTranslatedAddress() < rules[j].GetTranslatedAddress()
|
|
}
|
|
if rules[i].GetProtocol() != rules[j].GetProtocol() {
|
|
return rules[i].GetProtocol() < rules[j].GetProtocol()
|
|
}
|
|
|
|
return getFirstPort(rules[i].GetDestinationPort()) < getFirstPort(rules[j].GetDestinationPort())
|
|
})
|
|
|
|
var lastIP string
|
|
for _, rule := range rules {
|
|
dPort := portToString(rule.GetDestinationPort())
|
|
tPort := portToString(rule.GetTranslatedPort())
|
|
if lastIP != rule.GetTranslatedAddress() {
|
|
lastIP = rule.GetTranslatedAddress()
|
|
cmd.Printf("\nTranslated peer: %s\n", rule.GetTranslatedHostname())
|
|
}
|
|
|
|
cmd.Printf(" Local %s/%s to %s:%s\n", rule.GetProtocol(), dPort, rule.GetTranslatedAddress(), tPort)
|
|
}
|
|
}
|
|
|
|
func getFirstPort(portInfo *proto.PortInfo) int {
|
|
switch v := portInfo.PortSelection.(type) {
|
|
case *proto.PortInfo_Port:
|
|
return int(v.Port)
|
|
case *proto.PortInfo_Range_:
|
|
return int(v.Range.GetStart())
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
func portToString(translatedPort *proto.PortInfo) string {
|
|
switch v := translatedPort.PortSelection.(type) {
|
|
case *proto.PortInfo_Port:
|
|
return fmt.Sprintf("%d", v.Port)
|
|
case *proto.PortInfo_Range_:
|
|
return fmt.Sprintf("%d-%d", v.Range.GetStart(), v.Range.GetEnd())
|
|
default:
|
|
return "No port specified"
|
|
}
|
|
}
|