VirtualBox

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

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

Linux ip config fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 KB
Line 
1/* $Id: VBoxNetAdpCtl.cpp 17855 2009-03-13 18:28:26Z 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
36#ifdef RT_OS_LINUX
37#define VBOXADPCTL_DEL_CMD "del"
38#else
39#define VBOXADPCTL_DEL_CMD "delete"
40#endif
41
42static void showUsage(void)
43{
44 fprintf(stderr, "Usage: VBoxNetAdpCtl <adapter> <address> ([netmask <address>] | remove)\n");
45}
46
47static int executeIfconfig(const char *pcszAdapterName, const char *pcszArg1,
48 const char *pcszArg2 = NULL,
49 const char *pcszArg3 = NULL,
50 const char *pcszArg4 = NULL,
51 const char *pcszArg5 = NULL)
52{
53 const char * const argv[] =
54 {
55 VBOXADPCTL_IFCONFIG_PATH,
56 pcszAdapterName,
57 pcszArg1, /* [address family] */
58 pcszArg2, /* address */
59 pcszArg3, /* ['netmask'] */
60 pcszArg4, /* [network mask] */
61 pcszArg5, /* [network mask] */
62 NULL /* terminator */
63 };
64 int rc = EXIT_SUCCESS;
65 pid_t childPid = fork();
66 switch (childPid)
67 {
68 case -1: /* Something went wrong. */
69 perror("fork() failed");
70 rc = EXIT_FAILURE;
71 break;
72 case 0: /* Child process. */
73 if (execv(VBOXADPCTL_IFCONFIG_PATH, (char * const*)argv) == -1)
74 rc = EXIT_FAILURE;
75 break;
76 default: /* Parent process. */
77 waitpid(childPid, &rc, 0);
78 break;
79 }
80
81 return rc;
82}
83
84#define MAX_ADDRESSES 128
85#define MAX_ADDRLEN 64
86
87static bool removeAddresses(const char *pszAdapterName)
88{
89 char szCmd[1024], szBuf[1024];
90 char aszAddresses[MAX_ADDRESSES][MAX_ADDRLEN];
91
92 memset(aszAddresses, 0, sizeof(aszAddresses));
93 snprintf(szCmd, sizeof(szCmd), VBOXADPCTL_IFCONFIG_PATH " %s", pszAdapterName);
94 FILE *fp = popen(szCmd, "r");
95
96 if (!fp)
97 return false;
98
99 int cAddrs;
100 for (cAddrs = 0; cAddrs < MAX_ADDRESSES && fgets(szBuf, sizeof(szBuf), fp);)
101 {
102 int cbSkipWS = strspn(szBuf, " \t");
103#if 0 /* Don't use this! assert() breaks the mac build. Use IPRT or be a rectangular building thing. */
104 assert(cbSkipWS < 20);
105#endif
106 char *pszWord = strtok(szBuf + cbSkipWS, " ");
107 /* We are concerned with IPv6 address lines only. */
108 if (!pszWord || strcmp(pszWord, "inet6"))
109 continue;
110#ifdef RT_OS_LINUX
111 pszWord = strtok(NULL, " ");
112 /* Skip "addr:". */
113 if (!pszWord || strcmp(pszWord, "addr:"))
114 continue;
115#endif
116 pszWord = strtok(NULL, " ");
117 /* Skip link-local addresses. */
118 if (!pszWord || !strncmp(pszWord, "fe80", 4))
119 continue;
120 strncpy(aszAddresses[cAddrs++], pszWord, MAX_ADDRLEN-1);
121 }
122 pclose(fp);
123
124 for (int i = 0; i < cAddrs; i++)
125 {
126 if (executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_DEL_CMD, aszAddresses[i]) != EXIT_SUCCESS)
127 return false;
128 }
129
130 return true;
131}
132
133
134int main(int argc, char *argv[])
135
136{
137 const char *pszAdapterName;
138 const char *pszAddress;
139 const char *pszNetworkMask = NULL;
140 const char *pszOption = NULL;
141 int rc = EXIT_SUCCESS;
142 bool fRemove = false;
143
144 switch (argc)
145 {
146 case 5:
147 if (strcmp("netmask", argv[3]))
148 {
149 fprintf(stderr, "Invalid argument: %s\n\n", argv[3]);
150 showUsage();
151 return 1;
152 }
153 pszOption = "netmask";
154 pszNetworkMask = argv[4];
155 pszAdapterName = argv[1];
156 pszAddress = argv[2];
157 break;
158 case 4:
159 if (strcmp("remove", argv[3]))
160 {
161 fprintf(stderr, "Invalid argument: %s\n\n", argv[3]);
162 showUsage();
163 return 1;
164 }
165 fRemove = true;
166 pszAdapterName = argv[1];
167 pszAddress = argv[2];
168 break;
169 case 3:
170 pszAdapterName = argv[1];
171 pszAddress = argv[2];
172 break;
173 default:
174 fprintf(stderr, "Invalid number of arguments.\n\n");
175 /* Fall through */
176 case 1:
177 showUsage();
178 return 1;
179 }
180
181 if (strcmp("vboxnet0", pszAdapterName))
182 {
183 fprintf(stderr, "Setting configuration for %s is not supported.\n", pszAdapterName);
184 return 2;
185 }
186
187 if (fRemove)
188 {
189 if (strchr(pszAddress, ':'))
190 rc = executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_DEL_CMD, pszAddress);
191 else
192 {
193#ifdef RT_OS_LINUX
194 rc = executeIfconfig(pszAdapterName, "0.0.0.0");
195#else
196 rc = executeIfconfig(pszAdapterName, "delete", pszAddress);
197#endif
198 }
199 }
200 else
201 {
202 /* We are setting/replacing address. */
203 if (strchr(pszAddress, ':'))
204 {
205 /*
206 * Before we set IPv6 address we'd like to remove
207 * all previously assigned addresses except the
208 * self-assigned one.
209 */
210 if (!removeAddresses(pszAdapterName))
211 rc = EXIT_FAILURE;
212 else
213 rc = executeIfconfig(pszAdapterName, "inet6", "add", pszAddress, pszOption, pszNetworkMask);
214 }
215 else
216 rc = executeIfconfig(pszAdapterName, pszAddress, pszOption, pszNetworkMask);
217 }
218 return rc;
219}
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