2012-12-03 7 views
2

친애하는 동료 StackOverflowers,마이크로 칩의 TCP/IP 스택 PIC18F 잘못된 패킷 SEQ/ACK 번호

임은 마이크로 칩의 TCP/IP 스택을 사용하여 내 사용자 정의 (및 테스트) 보드에 PIC18F87J60에 뭔가를 구현하는 프로젝트를 진행

. 테스트로서 연결을 설정하고 x 초 동안 유지 한 다음 정상적으로 종료하는 코드를 작성했습니다. 필자는이를 유한 상태 기계로 구현했습니다. 나는 아직 데이터를 보내고받는 것을 추가하지 않았다.

그러나 내 프로그램이 연결을 설정하지 못했습니다. Wireshark 사용 내 장치가 DHCP를 통해 IP 주소를 성공적으로 수신하고 ARP 확인이 제대로 수행되었음을 확인했습니다. 나는 이것이 잘못되었으므로 지금 DNS를 생략했지만 나중에 이것을 풀 것이다. 또한 첫 번째 SYN 패킷이 내 장치에서 전송되고 서버에서 응답하지만 3 방향 핸드 셰이크의 3 단계가 잘못되었음을 확인했습니다. 확인 번호는 임의 번호이므로 서버가 혼란스러워지고 RST 패킷으로 연결을 재설정합니다. 그런 다음 장치가 다른 임의의 시퀀스 번호를 사용하여 ACK 패킷을 사용하여 재설정을 확인하면 서버가 어떻게 든이 패킷을 받아들입니다. 그런 다음 서버가 SYN 패킷으로 연결을 다시 설정하려고 시도하지만 내 코드가 들어오는 연결을 수신하지 않으므로 연결이 끝납니다.

다음
#define THIS_IS_STACK_APPLICATION 
#include "TCPIP.h" 

APP_CONFIG AppConfig; 

ROM char serverAddress[] = "data.zienu.eu"; //unused in this codefile: DNS doesn't work yet 
ROM char serverIP[] = "80.69.92.56"; 
short authenticationPort = 5588; 

typedef enum _SOCKET_STATE { 
    SOCKET_DONE = 0, 
    SETUP_CONNECTION, 
    CONNECTING, 
    CONNECTED, 
    AWAITING_ANSWER, 
    SENDING_DATA, 
    CLOSE_CONNECTION, 
    DISCONNECTING, 
    DISCONNECTED 
} SOCKET_STATE; 

typedef struct _CONNECTION { 
    TCP_SOCKET socketID; 
    SOCKET_INFO* remoteInfo; 
    const char* remoteHostName; 
    WORD remotePort; 
    SOCKET_STATE state, previousState; 
    DWORD timeOut; 
    BYTE purpose; 
} CONNECTION; 

void InitHardware(); 
void AuthenticateTask(); 
void FTPDownloadTask(); 
void HandleTCPConnection(CONNECTION* connection); 

ROM BYTE SerializedMACAddress[6] = {MY_DEFAULT_MAC_BYTE1, MY_DEFAULT_MAC_BYTE2, MY_DEFAULT_MAC_BYTE3, MY_DEFAULT_MAC_BYTE4, MY_DEFAULT_MAC_BYTE5, MY_DEFAULT_MAC_BYTE6}; 
void InitAppConfig(void) { 
    AppConfig.Flags.bIsDHCPEnabled = TRUE; 
    AppConfig.Flags.bInConfigMode = TRUE; 
    memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr)); 
    AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul; 
    AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val; 
    AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul; 
    AppConfig.DefaultMask.Val = AppConfig.MyMask.Val; 
    AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul; 
    AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul; 
    AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul; 

    // Load the default NetBIOS Host Name 
    memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 10); 
    FormatNetBIOSName(AppConfig.NetBIOSName); 
} 

void InitHardware() { 
    /** \var isBoot (LATH0_bit) tells the boot-interrupt handler that boot is busy */ 
    LATHbits.LATH0 = 1; 

    ADCON1 |= 0x0f;   // adc pins as I/0 
    CMCON |= 7;   // Disable comperator 

    OSCCON = 0x04; 
    OSCTUNE = 0x40; //41 MHz 

    /******************************************************************/ 
    // init======== 
// Het TRISA en TRISF register moeten goed zijn ingesteld voor de analoge input: 
    PORTA = 0x00; 
    TRISA = 0x20; /* Bit 1 and 2 are used by ethernet LEDS */ 
    PORTB = 0x00; 
    TRISB = 0x00; /* output mode */ 
    PORTC = 0x03; /* LED R en G off */ 
    TRISC = 0xc0; /* Bit 6 and 7 are used by UART 1 */ 
    PORTD = 0x00; /* used to display ethernetsecond_timer in DEBUG mode*/ 
    TRISD = 0x00; /* output mode */ 
    PORTE = 0x00; 
    TRISE = 0x00; /* output mode */ 
    PORTF = 0x00; 
    TRISF = 0x0E; /* output mode */ 
    PORTG = 0x00; 
    TRISG = 0x00; 
    PORTH = 0x00; 
    TRISH = 0x00; 

    /* interrupt priorities are possible with microC */ 
    IPR1bits.ADIP = 0;  //give ADC LOW interrupt priority 
    RCONbits.IPEN = 1;  //Enable interrupt priorities 
    INTCON2bits.RBPU = 1; // Disable internal PORTB pull-ups 

    INTCONbits.GIEH = 1; 
    INTCONbits.GIEL = 1; 
} 

