├── .gitignore ├── README.md ├── getip └── getip_cli.go ├── ndgui ├── app.manifest ├── gui.go └── hw.ico ├── netdialer.go ├── netdialer └── netdialer_cli.go └── router ├── README.md ├── asus └── asus_cli.go ├── hiwifi └── hiwifi_cli.go ├── openwrt └── openwrt_cli.go ├── routers.go └── tplink └── tplink_cli.go /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.syso 3 | *.log 4 | *.json 5 | *.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Netdialer 2 | ========= 3 | 4 | The dialer for the fucking shanxun network in Zhejiang, written in go. 5 | 6 | ### for developer 7 | 8 | get this by following command 9 | 10 | > go get -v -u github.com/pa001024/netdialer/netdialer 11 | 12 | 简介 13 | ---- 14 | 15 | 本程序分GUI版本和CLI(命令行)版本 16 | 17 | 以下是使用说明 18 | 19 | GUI版本使用说明 20 | --------------- 21 | 22 | (有BUG请在 issues 里说) 23 | 24 | 因为是 GUI 其实没啥可说的。 25 | 26 | 就说几个 tips: (亲,看完再下载) 27 | 28 | ### 关于模式 29 | 30 | 内建几种路由器适配。(目前还没有 TP 真是抱歉 233) 31 | 32 | __注意:要使用路由模式,你需要先将网线插到路由器WAN口 然后进路由器后台 33 | 将WAN口设置为 DHCP 模式(也可能叫动态IP)。__ 34 | 35 | 然后打开软件,选择对应的模式并且改好路由器的地址密码(注意密码不是 WiFi 密码而是后台管理密码)等参数之后就可以直接用了。 36 | 37 | 如果没有自己的路由器的模式,那么就去路由界面自行获取IP直接填到模式内即可。 38 | 39 | 40 | 命令行版本使用说明 41 | ---------------------- 42 | 43 | 参数跟GUI基本一样 44 | 45 | 不过因为可以命令行使用,所以方便到任何平台运行,也可设置开机启动、计划任务等等,总之想怎么玩怎么玩。 46 | 47 | #### 开始连接 48 | 49 | 日常使用方法如下: 50 | 51 | 如果是本地拨号: 52 | > netdialer -u xx -p xx 53 | 54 | 如果是路由器: 55 | > netdialer -ip hiwifi -ra xx -ru xx -rp xx -u xx -p xx 56 | 57 | #### 断开连接 58 | 59 | ps.断开连接可以不要闪讯账号密码。 60 | 61 | 如果是本地拨号: 62 | > netdialer -d 63 | 64 | 如果是路由器: 65 | > netdialer -ip hiwifi -ra xx -ru xx -rp xx 66 | 67 | 68 | #### 支持自己开发路由器适配 69 | 70 | 只要`-ip stdin`并用管道传入WAN口IP即可。 71 | 72 | > 比如 `yourrouter -u xxx -p xxxx | netdialer -u xxx -p xxx -ip stdin` 73 | 74 | #### 依然可以使用内建的几种路由支持: 75 | 76 | > 比如 `-ip hiwifi` 然后填写`-ra [路由地址] -ru [路由用户名] -rp [路由密码]`参数即可 77 | 78 | #### 关于路由模式2 79 | 80 | (也就是 `-r` 参数) 81 | 82 | 这个是通过WAN口直接拨号的,本程序没有提供相应的适配器(除了TP),因为生成的用户名每五秒就会变,所以实用性不高。 83 | 84 | 如果你需要使用,可以自己编写适配器,可拨到本地或路由。 85 | 86 | 只需开启 `-r` 模式,程序就会通过stdout输出两行文本。第一行是经过URL编码的用户名,第二行是密码。只需要将PPPoE的账号密码设置成这个然后立刻拨号即可(一定要快,因为有效期只有五秒)。 87 | 88 | ##### 目前只有一个TP的拨号程序,使用方法如下: 89 | 90 | > netdialer -u xx -p xx -r | tplink -p xx -a 192.168.1.1 91 | 92 | 93 | 94 | 下载 95 | ---- 96 | 97 | 度云 [http://pan.baidu.com/s/1dDQiXpf](http://pan.baidu.com/s/1dDQiXpf) 98 | -------------------------------------------------------------------------------- /getip/getip_cli.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "time" 7 | 8 | "github.com/pa001024/reflex/util" 9 | ) 10 | 11 | func main() { 12 | check() 13 | } 14 | 15 | func check() { 16 | ch := make(chan string) 17 | go func() { 18 | ip := util.GetIPInfo() 19 | if ip != nil { 20 | ch <- ip.IP 21 | } else { 22 | os.Exit(2) 23 | } 24 | }() 25 | select { 26 | case <-time.After(time.Second * 2): 27 | os.Exit(2) 28 | case ip := <-ch: 29 | fmt.Println(ip) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ndgui/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ndgui/gui.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "encoding/json" 6 | "io/ioutil" 7 | "os" 8 | "runtime" 9 | "strings" 10 | 11 | "github.com/lxn/walk" 12 | . "github.com/lxn/walk/declarative" 13 | 14 | "github.com/pa001024/netdialer" 15 | "github.com/pa001024/netdialer/router" 16 | "github.com/pa001024/reflex/util" 17 | ) 18 | 19 | type Config struct { 20 | Username string `json:"username"` 21 | Password string `json:"password"` 22 | RouterAddr string `json:"routerAddr"` 23 | RouterUser string `json:"routerUser"` 24 | RouterPwd string `json:"routerPwd"` 25 | RouterType string `json:"routerType"` 26 | } 27 | 28 | var ( 29 | config *Config = &Config{ 30 | Username: "18xxxxxxxxx@XXXX.XX", 31 | Password: "******", 32 | RouterAddr: "192.168.1.1", 33 | RouterUser: "root", 34 | RouterPwd: "admin", 35 | RouterType: "local", // asus hiwifi openwrt 36 | } 37 | ) 38 | 39 | const ( 40 | TITLE = "NDGUI v0.6.1" 41 | ) 42 | 43 | func main() { 44 | fout, _ := os.Create("dialer.log") 45 | defer fout.Close() 46 | bo := bufio.NewWriter(fout) 47 | defer bo.Flush() 48 | util.INFO.SetOutput(bo) 49 | util.ERROR.SetOutput(bo) 50 | 51 | bin, err := ioutil.ReadFile("config.json") 52 | if err == nil { 53 | json.Unmarshal(bin, config) 54 | } else { 55 | util.ERROR.Log(err) 56 | err = nil 57 | } 58 | 59 | var usr, pwd *walk.LineEdit 60 | var raddr, rusr, rpwd *walk.LineEdit 61 | var lb, rb *walk.PushButton 62 | var mode *walk.ComboBox 63 | var mw *walk.MainWindow 64 | var db *walk.DataBinder 65 | var laddr, lusr, lpwd *walk.Splitter 66 | go func() { 67 | for mw == nil { 68 | runtime.Gosched() 69 | } 70 | ic, err := walk.NewIconFromResourceId(6) 71 | if err == nil { 72 | // func onLoad() { 73 | db.SetAutoSubmit(true) 74 | mw.SetIcon(ic) 75 | switch config.RouterType { 76 | case "hiwifi": 77 | laddr.SetVisible(true) 78 | lusr.SetVisible(false) 79 | lpwd.SetVisible(true) 80 | case "openwrt": 81 | laddr.SetVisible(true) 82 | lusr.SetVisible(true) 83 | lpwd.SetVisible(true) 84 | case "tplinkwr700n": 85 | laddr.SetVisible(true) 86 | lusr.SetVisible(true) 87 | lpwd.SetVisible(true) 88 | case "asus": 89 | laddr.SetVisible(true) 90 | lusr.SetVisible(true) 91 | lpwd.SetVisible(true) 92 | default: 93 | laddr.SetVisible(false) 94 | lusr.SetVisible(false) 95 | lpwd.SetVisible(false) 96 | } 97 | mw.SetSize(walk.Size{0, 0}) 98 | // } 99 | } 100 | }() 101 | MainWindow{ 102 | AssignTo: &mw, 103 | Title: TITLE, 104 | MinSize: Size{340, 0}, 105 | Layout: VBox{}, 106 | DataBinder: DataBinder{ 107 | AssignTo: &db, 108 | DataSource: config, 109 | }, 110 | Children: []Widget{ 111 | HSplitter{ 112 | Children: []Widget{ 113 | Label{Text: "用户名", MaxSize: Size{60, 20}}, 114 | LineEdit{Text: Bind("Username"), AssignTo: &usr, MaxSize: Size{0, 20}}, 115 | }, MaxSize: Size{0, 20}, 116 | }, 117 | HSplitter{ 118 | Children: []Widget{ 119 | Label{Text: "密码", MaxSize: Size{60, 20}}, 120 | LineEdit{Text: Bind("Password"), AssignTo: &pwd, MaxSize: Size{0, 20}, PasswordMode: true, 121 | OnMouseDown: func(x, y int, button walk.MouseButton) { 122 | pwd.SetPasswordMode(false) 123 | }, 124 | OnMouseUp: func(x, y int, button walk.MouseButton) { 125 | pwd.SetPasswordMode(true) 126 | }, 127 | }, 128 | }, MaxSize: Size{0, 20}, 129 | }, 130 | HSplitter{ 131 | Children: []Widget{ 132 | Label{Text: "模式", MaxSize: Size{60, 20}}, 133 | ComboBox{AssignTo: &mode, 134 | Editable: true, Value: Bind("RouterType"), 135 | Model: []string{"local", "10.0.x.x(手动填写)", "openwrt", "hiwifi", "asus", "tplinkwr700n"}, 136 | MaxSize: Size{0, 20}, 137 | OnCurrentIndexChanged: func() { 138 | switch mode.CurrentIndex() { 139 | case 2: //"openwrt": 140 | laddr.SetVisible(true) 141 | lusr.SetVisible(true) 142 | lpwd.SetVisible(true) 143 | case 3: //"hiwifi": 144 | config.RouterAddr = "192.168.199.1" 145 | laddr.SetVisible(true) 146 | lusr.SetVisible(false) 147 | lpwd.SetVisible(true) 148 | case 4: //"asus": 149 | laddr.SetVisible(true) 150 | lusr.SetVisible(true) 151 | lpwd.SetVisible(true) 152 | default: 153 | laddr.SetVisible(false) 154 | lusr.SetVisible(false) 155 | lpwd.SetVisible(false) 156 | } 157 | mw.SetSize(walk.Size{0, 0}) 158 | }, 159 | }, 160 | }, MaxSize: Size{0, 20}, 161 | }, 162 | HSplitter{ 163 | AssignTo: &laddr, 164 | Children: []Widget{ 165 | Label{Text: "路由地址", MaxSize: Size{60, 20}}, 166 | LineEdit{Text: Bind("RouterAddr"), AssignTo: &raddr, MaxSize: Size{0, 20}}, 167 | }, MaxSize: Size{0, 20}, 168 | }, 169 | HSplitter{ 170 | AssignTo: &lusr, 171 | Children: []Widget{ 172 | Label{Text: "路由用户名", MaxSize: Size{60, 20}}, 173 | LineEdit{Text: Bind("RouterUser"), AssignTo: &rusr, MaxSize: Size{0, 20}}, 174 | }, MaxSize: Size{0, 20}, 175 | }, 176 | HSplitter{ 177 | AssignTo: &lpwd, 178 | Children: []Widget{ 179 | Label{Text: "路由密码", MaxSize: Size{60, 20}}, 180 | LineEdit{Text: Bind("RouterPwd"), AssignTo: &rpwd, MaxSize: Size{0, 20}, PasswordMode: true, 181 | OnMouseDown: func(x, y int, button walk.MouseButton) { 182 | rpwd.SetPasswordMode(false) 183 | }, 184 | OnMouseUp: func(x, y int, button walk.MouseButton) { 185 | rpwd.SetPasswordMode(true) 186 | }, 187 | }, 188 | }, MaxSize: Size{0, 20}, 189 | }, 190 | HSplitter{ 191 | Children: []Widget{ 192 | PushButton{ 193 | AssignTo: &lb, 194 | Text: "开始连接", 195 | OnClicked: func() { 196 | mode.SetText(strings.TrimSpace(mode.Text())) 197 | if mode.Text() == "10.0.x.x(手动填写)" { 198 | walk.MsgBox(mw, "请填写IP", "手动填写需要自己获取IP 你可在路由器中自己查找 本地拨号请用local", walk.MsgBoxOK) 199 | return 200 | } 201 | lb.SetText("连接中...") 202 | lb.SetEnabled(false) 203 | rb.SetEnabled(false) 204 | 205 | go func() { 206 | d := netdialer.NewDialer(usr.Text(), pwd.Text()) 207 | d.UserIP = selectMode(mode.Text()) 208 | 209 | if d.UserIP == "" { 210 | walk.MsgBox(mw, "连接失败", "请检查设置", walk.MsgBoxOK) 211 | d = nil 212 | lb.SetEnabled(true) 213 | rb.SetEnabled(true) 214 | return 215 | } else if d.UserIP == "tplinkwr700n" { 216 | user, pass := d.GetRouterConnectInfo() 217 | router.SetWanInfo_TPLink(raddr.Text(), rusr.Text(), rpwd.Text(), user, pass) 218 | } else { 219 | d.ConnectDirect() 220 | } 221 | mw.SetTitle(TITLE + " [" + d.UserIP + "]") 222 | d = nil 223 | lb.SetEnabled(true) 224 | rb.SetEnabled(true) 225 | lb.SetText("开始连接") 226 | if err == nil { 227 | walk.MsgBox(mw, "连接成功", "感谢使用", walk.MsgBoxOK) 228 | util.INFO.Log("连接成功: 感谢使用") 229 | } else { 230 | walk.MsgBox(mw, "连接失败", err.Error(), walk.MsgBoxOK) 231 | util.INFO.Log("连接失败: ", err.Error()) 232 | } 233 | }() 234 | 235 | }, 236 | }, 237 | PushButton{ 238 | AssignTo: &rb, 239 | Text: "断开连接", 240 | OnClicked: func() { 241 | mode.SetText(strings.TrimSpace(mode.Text())) 242 | if mode.Text() == "10.0.x.x(手动填写)" { 243 | walk.MsgBox(mw, "请填写IP", "手动填写需要自己获取IP 你可在路由器中自己查找", walk.MsgBoxOK) 244 | return 245 | } 246 | if mode.Text() == "tplinkwr700n" { 247 | walk.MsgBox(mw, "无效操作", "此模式不存在断开", walk.MsgBoxOK) 248 | return 249 | } 250 | rb.SetText("断开中...") 251 | lb.SetEnabled(false) 252 | rb.SetEnabled(false) 253 | go func() { 254 | d := netdialer.NewDialer(usr.Text(), pwd.Text()) 255 | d.UserIP = selectMode(mode.Text()) 256 | if d.UserIP == "" { 257 | walk.MsgBox(mw, "连接失败", "请检查设置", walk.MsgBoxOK) 258 | util.INFO.Log("连接失败: 请检查设置") 259 | d = nil 260 | lb.SetEnabled(true) 261 | rb.SetEnabled(true) 262 | return 263 | } 264 | err := d.DisconnectDirect() 265 | mw.SetTitle(TITLE + " [" + d.UserIP + "]") 266 | d = nil 267 | lb.SetEnabled(true) 268 | rb.SetEnabled(true) 269 | rb.SetText("断开连接") 270 | if err == nil { 271 | walk.MsgBox(mw, "断开成功", "感谢使用", walk.MsgBoxOK) 272 | util.INFO.Log("断开成功: 感谢使用") 273 | } else { 274 | walk.MsgBox(mw, "断开失败", err.Error(), walk.MsgBoxOK) 275 | util.INFO.Log("断开失败: ", err.Error()) 276 | } 277 | }() 278 | }, 279 | }, 280 | }, MaxSize: Size{0, 20}, 281 | }, 282 | }, 283 | }.Run() 284 | saveConfig(config) 285 | bo.Flush() 286 | } 287 | 288 | func selectMode(typ string) (rst string) { 289 | switch typ { 290 | case "hiwifi": 291 | rst = router.GetLanIP_HiwifiV3(config.RouterAddr, config.RouterPwd) 292 | if rst == "" { 293 | rst = router.GetLanIP_HiwifiV2(config.RouterAddr, config.RouterPwd) 294 | } 295 | if rst == "" { 296 | rst = router.GetLanIP_Hiwifi(config.RouterAddr, config.RouterPwd) 297 | } 298 | case "openwrt": 299 | rst = router.GetLanIP_Openwrt(config.RouterAddr, config.RouterPwd) 300 | case "asus": 301 | rst = router.GetLanIP_Asus(config.RouterAddr, config.RouterUser, config.RouterPwd) 302 | // case "tplinkwr700n": 303 | default: 304 | rst = typ 305 | } 306 | return 307 | } 308 | 309 | func saveConfig(config *Config) { 310 | b, err := json.MarshalIndent(config, "", "\t") 311 | if err == nil { 312 | ioutil.WriteFile("config.json", b, 0644) 313 | } else { 314 | util.ERROR.Log(err) 315 | } 316 | } 317 | -------------------------------------------------------------------------------- /ndgui/hw.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pa001024/netdialer/1a7d7f2e9afb57581cb6cf98971c8369cd4ecefb/ndgui/hw.ico -------------------------------------------------------------------------------- /netdialer.go: -------------------------------------------------------------------------------- 1 | package netdialer 2 | 3 | import ( 4 | "encoding/xml" 5 | "errors" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | "net/url" 10 | "regexp" 11 | "strings" 12 | 13 | "github.com/pa001024/reflex/util" 14 | ) 15 | 16 | const ( 17 | NET_PWD_MASK = "7%ChIna3#@Net*%" 18 | RADIUS = "singlenet01" //"\x73\x69\x6e\x67\x6c\x65\x6e\x65\x74\x30\x31" 19 | ) 20 | 21 | type Dialer struct { 22 | username string 23 | rawPassword string 24 | password string 25 | UserIP string 26 | uuid string 27 | logoffURL string 28 | ratingtype string 29 | Router RouterInfo 30 | } 31 | 32 | type RouterInfo struct { 33 | Type int 34 | Addr string 35 | User string 36 | Pwd string 37 | } 38 | 39 | const ( 40 | Router_TP = iota 41 | ) 42 | 43 | func NewDialer(username, password string) (obj *Dialer) { 44 | obj = &Dialer{ 45 | username: username, 46 | ratingtype: "1", 47 | Router: RouterInfo{ 48 | Type: Router_TP, 49 | Addr: "192.168.1.1", 50 | User: "admin", 51 | Pwd: "admin", 52 | }, 53 | } 54 | obj.SetPassword(password) 55 | return 56 | } 57 | 58 | // 路由器拨号命令行调用 59 | func (this *Dialer) ConnectRouter() (err error) { 60 | fmt.Println(url.QueryEscape(this.getCryptUsername())) 61 | fmt.Println(this.rawPassword) 62 | return 63 | } 64 | 65 | // 路由器拨号外部调用 66 | func (this *Dialer) GetRouterConnectInfo() (user, pass string) { 67 | user = this.getCryptUsername() 68 | pass = this.rawPassword 69 | return 70 | } 71 | 72 | //本地拨号 73 | func (this *Dialer) ConnectDirect() (err error) { 74 | defer util.Catch(&err) 75 | this.checkIP() 76 | info, err := this.dial_getinfo() 77 | util.Try(err) 78 | rst, err := this.dial_login(info) 79 | util.Try(err) 80 | util.DEBUG.Log(rst) 81 | return 82 | } 83 | 84 | //本地拨号 85 | func (this *Dialer) DisconnectDirect() (err error) { 86 | defer util.Catch(&err) 87 | this.checkIP() 88 | info, err := this.dial_getinfo() 89 | util.Try(err) 90 | rst, err := this.dial_logout(info) 91 | util.Try(err) 92 | util.DEBUG.Log(rst) 93 | return 94 | } 95 | 96 | func (this *Dialer) checkIP() { 97 | r := regexp.MustCompile(`\b(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b`) 98 | this.UserIP = r.FindString(this.UserIP) 99 | if this.UserIP == "" { 100 | this.RefreshIP() 101 | } 102 | } 103 | 104 | type loginInfo struct { 105 | UserIP string `xml:"Redirect>UserIP"` 106 | LoginURL string `xml:"Redirect>LoginURL"` 107 | Uuid string `xml:"Redirect>Uuid"` 108 | } 109 | type loginResult struct { 110 | MessageType int `xml:"AuthenticationReply>MessageType"` 111 | ResponseCode int `xml:"AuthenticationReply>ResponseCode"` 112 | LogoffURL string `xml:"AuthenticationReply>LogoffURL"` 113 | Uuid string `xml:"AuthenticationReply>Uuid"` 114 | UserIP string `xml:"AuthenticationReply>UserIP"` 115 | } 116 | type logoff struct { 117 | MessageType int `xml:"LogoffReply>MessageType"` 118 | ResponseCode int `xml:"LogoffReply>ResponseCode"` 119 | Date string `xml:"LogoffReply>Date"` 120 | } 121 | 122 | func (this *Dialer) dial_getinfo() (info *loginInfo, err error) { 123 | defer util.Catch(&err) 124 | body := ioutil.NopCloser(strings.NewReader((url.Values{"wlanuserip": {this.UserIP}}).Encode())) 125 | req, err := http.NewRequest("POST", "http://115.239.134.163:8080/showlogin.do", body) 126 | util.Try(err) 127 | req.Header.Set("User-Agent", "China Telecom Client") 128 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 129 | res, err := http.DefaultClient.Do(req) 130 | util.Try(err) 131 | data, _ := ioutil.ReadAll(res.Body) 132 | res.Body.Close() 133 | info = &loginInfo{} 134 | xml.Unmarshal(data, &info) 135 | util.DEBUG.Log("[dial_getinfo] ", string(data)) 136 | return 137 | } 138 | func (this *Dialer) dial_login(info *loginInfo) (rst *loginResult, err error) { 139 | defer util.Catch(&err) 140 | parms := url.Values{ 141 | "uuid": {info.Uuid}, 142 | "userip": {info.UserIP}, 143 | "username": {this.username}, 144 | "password": {this.rawPassword}, 145 | "ratingtype": {this.ratingtype}, 146 | } 147 | body := ioutil.NopCloser(strings.NewReader(parms.Encode())) 148 | util.DEBUG.Log("[dial_login] ", parms) 149 | req, err := http.NewRequest("POST", info.LoginURL, body) 150 | util.Try(err) 151 | req.Header.Set("User-Agent", "China Telecom Client") 152 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 153 | res, err := http.DefaultClient.Do(req) 154 | util.Try(err) 155 | data, _ := ioutil.ReadAll(res.Body) 156 | res.Body.Close() 157 | rst = &loginResult{} 158 | xml.Unmarshal(data, &rst) 159 | util.DEBUG.Log("[dial_login] ", string(data)) 160 | if rst.ResponseCode != 200 { 161 | if rst.ResponseCode == 73 { 162 | err = errors.New("请检查账号是否正常 有可能是欠费") 163 | } else { 164 | err = errors.New("错误(" + string(rst.ResponseCode) + ") 请检查账号是否正常") 165 | } 166 | } 167 | return 168 | } 169 | 170 | func (this *Dialer) dial_logout(info *loginInfo) (rst *loginResult, err error) { 171 | defer util.Catch(&err) 172 | parms := url.Values{ 173 | "uuid": {info.Uuid}, 174 | "userip": {info.UserIP}, 175 | } 176 | body := ioutil.NopCloser(strings.NewReader(parms.Encode())) 177 | util.DEBUG.Log("[dial_logout] ", parms) 178 | req, err := http.NewRequest("POST", "http://115.239.134.163:8080/servlets/G3logoutServlet", body) 179 | util.Try(err) 180 | req.Header.Set("User-Agent", "China Telecom Client") 181 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 182 | res, err := http.DefaultClient.Do(req) 183 | util.Try(err) 184 | data, _ := ioutil.ReadAll(res.Body) 185 | res.Body.Close() 186 | rst = &loginResult{} 187 | xml.Unmarshal(data, &rst) 188 | util.DEBUG.Log("[dial_logout] ", string(data)) 189 | if rst.ResponseCode != 200 { 190 | if rst.ResponseCode == 73 { 191 | err = errors.New("请检查账号是否正常 有可能是欠费") 192 | } else { 193 | err = errors.New("错误(" + string(rst.ResponseCode) + ") 请检查账号是否正常") 194 | } 195 | } 196 | return 197 | } 198 | 199 | func (this *Dialer) SetPassword(pwd string) { 200 | this.rawPassword = pwd 201 | this.password = util.AESCBCStringX(util.MD5(NET_PWD_MASK), []byte(pwd), true) 202 | } 203 | 204 | func (this *Dialer) RefreshIP() { 205 | for _, v := range util.GetIPLocal() { 206 | if v[:3] == "10." { 207 | this.UserIP = v 208 | return 209 | } 210 | } 211 | } 212 | 213 | // 路由拨号加密用户名 214 | func (this *Dialer) getCryptUsername() string { 215 | time := util.JsCurrentSecond() / 5 216 | data := string([]rune{ 217 | rune(time >> 24 & 0xff), 218 | rune(time >> 16 & 0xff), 219 | rune(time >> 8 & 0xff), 220 | rune(time & 0xff), 221 | }) 222 | data += this.username[:strings.IndexRune(this.username, '@')] 223 | data += RADIUS 224 | aftermd5 := util.MD5String(data) 225 | util.DEBUG.Log(aftermd5) 226 | sig := aftermd5[:2] 227 | temp := make([]byte, 32) 228 | timechar := []byte{ 229 | byte(time >> 24 & 0xff), 230 | byte(time >> 16 & 0xff), 231 | byte(time >> 8 & 0xff), 232 | byte(time & 0xff), 233 | } 234 | for i := 0; i < 32; i++ { 235 | temp[i] = timechar[(31-i)>>3] & 1 236 | timechar[(31-i)>>3] = timechar[(31-i)>>3] >> 1 237 | } 238 | timeHash := make([]byte, 4) 239 | for i := 0; i < 4; i++ { 240 | timeHash[i] = temp[i]<<7 + temp[4+i]<<6 + temp[8+i]<<5 + temp[12+i]<<4 + temp[16+i]<<3 + temp[20+i]<<2 + temp[24+i]<<1 + temp[28+i] 241 | } 242 | temp[0] = (timeHash[0] >> 2) & 0x3F 243 | temp[1] = (timeHash[0]&3)<<4 + (timeHash[1] >> 4 & 0xF) 244 | temp[2] = ((timeHash[2] >> 6) & 0x3) + (timeHash[1]&0xF)<<2 245 | temp[3] = timeHash[2] & 0x3F 246 | temp[4] = (timeHash[3] >> 2) & 0x3F 247 | temp[5] = (timeHash[3] & 3) << 4 248 | sig2 := "" 249 | for i := 0; i < 6; i++ { 250 | var tp = temp[i] + 0x20 251 | if tp >= 0x40 { 252 | tp++ 253 | } 254 | sig2 += string([]byte{byte(tp)}) 255 | } 256 | return "\r\n" + sig2 + sig + this.username 257 | } 258 | -------------------------------------------------------------------------------- /netdialer/netdialer_cli.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "os" 7 | 8 | "github.com/pa001024/netdialer" 9 | "github.com/pa001024/netdialer/router" 10 | "github.com/pa001024/reflex/util" 11 | ) 12 | 13 | const ( 14 | VERSION = "netdialer CLI ver.0.4.3 by pa001024" 15 | EXAMPLE = `usage example: > netdialer -ip 10.0.10.20 -u 18123123122@ZZZ.XY -p 123456 16 | netdialer -ip hiwifi -ra 192.168.199.1 -rp 1231123 -u 18123123122@ZZZ.XY -p 123456` 17 | ) 18 | 19 | type Config struct { 20 | Username string `json:"username"` 21 | Password string `json:"password"` 22 | RouterType string `json:"routerType"` 23 | RouterAddr string `json:"routerAddr"` 24 | RouterUser string `json:"routerUser"` 25 | RouterPwd string `json:"routerPwd"` 26 | } 27 | 28 | var config *Config 29 | 30 | func main() { 31 | username := flag.String("u", "", "shanxun username") 32 | password := flag.String("p", "", "shanxun password") 33 | isRouter := flag.Bool("r", false, "use router mode 2? (defalut off)") 34 | isDisconnect := flag.Bool("d", false, "disconnect?") 35 | realIP := flag.String("ip", "local", "real IP, 'stdin' or 'local' works router support [hiwifi openwrt asus]") 36 | raddress := flag.String("ra", "192.168.1.1", "router address") 37 | rusername := flag.String("ru", "root", "router username") 38 | rpassword := flag.String("rp", "admin", "router password") 39 | flag.Parse() 40 | config = &Config{*username, *password, *realIP, *raddress, *rusername, *rpassword} 41 | 42 | if !*isDisconnect { 43 | if config.Username == "" && !*isDisconnect { 44 | println(VERSION) 45 | println(EXAMPLE) 46 | flag.Usage() 47 | return 48 | } else if len(config.Username) < 12 || len(config.Password) != 6 { 49 | util.ERROR.Log("Invalid username or password") 50 | println(VERSION) 51 | println(EXAMPLE) 52 | flag.Usage() 53 | return 54 | } 55 | } 56 | d := netdialer.NewDialer(config.Username, config.Password) 57 | if config.RouterType != "" && config.RouterType != "local" { 58 | if config.RouterType == "stdin" { 59 | in := bufio.NewReader(os.Stdin) 60 | str, _ := in.ReadString(0) 61 | d.UserIP = str 62 | } else { 63 | d.UserIP = selectMode(config.RouterType) 64 | } 65 | } 66 | var err error 67 | if *isRouter { 68 | err = d.ConnectRouter() 69 | } else { 70 | if *isDisconnect { 71 | err = d.DisconnectDirect() 72 | } else { 73 | err = d.ConnectDirect() 74 | } 75 | } 76 | if err != nil { 77 | util.ERROR.Log(err) 78 | } 79 | } 80 | func selectMode(typ string) (rst string) { 81 | switch typ { 82 | case "hiwifi": 83 | rst = router.GetLanIP_HiwifiV3(config.RouterAddr, config.RouterPwd) 84 | if rst == "" { 85 | rst = router.GetLanIP_HiwifiV2(config.RouterAddr, config.RouterPwd) 86 | if rst == "" { 87 | rst = router.GetLanIP_Hiwifi(config.RouterAddr, config.RouterPwd) 88 | } 89 | } 90 | case "openwrt": 91 | rst = router.GetLanIP_Openwrt(config.RouterAddr, config.RouterPwd) 92 | case "asus": 93 | rst = router.GetLanIP_Asus(config.RouterAddr, config.RouterUser, config.RouterPwd) 94 | default: 95 | rst = config.RouterType 96 | } 97 | return 98 | } 99 | -------------------------------------------------------------------------------- /router/README.md: -------------------------------------------------------------------------------- 1 | Router Adapter 2 | ============== 3 | 4 | use for different kinds of routers 5 | 6 | general cmd format 7 | ------------------ 8 | 9 | ``` 10 | // router mode 11 | netdialer -r -u xxxxx@xxx.xy -p xxxxxx | hiwifi -wan -p xxxxx 12 | 13 | // direct mode 14 | hiwifi -p xxxxx | netdialer -u xxxxx@xxx.xy -p xxxxxx -ip stdin 15 | ``` 16 | 17 | 18 | azezszzczbzcz 19 | ____youdianyisi. 20 | you did it . 21 | 22 | 23 | YXplenN6emN6Ynpjeg==X19fX3lvdWRpYW55aXNpLg==rhkmqpDLO3FZSWL4KWShxQ== -------------------------------------------------------------------------------- /router/asus/asus_cli.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "regexp" 9 | ) 10 | 11 | func GetLanIP_Asus() string { 12 | address := flag.String("a", "192.168.1.1", "admin's address") 13 | username := flag.String("u", "admin", "admin's username") 14 | password := flag.String("p", "admin", "admin's password") 15 | flag.Parse() 16 | client := &http.Client{} 17 | req, err := http.NewRequest("GET", "http://"+*address+"/status.asp", nil) 18 | req.SetBasicAuth(*username, *password) 19 | if err != nil { 20 | fmt.Println(err) 21 | return "" 22 | } 23 | res, err := client.Do(req) 24 | if err != nil { 25 | fmt.Println(err) 26 | return "" 27 | } 28 | bin, _ := ioutil.ReadAll(res.Body) 29 | res.Body.Close() 30 | str := string(bin) 31 | ex := regexp.MustCompile(`wanlink_ipaddr\(\) \{ return '(.+?)';\}`) 32 | li := ex.FindStringSubmatch(str) 33 | if len(li) > 1 { 34 | return li[1] 35 | } 36 | return "" 37 | } 38 | func main() { 39 | ip := GetLanIP_Asus() 40 | fmt.Println(ip) 41 | } 42 | -------------------------------------------------------------------------------- /router/hiwifi/hiwifi_cli.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | "net/http/cookiejar" 10 | "net/url" 11 | "os" 12 | "regexp" 13 | ) 14 | 15 | func GetLanIP_Hiwifi(address, password string) string { 16 | jar, _ := cookiejar.New(nil) 17 | client := &http.Client{Jar: jar} 18 | res, err := client.PostForm("http://"+address+"/cgi-bin/turbo/admin_web", url.Values{"username": {"admin"}, "password": {password}}) 19 | if err != nil { 20 | fmt.Println(err) 21 | return "" 22 | } 23 | bin, _ := ioutil.ReadAll(res.Body) 24 | res.Body.Close() 25 | str := string(bin) 26 | ex := regexp.MustCompile(`URL_ROOT_PATH = "(.+?)";`) // /cgi-bin/turbo/;stok=8ab11a0e6a60d45e3658a4f81b0f2884 27 | li := ex.FindStringSubmatch(str) 28 | if len(li) > 1 { 29 | res, err = client.Get("http://" + address + "" + li[1] + "/api/network/get_wan_info") 30 | if err != nil { 31 | fmt.Println(err) 32 | return "" 33 | } 34 | bin, _ = ioutil.ReadAll(res.Body) 35 | res.Body.Close() 36 | str = string(bin) 37 | ex = regexp.MustCompile(`"ip": "(10\..+?)" }`) 38 | li = ex.FindStringSubmatch(str) 39 | if len(li) > 1 { 40 | return li[1] 41 | } 42 | } 43 | return "" 44 | } 45 | func SetWanInfo_Hiwifi(address, password, wanUser, wanPwd string) { 46 | jar, _ := cookiejar.New(nil) 47 | client := &http.Client{Jar: jar} 48 | res, err := client.PostForm("http://"+address+"/cgi-bin/turbo/admin_web", url.Values{"username": {"admin"}, "password": {password}}) 49 | if err != nil { 50 | fmt.Println(err) 51 | return 52 | } 53 | bin, _ := ioutil.ReadAll(res.Body) 54 | res.Body.Close() 55 | str := string(bin) 56 | ex := regexp.MustCompile(`URL_ROOT_PATH = "(.+?)";`) // /cgi-bin/turbo/;stok=8ab11a0e6a60d45e3658a4f81b0f2884 57 | li := ex.FindStringSubmatch(str) 58 | if len(li) > 1 { 59 | res, err = client.PostForm("http://"+address+""+li[1]+"/api/network/set_wan_connect", url.Values{ 60 | "network_type": {"pppoe"}, 61 | "type": {"pppoe"}, 62 | "pppoe_name": {wanUser}, 63 | "pppoe_passwd": {wanPwd}, 64 | "ip_type": {"dhcp"}, 65 | "static_ip": {""}, 66 | "static_mask": {""}, 67 | "static_gw": {""}, 68 | "static_dns": {""}, 69 | "static_dns2": {""}, 70 | "ssid": {""}, 71 | "channel": {""}, 72 | "bssid": {""}, 73 | "encryption": {""}, 74 | "ssid_select_mode": {""}, 75 | "key": {""}, 76 | "key_show": {""}, 77 | "peerdns": {"0"}, 78 | "override_dns": {"119.29.29.29"}, 79 | "override_dns2": {"180.76.76.76"}, 80 | "uptime": {"0"}, 81 | "switch_status_wan": {"auto"}, 82 | }) 83 | if err != nil { 84 | fmt.Println(err) 85 | return 86 | } 87 | res.Body.Close() 88 | } 89 | return 90 | } 91 | func main() { 92 | address := flag.String("a", "192.168.199.1", "admin's address") 93 | password := flag.String("p", "admin", "admin's password") 94 | isSetWan := flag.Bool("wan", false, "set wan info?") 95 | flag.Parse() 96 | if *isSetWan { 97 | lineIn := bufio.NewReader(os.Stdin) 98 | wanUser, _ := lineIn.ReadString('\n') 99 | wanPwd, _ := lineIn.ReadString('\n') 100 | wanUser, _ = url.QueryUnescape(wanUser) 101 | os.Stdin.Close() 102 | SetWanInfo_Hiwifi(*address, *password, wanUser, wanPwd) 103 | } else { 104 | ip := GetLanIP_Hiwifi(*address, *password) 105 | fmt.Println(ip) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /router/openwrt/openwrt_cli.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | // "bufio" 5 | "flag" 6 | "fmt" 7 | "io/ioutil" 8 | "net/http" 9 | "net/http/cookiejar" 10 | "net/url" 11 | // "os" 12 | "regexp" 13 | ) 14 | 15 | func GetLanIP_Openwrt(address, password string) string { 16 | // Login first 17 | jar, _ := cookiejar.New(nil) 18 | client := &http.Client{Jar: jar} 19 | res, err := client.PostForm("http://"+address+"/", url.Values{"luci_username": {"root"}, "luci_password": {password}}) 20 | if err != nil { 21 | fmt.Println(err) 22 | return "" 23 | } 24 | bin, _ := ioutil.ReadAll(res.Body) 25 | res.Body.Close() 26 | str := string(bin) 27 | ex := regexp.MustCompile(`/cgi-bin/luci/;stok=([a-z0-9]{32})`) // /cgi-bin/luci/;stok=dfc41c0ba4035a36922a6df4e26f6dd7/ 28 | li := ex.FindStringSubmatch(str) 29 | if len(li) > 1 { 30 | res, err = client.Get("http://" + address + li[0] + "?status=1") 31 | if err != nil { 32 | fmt.Println(err) 33 | return "" 34 | } 35 | bin, _ = ioutil.ReadAll(res.Body) 36 | res.Body.Close() 37 | str = string(bin) 38 | ex = regexp.MustCompile(`"ipaddr":"(10\.[\.0-9]+?)",`) 39 | li = ex.FindStringSubmatch(str) 40 | if len(li) > 1 { 41 | return li[1] 42 | } 43 | } 44 | return "" 45 | } 46 | func SetWanInfo_Openwrt(address, password, wanUser, wanPwd string) { 47 | /// todo 48 | return 49 | } 50 | func main() { 51 | address := flag.String("a", "192.168.99.1", "admin's address") 52 | password := flag.String("p", "admin", "admin's password") 53 | // isSetWan := flag.Bool("wan", false, "set wan info?") 54 | flag.Parse() 55 | if false { 56 | // lineIn := bufio.NewReader(os.Stdin) 57 | // wanUser, _ := lineIn.ReadString('\n') 58 | // wanPwd, _ := lineIn.ReadString('\n') 59 | // wanUser, _ = url.QueryUnescape(wanUser) 60 | // os.Stdin.Close() 61 | // SetWanInfo_Hiwifi(*address, *password, wanUser, wanPwd) 62 | } else { 63 | ip := GetLanIP_Openwrt(*address, *password) 64 | fmt.Println(ip) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /router/routers.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "net/http/cookiejar" 9 | "net/url" 10 | "regexp" 11 | "strings" 12 | 13 | "encoding/json" 14 | ) 15 | 16 | func GetLanIP_TPLink(address, username, password string) string { 17 | // TODO 18 | return "" 19 | } 20 | func SetWanInfo_TPLink(address, username, password, wanUser, wanPwd string) { 21 | req, err := http.NewRequest("GET", "http://"+address+"/userRpm/PPPoECfgRpm.htm?wan=0&wantype=2&acc="+ 22 | strings.Replace(strings.Replace(url.QueryEscape(url.QueryEscape(wanUser)), "+", "%20", -1), "%40", "@", -1)+ 23 | "&psw="+wanPwd+"&confirm="+wanPwd+ 24 | "&specialDial=0&SecType=0&sta_ip=0.0.0.0&sta_mask=0.0.0.0&linktype=4&waittime2=0&Connect=%C1%AC+%BD%D3", nil) 25 | req.Header.Set("Accept", "*/*") 26 | req.Header.Set("Content-Type", "text/plain; Charset=UTF-8") 27 | req.Header.Set("Connection", "Close") 28 | req.Header.Set("Referer", req.URL.String()) 29 | 30 | req.SetBasicAuth(username, password) 31 | if err != nil { 32 | return 33 | } 34 | res, err := http.DefaultClient.Do(req) 35 | if err != nil { 36 | return 37 | } 38 | res.Body.Close() 39 | return 40 | } 41 | 42 | func GetLanIP_Asus(address, username, password string) string { 43 | client := &http.Client{} 44 | req, err := http.NewRequest("GET", "http://"+address+"/status.asp", nil) 45 | req.SetBasicAuth(username, password) 46 | if err != nil { 47 | fmt.Println(err) 48 | return "" 49 | } 50 | res, err := client.Do(req) 51 | if err != nil { 52 | fmt.Println(err) 53 | return "" 54 | } 55 | bin, _ := ioutil.ReadAll(res.Body) 56 | res.Body.Close() 57 | str := string(bin) 58 | ex := regexp.MustCompile(`wanlink_ipaddr\(\) \{ return '(.+?)';\}`) 59 | li := ex.FindStringSubmatch(str) 60 | if len(li) > 1 { 61 | return li[1] 62 | } 63 | return "" 64 | } 65 | 66 | func GetLanIP_Hiwifi(address, password string) string { 67 | jar, _ := cookiejar.New(nil) 68 | client := &http.Client{Jar: jar} 69 | res, err := client.PostForm("http://"+address+"/cgi-bin/turbo/admin_web", url.Values{"username": {"admin"}, "password": {password}}) 70 | if err != nil { 71 | fmt.Println(err) 72 | return "" 73 | } 74 | bin, _ := ioutil.ReadAll(res.Body) 75 | res.Body.Close() 76 | str := string(bin) 77 | ex := regexp.MustCompile(`URL_ROOT_PATH = "(.+?)";`) // /cgi-bin/turbo/;stok=8ab11a0e6a60d45e3658a4f81b0f2884 78 | li := ex.FindStringSubmatch(str) 79 | if len(li) > 1 { 80 | res, err = client.Get("http://" + address + "" + li[1] + "/api/network/get_wan_info") 81 | if err != nil { 82 | fmt.Println(err) 83 | return "" 84 | } 85 | bin, _ = ioutil.ReadAll(res.Body) 86 | res.Body.Close() 87 | str = string(bin) 88 | ex = regexp.MustCompile(`"ip": "(10\..+?)" }`) 89 | li = ex.FindStringSubmatch(str) 90 | if len(li) > 1 { 91 | return li[1] 92 | } 93 | } 94 | return "" 95 | } 96 | 97 | func GetLanIP_HiwifiV2(address, password string) string { 98 | jar, _ := cookiejar.New(nil) 99 | client := &http.Client{Jar: jar} 100 | res, err := client.Get("http://" + address + "/cgi-bin/turbo/admin_web/login_admin?" + url.Values{"username": {"admin"}, "password": {password}}.Encode()) 101 | if err != nil { 102 | fmt.Println(err) 103 | return "" 104 | } 105 | bin, _ := ioutil.ReadAll(res.Body) 106 | res.Body.Close() 107 | str := string(bin) 108 | ex := regexp.MustCompile(`"stok": "(.+?)",`) // /cgi-bin/turbo/;stok=8ab11a0e6a60d45e3658a4f81b0f2884 109 | li := ex.FindStringSubmatch(str) 110 | if len(li) > 1 { 111 | postBody := bytes.NewBufferString(`{"method":"network.wan.get_simple_info","data":{}}`) 112 | res, err := client.Post("http://"+address+"/cgi-bin/turbo"+li[1]+"/proxy/call", "application/x-www-form-urlencoded", postBody) 113 | if err != nil { 114 | fmt.Println(err) 115 | return "" 116 | } 117 | bin, _ = ioutil.ReadAll(res.Body) 118 | res.Body.Close() 119 | str = string(bin) 120 | ex = regexp.MustCompile(`"wan_ip":"(10\..+?)"`) 121 | li = ex.FindStringSubmatch(str) 122 | if len(li) > 1 { 123 | return li[1] 124 | } 125 | } 126 | return "" 127 | } 128 | 129 | func GetLanIP_HiwifiV3(address, password string) string { 130 | jar, _ := cookiejar.New(nil) 131 | client := &http.Client{Jar: jar} 132 | res, err := client.Get("http://" + address + "/cgi-bin/turbo/api/login/login_admin?" + url.Values{"username": {"admin"}, "password": {password}}.Encode()) 133 | if err != nil { 134 | fmt.Println(err) 135 | return "" 136 | } 137 | bin, _ := ioutil.ReadAll(res.Body) 138 | res.Body.Close() 139 | str := string(bin) 140 | ex := regexp.MustCompile(`"/;stok=(.+?)",`) // /cgi-bin/turbo/;stok=8ab11a0e6a60d45e3658a4f81b0f2884 141 | li := ex.FindStringSubmatch(str) 142 | if len(li) > 1 { 143 | postBody := bytes.NewBufferString(`{"method":"wan.get_status","data":{},"lang":"zh-CN","version":"v1"}`) 144 | res, err := client.Post("http://"+address+"/cgi-bin/turbo/;stok="+li[1]+"/proxy/call", "application/json", postBody) 145 | if err != nil { 146 | fmt.Println(err) 147 | return "" 148 | } 149 | bin, _ = ioutil.ReadAll(res.Body) 150 | res.Body.Close() 151 | str = string(bin) 152 | ex = regexp.MustCompile(`"wan_ip":"(10\..+?)"`) 153 | li = ex.FindStringSubmatch(str) 154 | if len(li) > 1 { 155 | return li[1] 156 | } 157 | } 158 | return "" 159 | } 160 | 161 | func SetWanInfo_HiwifiV3(address, password, wanUser, wanPwd string) (err error) { 162 | jar, _ := cookiejar.New(nil) 163 | client := &http.Client{Jar: jar} 164 | res, err := client.Get("http://" + address + "/cgi-bin/turbo/api/login/login_admin?" + url.Values{"username": {"admin"}, "password": {password}}.Encode()) 165 | if err != nil { 166 | fmt.Println(err) 167 | return 168 | } 169 | bin, _ := ioutil.ReadAll(res.Body) 170 | res.Body.Close() 171 | str := string(bin) 172 | ex := regexp.MustCompile(`"/;stok=(.+?)",`) // /cgi-bin/turbo/;stok=8ab11a0e6a60d45e3658a4f81b0f2884 173 | li := ex.FindStringSubmatch(str) 174 | if len(li) > 1 { 175 | bin, _ = json.Marshal(map[string]interface{}{ 176 | "method": "wan.set_pppoe_way", 177 | "data": map[string]string{ 178 | "type": "pppoe", 179 | "peerdns": "0", 180 | "pppoe_name": wanUser, 181 | "pppoe_passwd": wanPwd, 182 | "switch_status_wan": "auto", 183 | "special_dial": "0", 184 | "override_dns": "119.29.29.29", 185 | "override_dns2": "180.76.76.76", 186 | "mac_clone": "0", 187 | }, 188 | "lang": "zh-CN", 189 | "version": "v1", 190 | }) 191 | fmt.Println(wanUser, string(bin)) 192 | postBody := bytes.NewBuffer(bin) 193 | res, err = client.Post("http://"+address+"/cgi-bin/turbo/;stok="+li[1]+"/proxy/call", "application/json", postBody) 194 | if err != nil { 195 | fmt.Println(err) 196 | return 197 | } 198 | bin, _ = ioutil.ReadAll(res.Body) 199 | res.Body.Close() 200 | str = string(bin) 201 | ex = regexp.MustCompile(`成功`) 202 | li = ex.FindStringSubmatch(str) 203 | if len(li) > 1 { 204 | return nil 205 | } 206 | } 207 | return 208 | } 209 | 210 | func GetLanIP_Openwrt(address, password string) string { 211 | // Login first 212 | jar, _ := cookiejar.New(nil) 213 | client := &http.Client{Jar: jar} 214 | res, err := client.PostForm("http://"+address+"/", url.Values{"luci_username": {"root"}, "luci_password": {password}}) 215 | if err != nil { 216 | fmt.Println(err) 217 | return "" 218 | } 219 | bin, _ := ioutil.ReadAll(res.Body) 220 | res.Body.Close() 221 | str := string(bin) 222 | ex := regexp.MustCompile(`/cgi-bin/luci/;stok=([a-z0-9]{32})`) // /cgi-bin/luci/;stok=dfc41c0ba4035a36922a6df4e26f6dd7/ 223 | li := ex.FindStringSubmatch(str) 224 | if len(li) == 0 { 225 | // Login ... 226 | jar, _ = cookiejar.New(nil) 227 | client = &http.Client{Jar: jar} 228 | res, err = client.PostForm("http://"+address+"/", url.Values{"username": {"root"}, "password": {password}}) 229 | if err != nil { 230 | fmt.Println(err) 231 | return "" 232 | } 233 | bin, _ = ioutil.ReadAll(res.Body) 234 | res.Body.Close() 235 | str = string(bin) 236 | ex = regexp.MustCompile(`/cgi-bin/luci/;stok=([a-z0-9]{32})`) // /cgi-bin/luci/;stok=dfc41c0ba4035a36922a6df4e26f6dd7/ 237 | li = ex.FindStringSubmatch(str) 238 | } 239 | if len(li) > 1 { 240 | res, err = client.Get("http://" + address + li[0] + "?status=1") 241 | if err != nil { 242 | fmt.Println(err) 243 | return "" 244 | } 245 | bin, _ = ioutil.ReadAll(res.Body) 246 | res.Body.Close() 247 | str = string(bin) 248 | ex = regexp.MustCompile(`"ipaddr":\s*"(10\.[\.0-9]+?)",`) 249 | li = ex.FindStringSubmatch(str) 250 | if len(li) > 1 { 251 | return li[1] 252 | } 253 | } 254 | return "" 255 | } 256 | -------------------------------------------------------------------------------- /router/tplink/tplink_cli.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "net/http" 8 | "net/url" 9 | "os" 10 | "strings" 11 | ) 12 | 13 | func GetLanIP_TPLink(address, username, password string) string { 14 | // TODO 15 | return "" 16 | } 17 | func SetWanInfo_TPLink(address, username, password, wanUser, wanPwd string) { 18 | req, err := http.NewRequest("GET", "http://"+address+"/userRpm/PPPoECfgRpm.htm?wan=0&wantype=2&acc="+ 19 | strings.Replace(strings.Replace(url.QueryEscape(wanUser), "+", "%20", -1), "%40", "@", -1)+ 20 | "&psw="+wanPwd+"&confirm="+wanPwd+ 21 | "&specialDial=0&SecType=0&sta_ip=0.0.0.0&sta_mask=0.0.0.0&linktype=4&waittime2=0&Connect=%C1%AC+%BD%D3", nil) 22 | req.Header.Set("Accept", "*/*") 23 | req.Header.Set("Content-Type", "text/plain; Charset=UTF-8") 24 | req.Header.Set("Connection", "Close") 25 | req.Header.Set("Referer", req.URL.String()) 26 | 27 | req.SetBasicAuth(username, password) 28 | if err != nil { 29 | return 30 | } 31 | res, err := http.DefaultClient.Do(req) 32 | if err != nil { 33 | return 34 | } 35 | res.Body.Close() 36 | return 37 | } 38 | func main() { 39 | address := flag.String("a", "192.168.1.1", "admin's address") 40 | username := flag.String("u", "admin", "admin's username") 41 | password := flag.String("p", "admin", "admin's password") 42 | isSetWan := flag.Bool("wan", false, "set wan info?") 43 | flag.Parse() 44 | if *isSetWan { 45 | lineIn := bufio.NewReader(os.Stdin) 46 | wanUser, _ := lineIn.ReadString('\n') 47 | wanPwd, _ := lineIn.ReadString('\n') 48 | os.Stdin.Close() 49 | SetWanInfo_TPLink(*address, *username, *password, wanUser, wanPwd) 50 | } else { 51 | ip := GetLanIP_TPLink(*address, *username, *password) 52 | fmt.Println(ip) 53 | } 54 | } 55 | --------------------------------------------------------------------------------