Skip to content

Commit 68415ca

Browse files
committed
Refacto the codde to make it work for new livebox
1 parent 2f2986e commit 68415ca

File tree

16 files changed

+474
-1175
lines changed

16 files changed

+474
-1175
lines changed

.github/workflows/main.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
- name: Setup Go
1010
uses: actions/setup-go@v3
1111
with:
12-
go-version: '1.20'
12+
go-version: '1.24'
1313
- name: Install dependencies
1414
run: go get .
1515
- name: Build

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ cd GO-BOX_Linux_x86_64
2525

2626
## Compile by yourself
2727
```bash
28-
git clone https://github.com/StephanGR/GO-BOX.git
28+
git clone https://github.com/Stoufiler/GO-BOX.git
2929
cd GO-BOX
3030
go build .
3131
./GO-BOX
@@ -37,31 +37,36 @@ NAME:
3737
GO-BOX - CLI tool to fetch infos from Livebox/Funbox
3838

3939
USAGE:
40-
GO-BOX --ip <box ip> --box <livebox/funbox>
40+
GO-BOX [global options] command [command options]
4141

4242
COMMANDS:
43+
livebox Fetch infos from Livebox
44+
funbox Fetch infos from Funbox
4345
help, h Shows a list of commands or help for one command
4446

4547
GLOBAL OPTIONS:
46-
--box value Type of orange box (Livebox, Funbox)
47-
--ip value IP address of box
48-
--help, -h show help
48+
--ip value IP address of box
49+
--password value Password of box
50+
--help, -h show help
4951
```
52+
5053
## Windows
54+
5155
Open a powershell terminal or cmd and go to executable file
5256
```powershell
53-
.\GO_BOX.exe --ip 192.168.1.1 --box livebox
57+
.\GO_BOX.exe --ip 192.168.1.1 --password xxxx livebox
5458
```
5559

