1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "netsys_addr_info_parcel.h"
17
18 #include <cstring>
19 #include <securec.h>
20
21 #include "netnative_log_wrapper.h"
22
23 namespace OHOS {
24 namespace NetsysNative {
NetsysAddrInfoParcel(const addrinfo * addr,const uint16_t netId,const std::string node,const std::string service)25 NetsysAddrInfoParcel::NetsysAddrInfoParcel(const addrinfo *addr, const uint16_t netId, const std::string node,
26 const std::string service)
27 : addrHead(nullptr)
28 {
29 if (addr == nullptr) {
30 isHintsNull = 1;
31 NETNATIVE_LOG_D("hints is nullptr");
32 } else {
33 isHintsNull = 0;
34 aiFamily = addr->ai_family;
35 aiSocktype = addr->ai_socktype;
36 aiFlags = addr->ai_flags;
37 aiProtocol = addr->ai_protocol;
38 aiAddrlen = addr->ai_addrlen;
39 }
40 this->netId = netId;
41 hostName = node;
42 serverName = service;
43 }
44
Marshalling(Parcel & parcel) const45 bool NetsysAddrInfoParcel::Marshalling(Parcel &parcel) const
46 {
47 if (!parcel.WriteInt16(isHintsNull)) {
48 return false;
49 }
50 if (!isHintsNull) {
51 if ((!parcel.WriteInt16(aiFamily)) || (!parcel.WriteInt16(aiSocktype)) || (!parcel.WriteInt16(aiFlags)) ||
52 (!parcel.WriteInt16(aiProtocol))) {
53 return false;
54 }
55 }
56 if (!parcel.WriteInt16(netId) || !parcel.WriteString(hostName) || !parcel.WriteString(serverName)) {
57 return false;
58 }
59 return true;
60 }
61
Unmarshalling(MessageParcel & parcelMsg)62 sptr<NetsysAddrInfoParcel> NetsysAddrInfoParcel::Unmarshalling(MessageParcel &parcelMsg)
63 {
64 sptr<NetsysAddrInfoParcel> ptr = new (std::nothrow) NetsysAddrInfoParcel();
65 if (ptr == nullptr) {
66 return nullptr;
67 }
68 ptr->ret = parcelMsg.ReadInt32();
69 ptr->addrSize = parcelMsg.ReadInt32();
70 int size = ptr->addrSize;
71 addrinfo *headNode = nullptr;
72 ptr->addrHead = headNode;
73 if (!UnmarshallingAddrinfo(parcelMsg, size, headNode)) {
74 return nullptr;
75 }
76 return ptr;
77 }
78
UnmarshallingAddrinfo(MessageParcel & parcelMsg,int size,addrinfo * headNode)79 bool NetsysAddrInfoParcel::UnmarshallingAddrinfo(MessageParcel &parcelMsg, int size, addrinfo *headNode)
80 {
81 int count = 0;
82 addrinfo *nextNode = nullptr;
83 while (size--) {
84 addrinfo *node = static_cast<addrinfo *>(malloc(sizeof(addrinfo)));
85 if (node == nullptr) {
86 break;
87 }
88 node->ai_flags = parcelMsg.ReadInt16();
89 node->ai_family = parcelMsg.ReadInt16();
90 node->ai_socktype = parcelMsg.ReadInt16();
91 node->ai_protocol = parcelMsg.ReadInt16();
92 node->ai_addrlen = static_cast<socklen_t>(parcelMsg.ReadUint32());
93 int16_t canSize = parcelMsg.ReadInt16();
94 node->ai_canonname = nullptr;
95 const uint8_t *buffer = canSize > 0 ? static_cast<const uint8_t *>(parcelMsg.ReadRawData(canSize)) : nullptr;
96 if (buffer != nullptr) {
97 node->ai_canonname = static_cast<char *>(calloc(sizeof(char), (canSize + 1)));
98 if (memcpy_s(node->ai_canonname, canSize, buffer, canSize) != 0) {
99 NETNATIVE_LOGE("memcpy_s faild");
100 return false;
101 }
102 }
103 node->ai_addr = nullptr;
104 const sockaddr *aiAddr = static_cast<sockaddr *>(const_cast<void *>(parcelMsg.ReadRawData(node->ai_addrlen)));
105
106 if (aiAddr) {
107 node->ai_addr = static_cast<sockaddr *>(calloc(1, node->ai_addrlen + 1));
108 if (memcpy_s(node->ai_addr, node->ai_addrlen, aiAddr, node->ai_addrlen) != 0) {
109 NETNATIVE_LOGE("memcpy_s faild");
110 return false;
111 }
112 }
113 node->ai_next = nullptr;
114 if (count == 0) {
115 headNode = node;
116 nextNode = headNode;
117 } else {
118 nextNode->ai_next = node;
119 nextNode = node;
120 }
121 count++;
122 }
123 return true;
124 }
125
126 } // namespace NetsysNative
127 } // namespace OHOS
128