NetBurner 3.1
ip.h
1 /*NB_REVISION*/
2 
3 /*NB_COPYRIGHT*/
4 
5 /* Definitions for various IP definitions and structures. */
6 #ifndef _NB_IP_H
7 #define _NB_IP_H
8 
9 // NB Definitions
10 #include <predef.h>
11 
12 #ifndef NB_NET_TYPES_H
13 #include "nettypes.h"
14 #endif
15 
16 #ifndef _NB_BUFFERS_H
17 #include "buffers.h"
18 #endif
19 /*
20  ******************************************************************************
21  *
22  * Debugging
23  *
24  ******************************************************************************
25  */
26 // #define IP_DEBUG ( 0 )
27 
28 /*
29  ******************************************************************************
30  *
31  * Definitions
32  *
33  ******************************************************************************
34  */
35 /*
36  * IP Version
37  */
38 #define IP_VERSION_MASK (0xF0)
39 #define IP_VERSION_IPv4 (0x40)
40 #define IP_VERSION_IPv6 (0x60)
41 
42 /*
43  * Header Length
44  */
45 #define IP_HEADER_LENGTH_MASK (0x0F)
46 #define IP_HEADER_LENGTH_NO_OPTIONS (0x05)
47 
48 /*
49  * Flags and Fragment Offset
50  */
51 #define IP_FLAGS_MASK (0xE000)
52 #define IP_FRAGMENT_OFFSET_MASK (0x1FFF)
53 
54 /*
55  * IANA IP protocol numbers
56  */
57 #define IP_PROTOCOL_ICMP (0x01)
58 #define IP_PROTOCOL_IGMP (0x02)
59 #define IP_PROTOCOL_INTERNET (0x04)
60 #define IP_PROTOCOL_TCP (0x06)
61 #define IP_PROTOCOL_UDP (0x11)
62 
63 /*
64  * ICMP control message type(s) and code(s)
65  */
66 #define ICMP_TYPE_ECHO_REPLY (0)
67 #define ICMP_CODE_ECHO_REPLY (0)
68 #define ICMP_TYPE_DEST_UNREACHABLE (3)
69 #define ICMP_CODE_PORT_UNREACHABLE (3)
70 #define ICMP_TYPE_SOURCE_QUENCH (4)
71 #define ICMP_CODE_SOURCE_QUENCH (0)
72 #define ICMP_TYPE_REDIRECT_MESSAGE (5)
73 #define ICMP_TYPE_ECHO_REQUEST (8)
74 #define ICMP_CODE_ECHO_REQUEST (0)
75 
76 /*
77  * IANA Well Known Ports
78  */
79 #define IANA_ECHO_PORT (7)
80 #define IANA_DISCARD_PORT (9)
81 #define IANA_SSH_PORT (22)
82 #define IANA_TELNET_PORT (23)
83 //#define IANA_TFTP_PORT (69)
84 #define IANA_NETBIOS_NAME_SERVICE_PORT (137)
85 
86 /*
87  * Data size for ICMP echo request and replay ("ping")
88  */
89 #define ICMP_PING_DATA_SIZE (32)
90 
91 /*
92  ******************************************************************************
93  *
94  * Data Structures
95  *
96  ******************************************************************************
97  */
98 
99 /*
100  * IP Header (IPv4) <Internal header members>
101  *
102  * versionNLength - Version and header length nibbles <bVerHdrLen>
103  * diffServNEcn - Service and congestion related <bTos>
104  * totalLength - Datagram size including IP header <wLength>
105  * identification - Fragment identification <wpktId >
106  * flagsNFragmentOffset - Flags and fragment offset fields <wFlags_Frag>
107  * timeToLive - Usually hop count <bTTL>
108  * protocol - IANA protocol number <proto>
109  * headerChecksum - 16-bit one's complement of the one's <hCSum>
110  * complement sum of all 16-bit words in the
111  * header
112  * sourceAddress - IP address of source 4 8-bit octets <ipSrc>
113  * destinationAddress - IP destination address 4 8-bit octets<ipDst>
114  *
115  * Note:
116  * Can contain options, determined by header length ( No options header
117  * length is 5 for 5 32 bit words ( 20 bytes )
118  * IETF RFC 791 September 1981, MIL-STD-1777
119  *
120  */
121 typedef struct _IpHeaderIPv4
122 {
123  uint8_t versionNLength;
124  uint8_t diffServNEcn;
125  beuint16_t totalLength;
126  beuint16_t identification;
127  beuint16_t flagsNFragmentOffset;
128  uint8_t timeToLive;
129  uint8_t protocol;
130  beuint16_t headerChecksum;
131  beuint32_t sourceAddress;
132  beuint32_t destinationAddress;
133 
134 } __attribute__((packed)) IpHeaderIPv4;
135 
136 /*
137  * Internal IPv4 Header
138  */
139 typedef struct
140 {
141  uint8_t bVerHdrLen;
142  uint8_t bTos;
143  beuint16_t wLength;
144  beuint16_t wpktId;
145  beuint16_t wFlags_Frag;
146  uint8_t bTTL;
147  uint8_t proto;
148  uint16_t hCSum; // do not make a big endian var, checksumming is treated as native endian
149  IPADDR4 ipSrc;
150  IPADDR4 ipDst;
151  uint8_t DATA[]; /*The data field is actually as long as the packet.... */
152 } IPPKT;
153 typedef IPPKT *PIPPKT;
154 
155 /*
156  * UDP header
157  *
158  * srcPort - Source port number
159  * dstPort - Destination port number
160  * UdpLen - Datagram length including header
161  * UdpCSum - Checksum (zero in IPv4)
162  */
163 typedef struct
164 {
165  beuint16_t srcPort;
166  beuint16_t dstPort;
167  beuint16_t UdpLen;
168  uint16_t UdpCSum; // do not make big endian, see IPPKT
169  uint8_t DATA[]; /*The data field is actually as long as the packet.... */
170 } UDPPKT;
171 typedef UDPPKT *PUDPPKT;
172 
173 /*
174  * UDP IPv4 Pseudo-header segment (bits 0 through 95)
175  *
176  * proto - Protocol (UDP 0x11)
177  * len - UDP header and data
178  * srcip - Source IP address
179  * dstip - Destination IP address
180  */
181 
182 /********************WARNING ************************
183 
184 This structure has the elements in a differnt order than usuallyt defined.
185 The IPChecksum is order invariant on 16 bit values.
186 The struucture is this way so it can MAP over a section of UDP and TCP IP packets without messing them up.
187 Dont change the order
188 ******************WARNING ***************************/
189 
190 typedef struct
191 {
192  beuint16_t proto;
193  beuint16_t len;
194  IPADDR4 srcip;
195  IPADDR4 dstip;
196 
197 } PsudeoHeader;
198 typedef PsudeoHeader *PPSUH;
199 
200 /*
201  *******************************************************************************
202  *
203  * Global Data
204  *
205  *******************************************************************************
206  */
207 /* Default number of hops (time to live) */
208 extern uint8_t bTTL_Default;
209 
210 /* ARP lifetime in seconds */
211 extern uint16_t wArpLifetime;
212 
213 /* Quiet start */
214 extern BOOL bQuietStart;
215 
216 /*
217  *******************************************************************************
218  *
219  * "C" Internal Functions
220  *
221  *******************************************************************************
222  */
223 
224 /* IP packet insertion for processing */
225 void IpProcessEthernetPacket(PoolPtr poolPtr, uint16_t packetSizeInBytes);
226 
227 extern "C"
228 {
229  /* Checksum */
230  uint16_t GetSum(puint16_t addr, uint16_t count);
231  /* Checksum */
232  uint16_t GetSum20(puint32_t addr);
233  /* Checksum using pseudo-header */
234  uint16_t GetSumHdr(PsudeoHeader &hdr, puint16_t addr, uint16_t count);
235 }
236 
237 /* Is this my IP address? */
238 BOOL IsMyIp4(IPADDR4 ip, int ifc = -1);
239 
240 /* Get source IP address for this destination */
241 IPADDR4 GetSrcIp4(IPADDR4 dst);
242 
243 #ifdef IPV6
244 /* Is this my IP address? */
245 BOOL IsMyIp6(const IPADDR6 &ip, int ifc = -1);
246 inline BOOL IsMyIp(const IPADDR6 &ip, int ifc = -1)
247 {
248  return IsMyIp6(ip, ifc);
249 };
250 
251 /* Get source IP address for this destination */
252 IPADDR6 GetSrcIp6(const IPADDR6 &dst);
253 inline IPADDR6 GetSrcIp(const IPADDR6 &dst)
254 {
255  return GetSrcIp6(dst);
256 };
257 
258 #else
259 inline BOOL IsMyIp(IPADDR4 ip, int ifc = -1)
260 {
261  return IsMyIp4(ip, ifc);
262 };
263 inline IPADDR4 GetSrcIp(IPADDR4 dst)
264 {
265  return GetSrcIp4(dst);
266 };
267 #endif
268 
269 /*
270  *******************************************************************************
271  *
272  * "C++" Internal Functions
273  *
274  *******************************************************************************
275  */
276 /* Send ICMP error */
277 void SendICMPError(PoolPtr pBadPacket, uint8_t type, uint8_t code);
278 
279 /* Complete header and send on primary network interface */
280 void FixHeaderAndSend(PoolPtr p, PIPPKT pIp);
281 
282 /* Complete header and send on an interface */
283 void FixHeaderAndSendViaInterface(PoolPtr p, PIPPKT pIp, int Interface);
284 
285 /* Get IP Packet pointer from network buffer pool buffer */
286 inline PIPPKT GetIpPkt(PoolPtr p)
287 {
288  return (p == NULL) ? NULL : (PIPPKT)(p->pData + 14);
289 };
290 
291 /* Get IP packet pointer from pointer to frame */
292 inline PIPPKT GetIpPkt(PEFRAME pFrame)
293 {
294  return (PIPPKT)(pFrame->pData);
295 };
296 /*
297  * WARNING WARNING WARNING
298  *
299  * If you use these functions on an uninitialized buffer you will get bogus
300  * values for the pointer as the header length field in the IP packet is not
301  * yet set up!
302  */
303 /* Get UPD packet pointer from IP packet pointer */
304 
305 inline PUDPPKT GetUdpPkt(PIPPKT pIp)
306 {
307  if (pIp == NULL) { return NULL; }
308  if (pIp->bVerHdrLen == 0x45) { return (PUDPPKT)pIp->DATA; }
309  return (PUDPPKT)(pIp->DATA + (((pIp->bVerHdrLen & 0XF) * 4) - 20));
310 }
311 
312 /*
313  *******************************************************************************
314  *
315  * "C++" Runtime Library Functions
316  *
317  *******************************************************************************
318  */
319 /*
320  *******************************************************************************
321  *
322  * Initializes the IP stack.
323  *
324  * Parameters:
325  * ipaddr - Address of primary network interface
326  * ipMask - Subnetwork mask
327  * ipGate - Gateway address.
328  * dns - Domain name system (DNS)server address
329  *
330  * Return:
331  * >=0 Ticks wait for the response
332  * -1 Timeout
333  *
334  * Notes:
335  * Should be called once and only once before UserMain resets it priority.
336  * The default settings cause the configuration record settings to be used.
337  * Add addresses and masks are IPv4
338  * This provides the network infrastructure for additional network interfaces
339  *
340  *******************************************************************************
341  */
342 void InitializeStack();
343 
344 /*
345  *******************************************************************************
346  *
347  * UPD fragment packet pointer for user defined function.
348  *
349  * Parameters:
350  * pp - Packet pointer from network buffer pool
351  *
352  * Return:
353  * None
354  *
355  * Notes:
356  * This is only called for packets with the fragmentation flag set
357  *
358  *******************************************************************************
359  */
360 typedef void(FragmentProcessFunction)(PoolPtr pp);
361 extern FragmentProcessFunction *pFragFunc;
362 
363 /*
364  *******************************************************************************
365  *
366  * Promiscuous packet pointer for user defined function.
367  *
368  * Parameters:
369  * pp - Packet pointer from network buffer pool
370  *
371  * Return:
372  * None
373  *
374  * Notes:
375  * This is only called for packets that fail the IP address == my address.
376  * This function must free the buffers it receives!
377  *
378  *******************************************************************************
379  */
380 typedef void(PromisciousPacketFunc)(PoolPtr pp);
381 extern PromisciousPacketFunc *pPromisciousPacketFunc;
382 
383 /*
384  *******************************************************************************
385  *
386  * UDP task packet function pointer
387  *
388  * Parameters:
389  * pkt - UDP packet
390  * ifn - Interface number
391  *
392  * Return:
393  * None
394  *
395  * Notes:
396  * None
397  *
398  *******************************************************************************
399  */
400 class UDPPacket;
401 typedef int(TaskPacketFunc)(UDPPacket &pkt, int ifn);
402 extern TaskPacketFunc *pTaskPacketFunc;
403 
404 /*
405  *******************************************************************************
406  *
407  * Display buffer for diagnostic purposes
408  *
409  * Parameters:
410  * rp - Packet pointer from network buffer pool
411  *
412  * Return:
413  * None
414  *
415  * Notes:
416  * Uses iprintf
417  *
418  *******************************************************************************
419  */
420 void ShowIPBuffer(PoolPtr rp);
421 
422 /*
423  *******************************************************************************
424  *
425  * Sends a "ping" packet and waits the specified timeout for a response.
426  *
427  * Ping uses the primary network interface (usually the Ethernet)
428  * PingViaInterface allows the selection of network interface
429  * SendPing does not wait for a response.
430  *
431  * Parameters:
432  * to - Destination address
433  * id - Identifier
434  * seq - Sequence number
435  * maxwaitticks - Wait time in ticks
436  *
437  * Return:
438  * >=0 Ticks wait for the response
439  * -1 Timeout
440  * -2 Error other than timeout.
441  * Notes:
442  * Sends ICMP echo request with specified identifier, sequence number and
443  * 32 bytes of ASCII data ('a' (0x61) through 0xFF ).
444  * Expects echo reply with same data
445  *
446  *******************************************************************************
447  */
448 int Ping4(IPADDR4 to, uint16_t id, uint16_t seq, uint16_t maxwaitticks);
449 int Ping4ViaInterface(IPADDR4 to, uint16_t id, uint16_t seq, uint16_t wait, int interface);
450 
451 #ifdef IPV6
452 int Ping6(const IPADDR6 &to, uint16_t id, uint16_t seq, uint16_t maxwaitticks, int size = 32);
453 int Ping6ViaInterface(const IPADDR6 &to, uint16_t id, uint16_t seq, uint16_t wait, int interface, int size = 32);
454 inline int Ping(const IPADDR6 &to, uint16_t id, uint16_t seq, uint16_t maxwaitticks, int size = 32)
455 {
456  return Ping6(to, id, seq, maxwaitticks, size);
457 };
458 inline int PingViaInterface(const IPADDR6 &to, uint16_t id, uint16_t seq, uint16_t wait, int interface, int size = 32)
459 {
460  return Ping6ViaInterface(to, id, seq, wait, interface, size);
461 };
462 #else
463 inline int Ping(IPADDR4 to, uint16_t id, uint16_t seq, uint16_t maxwaitticks)
464 {
465  return Ping4(to, id, seq, maxwaitticks);
466 };
467 inline int PingViaInterface(IPADDR4 to, uint16_t id, uint16_t seq, uint16_t wait, int interface)
468 {
469  return Ping4ViaInterface(to, id, seq, wait, interface);
470 };
471 #endif
472 
473 BOOL IsLocal4(IPADDR4 ip, int ifc);
474 int GetProperInterface4(IPADDR4 dst);
475 
476 #if defined MULTIHOME || defined AUTOIP
477 int AddInterface(IPADDR4 addr, IPADDR4 mask, IPADDR4 gateway, int root_if);
478 int GetMultiHomeInterface(IPADDR4 ipa, int norgif);
479 int GetLocalIPInterface4(IPADDR4 ipa);
480 #ifdef IPV6
481 int GetLocalIPInterface6(const IPADDR6 &ipa);
482 inline int GetLocalIPInterface(const IPADDR6 &ipa)
483 {
484  return GetLocalIPInterface6(ipa);
485 };
486 #else
487 inline int GetLocalIPInterface(IPADDR4 ipa)
488 {
489  return GetLocalIPInterface4(ipa);
490 };
491 #endif
492 #endif
493 
494  /*
495  *******************************************************************************
496  *
497  * Deprecated and Backward Compatibility Runtime Library Functions
498  *
499  *******************************************************************************
500  */
501 
502 #ifndef IPV6
503 #ifndef IPV4ONLY
504 #error Got to pick an IP version
505 #endif
506 #endif
507 
508 // Get a random port value for random return port values
509 uint16_t GetEphemeralPort();
510 
511 #endif /* #ifndef _NB_IP_H */
Used to hold and manipulate IPv4 and IPv6 addresses in dual stack mode.
Definition: ipv6_addr.h:28
UDP Packet Class.
Definition: udp.h:70
#define NULL
Definition: nm_bsp.h:76
NetBurner Buffers API.