5660
## Linux / MacOS
61+
5762
Open a terminal and go to executable file
5863
```bash
59-
./GO-BOX --ip 192.168.1.1 --box livebox
64+
./GO-BOX --ip 192.168.1.1 --password xxxx livebox
6065
```
6166
## Example
6267
Do not copy, because some values are redacted due to security/privacy reasons and each modem has its own unique values
6368
```bash
64-
./GO-BOX --ip 192.168.1.1 --box livebox
69+
./GO-BOX --ip 192.168.1.1 --password xxxx livebox
6570
Password :
6671
✅ Successfully connected to Livebox !
6772

api/api.go

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
package api
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"context"
7+
"encoding/hex"
8+
"fmt"
9+
"os"
10+
"strconv"
11+
"strings"
12+
13+
"github.com/Tomy2e/livebox-api-client"
14+
"github.com/Tomy2e/livebox-api-client/api/request"
15+
)
16+
17+
// NewClient creates a new Livebox API client.
18+
func NewClient(ip, password string) (*livebox.Client, error) {
19+
client, err := livebox.NewClient(password, livebox.WithAddress("http://"+ip))
20+
if err != nil {
21+
return nil, fmt.Errorf("failed to create client: %w", err)
22+
}
23+
return client, nil
24+
}
25+
26+
// GetFunboxValues fetches values from a Funbox.
27+
func GetFunboxValues(client *livebox.Client) (*FunboxValues, error) {
28+
var fbvalues FunboxValues
29+
if err := client.Request(context.Background(), request.New("NeMo.Intf.data", "getMIBs", nil), &fbvalues); err != nil {
30+
return nil, fmt.Errorf("could not get funbox values: %w", err)
31+
}
32+
return &fbvalues, nil
33+
}
34+
35+
// GetOntInfos fetches ONT information from the Livebox.
36+
func GetOntInfos(client *livebox.Client) (*Ont, error) {
37+
var ont Ont
38+
if err := client.Request(context.Background(), request.New("NeMo.Intf.veip0", "getMIBs", map[string]interface{}{"mibs": "gpon"}), &ont); err != nil {
39+
return nil, fmt.Errorf("could not get ONT infos: %w", err)
40+
}
41+
return &ont, nil
42+
}
43+
44+
// GetMacAddress fetches the MAC address of the Livebox.
45+
func GetMacAddress(client *livebox.Client) (string, error) {
46+
var mac MacAddress
47+
if err := client.Request(context.Background(), request.New("NMC", "getWANStatus", nil), &mac); err != nil {
48+
return "", fmt.Errorf("could not get MAC address: %w", err)
49+
}
50+
return mac.Data.MACAddress, nil
51+
}
52+
53+
// GetInternetVlan fetches the VLAN ID for the internet connection.
54+
func GetInternetVlan(client *livebox.Client) (int, error) {
55+
var vlaninternet VlanInternet
56+
if err := client.Request(context.Background(), request.New("NeMo.Intf.data", "getFirstParameter", map[string]interface{}{"name": "VLANID"}), &vlaninternet); err != nil {
57+
return 0, fmt.Errorf("could not get internet vlan: %w", err)
58+
}
59+
return vlaninternet.Status, nil
60+
}
61+
62+
// GetDHCPInfos fetches DHCP information from the Livebox.
63+
func GetDHCPInfos(client *livebox.Client) (*DHCPInfo, error) {
64+
var dhcpinfos DHCP
65+
if err := client.Request(context.Background(), request.New("NeMo.Intf.data", "getMIBs", map[string]interface{}{"mibs": "dhcp"}), &dhcpinfos); err != nil {
66+
return nil, fmt.Errorf("could not get DHCP infos: %w", err)
67+
}
68+
69+
option60 := dhcpinfos.Status.Dhcp.DhcpData.SentOption.Num60.Value
70+
option60decoded, err := hex.DecodeString(option60)
71+
if err != nil {
72+
return nil, fmt.Errorf("could not decode option 60: %w", err)
73+
}
74+
75+
option70 := dhcpinfos.Status.Dhcp.DhcpData.SentOption.Num77.Value
76+
option70decoded, err := hex.DecodeString(option70)
77+
if err != nil {
78+
return nil, fmt.Errorf("could not decode option 70: %w", err)
79+
}
80+
81+
option70decodedstring := string(option70decoded)
82+
83+
opt70 := strings.Split(option70decodedstring, "+")
84+
85+
var dhcpoption77 string
86+
if len(opt70) > 1 {
87+
dhcpoption77 = opt70[1]
88+
} else {
89+
dhcpoption77 = option70decodedstring
90+
}
91+
92+
// Add : every 2 char for DHCP Option 90
93+
var buffer bytes.Buffer
94+
var n1 = 2 - 1
95+
var l1 = len(dhcpinfos.Status.Dhcp.DhcpData.SentOption.Num90.Value) - 1
96+
for i, runner := range dhcpinfos.Status.Dhcp.DhcpData.SentOption.Num90.Value {
97+
buffer.WriteRune(runner)
98+
if i%2 == n1 && i != l1 {
99+
buffer.WriteRune(':')
100+
}
101+
}
102+
dhcpoption90 := buffer.String()
103+
104+
return &DHCPInfo{
105+
Option60: string(option60decoded),
106+
Option77: dhcpoption77,
107+
Option90: dhcpoption90,
108+
}, nil
109+
}
110+
111+
var oltVendorIDMap = map[string]string{
112+
"HWTC": "136",
113+
"ALCL": "128",
114+
"130": "130", // Placeholder for your OLT Vendor ID
115+
}
116+
117+
func generateOMCC(oltvendorid, hwHwver, omciSwVer1, omciSwVer2 string) {
118+
id, ok := oltVendorIDMap[oltvendorid]
119+
if !ok {
120+
id = "128" // default value
121+
fmt.Println("Unknown OLT VENDOR ID, defaulting to 128")
122+
}
123+
124+
fmt.Println("Execute this command -> flash set OMCC_VER " + id)
125+
126+
if oltvendorid == "ALCL" {
127+
if len(hwHwver) != 0 {
128+
fmt.Println("flash set HW_HWVER " + hwHwver)
129+
}
130+
fmt.Println("flash set OMCI_SW_VER1 " + omciSwVer1)
131+
fmt.Println("flash set OMCI_SW_VER2 " + omciSwVer2)
132+
fmt.Println("flash set OMCI_TM_OPT 0")
133+
fmt.Println("flash set OMCI_OLT_MODE 1")
134+
}
135+
}
136+
137+
// GenerateGponCommands prints the GPON commands.
138+
func GenerateGponCommands(gponSn, ponVendorId, hwHwver, omciSwVer1, omciSwVer2 string) {
139+
//fmt.Println("flash set GPON_PLOAM_PASSWD DEFAULT012")
140+
fmt.Println("flash set GPON_SN " + gponSn)
141+
fmt.Println("flash set PON_VENDOR_ID " + ponVendorId)
142+
fmt.Println("## Unplug fiber from Livebox and plug it into UDM and wait a minute ##")
143+
fmt.Println("Execute this command -> omcicli mib get 131")
144+
145+
fmt.Print("OLT VENDOR ID (HWTC, ALCL, ...) : ")
146+
scanner := bufio.NewScanner(os.Stdin)
147+
if scanner.Scan() {
148+
oltvendorid := scanner.Text()
149+
generateOMCC(strings.ToUpper(strings.TrimSpace(oltvendorid)), hwHwver, omciSwVer1, omciSwVer2)
150+
}
151+
}
152+
153+
// DisplayUDMinfos prints the UDM information.
154+
func DisplayUDMinfos(vlanid int, macaddress string, dhcpinfos *DHCPInfo) {
155+
fmt.Println("NAME : LEOX GPON")
156+
fmt.Println("VLAN ID : " + strconv.Itoa(vlanid))
157+
fmt.Println("MAC Address Clone : " + macaddress)
158+
fmt.Println("DHCP OPTION 60 : " + dhcpinfos.Option60)
159+
fmt.Println("DHCP OPTION 77 : " + dhcpinfos.Option77)
160+
fmt.Println("DHCP OPTION 90 : " + dhcpinfos.Option90)
161+
fmt.Println("DHCP CoS : 6 (Requires Network App 7.4.X or later)")
162+
}
163+
164+
// DisplayFunboxValues prints the Funbox values.
165+
func DisplayFunboxValues(client *livebox.Client) error {
166+
fbvalues, err := GetFunboxValues(client)
167+
if err != nil {
168+
return err
169+
}
170+
171+
fmt.Println("===========UDM PRO SE SETTINGS===========")
172+
fmt.Println("PPPoE Username : " + fbvalues.Result.Status.Ppp.PppData.Username)
173+
fmt.Println("PPPoE Password : https://www.orange.pl/moj-orange -> Ustawienia -> Zabezpieczenia -> Hasło do Neostrady -> Zmień hasło")
174+
fmt.Println("VLAN ID: " + strconv.Itoa(fbvalues.Result.Status.Vlan.GvlanData.Vlanid))
175+
fmt.Println("=========================================")
176+
177+
gponSn := fbvalues.Result.Status.Gpon.Veip0.SerialNumber
178+
ponVendorId := fbvalues.Result.Status.Gpon.Veip0.SerialNumber[0:4]
179+
hwHwver := fbvalues.Result.Status.Gpon.Veip0.HardwareVersion
180+
omciSwVer1 := fbvalues.Result.Status.Gpon.Veip0.ONTSoftwareVersion0
181+
omciSwVer2 := fbvalues.Result.Status.Gpon.Veip0.ONTSoftwareVersion1
182+
183+
fmt.Println("")
184+
fmt.Println("============LEOX GPON COMMAND============")
185+
GenerateGponCommands(gponSn, ponVendorId, hwHwver, omciSwVer1, omciSwVer2)
186+
fmt.Println("=========================================")
187+
return nil
188+
}

api/types.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package api
2+
3+
type FunboxValues struct {
4+
Result struct {
5+
Status struct {
6+
Ppp struct {
7+
PppData struct {
8+
Username string `json:"Username"`
9+
} `json:"ppp_data"`
10+
} `json:"ppp"`
11+
Vlan struct {
12+
GvlanData struct {
13+
Vlanid int `json:"VLANID"`
14+
} `json:"gvlan_data"`
15+
} `json:"vlan"`
16+
Gpon struct {
17+
Veip0 struct {
18+
SerialNumber string `json:"SerialNumber"`
19+
HardwareVersion string `json:"HardwareVersion"`
20+
ONTSoftwareVersion0 string `json:"ONTSoftwareVersion0"`
21+
ONTSoftwareVersion1 string `json:"ONTSoftwareVersion1"`
22+
} `json:"veip0"`
23+
} `json:"gpon"`
24+
} `json:"status"`
25+
} `json:"result"`
26+
}
27+
28+
type Ont struct {
29+
Status struct {
30+
Gpon struct {
31+
Veip0 struct {
32+
SerialNumber string `json:"SerialNumber"`
33+
VendorID string `json:"VendorId"`
34+
HardwareVersion string `json:"HardwareVersion"`
35+
ONTSoftwareVersion0 string `json:"ONTSoftwareVersion0"`
36+
ONTSoftwareVersion1 string `json:"ONTSoftwareVersion1"`
37+
} `json:"veip0"`
38+
} `json:"gpon"`
39+
} `json:"status"`
40+
}
41+
42+
type MacAddress struct {
43+
Data struct {
44+
MACAddress string `json:"MACAddress"`
45+
} `json:"data"`
46+
}
47+
48+
type VlanInternet struct {
49+
Status int `json:"status"`
50+
}
51+
52+
type DHCP struct {
53+
Status struct {
54+
Dhcp struct {
55+
DhcpData struct {
56+
SentOption struct {
57+
Num60 struct {
58+
Value string `json:"Value"`
59+
} `json:"60"`
60+
Num77 struct {
61+
Value string `json:"Value"`
62+
} `json:"77"`
63+
Num90 struct {
64+
Value string `json:"Value"`
65+
} `json:"90"`
66+
} `json:"SentOption"`
67+
} `json:"dhcp_data"`
68+
} `json:"dhcp"`
69+
} `json:"status"`
70+
}
71+
72+
type OltVendor struct {
73+
Status struct {
74+
Classp []struct {
75+
Meid int `json:"MEId"`
76+
Attributes string `json:"Attributes"`
77+
} `json:"classp"`
78+
} `json:"status"`
79+
}
80+
81+
// DHCPInfo holds the DHCP options.
82+
type DHCPInfo struct {
83+
Option60 string
84+
Option77 string
85+
Option90 string
86+
}

cli/cli.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package cli
2+
3+
import (
4+
"log"
5+
"os"
6+
7+
"github.com/Stoufiler/go-box/commands"
8+
"github.com/Stoufiler/go-box/utils"
9+
"github.com/urfave/cli/v2"
10+
)
11+
12+
func Run() {
13+
app := &cli.App{
14+
Name: "GO-BOX",
15+
Usage: "CLI tool to fetch infos from Livebox/Funbox",
16+
Flags: []cli.Flag{
17+
&cli.StringFlag{
18+
Name: "ip",
19+
Usage: "IP address of box",
20+
Required: true,
21+
},
22+
&cli.StringFlag{
23+
Name: "password",
24+
Usage: "Password of box",
25+
},
26+
},
27+
Before: func(ctx *cli.Context) error {
28+
if ctx.String("password") == "" {
29+
password, err := utils.GetPassword()
30+
if err != nil {
31+
return err
32+
}
33+
return ctx.Set("password", password)
34+
}
35+
return nil
36+
},
37+
Commands: []*cli.Command{
38+
commands.LiveboxCommand(),
39+
commands.FunboxCommand(),
40+
},
41+
}
42+
43+
if err := app.Run(os.Args); err != nil {
44+
log.Fatal(err)
45+
}
46+
}

0 commit comments

Comments
 (0)