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