]> git.stg.codes - stg.git/blob - include/stg/raw_ip_packet.h
Add name to anonymous union
[stg.git] / include / stg / raw_ip_packet.h
1 #ifndef RAW_IP_PACKET_H
2 #define RAW_IP_PACKET_H
3
4 #if defined(FREE_BSD) || defined(FREE_BSD5)
5 #include <netinet/in_systm.h> // n_long in netinet/ip.h
6 #endif
7
8 #include <netinet/in.h> // for htons
9 #include <netinet/ip.h> // for struct ip
10
11 #include <cstring>
12
13 #include "const.h"
14 #include "common.h"
15
16 #define IPv4 (2)
17
18 enum { pcktSize = 68 }; //60(max) ip + 8 udp or tcp (part of tcp or udp header to ports)
19 //-----------------------------------------------------------------------------
20 struct RAW_PACKET
21 {
22     RAW_PACKET()
23         : rawPacket(),
24           dataLen(-1)
25     {
26     memset(rawPacket.pckt, 0, pcktSize);
27     }
28
29     RAW_PACKET(const RAW_PACKET & rp)
30         : rawPacket(),
31           dataLen(rp.dataLen)
32     {
33     memcpy(rawPacket.pckt, rp.rawPacket.pckt, pcktSize);
34     }
35
36 uint16_t    GetIPVersion() const;
37 uint8_t     GetHeaderLen() const;
38 uint8_t     GetProto() const;
39 uint32_t    GetLen() const;
40 uint32_t    GetSrcIP() const;
41 uint32_t    GetDstIP() const;
42 uint16_t    GetSrcPort() const;
43 uint16_t    GetDstPort() const;
44
45 bool        operator==(const RAW_PACKET & rvalue) const;
46 bool        operator!=(const RAW_PACKET & rvalue) const { return !(*this == rvalue); };
47 bool        operator<(const RAW_PACKET & rvalue) const;
48
49 union
50     {
51     uint8_t pckt[pcktSize]; // Packet header as a raw data
52     struct
53         {
54         struct ip   ipHeader;
55         // Only for packets without options field
56         uint16_t    sPort;
57         uint16_t    dPort;
58         } header __attribute__ ((packed));
59     } rawPacket;
60 int32_t dataLen; // IP packet length. Set to -1 to use length field from the header
61 };
62 //-----------------------------------------------------------------------------
63 inline uint16_t RAW_PACKET::GetIPVersion() const
64 {
65 return rawPacket.header.ipHeader.ip_v;
66 }
67 //-----------------------------------------------------------------------------
68 inline uint8_t RAW_PACKET::GetHeaderLen() const
69 {
70 return rawPacket.header.ipHeader.ip_hl * 4;
71 }
72 //-----------------------------------------------------------------------------
73 inline uint8_t RAW_PACKET::GetProto() const
74 {
75 return rawPacket.header.ipHeader.ip_p;
76 }
77 //-----------------------------------------------------------------------------
78 inline uint32_t RAW_PACKET::GetLen() const
79 {
80 if (dataLen != -1)
81     return dataLen;
82 return ntohs(rawPacket.header.ipHeader.ip_len);
83 }
84 //-----------------------------------------------------------------------------
85 inline uint32_t RAW_PACKET::GetSrcIP() const
86 {
87 return rawPacket.header.ipHeader.ip_src.s_addr;
88 }
89 //-----------------------------------------------------------------------------
90 inline uint32_t RAW_PACKET::GetDstIP() const
91 {
92 return rawPacket.header.ipHeader.ip_dst.s_addr;
93 }
94 //-----------------------------------------------------------------------------
95 inline uint16_t RAW_PACKET::GetSrcPort() const
96 {
97 if (rawPacket.header.ipHeader.ip_p == 1) // for icmp proto return port 0
98     return 0;
99 return ntohs(*((uint16_t*)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4)));
100 }
101 //-----------------------------------------------------------------------------
102 inline uint16_t RAW_PACKET::GetDstPort() const
103 {
104 if (rawPacket.header.ipHeader.ip_p == 1) // for icmp proto return port 0
105     return 0;
106 return ntohs(*((uint16_t*)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4 + 2)));
107 }
108 //-----------------------------------------------------------------------------
109 inline bool RAW_PACKET::operator==(const RAW_PACKET & rvalue) const
110 {
111 if (rawPacket.header.ipHeader.ip_src.s_addr != rvalue.rawPacket.header.ipHeader.ip_src.s_addr)
112     return false;
113
114 if (rawPacket.header.ipHeader.ip_dst.s_addr != rvalue.rawPacket.header.ipHeader.ip_dst.s_addr)
115     return false;
116
117 if (rawPacket.header.ipHeader.ip_p != 1 && rvalue.rawPacket.header.ipHeader.ip_p != 1)
118     {
119     if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4)) !=
120         *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4)))
121         return false;
122
123     if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4 + 2)) !=
124         *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4 + 2)))
125         return false;
126     }
127
128 if (rawPacket.header.ipHeader.ip_p != rvalue.rawPacket.header.ipHeader.ip_p)
129     return false;
130
131 return true;
132 }
133 //-----------------------------------------------------------------------------
134 inline bool RAW_PACKET::operator<(const RAW_PACKET & rvalue) const
135 {
136 if (rawPacket.header.ipHeader.ip_src.s_addr < rvalue.rawPacket.header.ipHeader.ip_src.s_addr) 
137     return true;
138 if (rawPacket.header.ipHeader.ip_src.s_addr > rvalue.rawPacket.header.ipHeader.ip_src.s_addr) 
139     return false;
140
141 if (rawPacket.header.ipHeader.ip_dst.s_addr < rvalue.rawPacket.header.ipHeader.ip_dst.s_addr) 
142     return true;
143 if (rawPacket.header.ipHeader.ip_dst.s_addr > rvalue.rawPacket.header.ipHeader.ip_dst.s_addr) 
144     return false;
145
146 if (rawPacket.header.ipHeader.ip_p != 1 && rvalue.rawPacket.header.ipHeader.ip_p != 1)
147     {
148     if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4)) <
149         *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4))) 
150         return true;
151     if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4)) >
152         *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4))) 
153         return false;
154
155     if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4 + 2)) <
156         *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4 + 2))) 
157         return true;
158     if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4 + 2)) >
159         *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4 + 2))) 
160         return false;
161     }
162
163 if (rawPacket.header.ipHeader.ip_p < rvalue.rawPacket.header.ipHeader.ip_p) 
164     return true;
165
166 return false;
167 }
168 //-----------------------------------------------------------------------------
169
170 #endif