File indexing completed on 2024-06-02 05:05:15

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "pack.h"
0007 #include <arpa/inet.h>
0008 #include <util/error.h>
0009 #include <util/functions.h>
0010 
0011 using namespace bt;
0012 
0013 namespace dht
0014 {
0015 void PackBucketEntry(const KBucketEntry &e, QByteArray &ba, Uint32 off)
0016 {
0017     const net::Address &addr = e.getAddress();
0018     Uint8 *data = (Uint8 *)ba.data();
0019     Uint8 *ptr = data + off;
0020 
0021     if (addr.ipVersion() == 4) {
0022         // first check size
0023         if ((int)off + 26 > ba.size())
0024             throw bt::Error("Not enough room in buffer");
0025 
0026         // copy ID, IP address and port into the buffer
0027         memcpy(ptr, e.getID().getData(), 20);
0028         bt::WriteUint32(ptr, 20, addr.toIPv4Address());
0029         bt::WriteUint16(ptr, 24, addr.port());
0030     } else {
0031         // first check size
0032         if ((int)off + 38 > ba.size())
0033             throw bt::Error("Not enough room in buffer");
0034 
0035         // copy ID, IP address and port into the buffer
0036         memcpy(ptr, e.getID().getData(), 20);
0037         memcpy(ptr + 20, addr.toIPv6Address().c, 16);
0038         bt::WriteUint16(ptr, 36, addr.port());
0039     }
0040 }
0041 
0042 KBucketEntry UnpackBucketEntry(const QByteArray &ba, Uint32 off, int ip_version)
0043 {
0044     if (ip_version == 4) {
0045         if ((int)off + 26 > ba.size())
0046             throw bt::Error("Not enough room in buffer");
0047 
0048         const Uint8 *data = (Uint8 *)ba.data();
0049         const Uint8 *ptr = data + off;
0050 
0051         // get the port, ip and key);
0052         Uint16 port = bt::ReadUint16(ptr, 24);
0053         Uint32 ip = bt::ReadUint32(ptr, 20);
0054         Uint8 key[20];
0055         memcpy(key, ptr, 20);
0056 
0057         return KBucketEntry(net::Address(ip, port), dht::Key(key));
0058     } else {
0059         if ((int)off + 38 > ba.size())
0060             throw bt::Error("Not enough room in buffer");
0061 
0062         const Uint8 *data = (Uint8 *)ba.data();
0063         const Uint8 *ptr = data + off;
0064 
0065         // get the port, ip and key);
0066         Uint16 port = bt::ReadUint16(ptr, 36);
0067         Uint8 key[20];
0068         memcpy(key, ptr, 20);
0069 
0070         return KBucketEntry(net::Address((quint8 *)ptr + 20, port), dht::Key(key));
0071     }
0072 }
0073 
0074 }