void interrupt low_priority LowISR(void) { 
    TickUpdate(); 
} 

void interrupt HighISR(void) { 
} 

void HandleTCPConnection(CONNECTION* connection) { 
    switch(connection->state) { 
     case SETUP_CONNECTION: 
      if(!AppConfig.Flags.bInConfigMode) { 
       connection->socketID = TCPOpen((DWORD) (PTR_BASE)&serverIP[0], TCP_OPEN_ROM_HOST, connection->remotePort, connection->purpose); 

       connection->timeOut = TickGet() + TICK_SECOND * 15; 
       connection->previousState = SETUP_CONNECTION; 
       connection->state = CONNECTING; 
       TCPWasReset(connection->socketID); 
      } 
      break; 
     case CONNECTING: 
      if(TCPIsConnected(connection->socketID)) { 
       connection->previousState = CONNECTING; 
       connection->state = CONNECTED; 
       connection->remoteInfo = TCPGetRemoteInfo(connection->socketID); 
       connection->timeOut = TickGet() + TICK_SECOND * 10; 
      } 
      else if(TickGet() >= connection->timeOut) { 
       connection->previousState = CONNECTING; 
       connection->state = CLOSE_CONNECTION; 
      } 
      break; 
     case CONNECTED: 
      if(TickGet() >= connection->timeOut) { 
       connection->previousState = CONNECTED; 
       connection->state = CLOSE_CONNECTION; 
      } 
      else if(TCPWasReset(connection->socketID)) { 
       connection->previousState = CONNECTED; 
       connection->state = CLOSE_CONNECTION; 
      } 
      break; 
     case CLOSE_CONNECTION: 
       connection->previousState = CLOSE_CONNECTION; 
       connection->state = DISCONNECTING; 
       TCPDisconnect(connection->socketID);  //Send a TCP FIN packet 
       connection->timeOut = TickGet() + TICK_SECOND * 5; 
      break; 
     case DISCONNECTING: 
      if(TCPIsConnected(connection->socketID)) { 
       connection->previousState = DISCONNECTING; 
       connection->state = DISCONNECTED; 
      } 
      else if(TickGet() >= connection->timeOut) { 
       TCPDisconnect(connection->socketID); 
       TCPDisconnect(connection->socketID); //Time out: Send a RST packet and proceed 
       connection->previousState = DISCONNECTING; 
       connection->state = DISCONNECTED; 
      } 
      break; 
     case DISCONNECTED: 
      connection->previousState = DISCONNECTED; 
      connection->state = SOCKET_DONE; 
      break; 
     case SOCKET_DONE: 
      break; 
     default: 
      break; 
    } 
} 

void main() { 
    InitHardware(); 
    TickInit(); 
    InitAppConfig(); 
    StackInit(); 

    CONNECTION connection; 
    connection.purpose = TCP_PURPOSE_CUSTOM_FTP_CMD; 
    connection.remoteHostName = serverIP; 
    connection.remotePort = authenticationPort; 
    connection.previousState = SOCKET_DONE; 
    connection.state = SETUP_CONNECTION; 
    while(TRUE) { 
     HandleTCPConnection(&connection); 
     StackTask(); 
     StackApplications(); 
    } 
} 

Wireshark logs의 스크린 샷입니다 :

여기 내 코드입니다. 사전에

감사합니다, BitJunky

편집 : 다음은 wireshark dumpfile입니다. MAC 주소로 필터링 했으므로 DHCP 처리의 일부가이 덤프에 표시되지 않습니다.

+0

전체 SEQ/ACK nunmbers로 추적을 게시 할 수 있습니까? 어쩌면 tcpdump처럼? – cxxl

+0

@cxxl 원래 게시물에서 내 편집을 봅니다. – Jupiter

답변

1

나는이 문제를 해결했다. 나는 TCPIP 스택이 하이테크 컴파일러와 호환되었다고 생각했지만, 그렇지는 않은 것 같다. C18 및 XC8 컴파일러는 내가 게시 한 코드와 완벽하게 작동합니다.

Greetz BitJunky