]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - tools/tools/vimage/vimage.c
Copy head to stable/8 as part of 8.0 Release cycle.
[FreeBSD/stable/8.git] / tools / tools / vimage / vimage.c
1 /*
2  * Copyright (c) 2002-2004 Marko Zec <zec@fer.hr>
3  * Copyright (c) 2009 University of Zagreb
4  * Copyright (c) 2009 FreeBSD Foundation
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/ioctl.h>
33 #include <sys/jail.h>
34 #include <sys/socket.h>
35
36 #include <net/if.h>
37
38 #include <errno.h>
39 #include <jail.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44
45 #define VI_CREATE               0x00000001
46 #define VI_DESTROY              0x00000002
47 #define VI_SWITCHTO             0x00000008
48 #define VI_IFACE                0x00000010
49 #define VI_GET                  0x00000100
50 #define VI_GETNEXT              0x00000200
51
52 static int getjail(char *name, int lastjid, int *vnet);
53
54 int
55 main(int argc, char **argv)
56 {
57         int s;
58         char *shell;
59         int cmd;
60         int jid, vnet;
61         struct ifreq ifreq;
62         char name[MAXHOSTNAMELEN];
63
64         switch (argc) {
65
66         case 1:
67                 cmd = 0;
68                 break;
69
70         case 2:
71                 if (strcmp(argv[1], "-l") == 0)
72                         cmd = VI_GETNEXT;
73                 else if (strcmp(argv[1], "-lr") == 0)
74                         cmd = VI_GETNEXT;
75                 else {
76                         strcpy(name, argv[1]);
77                         cmd = VI_SWITCHTO;
78                 }
79                 break;
80
81         case 3:
82                 strcpy(name, argv[2]);
83                 if (strcmp(argv[1], "-l") == 0)
84                         cmd = VI_GET;
85                 if (strcmp(argv[1], "-c") == 0)
86                         cmd = VI_CREATE;
87                 if (strcmp(argv[1], "-d") == 0)
88                         cmd = VI_DESTROY;
89                 break;
90
91         default:
92                 strcpy(name, argv[2]);
93                 if (strcmp(argv[1], "-c") == 0)
94                         cmd = VI_CREATE;
95                 if (strcmp(argv[1], "-i") == 0)
96                         cmd = VI_IFACE;
97         }
98
99         switch (cmd) {
100
101         case VI_GET:
102                 jid = getjail(name, -1, &vnet);
103                 if (jid < 0)
104                         goto abort;
105                 printf("%d: %s%s\n", jid, name, vnet ? "" : " (no vnet)");
106                 exit(0);
107
108         case VI_GETNEXT:
109                 jid = 0;
110                 while ((jid = getjail(name, jid, &vnet)) > 0)
111                         printf("%d: %s%s\n", jid, name,
112                             vnet ? "" : " (no vnet)");
113                 exit(0);
114
115         case VI_IFACE:
116                 s = socket(AF_INET, SOCK_DGRAM, 0);
117                 if (s == -1)
118                         goto abort;
119                 jid = jail_getid(name);
120                 if (jid < 0)
121                         goto abort;
122                 ifreq.ifr_jid = jid;
123                 strncpy(ifreq.ifr_name, argv[3], sizeof(ifreq.ifr_name));
124                 if (ioctl(s, SIOCSIFVNET, (caddr_t)&ifreq) < 0)
125                         goto abort;
126                 printf("%s@%s\n", ifreq.ifr_name, name);
127                 exit(0);
128
129         case VI_CREATE:
130                 if (jail_setv(JAIL_CREATE, "name", name, "vnet", NULL,
131                     "host", NULL, "persist", NULL, NULL) < 0)
132                         goto abort;
133                 exit(0);
134
135         case VI_SWITCHTO:
136                 jid = jail_getid(name);
137                 if (jid < 0)
138                         goto abort;
139                 if (jail_attach(jid) < 0)
140                         goto abort;
141
142                 if (argc == 2) {
143                         printf("Switched to jail %s\n", argv[1]);
144                         if ((shell = getenv("SHELL")) == NULL)
145                                 execlp("/bin/sh", argv[0], NULL);
146                         else
147                                 execlp(shell, argv[0], NULL);
148                 } else 
149                         execvp(argv[2], &argv[2]);
150                 break;
151
152         case VI_DESTROY:
153                 jid = jail_getid(name);
154                 if (jid < 0)
155                         goto abort;
156                 if (jail_remove(jid) < 0)
157                         goto abort;
158                 exit(0);
159
160         default:
161                 fprintf(stderr, "usage: %s [-cdilr] vi_name [args]\n",
162                     argv[0]);
163                 exit(1);
164         }
165
166 abort:
167         if (jail_errmsg[0])
168                 fprintf(stderr, "Error: %s\n", jail_errmsg);
169         else
170                 perror("Error");
171         exit(1);
172 }
173
174 static int
175 getjail(char *name, int lastjid, int *vnet)
176 {
177         struct jailparam params[3];
178         int jid;
179
180         if (lastjid < 0) {
181                 jid = jail_getid(name);
182                 if (jid < 0)
183                         return (jid);
184                 jailparam_init(&params[0], "jid");
185                 jailparam_import_raw(&params[0], &jid, sizeof jid);
186         } else {
187                 jailparam_init(&params[0], "lastjid");
188                 jailparam_import_raw(&params[0], &lastjid, sizeof lastjid);
189         }
190         jailparam_init(&params[1], "name");
191         jailparam_import_raw(&params[1], name, MAXHOSTNAMELEN);
192         name[0] = 0;
193         jailparam_init(&params[2], "vnet");
194         jailparam_import_raw(&params[2], vnet, sizeof(*vnet));
195         jid = jailparam_get(params, 3, 0);
196         jailparam_free(params, 3);
197         return (jid);
198 }