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