-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathip_slice.cpp
More file actions
143 lines (119 loc) · 3.74 KB
/
Copy pathip_slice.cpp
File metadata and controls
143 lines (119 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "ip_slice.h"
#include <QTime>
#include <QDataStream>
ip_slice::ip_slice(const qint16 mtu):
MTU(mtu)
{
frame = 0;
head = IP::MakeHeaderIP();
}
ip_slice::~ip_slice()
{
}
void ip_slice::set_tos(IP::ToSPriority prio, IP::ToSSubfield subf)
{
head.priority = prio;
head.subfield = subf;
}
void ip_slice::set_mtu(const int value)
{
MTU = value;
}
void ip_slice::set_protocol(IP::Protocol p)
{
head.protocol = p;
}
void ip_slice::set_addr_src(const QString &ip)
{
head.addrs = ::inet_addr(ip.toLatin1().data());
}
void ip_slice::set_addr_dst(const QString &ip)
{
head.addrd = ::inet_addr(ip.toLatin1().data());
}
/*
static quint32 current_ts()
{
QTime tm = QTime::currentTime();
return (tm.hour() << 22) | (tm.minute() << 16) | (tm.second() << 10) | tm.msec();
};*/
IP::DataPackList ip_slice::fragment (const QByteArray &data)
{
IP::DataPackList out;
IP::DataPack ipdp(MTU);
char *ptr = (char*)data.data();
::memcpy(ipdp.head(), &head, sizeof(head));
const quint16 hlen = (ipdp.head()->headlen <<2);
const quint32 dlen = data.size()+ hlen;
const quint32 buf[] = {ipdp.head()->addrs, ipdp.head()->addrd, dlen, frame++};
ipdp.head()->id = IP::HashID((char*)buf, sizeof(buf));
ipdp.head()->flag = IP::IP_Congestion;
ipdp.head()->length = dlen;
ipdp.head()->checksum = IP::CheckSum((quint16*)ipdp.head(), sizeof(IP::Header));
// 小于MTU大小不分片
if (dlen <= MTU)
{
::memcpy(ipdp.data(), ptr, dlen - hlen);
out.append(ipdp);
return out;
}
// 超出MTU大小,进行分片
for (int total = dlen -hlen, offset = 0, num = (MTU - hlen);
total > 0;
total -= num, offset += num, num = (total < num) ? total : num)
{
::memcpy(ipdp.data(), ptr + offset, num);
ipdp.head()->flag = IP::IP_MoreFragment;
ipdp.head()->offset = (offset >>3);
ipdp.head()->length = num + (ipdp.head()->headlen <<2);
ipdp.head()->checksum = IP::CheckSum((quint16*)ipdp.head(), sizeof(IP::Header));
out.append(ipdp);
}
return out;
}
IP::DataPackList ip_slice::direct(const QByteArray &data)
{
IP::DataPackList out;
IP::DataPack ipdp(MTU);
char *ptr = (char*)data.data();
::memcpy(ipdp.head(), &head, sizeof(head));
const quint16 hlen = (ipdp.head()->headlen <<2);
const quint32 dlen = data.size()+ hlen;
if (dlen <= MTU)
{
const quint32 buf[] = {ipdp.head()->addrs, ipdp.head()->addrd, dlen, frame++};
ipdp.head()->flag = IP::IP_Congestion;
ipdp.head()->id = IP::HashID((char*)buf, sizeof(buf));
ipdp.head()->length = dlen;
ipdp.head()->checksum = IP::CheckSum((quint16*)ipdp.head(), sizeof(IP::Header));
::memcpy(ipdp.data(), ptr, dlen - hlen);
out.append(ipdp);
return out;
}
// 超出MTU大小,进行多次分发
for (int total = dlen -hlen, offset = 0, num = (MTU - hlen);
total > 0;
total -= num, offset += num, num = (total < num) ? total : num)
{
::memcpy(ipdp.data(), ptr + offset, num);
ipdp.head()->flag = IP::IP_DontFragment;
ipdp.head()->length = num + (ipdp.head()->headlen <<2);
const quint32 rebuf[] = {ipdp.head()->addrs, ipdp.head()->addrd, dlen, frame++};
ipdp.head()->id = IP::HashID((char*)rebuf, sizeof(rebuf));
ipdp.head()->checksum = IP::CheckSum((quint16*)ipdp.head(), sizeof(IP::Header));
out.append(ipdp);
}
return out;
}
//!
//! \brief pack 封装
//! \param list
//! \return
//!
QByteArray ip_slice::pack(const IP::DataPackList &list)
{
QByteArray out;
foreach (const IP::DataPack &var, list)
out.append((char*)var.pack(), var.head()->length);
return out;
}