VirtualBox

source: vbox/trunk/src/apps/adpctl/VBoxNetAdpCtl.cpp@ 17805

Last change on this file since 17805 was 17805, checked in by vboxsync, 16 years ago

VBoxNetAdpCtl fix for Darwin build burns.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.5 KB
Line 
1/* $Id: VBoxNetAdpCtl.cpp 17805 2009-03-13 11:02:48Z vboxsync $ */
2/** @file
3 * Apps - VBoxAdpCtl, Configuration tool for vboxnetX adapters.
4 */
5
6/*
7 * Copyright (C) 2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#include <assert.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32#include <sys/wait.h>
33
34#define VBOXADPCTL_IFCONFIG_PATH "/sbin/ifconfig"
35
36static void showUsage(void)
37{
38 fprintf(stderr, "Usage: VBoxNetAdpCtl <adapter> <address> ([netmask <address>] | remove)\n");
39}
40
41static int executeIfconfig(const char *pcszAdapterName, const char *pcszArg1,
42 const char *pcszArg2 = NULL,
43 const char *pcszArg3 = NULL,
44 const char *pcszArg4 = NULL)
45{
46 const char * const argv[] =
47 {
48 VBOXADPCTL_IFCONFIG_PATH,
49 pcszAdapterName,
50 pcszArg1, /* [address family] */
51 pcszArg2, /* address */
52 pcszArg3, /* ['netmask'] */
53 pcszArg4, /* [network mask] */
54 NULL /* terminator */
55 };
56 int rc = EXIT_SUCCESS;
57 pid_t childPid = fork();
58 switch (childPid)
59 {
60 case -1: /* Something went wrong. */
61 perror("fork() failed");
62 rc = EXIT_FAILURE;
63 break;
64 case 0: /* Child process. */
65 if (execv(VBOXADPCTL_IFCONFIG_PATH, (char * const*)argv) == -1)
66 rc = EXIT_FAILURE;
67 break;
68 default: /* Parent process. */
69 waitpid(childPid, &rc, 0);
70 break;
71 }
72
73 return rc;
74}
75
76#define MAX_ADDRESSES 128
77#define MAX_ADDRLEN 64
78
79static bool removeAddresses(const char *pszAdapterName)
80{
81 char szCmd[1024], szBuf[1024];
82 char aszAddresses[MAX_ADDRESSES][MAX_ADDRLEN];
83
84 memset(aszAddresses, 0, sizeof(aszAddresses));
85 snprintf(szCmd, sizeof(szCmd), VBOXADPCTL_IFCONFIG_PATH " %s", pszAdapterName);
86 FILE *fp = popen(szCmd, "r");
87
88 if (!fp)
89 return false;
90
91 int cAddrs;
92 for (cAddrs = 0; cAddrs < MAX_ADDRESSES && fgets(szBuf, sizeof(szBuf), fp);)
93 {
94 int cbSkipWS = strspn(szBuf, " \t");
95 assert(cbSkipWS < 20);
96 char *pszWord = strtok(szBuf + cbSkipWS, " ");
97 /* We are concerned with IPv6 address lines only. */
98 if (!pszWord || strcmp(pszWord, "inet6"))
99 continue;
100 pszWord = strtok(NULL, " ");
101 /* Skip link-local addresses. */
102 if (!pszWord || !strncmp(pszWord, "fe80", 4))
103 continue;
104 strncpy(aszAddresses[cAddrs++], pszWord, MAX_ADDRLEN-1);
105 }
106 pclose(fp);
107
108 for (int i = 0; i < cAddrs; i++)
109 {
110 if (executeIfconfig(pszAdapterName, "inet6", aszAddresses[i], "remove") != EXIT_SUCCESS)
111 return false;
112 }
113
114 return true;
115}
116
117
118int main(int argc, char *argv[])
119
120{
121 const char *pszAdapterName;
122 const char *pszAddress;
123 const char *pszNetworkMask = NULL;
124 const char *pszOption = NULL;
125 int rc = EXIT_SUCCESS;
126
127 switch (argc)
128 {
129 case 5:
130 if (strcmp("netmask", argv[3]))
131 {
132 fprintf(stderr, "Invalid argument: %s\n\n", argv[3]);
133 showUsage();
134 return 1;
135 }
136 pszOption = "netmask";
137 pszNetworkMask = argv[4];
138 pszAdapterName = argv[1];
139 pszAddress = argv[2];
140 break;
141 case 4:
142 if (strcmp("remove", argv[3]))
143 {
144 fprintf(stderr, "Invalid argument: %s\n\n", argv[3]);
145 showUsage();
146 return 1;
147 }
148 pszOption = "remove";
149 pszAdapterName = argv[1];
150 pszAddress = argv[2];
151 break;
152 case 3:
153 pszAdapterName = argv[1];
154 pszAddress = argv[2];
155 break;
156 default:
157 fprintf(stderr, "Invalid number of arguments.\n\n");
158 /* Fall through */
159 case 1:
160 showUsage();
161 return 1;
162 }
163
164 if (strcmp("vboxnet0", pszAdapterName))
165 {
166 fprintf(stderr, "Setting configuration for %s is not supported.\n", pszAdapterName);
167 return 2;
168 }
169
170 if (strchr(pszAddress, ':'))
171 {
172 /*
173 * Before we set IPv6 address we'd like to remove
174 * all previously assigned addresses except the
175 * self-assigned one.
176 */
177 if (pszOption && !strcmp(pszOption, "remove"))
178 rc = executeIfconfig(pszAdapterName, "inet6", pszAddress, pszOption);
179 else if (!removeAddresses(pszAdapterName))
180 rc = EXIT_FAILURE;
181 else
182 rc = executeIfconfig(pszAdapterName, "inet6", pszAddress, pszOption, pszNetworkMask);
183 }
184 else
185 rc = executeIfconfig(pszAdapterName, pszAddress, pszOption, pszNetworkMask);
186 return rc;
187}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette