我正在尝试在Ubuntu GNU / Linux机器上创建软件模拟,它将像PPPoE一样工作。我希望这个模拟器取出传出的数据包,剥离以太网头,插入PPP标志(7E,FF,03,00和21)并将IP层信息放在PPP数据包中。我遇到了数据之后的FCS问题。据我所知,我使用的单元调制解调器使用CRC16-CCITT方法具有2字节FCS。我发现了几个可以计算这个校验和的软件,但它们都不会产生串行线路上的内容(我有一个串口线“嗅探器”,它显示了调制解调器发送的所有内容)。
我一直在研究pppd和linux内核本身的来源,我可以看到它们都有一种向数据添加FCS的方法。这似乎很难实现,因为我没有内核黑客的经验。有人能想出一种简单的方法(最好是用Python)来计算与内核生成的FCS相匹配的FCS吗?
感谢。
P.S。如果有人想要,我可以添加我收到的数据输出样本到串口调制解调器。
答案 0 :(得分:0)
我最近在测试代码以杀死ppp连接时做了类似的事情。 这对我有用:
# RFC 1662 Appendix C
def mkfcstab():
P = 0x8408
def valiter():
for b in range(256):
v = b
i = 8
while i:
v = (v >> 1) ^ P if v & 1 else v >> 1
i -= 1
yield v & 0xFFFF
return tuple(valiter())
fcstab = mkfcstab()
PPPINITFCS16 = 0xffff # Initial FCS value
PPPGOODFCS16 = 0xf0b8 # Good final FCS value
def pppfcs16(fcs, bytelist):
for b in bytelist:
fcs = (fcs >> 8) ^ fcstab[(fcs ^ b) & 0xff]
return fcs
获取值:
fcs = pppfcs16(PPPINITFCS16, (ord(c) for c in frame)) ^ 0xFFFF
并交换字节(我使用chr((fcs& 0xFF00)>> 8),chr(fcs& 0x00FF))
答案 1 :(得分:0)
// http://www.sunshine2k.de/coding/javascript/crc/crc_js.html - Correctly calculates
// the 16-bit FCS (crc) on our frames (Choose CRC16_CCITT_FALSE)
int crc;
void crcReset()
{
crc=0xffff; // crc restart
}
void crcDo(int x) // cumulative crc
{
for (int i=0; i<8; i++) {
crc=((crc&1)^(x&1))?(crc>>1)^0x8408:crc>>1; // crc calculator
x>>=1;
}
}
int crcBuf(char * buf, int size) // crc on an entire block of memory
{
crcReset();
for(int i=0; i<size; i++)crcDo(*buf++);
return crc;
}
答案 2 :(得分:0)
使用了简单的python库crcmod。
import crcmod #pip3 install crcmod
fcsData = "A0 19 03 61 DC"
fcsData=''.join(fcsData.split(' '))
print(fcsData)
crc16 = crcmod.mkCrcFun(0x11021, rev=True,initCrc=0x0000, xorOut=0xFFFF)
print(hex(crc16(bytes.fromhex(fcsData))))
fcs=hex(crc16(bytes.fromhex(fcsData)))