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.
150 lines
3.6 KiB
150 lines
3.6 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(ð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 = 0;
|
|
|
|
// 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);
|
|
|
|
// 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_P(PSTR("Sending IP packet on local net\r\n"));
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
arpIpOut(ethIpHeader,IpMyConfig.gateway); // gateway send
|
|
#ifdef NET_DEBUG
|
|
SPrint_P(PSTR("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 = 0;
|
|
|
|
#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_P(PSTR("IP Addr : ")); netPrintIPAddr(config->ip); Serial.println();
|
|
SPrint_P(PSTR("Netmask : ")); netPrintIPAddr(config->netmask); Serial.println();
|
|
SPrint_P(PSTR("Gateway : ")); netPrintIPAddr(config->gateway); Serial.println();
|
|
}
|