14c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh/*
24c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * Copyright (C) 2010 The Android Open Source Project
34c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh *
44c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License");
54c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * you may not use this file except in compliance with the License.
64c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * You may obtain a copy of the License at
74c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh *
84c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh *      http://www.apache.org/licenses/LICENSE-2.0
94c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh *
104c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software
114c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS,
124c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * See the License for the specific language governing permissions and
144c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh * limitations under the License.
154c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh */
164c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh
174c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh#include <stdio.h>
184c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh#include <string.h>
194c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh#include <arpa/inet.h>
204c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh#include <netinet/in.h>
214c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh
224c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh#include "jni.h"
234c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh#include "JNIHelp.h"
244c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh
254c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yehint parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss)
264c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh{
274c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    if (!jAddress) {
284c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        jniThrowNullPointerException(env, "address");
294c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        return -1;
304c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    }
314c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    if (port < 0 || port > 65535) {
324c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        jniThrowException(env, "java/lang/IllegalArgumentException", "port");
334c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        return -1;
344c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    }
354c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    const char *address = env->GetStringUTFChars(jAddress, NULL);
364c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    if (!address) {
374c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        // Exception already thrown.
384c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        return -1;
394c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    }
404c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    memset(ss, 0, sizeof(*ss));
414c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh
424c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    sockaddr_in *sin = (sockaddr_in *)ss;
434c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    if (inet_pton(AF_INET, address, &(sin->sin_addr)) > 0) {
444c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        sin->sin_family = AF_INET;
454c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        sin->sin_port = htons(port);
464c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        env->ReleaseStringUTFChars(jAddress, address);
474c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        return 0;
484c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    }
494c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh
504c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    sockaddr_in6 *sin6 = (sockaddr_in6 *)ss;
514c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    if (inet_pton(AF_INET6, address, &(sin6->sin6_addr)) > 0) {
524c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        sin6->sin6_family = AF_INET6;
534c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        sin6->sin6_port = htons(port);
544c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        env->ReleaseStringUTFChars(jAddress, address);
554c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh        return 0;
564c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    }
574c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh
584c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    env->ReleaseStringUTFChars(jAddress, address);
594c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    jniThrowException(env, "java/lang/IllegalArgumentException", "address");
604c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh    return -1;
614c5d28cee0537c83ff0e5bc0daaae78f68dfc7c8Chia-chi Yeh}
62