2010-11-29 2 views
0

Я пытаюсь создать имитацию программного обеспечения на машине Ubuntu GNU/Linux, которая будет работать как PPPoE. Я хотел бы, чтобы этот симулятор принимал исходящие пакеты, отключал заголовок ethernet, вставлял флаги PPP (7E, FF, 03, 00 и 21) и размещал информацию об уровне IP в пакете PPP. У меня возникают проблемы с FCS, который идет после данных. Из того, что я могу сказать, модем ячейки, который я использую, имеет 2 байта FCS, используя метод CRC16-CCITT. Я нашел несколько программ, которые будут вычислять эту контрольную сумму, но ни один из них не производит то, что выходит из последовательной линии (у меня есть последовательный порт «сниффер», который показывает мне все, что отправляется модем).Как создать FCS для PPP-пакетов?

Я изучал источник pppd и самого ядра linux, и я вижу, что оба они имеют способ добавления FCS к данным. Это довольно сложно реализовать, поскольку у меня нет опыта в хакерстве ядра. Может ли кто-нибудь придумать простой способ (желательно на Python) вычисления FCS, который соответствует той, которую производит ядро?

Спасибо.

P.S. Если кто-то захочет, я могу добавить образец вывода данных, который я получаю к серийному модему.

ответ

0

Недавно я сделал что-то вроде этого в то время как код проверки, чтобы убить РРР-соединение .. Это работает для меня:

# 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))

0

получил от этого mbed.org PPP-Blinky:

// 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; 
}