verificación FCS de la trama de Ethernet

1

estoy tratando de transmitir una trama de Ethernet desde fpga a pc. mi marco udp es:

constant udp_frameB :frame60:=
(x"FF",x"FF",x"FF",x"FF", -- mac dest
x"FF",x"FF",x"00",x"00",
x"00",x"04",x"14",x"13", -- mac src
x"08",x"00",x"45",x"00", -- IP header
x"00",x"2E",x"00",x"00",
x"00",x"00",x"40",x"11",
x"7A",x"C0",x"00",x"00", -- IP src
x"00",x"00",x"FF",x"FF", -- IP dest
x"FF",x"FF",x"00",x"00", -- port src
x"50",x"DA",x"00",x"12",-- port dest + len
x"00",x"00",x"42",x"42", -- checksum udp + data "B"
x"42",x"42",x"42",x"42",
x"42",x"42",x"42",x"42",
x"42",x"42",x"42",x"42",
x"42",x"42",x"42",x"42");

para el cuadro anterior, he calculado el FCS usando el crc-32.

polinomio-X "04C11DB7".

FCS es-X "D96F0BBF"

He adoptado el siguiente método para calcular FCS:

IEEE 802.3 define el polinomio M (x) como la dirección de destino, dirección de origen, longitud / tipo y datos de una trama, con los primeros 32 bits complementado El resultado de CRC se complementa, y el resultado es el IEEE 802.3 CRC de 32 bits, conocida como la secuencia de verificación de trama (FCS) campo. El FCS se adjunta al final del marco de Ethernet, y es primero se transmite el bit de orden más alto (x31, x30,…, x1, x0).

dígame, ¿FCS es correcto o no?

y también dime que si el FCS no es correcto, wirehark ¿Capturarlo o no?

la lógica CRC que he usado para calcular-

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity ethcrc32 is
port (clk: in STD_LOGIC;                    -- Input clock
     rst: in STD_LOGIC;                 -- Asynchronous reset
     en : in STD_LOGIC;             -- Assert to compute calculations
     is_msb: in STD_LOGIC;              -- Assert to indicate the sens of data_in
       data_in: in STD_LOGIC_VECTOR(7 downto 0);        -- Data to compute
     crc_out: out STD_LOGIC_VECTOR (31 downto 0)    -- CRC output
);

end ethcrc32;

arquitectura nano de ethcrc32 es

-- The Generator polynomial is
--  32   26   23   22   16   12   11   10   8   7   5   4   2   
-- x  + x  + x  + x  + x  + x  + x  + x  + x + x + x + x + x + x + 1
constant GENERATOR : STD_LOGIC_VECTOR := X"04C11DB7";
begin
process (clk,rst) is
    variable crc_buf : STD_LOGIC_VECTOR (31 downto 0):=x"00000000";
begin
    if rst = '1' then   -- reset signals to values
        crc_buf := (others => '0');
    elsif rising_edge(clk) then  -- operate on positive edge
        if (en='1') then
            if is_msb='1' then
                    for I in data_in'reverse_range loop
                        crc_buf := (crc_buf(30 downto 0) & data_in(I)) XOR (GENERATOR AND (0 to 31=>crc_buf(31)));
                    end loop;
            else
                    for I in data_in'reverse_range loop
                        crc_buf := (crc_buf(30 downto 0) & data_in(I)) XOR (GENERATOR AND (0 to 31=>crc_buf(31)));
                    end loop;
            end if;
        end if;
    end if;
    crc_out<=crc_buf;
end process;

fin nano;

    
pregunta sidharth kashyap

2 respuestas

2

Aquí se muestra una implementación de ejemplo de un CRC de Ethernet en VHDL, adecuado para un banco de pruebas:

TYPE arr_byte IS ARRAY(natural RANGE <>) OF unsigned(7 DOWNTO 0);
CONSTANT CRC_POLY : unsigned(31 DOWNTO 0) := x"04C11DB7";

FUNCTION crc (data : arr_byte) RETURN arr_byte IS
  VARIABLE r  : arr_byte(0 TO 3) := (x"00",x"00",x"00",x"00");
  VARIABLE c  : unsigned(31 DOWNTO 0) :=x"FFFFFFFF";
  VARIABLE mm : unsigned(31 DOWNTO 0);
BEGIN
  FOR I IN data'range LOOP
    FOR J IN 0 TO 7 LOOP
      mm:=(OTHERS => data(I)(J) XOR c(31));
      c:=(c(30 DOWNTO 0) & '0') XOR (mm AND CRC_POLY);
    END LOOP;
  END LOOP;
  FOR I IN 0 TO 31 LOOP
    mm(I):=NOT c(31-I);
  END LOOP;

  r(3):=mm(31 DOWNTO 24);
  r(2):=mm(23 DOWNTO 16);
  r(1):=mm(15 DOWNTO  8);
  r(0):=mm( 7 DOWNTO  0);
  RETURN r;
END FUNCTION crc;

El CRC para su marco es (como está escrito en la respuesta anterior): 9B F6 D0 FD.

Si tiene una interfaz MII (4 bits de ancho), el final del marco debería aparecer como:

2 4 2 4 2 4 2 4 2 4 2 4 | B 9 6 F 0 D D F ]
     end of the payload | CRC

El CRC se inicia con FFFFFFFF para detectar correctamente los ceros iniciales en el marco. Se invierte y se complementa al final para generar un resto constante a la división polinomial de Galois: si aplica el algoritmo CRC a todo el marco, incluido el FCS de 4 bytes, siempre debe obtener la constante 'mágica' 0xC704DD7B, para todos los casos válidos marcos.

    
respondido por el TEMLIB
0

Wireshark lo capturará a menos que su NIC lo deje caer debido al CRC incorrecto. Además, creo que el FCS de ese paquete debería ser fdd0f69b. No olvide que hay algunas reordenaciones de bits impares que tiene que hacer para que el CRC funcione correctamente.

Tenga en cuenta que también hay implementaciones de código abierto que puede usar como referencia, por ejemplo enlace .

    
respondido por el alex.forencich

Lea otras preguntas en las etiquetas