Skip to content

Commit b7fd5a7

Browse files
committed
bump v0.3
1 parent f4c3e91 commit b7fd5a7

File tree

2 files changed

+265
-1
lines changed

2 files changed

+265
-1
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
client-micropy
22
==============
33

4-
micropython dev 0.2
4+
micropython dev 0.3
55

66

77
仍在更新,请勿使用,但可以测试,有问题请发issue:)
8+
9+
PS:OpenWRT的micropython有问题,估计是uclibc的锅。

latest-pppoe.py

+262
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
#!/usr/bin/micropython
2+
# -*- coding: utf-8 -*-
3+
import sys
4+
from libs import struct, time, os, random, binascii
5+
import usocket as socket
6+
7+
# CONFIG
8+
server = '1.1.1.1'
9+
pppoe_flag = '\x18'
10+
keep_alive2_flag = '\xd7'
11+
# CONFIG_END
12+
13+
host_ip = server
14+
IS_TEST = True
15+
CONF = "/etc/drcom.conf"
16+
DEBUG = False #log saves to file
17+
if IS_TEST:
18+
CONF = ''
19+
DEBUG = False
20+
LOG_PATH = 'drcom_client.log'
21+
22+
def log(*args, **kwargs):
23+
s = ' '.join(args)
24+
if 'pkt' in kwargs and DEBUG == True:
25+
s += '\n\tpacket:' + kwargs['pkt'].encode('hex')
26+
print (s)
27+
if DEBUG:
28+
with open(LOG_PATH,'ab') as f:
29+
try:
30+
f.write(s)
31+
f.write('\n')
32+
except:
33+
f.write('FUCK WINDOWS' + '\n')
34+
35+
def dump(n):
36+
s = '%x' % n
37+
if len(s) & 1:
38+
s = '0' + s
39+
return s.decode('hex')
40+
41+
class Socket:
42+
def __init__(self, server, port=61440):
43+
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
44+
self.ai = socket.getaddrinfo(server, port)
45+
self.addr = self.ai[0][4]
46+
self.s.connect(self.addr)
47+
log("open local port:" + str(port))
48+
log("DEBUG MODE:"+ str(DEBUG))
49+
self.server = server
50+
self.port = port
51+
# self.s.settimeout(3)
52+
53+
def send(self, data):
54+
self.s.send(data)
55+
56+
def recv(self):
57+
while True:
58+
data = self.s.recv(1024)
59+
if data[:1] == '\x4d':
60+
log('received message packet, dropped.')
61+
continue
62+
return data, address
63+
64+
def get_socket(self):
65+
return self.s
66+
67+
class PPPOEHeartbeat:
68+
def __init__(self, num=1):
69+
self.count = num # 计数器
70+
def _make_challenge(self):
71+
data = '\x07'
72+
data += chr(self.count)
73+
data += '\x08\x00\x01\x00'
74+
data += '\x00\x00'
75+
return data
76+
77+
def _DrcomCRC32(self, data, init = 0):
78+
ret = init
79+
for i in range(len(data))[::4]:
80+
ret ^= struct.unpack('I', data[i:i+4])[0]
81+
ret &= 0xFFFFFFFF
82+
return ret
83+
84+
def _make_heartbeat(self, sip, challenge_seed, first=False):
85+
# DrcomDialExtProtoHeader - 5 bytes
86+
data = '\x07' # code
87+
data += chr(self.count) # id
88+
data += '\x60\x00' # length
89+
data += '\x03' # type
90+
data += '\x00' # uid length
91+
data += '\x00\x00\x00\x00\x00\x00' # mac
92+
data += sip # AuthHostIP
93+
if first:
94+
data += '\x00\x62\x00' + pppoe_flag # 非第一次则是 data += '\x00\x62\x00\x14'
95+
else:
96+
data += '\x00\x63\x00' + pppoe_flag
97+
data += challenge_seed # Challenge Seed
98+
data += struct.pack('I',20000711) # DRCOM_DIAL_EXT_PROTO_CRC_INIT
99+
data += struct.pack('I',126)
100+
crc = (self._DrcomCRC32(data) * 19680126) & 0xFFFFFFFF
101+
data = data[:-8] + struct.pack("I", crc) + '\x00\x00\x00\x00'
102+
# data += '\x7e\x00\x00\x00'
103+
# data += '\x00\x00\x00\x7e'
104+
# - DrcomDialExtProtoHeader end -
105+
data += '\x00'*16 # ip1
106+
data += '\x00'*16 # ip2
107+
data += '\x00'*16 # ip3
108+
data += '\x00'*16 # ip4
109+
return data
110+
111+
def send(self, s):
112+
while True:
113+
#1. challenge
114+
data = self._make_challenge()
115+
log('pppoe: send challenge request', pkt=data)
116+
s.send(data)
117+
data, address = s.recv()
118+
log('pppoe: received challenge response', pkt=data)
119+
120+
self.count += 1
121+
self.count %= 0xFF
122+
123+
#2. heartbeat
124+
seed = data[8:12]
125+
sip = data[12:16]
126+
if self.count != 2 and self.count != 1:
127+
data = self._make_heartbeat(sip=sip, challenge_seed=seed)
128+
else:
129+
data = self._make_heartbeat(sip=sip, challenge_seed=seed, first=True)
130+
log('pppoe: send heartbeat request', pkt=data)
131+
s.send(data)
132+
try:
133+
data, address = s.recv()
134+
log('pppoe: received heartbeat response', pkt=data)
135+
break
136+
except:
137+
log('pppoe: heartbeat response failed, retry')
138+
log('pppoe: reset idx to 0x01')
139+
self.count = 1
140+
continue
141+
142+
self.count += 1
143+
self.count %= 0xFF
144+
145+
146+
def keep_alive_package_builder(number,random,tail,type=1,first=False):
147+
data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type)
148+
if first :
149+
data += '\x0f\x27'
150+
else:
151+
data += keep_alive2_flag + '\x02'
152+
data += '\x2f\x12' + '\x00' * 6
153+
data += tail
154+
data += '\x00' * 4
155+
#data += struct.pack("!H",0xdc02)
156+
if type == 3:
157+
foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip
158+
#CRC
159+
# edited on 2014/5/12, filled zeros to checksum
160+
# crc = packet_CRC(data+foo)
161+
crc = '\x00' * 4
162+
#data += struct.pack("!I",crc) + foo + '\x00' * 8
163+
data += crc + foo + '\x00' * 8
164+
else: #packet type = 1
165+
data += '\x00' * 16
166+
return data
167+
168+
def keep_alive2(s, pppoe):
169+
tail = ''
170+
packet = ''
171+
svr = server
172+
173+
ran = random.randint(0,0xFFFF)
174+
ran += random.randint(1,10)
175+
# 2014/10/15 add by latyas, maybe svr sends back a file packet
176+
svr_num = 0
177+
packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True)
178+
while True:
179+
log('[keep-alive2] send1', pkt=packet)
180+
s.send(packet)
181+
data = s.recv(1024)
182+
if data[:1] == '\x07' and data[2] == '\x28':
183+
break
184+
elif data[:1] == '\x07' and data[2] == '\x10':
185+
log('[keep-alive2] recv file, resending..')
186+
svr_num = svr_num + 1
187+
packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,svr_num,False)
188+
else:
189+
log('[keep-alive2] recv1/unexpected', pkt=data)
190+
log('[keep-alive2] recv1', pkt=data)
191+
192+
ran += random.randint(1,10)
193+
packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False)
194+
log('[keep-alive2] send2', pkt=packet)
195+
s.send(packet)
196+
while True:
197+
data = s.recv(1024)
198+
if data[:1] == '\x07':
199+
svr_num = svr_num + 1
200+
break
201+
else:
202+
log('[keep-alive2] recv2/unexpected', pkt=data)
203+
log('[keep-alive2] recv2', pkt=data)
204+
tail = data[16:20]
205+
206+
207+
ran += random.randint(1,10)
208+
packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False)
209+
log('[keep-alive2] send3', pkt=packet)
210+
s.send(packet)
211+
while True:
212+
data = s.recv(1024)
213+
if data[:1] == '\x07':
214+
svr_num = svr_num + 1
215+
break
216+
else:
217+
log('[keep-alive2] recv3/unexpected', pkt=data)
218+
log('[keep-alive2] recv3', pkt=data)
219+
tail = data[16:20]
220+
log("[keep-alive2] keep-alive2 loop was in daemon.")
221+
222+
i = svr_num
223+
while True:
224+
try:
225+
ran += random.randint(1,10)
226+
packet = keep_alive_package_builder(i,dump(ran),tail,1,False)
227+
log('[keep_alive2] send',str(i), pkt=packet)
228+
s.send(packet)
229+
data = s.recv(1024)
230+
log('[keep_alive2] recv', pkt=data)
231+
tail = data[16:20]
232+
ran += random.randint(1,10)
233+
packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False)
234+
s.send(packet)
235+
log('[keep_alive2] send',str(i+1), pkt=packet)
236+
data = s.recv(1024)
237+
log('[keep_alive2] recv', pkt=data)
238+
tail = data[16:20]
239+
i = (i+2) % 0xFF
240+
time.sleep(10)
241+
#send pppoe heartbeat once
242+
pppoe.send(s)
243+
except:
244+
pass
245+
246+
def daemon():
247+
with open('/var/run/jludrcom.pid','w') as f:
248+
f.write(str(os.getpid()))
249+
250+
def main():
251+
if not IS_TEST:
252+
daemon()
253+
execfile(CONF, globals())
254+
log('auth svr:' + server + '\npppoe_flag:' + pppoe_flag + '\nkeep_alive2_flag:' + keep_alive2_flag)
255+
while True:
256+
s = Socket(server)
257+
pppoe = PPPOEHeartbeat(1)
258+
pppoe.send(s)
259+
keep_alive2(s, pppoe)
260+
261+
if __name__ == '__main__':
262+
main()

0 commit comments

Comments
 (0)