1951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen/*
2951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * Copyright (C) 2012 The Android Open Source Project
3951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen *
4951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * Licensed under the Apache License, Version 2.0 (the "License");
5951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * you may not use this file except in compliance with the License.
6951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * You may obtain a copy of the License at
7951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen *
8951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen *      http://www.apache.org/licenses/LICENSE-2.0
9951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen *
10951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * Unless required by applicable law or agreed to in writing, software
11951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * distributed under the License is distributed on an "AS IS" BASIS,
12951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * See the License for the specific language governing permissions and
14951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * limitations under the License.
15951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen */
16951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
17951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#include <arpa/inet.h>
18951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#include <linux/socket.h>
19951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
20951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#include <binder/Parcel.h>
21951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
22951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chennamespace android {
23951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
24951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chenbool canSerializeSockaddr(const struct sockaddr_storage* addr) {
25951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    switch (addr->ss_family) {
26951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        case AF_INET:
27951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        case AF_INET6:
28951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            return true;
29951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        default:
30951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            return false;
31951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    }
32951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}
33951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
34951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chenvoid serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr) {
35951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    switch (addr->ss_family) {
36951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        case AF_INET: {
37951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            const struct sockaddr_in* s =
38951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                reinterpret_cast<const struct sockaddr_in*>(addr);
39951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(AF_INET);
40951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(ntohl(s->sin_addr.s_addr));
41951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(static_cast<int32_t>(ntohs(s->sin_port)));
42951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        } break;
43951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
44951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        case AF_INET6: {
45951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            const struct sockaddr_in6* s =
46951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                reinterpret_cast<const struct sockaddr_in6*>(addr);
47951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            const int32_t* a =
48951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                reinterpret_cast<const int32_t*>(s->sin6_addr.s6_addr);
49951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(AF_INET6);
50951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(ntohl(a[0]));
51951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(ntohl(a[1]));
52951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(ntohl(a[2]));
53951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(ntohl(a[3]));
54951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(static_cast<int32_t>(ntohs(s->sin6_port)));
55951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(ntohl(s->sin6_flowinfo));
56951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            p->writeInt32(ntohl(s->sin6_scope_id));
57951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        } break;
58951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    }
59951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}
60951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
61951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chenvoid deserializeSockaddr(const Parcel* p, struct sockaddr_storage* addr) {
62951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    memset(addr, 0, sizeof(addr));
63951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
64951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    addr->ss_family = p->readInt32();
65951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    switch(addr->ss_family) {
66951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        case AF_INET: {
67951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            struct sockaddr_in* s =
68951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                reinterpret_cast<struct sockaddr_in*>(addr);
69951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            s->sin_addr.s_addr = htonl(p->readInt32());
70951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            s->sin_port = htons(static_cast<uint16_t>(p->readInt32()));
71951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        } break;
72951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
73951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        case AF_INET6: {
74951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            struct sockaddr_in6* s =
75951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                reinterpret_cast<struct sockaddr_in6*>(addr);
76951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            int32_t* a = reinterpret_cast<int32_t*>(s->sin6_addr.s6_addr);
77951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
78951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            a[0] = htonl(p->readInt32());
79951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            a[1] = htonl(p->readInt32());
80951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            a[2] = htonl(p->readInt32());
81951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            a[3] = htonl(p->readInt32());
82951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            s->sin6_port = htons(static_cast<uint16_t>(p->readInt32()));
83951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            s->sin6_flowinfo = htonl(p->readInt32());
84951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            s->sin6_scope_id = htonl(p->readInt32());
85951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        } break;
86951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    }
87951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}
88951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
89951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}  // namespace android
90