1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
3.8 KiB

/*! \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 <inttypes.h>
#include "HardwareSerial.h"
#include <avr/pgmspace.h>
#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(&ethaddr, 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(&ethIpHeader->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();
}