/* * * Connection Manager * * Copyright (C) 2012 Intel Corporation. All rights reserved. * Copyright (C) 2011 ProFUSION embedded systems * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #define CONNMAN_SERVICE "net.connman" #define MANAGER_PATH "/" #define MANAGER_INTERFACE CONNMAN_SERVICE ".Manager" #include #include #include #include #include #include #include #include #include #include #include #ifndef DBUS_TYPE_UNIX_FD #define DBUS_TYPE_UNIX_FD -1 #endif static int release_private_network(DBusConnection *conn) { DBusMessage *msg, *reply; DBusError error; msg = dbus_message_new_method_call(CONNMAN_SERVICE, MANAGER_PATH, MANAGER_INTERFACE, "ReleasePrivateNetwork"); dbus_error_init(&error); printf("Releasing private-network...\n"); reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error); dbus_message_unref(msg); if (!reply) { if (dbus_error_is_set(&error)) { fprintf(stderr, "1. %s\n", error.message); dbus_error_free(&error); } else { fprintf(stderr, "Release() failed"); } return -1; } return 0; } static void request_private_network(DBusConnection *conn, int *out_fd, char **out_server_ip, char **out_peer_ip, char **out_primary_dns, char **out_secondary_dns) { DBusMessageIter array, dict, entry; DBusMessage *msg, *reply; DBusError error; msg = dbus_message_new_method_call(CONNMAN_SERVICE, MANAGER_PATH, MANAGER_INTERFACE, "RequestPrivateNetwork"); dbus_error_init(&error); printf("Requesting private-network...\n"); reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error); dbus_message_unref(msg); if (!reply) { if (dbus_error_is_set(&error)) { fprintf(stderr, "1. %s\n", error.message); dbus_error_free(&error); } else { fprintf(stderr, "Request() failed"); } return; } if (!dbus_message_iter_init(reply, &array)) goto done; if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_UNIX_FD) goto done; dbus_message_iter_get_basic(&array, out_fd); printf("Fildescriptor = %d\n", *out_fd); dbus_message_iter_next(&array); if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY) goto done; dbus_message_iter_recurse(&array, &dict); while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter iter; const char *key; int type; dbus_message_iter_recurse(&dict, &entry); dbus_message_iter_get_basic(&entry, &key); printf("key %s", key); dbus_message_iter_next(&entry); dbus_message_iter_recurse(&entry, &iter); type = dbus_message_iter_get_arg_type(&iter); if (type != DBUS_TYPE_STRING) break; if (g_str_equal(key, "ServerIPv4") && type == DBUS_TYPE_STRING) { dbus_message_iter_get_basic(&iter, out_server_ip); printf(" = %s\n", *out_server_ip); } else if (g_str_equal(key, "PeerIPv4") && type == DBUS_TYPE_STRING) { dbus_message_iter_get_basic(&iter, out_peer_ip); printf(" = %s\n", *out_peer_ip); } else if (g_str_equal(key, "PrimaryDNS") && type == DBUS_TYPE_STRING) { dbus_message_iter_get_basic(&iter, out_primary_dns); printf(" = %s\n", *out_primary_dns); } else if (g_str_equal(key, "SecondaryDNS") && type == DBUS_TYPE_STRING) { dbus_message_iter_get_basic(&iter, out_secondary_dns); printf(" = %s\n", *out_secondary_dns); } dbus_message_iter_next(&dict); } done: dbus_message_unref(reply); } int main(int argc, char *argv[]) { DBusConnection *conn; int fd = -1; char *server_ip; char *peer_ip; char *primary_dns; char *secondary_dns; /* * IP packet: src: 192.168.219.2 dst www.connman.net * HTTP GET / request */ int buf1[81] = { 0x45, 0x00, 0x00, 0x51, 0x5a, 0xbe, 0x00, 0x00, 0x40, 0x06, 0x50, 0x73, 0xc0, 0xa8, 0xdb, 0x01, 0x3e, 0x4b, 0xf5, 0x80, 0x30, 0x3b, 0x00, 0x50, 0x00, 0x00, 0x00, 0x28, 0x04, 0xfd, 0xac, 0x9b, 0x50, 0x18, 0x02, 0x00, 0xa1, 0xb3, 0x00, 0x00, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x6d, 0x61, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x0d, 0x0a, 0x0d, 0x0a}; int buf2[81] = { 0x45, 0x00, 0x00, 0x51, 0x57, 0x9d, 0x00, 0x00, 0x40, 0x06, 0x53, 0x93, 0xc0, 0xa8, 0xdb, 0x02, 0x3e, 0x4b, 0xf5, 0x80, 0x30, 0x3b, 0x00, 0x50, 0x00, 0x00, 0x00, 0x28, 0x17, 0xdb, 0x2e, 0x6d, 0x50, 0x18, 0x02, 0x00, 0x0d, 0x03, 0x00, 0x00, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x6d, 0x61, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x0d, 0x0a, 0x0d, 0x0a}; if (DBUS_TYPE_UNIX_FD < 0) { fprintf(stderr, "File-descriptor passing not supported\n"); exit(1); } conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); if (!conn) { fprintf(stderr, "Can't get on system bus\n"); exit(1); } request_private_network(conn, &fd, &server_ip, &peer_ip, &primary_dns, &secondary_dns); if (fd < 0) return -1; fcntl(fd, F_SETFL, O_NONBLOCK); printf("Press ENTER to write data to the network.\n"); getchar(); if (!fork()) { if (write(fd, buf1, sizeof(buf1)) < 0) { fprintf(stderr, "err on write() buf1\n"); return -1; } if (write(fd, buf2, sizeof(buf2)) < 0) { fprintf(stderr, "err on write() buf2\n"); return -1; } printf("Press ENTER to release private network.\n"); getchar(); if (release_private_network(conn) < 0) return -1; close(fd); dbus_connection_unref(conn); } else { struct pollfd p; char buf[1500]; int len; p.fd = fd; p.events = POLLIN | POLLERR | POLLHUP; while (1) { p.revents = 0; if (poll(&p, 1, -1) <= 0) return -1; if (p.revents & (POLLERR | POLLHUP)) return -1; len = read(fd, buf, sizeof(buf)); if (len < 0) return -1; printf("%d bytes received\n", len); } } return 0; }