tcpip.c revision 8561
1/* 2 * $Id: tcpip.c,v 1.1 1995/05/16 02:53:28 jkh Exp $ 3 * 4 * Copyright (c) 1995 5 * Gary J Palmer. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer, 12 * verbatim and that no modifications are made prior to this 13 * point in the file. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Gary J Palmer 20 * for the FreeBSD Project. 21 * 4. The name of Gary J Palmer or the FreeBSD Project may not be used to 22 * endorse or promote products derived from this software without specific 23 * prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY GARY J PALMER ``AS IS'' AND ANY EXPRESS 26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL GARY J PALMER BE LIABLE FOR ANY 29 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 * 37 */ 38 39#include <stdio.h> 40#include <stdlib.h> 41#include <unistd.h> 42#include <sys/param.h> 43#include <string.h> 44#include <dialog.h> 45#include "ui_objects.h" 46#include "dir.h" 47#include "dialog.priv.h" 48#include "colors.h" 49#include "rc.h" 50#include "sysinstall.h" 51 52static char hostname[256], domainname[256], 53 gateway[32], nameserver[32], iface[8]; 54static int okbutton, cancelbutton; 55static char ipaddr[32], netmask[32], extras[256]; 56 57#define TCP_DIALOG_Y 0 58#define TCP_DIALOG_X 8 59#define TCP_DIALOG_WIDTH COLS - 16 60#define TCP_DIALOG_HEIGHT LINES - 2 61 62typedef struct _interface { 63 char ipaddr[32]; 64 char netmask[32]; 65 char extras[256]; 66 Device *dev; 67} Interface; 68 69/* The names and details of the available interfaces, for the list */ 70Interface if_list[INTERFACE_MAX]; 71char *iface_names[INTERFACE_MAX]; 72 73typedef struct _layout { 74 int y; 75 int x; 76 int len; 77 int maxlen; 78 char *prompt; 79 char *help; 80 void *var; 81 int type; 82 void *obj; 83} Layout; 84 85static Layout layout[] = { 86{ 1, 2, 25, 255, 87 "Host name:", "The name of your machine on a network, e.g. foo.bar.com", 88 hostname, STRINGOBJ, NULL }, 89{ 1, 35, 20, 255, 90 "Domain name:", 91 "The name of the domain that your machine is in, e.g. bar.com", 92 domainname, STRINGOBJ, NULL }, 93{ 5, 2, 18, 15, 94 "Gateway:", 95 "IP address of host forwarding packets to non-local hosts or nets", 96 gateway, STRINGOBJ, NULL }, 97{ 5, 35, 18, 15, 98 "Name server:", "IP address of your local DNS server", 99 nameserver, STRINGOBJ, NULL }, 100{ 9, 2, 9, 6, 101 "Interface:", "One of potentially several network interfaces", 102 iface, LISTOBJ, NULL }, 103{ 10, 18, 18, 15, 104 "IP Address:", 105 "The IP address to be used for your host - use 127.0.0.1 for loopback", 106 ipaddr, STRINGOBJ, NULL }, 107{ 10, 37, 18, 15, 108 "Netmask:", 109 "The netmask for your network, e.g. 0xffffff00 for a class C network", 110 netmask, STRINGOBJ, NULL }, 111{ 14, 18, 37, 255, 112 "Extra options to ifconfig:", 113 "Any options to ifconfig you'd like to specify manually", 114 extras, STRINGOBJ, NULL }, 115{ 19, 10, 0, 0, 116 "OK", "Select this if you are happy with these settings", 117 &okbutton, BUTTONOBJ, NULL }, 118{ 19, 30, 0, 0, 119 "CANCEL", "Select this if you wish to cancel this screen", 120 &cancelbutton, BUTTONOBJ, NULL }, 121{ NULL }, 122}; 123 124#define _validByte(b) ((b) > 0 && (b) < 255) 125 126static void 127feepout(char *msg) 128{ 129 beep(); 130 dialog_notify(msg); 131} 132 133static int 134verifyIP(char *ip) 135{ 136 int a, b, c, d; 137 138 if (ip && sscanf(ip, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && 139 _validByte(a) && _validByte(b) && _validByte(c) && 140 _validByte(d)) 141 return 1; 142 else 143 return 0; 144} 145 146static int 147verifySettings(void) 148{ 149 if (!hostname[0]) 150 feepout("Must specify a host name of some sort!"); 151 else if (!verifyIP(ipaddr)) 152 feepout("Invalid or missing value for IP address"); 153 else if (gateway[0] && !verifyIP(gateway)) 154 feepout("Invalid gateway IP address specified"); 155 else if (nameserver[0] && !verifyIP(nameserver)) 156 feepout("Invalid name server IP address specified"); 157 else if (netmask[0] < '0' || netmask[0] > '9') 158 feepout("Invalid or missing netmask"); 159 else 160 return 1; 161 return 0; 162} 163 164/* This is it - how to get TCP setup values */ 165int 166tcpOpenDialog(char *str) 167{ 168 WINDOW *ds_win; 169 ComposeObj *obj = NULL; 170 ComposeObj *first, *last; 171 int n=0, quit=FALSE, cancel=FALSE, ret, 172 max, n_iface; 173 char *tmp; 174 Device **devs; 175 char old_iface[8]; 176 177 ds_win = newwin(LINES, COLS, 0, 0); 178 if (ds_win == 0) 179 msgFatal("Cannot open TCP/IP dialog window!!"); 180 181 devs = deviceFind(NULL, DEVICE_TYPE_NETWORK); 182 if (!devs) { 183 msgConfirm("Couldn't find any potential network devices!"); 184 return 0; 185 } 186 187 while (devs[n] != NULL) { 188 iface_names[n] = (devs[n])->name; 189 ++n; 190 } 191 n_iface = --n; 192 193 draw_box(ds_win, TCP_DIALOG_Y, TCP_DIALOG_X, 194 TCP_DIALOG_HEIGHT, TCP_DIALOG_WIDTH, 195 dialog_attr, border_attr); 196 wattrset(ds_win, dialog_attr); 197 mvwaddstr(ds_win, TCP_DIALOG_Y, TCP_DIALOG_X + 20, 198 " Network Configuration "); 199 draw_box(ds_win, TCP_DIALOG_Y + 9, TCP_DIALOG_X + 16, 200 TCP_DIALOG_HEIGHT - 13, TCP_DIALOG_WIDTH - 21, 201 dialog_attr, border_attr); 202 wattrset(ds_win, dialog_attr); 203 mvwaddstr(ds_win, TCP_DIALOG_Y + 9, TCP_DIALOG_X + 24, 204 " Per Interface Configuration "); 205 206 207 strcpy(ipaddr, if_list[0].ipaddr); 208 strcpy(netmask, if_list[0].netmask); 209 strcpy(extras, if_list[0].extras); 210 211 tmp = getenv(VAR_HOSTNAME); 212 if (tmp) 213 strcpy(hostname, tmp); 214 else 215 bzero(hostname, sizeof(hostname)); 216 tmp = getenv(VAR_DOMAINNAME); 217 if (tmp) 218 strcpy(domainname, tmp); 219 else 220 bzero(domainname, sizeof(domainname)); 221 tmp = getenv(VAR_GATEWAY); 222 if (tmp) 223 strcpy(gateway, tmp); 224 else 225 bzero(gateway, sizeof(gateway)); 226 tmp = getenv(VAR_NAMESERVER); 227 if (tmp) 228 strcpy(nameserver, tmp); 229 else 230 bzero(nameserver, sizeof(nameserver)); 231 232 n = 0; 233#define lt layout[n] 234 while (lt.help != NULL) { 235 switch (lt.type) { 236 case STRINGOBJ: 237 lt.obj = NewStringObj(ds_win, lt.prompt, lt.var, 238 lt.y + TCP_DIALOG_Y, lt.x + TCP_DIALOG_X, 239 lt.len, lt.maxlen); 240 break; 241 242 case BUTTONOBJ: 243 lt.obj = NewButtonObj(ds_win, lt.prompt, lt.var, 244 lt.y + TCP_DIALOG_Y, lt.x + TCP_DIALOG_X); 245 break; 246 247 case LISTOBJ: 248 lt.obj = NewListObj(ds_win, lt.prompt, (char **) iface_names, 249 lt.var, lt.y + TCP_DIALOG_Y, 250 lt.x + TCP_DIALOG_X, lt.len, 12, n_iface); 251 break; 252 default: 253 msgFatal("Don't support this object yet!"); 254 } 255 AddObj(&obj, lt.type, (void *) lt.obj); 256 n++; 257 } 258 max = n - 1; 259 260 last = obj; 261 while (last->next) 262 last = last->next; 263 264 /* find the first object in the list */ 265 first = obj; 266 while (first->prev) 267 first = first->prev; 268 269 n = 0; 270 cancelbutton = okbutton = 0; 271 strcpy(iface, iface_names[0]); 272 strcpy(old_iface, iface); 273 274 while (!quit) { 275 char help_line[80]; 276 int i, len = strlen(lt.help); 277 278 for (i = 0; i < 79; i++) 279 help_line[i] = (i < len) ? lt.help[i] : ' '; 280 help_line[i] = '\0'; 281 use_helpline(help_line); 282 display_helpline(ds_win, LINES - 1, COLS - 1); 283 284 ret = PollObj(&obj); 285 286 switch (ret) { 287 case SEL_ESC: 288 quit = TRUE, cancel=TRUE; 289 break; 290 291 case KEY_UP: 292 if (obj->prev !=NULL ) { 293 obj = obj->prev; 294 --n; 295 } else { 296 obj = last; 297 n = max; 298 } 299 break; 300 301 case KEY_DOWN: 302 if (n == 7) { 303 n = 4; 304 obj = (((first->next)->next)->next)->next; 305 } else if (obj->next != NULL) { 306 obj = obj->next; 307 ++n; 308 } else { 309 obj = first; 310 n = 0; 311 } 312 break; 313 314 case SEL_TAB: 315 if (n == 7) { 316 n = 4; 317 obj = (((first->next)->next)->next)->next; 318 } else if (obj->next != NULL) { 319 ++n; 320 } else { 321 n = 0; 322 } 323 if (n == 5) { 324 n = 8; 325 obj = ((obj->next)->next)->next; 326 } 327 break; 328 329 case SEL_BUTTON: 330 if (cancelbutton) { 331 cancel = TRUE, quit = TRUE; 332 } else { 333 if (verifySettings()) 334 quit = TRUE; 335 } 336 break; 337 338 case SEL_CR: 339 if (strcmp(old_iface, iface)) { 340 /* First, find the old value */ 341 n_iface = 0; 342 while (strcmp(old_iface, iface_names[n_iface]) && 343 (iface_names[n_iface] != NULL)) 344 ++n_iface; 345 346 if (iface_names[n_iface] == NULL) 347 msgFatal("Erk - run off the end of the list of interfaces!"); 348 strcpy(if_list[n_iface].ipaddr, ipaddr); 349 strcpy(if_list[n_iface].netmask, netmask); 350 strcpy(if_list[n_iface].extras, extras); 351 352 /* Now go find the new location */ 353 n_iface = 0; 354 while (strcmp(iface, iface_names[n_iface]) && 355 (iface_names[n_iface] != NULL)) 356 ++n_iface; 357 if (iface_names[n_iface] == NULL) 358 msgFatal("Erk - run off the end of the list of interfaces!"); 359 strcpy(ipaddr, if_list[n_iface].ipaddr); 360 strcpy(netmask, if_list[n_iface].netmask); 361 strcpy(extras, if_list[n_iface].extras); 362 363 RefreshStringObj(layout[5].obj); 364 RefreshStringObj(layout[6].obj); 365 RefreshStringObj(layout[7].obj); 366 367 strcpy(old_iface, iface); 368 } 369 370 if (n == 7) { 371 n = 4; 372 obj = (((first->next)->next)->next)->next; 373 } else if (n < max) 374 ++n; 375 else 376 n = 0; 377 break; 378 379 case SEL_BACKTAB: 380 if (n) 381 --n; 382 else 383 n = max; 384 break; 385 386 default: 387 beep(); 388 } 389 390 if (n == 1) { 391 if ((tmp = index(hostname, '.')) != NULL) { 392 strncpy(domainname, tmp + 1, strlen(tmp + 1)); 393 domainname[strlen(tmp+1)] = '\0'; 394 RefreshStringObj(layout[1].obj); 395 } 396 } 397 } 398 399 dialog_clear(); 400 refresh(); 401 402 if (!cancel) { 403 variable_set2(VAR_HOSTNAME, hostname); 404 variable_set2(VAR_DOMAINNAME, domainname); 405 if (gateway[0]) 406 variable_set2(VAR_GATEWAY, gateway); 407 if (nameserver[0]) 408 variable_set2(VAR_NAMESERVER, nameserver); 409 return 1; 410 } 411 412 return 0; 413} 414