Hi Friends
I want to make a client using tm4c129xnczad development board. for this i modified enet_uip as follows.
i used Hercules as a server and Wireshark to analize Ethernet Packets. But when i ran this program and analize it on Wireshark, i found that client sent ARP Request, then hercules send ARP reply. After that client send Connect Request, but hercules does neither send ACK or NACK.
here i am not able to figure out the problem. Any help would be appreciated.
void SendARPRequest() {
ipaddr[0] = 0x7F0A;
ipaddr[1] = 0x3301;
uip_ethaddr.addr[0] = 0x00;
uip_ethaddr.addr[1] = 0x1a;
uip_ethaddr.addr[2] = 0xb6;
uip_ethaddr.addr[3] = 0x02;
uip_ethaddr.addr[4] = 0x93;
uip_ethaddr.addr[5] = 0x56;
memset(BUF->ethhdr.dest.addr, 0xff, 6);
memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
uip_ipaddr_copy(BUF->dipaddr, ipaddr);
uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
BUF->protocol = HTONS(UIP_ETHTYPE_IP);
BUF->hwlen = 6;
BUF->protolen = 4;
BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
uip_len = sizeof(struct arp_hdr);
}
void SendIPPacket() {
//Destination MAC Address, 6 Byte//
uip_buf[0] = 0x10;
uip_buf[1] = 0x78;
uip_buf[2] = 0xD2;
uip_buf[3] = 0x46;
uip_buf[4] = 0x65;
uip_buf[5] = 0xC6;
//Source MAC Address, 6 Byte//
uip_buf[6] = 0x00;
uip_buf[7] = 0x1a;
uip_buf[8] = 0xB6;
uip_buf[9] = 0x02;
uip_buf[10] = 0x93;
uip_buf[11] = 0x56;
//Type, 2 Byte //
uip_buf[12] = 0x08;
uip_buf[13] = 0x00;
//Version(4 Bit) + Header Length(4 Bit)//
uip_buf[14] = 0x45;
//Differentiated Services, 1 Byte//
uip_buf[15] = 0x00;
//Total Length, 2 Byte//
uip_buf[16] = 0x00;
uip_buf[17] = 0x34;
//Identification, 2 Byte//
uip_buf[18] = 0x06;
uip_buf[19] = 0x00;
//Flags(3 bit) + Fragment Offset(13 Bit)//
uip_buf[20] = 0x40;
uip_buf[21] = 0x00;
//Time To Live, 1 Byte//
uip_buf[22] = 0x80;
//Protocol, 1 Byte//
uip_buf[23] = 0x06;
//Header Checksum//
uip_buf[24] = 0x00;
uip_buf[25] = 0x00;
//Source IP Address//
uip_buf[26] = 0x0A;
uip_buf[27] = 0x7F;
uip_buf[28] = 0x01;
uip_buf[29] = 0x34;
//Destination IP Address//
uip_buf[30] = 0x0A;
uip_buf[31] = 0x7F;
uip_buf[32] = 0x01;
uip_buf[33] = 0x33;
//Source Port Address, 2 byte//
uip_buf[34] = 0x04;
uip_buf[35] = 0x01;
//Destination Port Address, 2 byte//
uip_buf[36] = 0x00;
uip_buf[37] = 0x50;
//Sequence Number, 4 byte//
uip_buf[38] = 0x00;
uip_buf[39] = 0x00;
uip_buf[40] = 0x00;
uip_buf[41] = 0x00;
//Ack Number, 4 byte//
uip_buf[42] = 0x00;
uip_buf[43] = 0x00;
uip_buf[44] = 0x00;
uip_buf[45] = 0x00;
//Header Length , 1 Byte//
//Header Len = (Higher Nibble * 4) //
uip_buf[46] = 0x80;
//Flags, 1 byte//
uip_buf[47] = 0x02;
//Window Size, 2 Byte//
uip_buf[48] = 0x06;
uip_buf[49] = 0x0a;
//Check Sum, 2 Byte//
uip_buf[50] = 0x49;
uip_buf[51] = 0xb7;
//urgent Pointer, 2 Byte//
uip_buf[52] = 0x00;
uip_buf[53] = 0x00;
//Option, 12 Byte//
uip_buf[54] = 0x02;
uip_buf[55] = 0x04;
uip_buf[56] = 0x06;
uip_buf[57] = 0x0a;
uip_buf[58] = 0x01;
uip_buf[59] = 0x03;
uip_buf[60] = 0x03;
uip_buf[61] = 0x08;
uip_buf[62] = 0x01;
uip_buf[63] = 0x01;
uip_buf[64] = 0x04;
uip_buf[65] = 0x02;
// uip_buf[66] = 0xf6;
// uip_buf[67] = 0xe6;
// uip_buf[68] = 0x50;
// uip_buf[69] = 0x70;
}
int
main(void)
{
uip_ipaddr_t sIPAddr;
static struct uip_eth_addr sTempAddr;
int32_t i32PeriodicTimer, i32ARPTimer;
#ifdef EXTERNAL_RMII_PHY
uint16_t ui16Val;
#endif
uint32_t ui32User0, ui32User1;
uint32_t ui32Temp, ui32PHYConfig, ui32SysClock;
uint8_t ui8PHYAddr;
//
// Run from the PLL at 120 MHz.
//
ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
//
// Configure the device pins.
//
PinoutSet();
//
// Initialize the display driver.
//
Kentec320x240x16_SSD2119Init(ui32SysClock);
//
// Initialize the graphics context.
//
GrContextInit(&g_sContext, &g_sKentec320x240x16_SSD2119);
//
// Draw the application frame.
//
FrameDraw(&g_sContext, "enet-uip");
//
// Initialize the UART.
//
UARTStdioConfig(0, 115200, ui32SysClock);
UARTprintf("Ethernet with uIP\n-----------------\n\n");
#ifdef EXTERNAL_RMII_PHY
UpdateStatus("Using RMII PHY.");
ui32PHYConfig = EMAC_PHY_TYPE_EXTERNAL_RMII;
ui8PHYAddr = 0;
#elif defined EXTERNAL_MII_PHY
UpdateStatus("Using MII PHY.");
ui32PHYConfig = EMAC_PHY_TYPE_EXTERNAL_MII;
ui8PHYAddr = 0;
#else
UpdateStatus("Using Internal PHY.");
ui32PHYConfig = (EMAC_PHY_TYPE_INTERNAL | EMAC_PHY_INT_MDIX_EN |
EMAC_PHY_AN_100B_T_FULL_DUPLEX);
ui8PHYAddr = 0;
#endif
//
// Read the MAC address from the user registers.
//
ROM_FlashUserGet(&ui32User0, &ui32User1);
if((ui32User0 == 0xffffffff) || (ui32User1 == 0xffffffff))
{
//
// We should never get here. This is an error if the MAC address has
// not been programmed into the device. Exit the program.
//
UpdateStatus("MAC Address Not Programmed!");
while(1)
{
}
}
//
// Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC
// address needed to program the hardware registers, then program the MAC
// address into the Ethernet Controller registers.
//
sTempAddr.addr[0] = ((ui32User0 >> 0) & 0xff);
sTempAddr.addr[1] = ((ui32User0 >> 8) & 0xff);
sTempAddr.addr[2] = ((ui32User0 >> 16) & 0xff);
sTempAddr.addr[3] = ((ui32User1 >> 0) & 0xff);
sTempAddr.addr[4] = ((ui32User1 >> 8) & 0xff);
sTempAddr.addr[5] = ((ui32User1 >> 16) & 0xff);
//
// Configure SysTick for a periodic interrupt.
//
ROM_SysTickPeriodSet(ui32SysClock / SYSTICKHZ);
ROM_SysTickEnable();
ROM_SysTickIntEnable();
//
// Enable and reset the Ethernet modules.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
//
// Wait for the MAC to be ready.
//
UpdateStatus("Waiting for MAC to be ready...");
while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0))
{
}
//
// Configure for use with the internal PHY.
//
ROM_EMACPHYConfigSet(EMAC0_BASE, ui32PHYConfig);
UpdateStatus("MAC ready.");
//
// Reset the MAC.
//
ROM_EMACReset(EMAC0_BASE);
//
// Initialize the MAC and set the DMA mode.
//
ROM_EMACInit(EMAC0_BASE, ui32SysClock,
EMAC_BCONFIG_MIXED_BURST | EMAC_BCONFIG_PRIORITY_FIXED, 4, 4,
0);
#ifdef EXTERNAL_RMII_PHY
//
// When using an external RMII PHY, we need to acquire link before we can
// determine how to configure the MAC. Unfortunately, the bit signalling
// on RMII changes depending upon whether the PHY is configured to use
// 10Mbps or 100Mbps and we need to tell the MAC which signalling method
// to use.
//
// With MII, the signalling is the same for both speeds so we don't need to
// include code to wait for the link to be acquired.
//
//
// Write the PHY register that tells it to start auto-negotiation.
//
UpdateStatus("Starting autonegotiation...");
ROM_EMACPHYWrite(EMAC0_BASE, ui8PHYAddr, EPHY_BMCR,
EPHY_BMCR_ANEN | EPHY_BMCR_RESTARTAN);
//
// Poll, waiting for auto-negotiation to complete.
//
UpdateStatus("Waiting for autonegotiation to complete...");
do
{
ui16Val = ROM_EMACPHYRead(EMAC0_BASE, ui8PHYAddr, EPHY_BMSR);
ROM_SysCtlDelay(ui32SysClock / (10 * 3));
}
while(!(ui16Val & EPHY_BMSR_ANC));
//
// Wait for link to be acquired.
//
UpdateStatus("Waiting for link...");
while(!(ui16Val & EPHY_BMSR_LINKSTAT))
{
ui16Val = ROM_EMACPHYRead(EMAC0_BASE, ui8PHYAddr, EPHY_BMSR);
}
UpdateStatus("Link acquired.");
//
// What's the operating speed?
//
ui16Val = ROM_EMACPHYRead(EMAC0_BASE, ui8PHYAddr, EPHY_STS);
//
// Set the MAC to PHY communication speed and duplex mode accordingly.
//
UARTprintf("Speed is 10%sMbps.\n", (ui16Val & EPHY_STS_SPEED) ? "" : "0");
ROM_EMACConfigSet(EMAC0_BASE,
(((ui16Val & EPHY_STS_SPEED) ? 0 : EMAC_CONFIG_100MBPS) |
((ui16Val & EPHY_STS_DUPLEX) ? EMAC_CONFIG_FULL_DUPLEX :
0) |
EMAC_CONFIG_FULL_DUPLEX |
EMAC_CONFIG_CHECKSUM_OFFLOAD |
EMAC_CONFIG_7BYTE_PREAMBLE |
EMAC_CONFIG_IF_GAP_96BITS | EMAC_CONFIG_USE_MACADDR0 |
EMAC_CONFIG_SA_FROM_DESCRIPTOR |
EMAC_CONFIG_BO_LIMIT_1024),
(EMAC_MODE_RX_STORE_FORWARD |
EMAC_MODE_TX_STORE_FORWARD |
EMAC_MODE_TX_THRESHOLD_64_BYTES |
EMAC_MODE_RX_THRESHOLD_64_BYTES), 0);
#else
//
// Set MAC configuration options.
//
ROM_EMACConfigSet(EMAC0_BASE,
(EMAC_CONFIG_FULL_DUPLEX | EMAC_CONFIG_CHECKSUM_OFFLOAD |
EMAC_CONFIG_7BYTE_PREAMBLE | EMAC_CONFIG_IF_GAP_96BITS |
EMAC_CONFIG_USE_MACADDR0 |
EMAC_CONFIG_SA_FROM_DESCRIPTOR |
EMAC_CONFIG_BO_LIMIT_1024),
(EMAC_MODE_RX_STORE_FORWARD |
EMAC_MODE_TX_STORE_FORWARD |
EMAC_MODE_TX_THRESHOLD_64_BYTES |
EMAC_MODE_RX_THRESHOLD_64_BYTES), 0);
#endif
//
// Initialize the Ethernet DMA descriptors.
//
InitDescriptors(EMAC0_BASE);
//
// Program the hardware with its MAC address (for filtering).
//
ROM_EMACAddrSet(EMAC0_BASE, 0, (uint8_t *)&sTempAddr);
#ifndef EXTERNAL_RMII_PHY
//
// Wait for the link to become active. If we are using an external
// RMII PHY, we already waited for link to be acquired prior to
// configuring the MAC so don't wait again here.
//
UpdateStatus("Waiting for Link");
while((ROM_EMACPHYRead(EMAC0_BASE, ui8PHYAddr, EPHY_BMSR) &
EPHY_BMSR_LINKSTAT) == 0)
{
}
UpdateStatus("Link Established");
#endif
//
// Set MAC filtering options. We receive all broadcast and multicast
// packets along with those addressed specifically for us.
//
ROM_EMACFrameFilterSet(EMAC0_BASE, (EMAC_FRMFILTER_SADDR |
EMAC_FRMFILTER_PASS_MULTICAST |
EMAC_FRMFILTER_PASS_NO_CTRL));
//
// Clear any pending interrupts.
//
ROM_EMACIntClear(EMAC0_BASE, EMACIntStatus(EMAC0_BASE, false));
//
// Initialize the uIP TCP/IP stack.
//
uip_init();
//
// Set the local MAC address (for uIP).
//
uip_setethaddr(sTempAddr);
#ifdef USE_STATIC_IP
uip_ipaddr(sIPAddr, DEFAULT_IPADDR0, DEFAULT_IPADDR1, DEFAULT_IPADDR2,
DEFAULT_IPADDR3);
uip_sethostaddr(sIPAddr);
ShowIPAddress(sIPAddr);
uip_ipaddr(sIPAddr, DEFAULT_NETMASK0, DEFAULT_NETMASK1, DEFAULT_NETMASK2,
DEFAULT_NETMASK3);
uip_setnetmask(sIPAddr);
#else
uip_ipaddr(sIPAddr, 0, 0, 0, 0);
uip_sethostaddr(sIPAddr);
UpdateStatus("Waiting for IP address...");
uip_ipaddr(sIPAddr, 0, 0, 0, 0);
uip_setnetmask(sIPAddr);
#endif
//
// Enable the Ethernet MAC transmitter and receiver.
//
ROM_EMACTxEnable(EMAC0_BASE);
ROM_EMACRxEnable(EMAC0_BASE);
//
// Enable the Ethernet interrupt.
//
ROM_IntEnable(INT_EMAC0);
//
// Enable the Ethernet RX Packet interrupt source.
//
ROM_EMACIntEnable(EMAC0_BASE, EMAC_INT_RECEIVE);
//
// Mark the first receive descriptor as available to the DMA to start
// the receive processing.
//
g_psRxDescriptor[g_ui32RxDescIndex].ui32CtrlStatus |= DES0_RX_CTRL_OWN;
//
// Initialize the TCP/IP Application (e.g. web server).
//
// httpd_init();
SendARPRequest();
PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
while(1) {
while (!g_ui32Flags) {
}
//
// If SysTick, Clear the SysTick interrupt flag and increment the
// timers.
//
if (HWREGBITW(&g_ui32Flags, FLAG_SYSTICK) == 1) {
HWREGBITW(&g_ui32Flags, FLAG_SYSTICK) = 0;
i32PeriodicTimer += SYSTICKMS;
i32ARPTimer += SYSTICKMS;
}
if(HWREGBITW(&g_ui32Flags, FLAG_RXPKT))
{
HWREGBITW(&g_ui32Flags, FLAG_RXPKT) = 0;
if (BUF ->type == htons(UIP_ETHTYPE_IP)) {
SendIPPacket1();
uip_len = 54;
PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
uip_len = 0;
}
//
// //
// // Process incoming ARP packets here.
// //
if (BUF ->type == htons(UIP_ETHTYPE_ARP)) {
uip_arp_arpin();
SendIPPacket();
uip_len = 66;
PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
uip_len = 0;
while(1);
}
}
//
// Process TCP/IP Periodic Timer here.
//
if(i32PeriodicTimer > (UIP_PERIODIC_TIMER_MS * 10))
{
i32PeriodicTimer = 0;
uip_len = 66;
PacketTransmit(EMAC0_BASE, uip_buf, uip_len);
uip_len = 0;
}
}