/*! \file ip.c \brief IP (Internet Protocol) Library. */ //***************************************************************************** // // File Name : 'ip.c' // Title : IP (Internet Protocol) Library // Author : Pascal Stang // Created : 8/30/2004 // Revised : 7/3/2005 // Version : 0.1 // Target MCU : Atmel AVR series // Editor Tabs : 4 // //***************************************************************************** #include #include "HardwareSerial.h" #include #include "programStrings.h" #include "debug.h" #include "net.h" #include "nic.h" #include "arp.h" #include "ip.h" struct ipConfig IpMyConfig; ///< Local IP address/config structure void ipSetConfig(uint32_t myIp, uint32_t netmask, uint32_t gatewayIp) { struct netEthAddr ethaddr; // set local addressing IpMyConfig.ip = myIp; IpMyConfig.netmask = netmask; IpMyConfig.gateway = gatewayIp; // set ARP association nicGetMacAddress(ethaddr.addr); arpSetAddress(ðaddr, myIp); } struct ipConfig* ipGetConfig(void) { return &IpMyConfig; } // deprecated /* uint32_t ipGetMyAddress(void) { return IpMyConfig.ip; } */ void ipSend(uint32_t dstIp, uint8_t protocol, uint16_t len, uint8_t* data) { // make pointer to ethernet/IP header struct netEthIpHeader* ethIpHeader; // move data pointer to make room for headers data -= ETH_HEADER_LEN+IP_HEADER_LEN; ethIpHeader = (struct netEthIpHeader*)data; #ifdef NET_BUG > 6 debugPrintHexTable(len+ETH_HEADER_LEN+IP_HEADER_LEN, data); #endif // adjust length to add IP header len += IP_HEADER_LEN; // fill IP header ethIpHeader->ip.destipaddr = HTONL(dstIp); ethIpHeader->ip.srcipaddr = HTONL(IpMyConfig.ip); ethIpHeader->ip.proto = protocol; ethIpHeader->ip.len = htons(len); ethIpHeader->ip.vhl = 0x45; ethIpHeader->ip.tos = 0; ethIpHeader->ip.ipid = 0; ethIpHeader->ip.ipoffset = 0; ethIpHeader->ip.ttl = IP_TIME_TO_LIVE; ethIpHeader->ip.ipchksum = 0x0000; // calculate and apply IP checksum // DO THIS ONLY AFTER ALL CHANGES HAVE BEEN MADE TO IP HEADER ethIpHeader->ip.ipchksum = netChecksum(ðIpHeader->ip, IP_HEADER_LEN); #ifdef NET_CHECKSUM_DEBUG SPrint("IP Header Checksum: "); Serial.println((uint16_t)ethIpHeader->ip.ipchksum, HEX); #endif // add ethernet routing // check if we need to send to gateway if( (dstIp & IpMyConfig.netmask) == (IpMyConfig.ip & IpMyConfig.netmask) ) { arpIpOut(ethIpHeader,0); // local send #ifdef NET_DEBUG SPrint("Sending IP packet on local net\r\n"); #endif } else { arpIpOut(ethIpHeader,IpMyConfig.gateway); // gateway send #ifdef NET_DEBUG SPrint("Sending IP packet to gateway\r\n"); #endif } // adjust length to add ethernet header len += ETH_HEADER_LEN; // debug #if NET_DEBUG > 6 debugPrintHexTable(ETH_HEADER_LEN, &data[0]); debugPrintHexTable(len-ETH_HEADER_LEN, &data[ETH_HEADER_LEN]); #endif // send it nicSend(len, data); } void udpSend(uint32_t dstIp, uint16_t dstPort, uint16_t len, uint8_t* data) { // make pointer to UDP header struct netUdpHeader* udpHeader; // move data pointer to make room for UDP header data -= UDP_HEADER_LEN; udpHeader = (struct netUdpHeader*)data; // adjust length to add UDP header len += UDP_HEADER_LEN; // fill UDP header udpHeader->destport = HTONS(dstPort); udpHeader->srcport = HTONS(dstPort); udpHeader->udplen = htons(len); udpHeader->udpchksum = 0x000; //udpHeader->udpchksum = ipChecksum((netUdpHeader*)&udpHeader, htons(udpHeader->ip.len)-UDP_HEADER_LEN); #if NET_DEBUG > 6 debugPrintHexTable(UDP_HEADER_LEN, (uint8_t*)udpHeader); #endif ipSend(dstIp, IP_PROTO_UDP, len, (uint8_t*)udpHeader); } void ipPrintConfig(struct ipConfig* config) { SPrint("IP Addr : "); netPrintIPAddr(config->ip); Serial.println(); SPrint("Netmask : "); netPrintIPAddr(config->netmask); Serial.println(); SPrint("Gateway : "); netPrintIPAddr(config->gateway); Serial.println(); }