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