A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
ip4.c
00001 00002 #include <stdint.h> 00003 #include <stdbool.h> 00004 00005 #include "log.h" 00006 #include "net.h" 00007 #include "action.h" 00008 #include "icmp4.h" 00009 #include "udptcp4.h" 00010 #include "ar4.h" 00011 #include "nr.h" 00012 #include "dhcp.h" 00013 #include "eth.h" 00014 #include "ip.h" 00015 #include "ip4addr.h" 00016 #include "ip4hdr.h" 00017 #include "ntp.h" 00018 #include "mac.h" 00019 #include "restart.h" 00020 #include "checksum.h" 00021 00022 bool Ip4Trace = true; 00023 uint32_t Ip4Remote = 0; 00024 00025 #define OFF_LINK_TTL 64 00026 00027 static void logHeader(char* pPacket) 00028 { 00029 if (NetTraceVerbose) 00030 { 00031 Log ("IP4 header\r\n"); 00032 LogF(" Version %d\r\n", Ip4HdrGetVersion (pPacket)); 00033 int headerLength = Ip4HdrGetHeaderLen (pPacket); 00034 LogF(" Header length %d\r\n", headerLength); 00035 LogF(" Type of service %d\r\n", Ip4HdrGetTos (pPacket)); 00036 LogF(" Total length %d\r\n", Ip4HdrGetLength (pPacket)); 00037 LogF(" Identification %d\r\n", Ip4HdrGetId (pPacket)); 00038 if (Ip4HdrGetDontFrag(pPacket)) LogF(" Don't fragment\r\n"); 00039 else LogF(" Do fragment\r\n"); 00040 if (Ip4HdrGetMoreFrags(pPacket)) LogF(" More fragments\r\n"); 00041 else LogF(" No more fragments\r\n"); 00042 LogF(" Frag offset %d\r\n", Ip4HdrGetFragOffset(pPacket)); 00043 LogF(" Time to live %d\r\n", Ip4HdrGetTtl (pPacket)); 00044 LogF(" Protocol "); IpProtocolLog(Ip4HdrGetProtocol(pPacket)); Log("\r\n"); 00045 LogF(" Checksum (hex) %04hX\r\n", Ip4HdrGetChecksum(pPacket)); 00046 LogF(" Calculated (hex) %04hX\r\n", CheckSum(headerLength, pPacket)); 00047 LogF(" Source IP "); Ip4AddrLog(Ip4HdrGetSrc(pPacket)); Log("\r\n"); 00048 LogF(" Destination IP "); Ip4AddrLog(Ip4HdrGetDst(pPacket)); Log("\r\n"); 00049 } 00050 else 00051 { 00052 Log ("IP4 header "); 00053 IpProtocolLog(Ip4HdrGetProtocol(pPacket)); 00054 Log(" "); 00055 Ip4AddrLog(Ip4HdrGetSrc(pPacket)); 00056 Log(" >>> "); 00057 Ip4AddrLog(Ip4HdrGetDst(pPacket)); 00058 Log("\r\n"); 00059 } 00060 } 00061 static void makeHeader(char* pPacket, uint16_t totalLength, uint8_t ttl, uint8_t protocol, uint32_t srcIp, uint32_t dstIp) 00062 { 00063 static uint16_t id = 0; 00064 Ip4HdrSetVersion (pPacket, 4 ); 00065 Ip4HdrSetHeaderLen(pPacket, IP4_HEADER_LENGTH); 00066 Ip4HdrSetTos (pPacket, 0 ); 00067 Ip4HdrSetLength (pPacket, totalLength ); 00068 Ip4HdrSetId (pPacket, id++ ); //Used by the recipient for collating packets fragmented in transit; unique per packet sent 00069 Ip4HdrSetFragInfo (pPacket, 0 ); //No flags and no offset 00070 Ip4HdrSetTtl (pPacket, ttl ); 00071 Ip4HdrSetProtocol (pPacket, protocol ); 00072 Ip4HdrSetSrc (pPacket, srcIp ); 00073 Ip4HdrSetDst (pPacket, dstIp ); 00074 Ip4HdrSetChecksum (pPacket, 0 ); 00075 uint16_t checksum = CheckSum(IP4_HEADER_LENGTH, pPacket); 00076 Ip4HdrSetChecksum (pPacket, checksum ); 00077 } 00078 static char* traceHeader; 00079 static void (*pTraceBack)(void); 00080 static void trace() 00081 { 00082 pTraceBack(); 00083 logHeader(traceHeader); 00084 } 00085 00086 int Ip4HandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx, char* macRemote) 00087 { 00088 int lastRestartPoint = RestartPoint; 00089 RestartPoint = FAULT_POINT_Ip4HandleReceivedPacket; 00090 00091 traceHeader = pPacketRx; 00092 pTraceBack = traceback; 00093 00094 int headerLengthRx = Ip4HdrGetHeaderLen(pPacketRx); 00095 uint16_t totalLengthRx = Ip4HdrGetLength (pPacketRx); 00096 uint8_t protocol = Ip4HdrGetProtocol (pPacketRx); 00097 uint32_t srcIp = Ip4HdrGetSrc (pPacketRx); 00098 uint32_t dstIp = Ip4HdrGetDst (pPacketRx); 00099 00100 Ip4Remote = srcIp; 00101 00102 char* pDataRx = pPacketRx + headerLengthRx; 00103 char* pDataTx = pPacketTx + IP4_HEADER_LENGTH; 00104 00105 if (sizeRx > totalLengthRx) sizeRx = totalLengthRx; 00106 int dataLengthRx = sizeRx - headerLengthRx; 00107 int dataLengthTx = *pSizeTx - IP4_HEADER_LENGTH; 00108 00109 bool isMe = dstIp == DhcpLocalIp; 00110 bool isLocalBroadcast = dstIp == (DhcpLocalIp | 0xFF000000); // dstIp == 192.168.1.255; '|' is lower precendence than '==' 00111 bool isBroadcast = dstIp == IP4_BROADCAST_ADDRESS; // dstIp == 255.255.255.255 00112 bool isMulticast = (dstIp & 0xE0) == 0xE0; // 224.x.x.x == 1110 0000 == E0.xx.xx.xx == xx.xx.xx.E0 in little endian 00113 00114 bool doIt = isMe || isLocalBroadcast || isBroadcast || isMulticast; 00115 if (!doIt) 00116 { 00117 if (Ip4Trace) 00118 { 00119 LogTimeF("IP4 filtered out ip "); Ip4AddrLog(dstIp); 00120 Log(" from "); 00121 Ip4AddrLog(srcIp); 00122 Log("\r\n"); 00123 } 00124 RestartPoint = lastRestartPoint; 00125 return DO_NOTHING; 00126 } 00127 00128 int remArIndex = Ar4AddIpRecord(trace, macRemote, srcIp); 00129 NrMakeRequestForNameFromAddress4(srcIp); 00130 00131 int action = DO_NOTHING; 00132 switch (protocol) 00133 { 00134 case ICMP: action = Icmp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break; 00135 case IGMP: break; 00136 case UDP: action = Udp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp); break; 00137 case TCP: action = Tcp4HandleReceivedPacket(trace, pDataRx, dataLengthRx, pDataTx, &dataLengthTx, &srcIp, &dstIp, remArIndex); break; 00138 case IP6IN4: break; 00139 default: 00140 LogTimeF("IP4 received packet unknown protocol %d\r\n", protocol); 00141 RestartPoint = lastRestartPoint; 00142 return DO_NOTHING; 00143 } 00144 if (!action) 00145 { 00146 RestartPoint = lastRestartPoint; 00147 return DO_NOTHING; 00148 } 00149 00150 uint8_t ttl = 0; 00151 if (DhcpIpNeedsToBeRouted(dstIp)) 00152 { 00153 Ar4IpToMac(DhcpRouterIp, macRemote); //Send back to the router 00154 ttl = OFF_LINK_TTL; 00155 } 00156 else 00157 { 00158 ttl = 255; 00159 } 00160 00161 *pSizeTx = IP4_HEADER_LENGTH + dataLengthTx; 00162 00163 makeHeader(pPacketTx, *pSizeTx, ttl, protocol, srcIp, dstIp); 00164 00165 if (ActionGetTracePart(action)) logHeader(pPacketTx); 00166 00167 RestartPoint = lastRestartPoint; 00168 return action; 00169 } 00170 int Ip4PollForPacketToSend(char* pPacket, int* pSize, char* pDstMac) 00171 { 00172 char* pData = pPacket + IP4_HEADER_LENGTH; 00173 int dataLength = *pSize - IP4_HEADER_LENGTH; 00174 00175 uint8_t protocol = 0; 00176 uint32_t srcIp = 0; 00177 uint32_t dstIp = 0; 00178 int action = DO_NOTHING; 00179 if (!action) { action = Udp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); protocol = UDP; } 00180 if (!action) { action = Tcp4PollForPacketToSend(pData, &dataLength, &srcIp, &dstIp); protocol = TCP; } 00181 if (!action) return DO_NOTHING; 00182 int dest = ActionGetDestPart(action); 00183 uint8_t ttl = 0; 00184 switch (dest) 00185 { 00186 case UNICAST: 00187 case UNICAST_DNS: 00188 case UNICAST_DHCP: 00189 case UNICAST_NTP: 00190 case UNICAST_TFTP: 00191 case UNICAST_USER: 00192 if (DhcpIpNeedsToBeRouted(dstIp)) 00193 { 00194 Ar4IpToMac(DhcpRouterIp, pDstMac); //send via router 00195 ttl = OFF_LINK_TTL; 00196 } 00197 else 00198 { 00199 Ar4IpToMac(dstIp, pDstMac); //Send direct 00200 ttl = 255; 00201 } 00202 break; 00203 case MULTICAST_NODE: 00204 case MULTICAST_ROUTER: 00205 case MULTICAST_MDNS: 00206 case MULTICAST_LLMNR: 00207 case MULTICAST_NTP: 00208 case BROADCAST: 00209 ttl = 255; 00210 break; 00211 default: 00212 LogTimeF("Ip4PollForPacketToSend - undefined destination %d\r\n", dest); 00213 return DO_NOTHING; 00214 } 00215 00216 *pSize = IP4_HEADER_LENGTH + dataLength; 00217 00218 makeHeader(pPacket, *pSize, ttl, protocol, srcIp, dstIp); 00219 00220 if (ActionGetTracePart(action)) logHeader(pPacket); 00221 00222 return action; 00223 }
Generated on Tue Jul 12 2022 18:53:40 by 1.7.2