1 /* SmoothWall libsmooth.
3 * This program is distributed under the terms of the GNU General Public
4 * Licence. See the file COPYING for details.
6 * (c) Lawrence Manning, 2001
7 * Contains network library functions.
11 #include "libsmooth.h"
19 newtComponent networkform
;
20 newtComponent addressentry
;
21 newtComponent netmaskentry
;
22 newtComponent statictyperadio
;
23 newtComponent dhcptyperadio
;
24 newtComponent pppoetyperadio
;
25 newtComponent pptptyperadio
;
26 newtComponent dhcphostnameentry
;
28 /* acceptable character filter for IP and netmaks entry boxes */
29 static int ip_input_filter(newtComponent entry
, void * data
, int ch
, int cursor
)
31 if ((ch
>= '0' && ch
<= '9') || ch
== '.' || ch
== '\r' || ch
>= NEWT_KEY_EXTRA_BASE
)
36 /* This is a groovie dialog for showing network info. Takes a keyvalue list,
37 * a colour and a dhcp flag. Shows the current settings, and rewrites them
38 * if necessary. DHCP flag sets wether to show the dhcp checkbox. */
39 int changeaddress(struct keyvalue
*kv
, char *colour
, int typeflag
,
40 char *defaultdhcphostname
)
44 char *dhcphostnameresult
;
45 struct newtExitStruct es
;
47 newtComponent addresslabel
;
48 newtComponent netmasklabel
;
49 newtComponent dhcphostnamelabel
;
50 newtComponent ok
, cancel
;
52 char temp
[STRING_SIZE
];
53 char addressfield
[STRING_SIZE
];
54 char netmaskfield
[STRING_SIZE
];
55 char typefield
[STRING_SIZE
];
56 char dhcphostnamefield
[STRING_SIZE
];
59 char type
[STRING_SIZE
];
60 int startstatictype
= 0;
61 int startdhcptype
= 0;
62 int startpppoetype
= 0;
63 int startpptptype
= 0;
65 /* Build some key strings. */
66 sprintf(addressfield
, "%s_ADDRESS", colour
);
67 sprintf(netmaskfield
, "%s_NETMASK", colour
);
68 sprintf(typefield
, "%s_TYPE", colour
);
69 sprintf(dhcphostnamefield
, "%s_DHCP_HOSTNAME", colour
);
71 sprintf(message
, ctr
[TR_INTERFACE
], colour
);
72 newtCenteredWindow(44, (typeflag
? 18 : 12), message
);
74 networkform
= newtForm(NULL
, NULL
, 0);
76 sprintf(message
, ctr
[TR_ENTER_THE_IP_ADDRESS_INFORMATION
], colour
);
77 header
= newtTextboxReflowed(1, 1, message
, 42, 0, 0, 0);
78 newtFormAddComponent(networkform
, header
);
80 /* See if we need a dhcp checkbox. If we do, then we shift the contents
81 * of the window down two rows to make room. */
84 strcpy(temp
, "STATIC"); findkey(kv
, typefield
, temp
);
85 if (strcmp(temp
, "STATIC") == 0) startstatictype
= 1;
86 if (strcmp(temp
, "DHCP") == 0) startdhcptype
= 1;
87 if (strcmp(temp
, "PPPOE") == 0) startpppoetype
= 1;
88 if (strcmp(temp
, "PPTP") == 0) startpptptype
= 1;
89 statictyperadio
= newtRadiobutton(2, 4, ctr
[TR_STATIC
], startstatictype
, NULL
);
90 dhcptyperadio
= newtRadiobutton(2, 5, "DHCP", startdhcptype
, statictyperadio
);
91 pppoetyperadio
= newtRadiobutton(2, 6, "PPPOE", startpppoetype
, dhcptyperadio
);
92 pptptyperadio
= newtRadiobutton(2, 7, "PPTP", startpptptype
, pppoetyperadio
);
93 newtFormAddComponents(networkform
, statictyperadio
, dhcptyperadio
,
94 pppoetyperadio
, pptptyperadio
, NULL
);
95 newtComponentAddCallback(statictyperadio
, networkdialogcallbacktype
, NULL
);
96 newtComponentAddCallback(dhcptyperadio
, networkdialogcallbacktype
, NULL
);
97 newtComponentAddCallback(pppoetyperadio
, networkdialogcallbacktype
, NULL
);
98 newtComponentAddCallback(pptptyperadio
, networkdialogcallbacktype
, NULL
);
99 dhcphostnamelabel
= newtTextbox(2, 9, 18, 1, 0);
100 newtTextboxSetText(dhcphostnamelabel
, ctr
[TR_DHCP_HOSTNAME
]);
101 strcpy(temp
, defaultdhcphostname
);
102 findkey(kv
, dhcphostnamefield
, temp
);
103 dhcphostnameentry
= newtEntry(20, 9, temp
, 20, &dhcphostnameresult
, 0);
104 newtFormAddComponent(networkform
, dhcphostnamelabel
);
105 newtFormAddComponent(networkform
, dhcphostnameentry
);
106 if (startdhcptype
== 0)
107 newtEntrySetFlags(dhcphostnameentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
110 addresslabel
= newtTextbox(2, (typeflag
? 11 : 4) + 0, 18, 1, 0);
111 newtTextboxSetText(addresslabel
, ctr
[TR_IP_ADDRESS_PROMPT
]);
113 findkey(kv
, addressfield
, temp
);
114 addressentry
= newtEntry(20, (typeflag
? 11 : 4) + 0, temp
, 20, &addressresult
, 0);
115 newtEntrySetFilter(addressentry
, ip_input_filter
, NULL
);
116 if (typeflag
== 1 && startstatictype
== 0 && startpptptype
== 0 )
117 newtEntrySetFlags(addressentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
118 newtFormAddComponent(networkform
, addresslabel
);
119 newtFormAddComponent(networkform
, addressentry
);
122 netmasklabel
= newtTextbox(2, (typeflag
? 11 : 4) + 1, 18, 1, 0);
123 newtTextboxSetText(netmasklabel
, ctr
[TR_NETMASK_PROMPT
]);
124 strcpy(temp
, "255.255.255.0"); findkey(kv
, netmaskfield
, temp
);
125 netmaskentry
= newtEntry(20, (typeflag
? 11 : 4) + 1, temp
, 20, &netmaskresult
, 0);
126 newtEntrySetFilter(netmaskentry
, ip_input_filter
, NULL
);
127 if (typeflag
== 1 && startstatictype
== 0 && startpptptype
== 0 )
128 newtEntrySetFlags(netmaskentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
130 newtFormAddComponent(networkform
, netmasklabel
);
131 newtFormAddComponent(networkform
, netmaskentry
);
134 ok
= newtButton(8, (typeflag
? 14 : 7), ctr
[TR_OK
]);
135 cancel
= newtButton(26, (typeflag
? 14 : 7), ctr
[TR_CANCEL
]);
137 newtFormAddComponents(networkform
, ok
, cancel
, NULL
);
140 newtDrawForm(networkform
);
145 newtFormRun(networkform
, &es
);
149 /* OK was pressed; verify the contents of each entry. */
150 strcpy(message
, ctr
[TR_INVALID_FIELDS
]);
152 strcpy(type
, "STATIC");
155 if (strcmp(type
, "STATIC") == 0 || strcmp(type
, "PPTP") == 0 )
157 if (inet_addr(addressresult
) == INADDR_NONE
)
159 strcat(message
, ctr
[TR_IP_ADDRESS_CR
]);
162 if (inet_addr(netmaskresult
) == INADDR_NONE
)
164 strcat(message
, ctr
[TR_NETWORK_MASK_CR
]);
168 if (strcmp(type
, "DHCP") == 0)
170 if (!strlen(dhcphostnameresult
))
172 strcat(message
, ctr
[TR_DHCP_HOSTNAME_CR
]);
180 /* No errors! Set new values, depending on dhcp flag etc. */
183 replacekeyvalue(kv
, dhcphostnamefield
, dhcphostnameresult
);
184 if (strcmp(type
, "STATIC") != 0 && strcmp(type
, "PPTP") != 0)
186 replacekeyvalue(kv
, addressfield
, "0.0.0.0");
187 replacekeyvalue(kv
, netmaskfield
, "0.0.0.0");
191 replacekeyvalue(kv
, addressfield
, addressresult
);
192 replacekeyvalue(kv
, netmaskfield
, netmaskresult
);
194 replacekeyvalue(kv
, typefield
, type
);
198 replacekeyvalue(kv
, addressfield
, addressresult
);
199 replacekeyvalue(kv
, netmaskfield
, netmaskresult
);
202 setnetaddress(kv
, colour
);
209 newtFormDestroy(networkform
);
215 /* for pppoe: return string thats type STATIC, DHCP or PPPOE */
216 int gettype(char *type
)
218 newtComponent selected
= newtRadioGetCurrent(statictyperadio
);
220 if (selected
== statictyperadio
)
221 strcpy(type
, "STATIC");
222 else if (selected
== dhcptyperadio
)
223 strcpy(type
, "DHCP");
224 else if (selected
== pppoetyperadio
)
225 strcpy(type
, "PPPOE");
226 else if (selected
== pptptyperadio
)
227 strcpy(type
, "PPTP");
229 strcpy(type
, "ERROR");
234 /* 0.9.9: calculates broadcast too. */
235 int setnetaddress(struct keyvalue
*kv
, char *colour
)
237 char addressfield
[STRING_SIZE
];
238 char netaddressfield
[STRING_SIZE
];
239 char netmaskfield
[STRING_SIZE
];
240 char broadcastfield
[STRING_SIZE
];
241 char address
[STRING_SIZE
];
242 char netmask
[STRING_SIZE
];
243 unsigned long int intaddress
;
244 unsigned long int intnetaddress
;
245 unsigned long int intnetmask
;
246 unsigned long int intbroadcast
;
251 /* Build some key strings. */
252 sprintf(addressfield
, "%s_ADDRESS", colour
);
253 sprintf(netaddressfield
, "%s_NETADDRESS", colour
);
254 sprintf(netmaskfield
, "%s_NETMASK", colour
);
255 sprintf(broadcastfield
, "%s_BROADCAST", colour
);
257 strcpy(address
, ""); findkey(kv
, addressfield
, address
);
258 strcpy(netmask
, ""); findkey(kv
, netmaskfield
, netmask
);
260 /* Calculate netaddress. Messy.. */
261 intaddress
= inet_addr(address
);
262 intnetmask
= inet_addr(netmask
);
264 intnetaddress
= intaddress
& intnetmask
;
265 temp
.s_addr
= intnetaddress
;
266 netaddress
= inet_ntoa(temp
);
268 replacekeyvalue(kv
, netaddressfield
, netaddress
);
270 intbroadcast
= intnetaddress
| ~intnetmask
;
271 temp
.s_addr
= intbroadcast
;
272 broadcast
= inet_ntoa(temp
);
274 replacekeyvalue(kv
, broadcastfield
, broadcast
);
279 /* Called when dhcp flag is toggled. Toggle disabled state of other 3
281 void networkdialogcallbacktype(newtComponent cm
, void *data
)
283 char type
[STRING_SIZE
];
287 if (strcmp(type
, "STATIC") != 0 && strcmp(type
, "PPTP") != 0 )
289 newtEntrySetFlags(addressentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
290 newtEntrySetFlags(netmaskentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
294 newtEntrySetFlags(addressentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_RESET
);
295 newtEntrySetFlags(netmaskentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_RESET
);
297 if (strcmp(type
, "DHCP") == 0)
298 newtEntrySetFlags(dhcphostnameentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_RESET
);
300 newtEntrySetFlags(dhcphostnameentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
303 newtDrawForm(networkform
);
306 int interfacecheck(struct keyvalue
*kv
, char *colour
)
308 char temp
[STRING_SIZE
];
309 char colourfields
[NETCHANGE_TOTAL
][STRING_SIZE
];
312 sprintf(colourfields
[ADDRESS
], "%s_ADDRESS", colour
);
313 sprintf(colourfields
[NETADDRESS
], "%s_NETADDRESS", colour
);
314 sprintf(colourfields
[NETMASK
], "%s_NETMASK", colour
);
316 for (c
= 0; c
< 3; c
++)
318 strcpy(temp
, ""); findkey(kv
, colourfields
[c
], temp
);
319 if (!(strlen(temp
))) return 0;
324 /* Funky routine for loading all drivers (cept those are already loaded.). */
325 int probecards(char *driver
, char *driveroptions
)
330 char *strupper(char *s
)
333 for (n
=0;s
[n
];n
++) s
[n
]=toupper(s
[n
]);
338 int write_configs_netudev(char *description
, char *macaddr
, char *colour
)
340 #define UDEV_NET_CONF "/etc/udev/rules.d/30-persistent-network.rules"
343 char commandstring
[STRING_SIZE
];
344 struct keyvalue
*kv
= initkeyvalues();
345 char temp1
[STRING_SIZE
], temp2
[STRING_SIZE
], temp3
[STRING_SIZE
];
346 char ucolour
[STRING_SIZE
];
348 sprintf(ucolour
, colour
);
351 if (!(readkeyvalues(kv
, CONFIG_ROOT
"/ethernet/settings")))
354 errorbox(ctr
[TR_UNABLE_TO_OPEN_SETTINGS_FILE
]);
358 sprintf(temp1
, "%s_DEV", ucolour
);
359 sprintf(temp2
, "%s_MACADDR", ucolour
);
360 sprintf(temp3
, "%s0", colour
);
361 replacekeyvalue(kv
, temp1
, temp3
);
362 replacekeyvalue(kv
, temp2
, macaddr
);
364 writekeyvalues(kv
, CONFIG_ROOT
"/ethernet/settings");
367 if( (fp
= fopen(KNOWN_NICS
, "a")) == NULL
)
369 fprintf(stderr
,"Couldn't open "KNOWN_NICS
);
372 fprintf(fp
,"%s;%s;\n", description
, macaddr
);
375 // Make sure that there is no conflict
376 snprintf(commandstring
, STRING_SIZE
, "/usr/bin/touch "UDEV_NET_CONF
" >/dev/null 2>&1");
377 system(commandstring
);
378 snprintf(commandstring
, STRING_SIZE
, "/bin/cat "UDEV_NET_CONF
" | /bin/grep -v \"%s\" > "UDEV_NET_CONF
" 2>/dev/null", macaddr
);
379 system(commandstring
);
380 snprintf(commandstring
, STRING_SIZE
, "/bin/cat "UDEV_NET_CONF
" | /bin/grep -v \"%s\" > "UDEV_NET_CONF
" 2>/dev/null", colour
);
381 system(commandstring
);
383 if( (fp
= fopen(UDEV_NET_CONF
, "a")) == NULL
)
385 fprintf(stderr
,"Couldn't open" UDEV_NET_CONF
);
388 fprintf(fp
,"ACTION==\"add\", SUBSYSTEM==\"net\", SYSFS{address}==\"%s\", NAME=\"%s0\" # %s\n", macaddr
, colour
, description
);
394 int nicmenu(char *colour
)
397 char temp_line
[STRING_SIZE
];
398 struct nic nics
[20], *pnics
;
400 struct knic knics
[20], *pknics
;
402 int rc
, choise
, count
= 0, kcount
= 0, i
, found
;
403 char macaddr
[STRING_SIZE
], description
[STRING_SIZE
];
404 char message
[STRING_SIZE
];
406 char MenuInhalt
[20][80];
407 char *pMenuInhalt
[20];
409 mysystem("/bin/probenic.sh");
411 // Read the nics we already use
412 if((fp
= fopen(KNOWN_NICS
, "r")) == NULL
)
414 fprintf(flog
,"Couldn't open " KNOWN_NICS
);
417 while (fgets(temp_line
, STRING_SIZE
, fp
) != NULL
)
419 strcpy(knics
[kcount
].description
, strtok(temp_line
,";"));
420 strcpy(knics
[kcount
].macaddr
, strtok(NULL
,";"));
421 if (strlen(knics
[kcount
].macaddr
) > 5 ) kcount
++;
425 // Read our scanned nics
426 if( (fp
= fopen(SCANNED_NICS
, "r")) == NULL
)
428 fprintf(stderr
,"Couldn't open "SCANNED_NICS
);
431 while (fgets(temp_line
, STRING_SIZE
, fp
) != NULL
)
433 strcpy(description
, strtok(temp_line
,";"));
434 strcpy(macaddr
, strtok(NULL
,";"));
436 if (strlen(macaddr
) > 5 ) {
437 for (i
=0; i
< kcount
; i
++)
439 // Check if the nic is already in use
440 if (strcmp(pknics
[i
].macaddr
, macaddr
) == NULL
)
447 strcpy( pnics
[count
].description
, description
);
448 strcpy( pnics
[count
].macaddr
, macaddr
);
455 // If new nics are found...
457 char cMenuInhalt
[STRING_SIZE
];
458 for (i
=0 ; i
< count
; i
++)
460 if ( strlen(nics
[i
].description
) < 52 )
461 strncpy(MenuInhalt
[i
], nics
[i
].description
+ 1, strlen(nics
[i
].description
)- 2);
464 strncpy(cMenuInhalt
, nics
[i
].description
+ 1, 50);
465 strncpy(MenuInhalt
[i
], cMenuInhalt
,(strrchr(cMenuInhalt
,' ') - cMenuInhalt
));
466 strcat (MenuInhalt
[i
], "...");
468 while ( strlen(MenuInhalt
[i
]) < 50)
470 strcat( MenuInhalt
[i
], " ");
472 strcat(MenuInhalt
[i
], " (");
473 strcat(MenuInhalt
[i
], nics
[i
].macaddr
);
474 strcat(MenuInhalt
[i
], ")");
475 pMenuInhalt
[i
] = MenuInhalt
[i
];
478 sprintf(message
, "Es wurde(n) %d freie Netzwerkkarte(n) in Ihrem System gefunden.\nBitte waehlen Sie im naechsten Dialog eine davon aus.\n", count
);
480 newtWinMessage("NetcardMenu", ctr
[TR_OK
], message
);
482 sprintf(message
, "Bitte waehlen Sie eine der untenstehenden Netzwerkkarten fuer die Schnittstelle \"%s\" aus.\n", colour
);
484 rc
= newtWinMenu("NetcardMenu", message
, 50, 5, 5, 6, pMenuInhalt
, &choise
, ctr
[TR_OK
], ctr
[TR_SELECT
], ctr
[TR_CANCEL
], NULL
);
486 if ( rc
== 0 || rc
== 1) {
487 write_configs_netudev(pnics
[choise
].description
, pnics
[choise
].macaddr
, colour
);
488 } else if (rc
== 2) {
489 manualdriver("pcnet32","");
491 errorbox("Sie haben keine Netzwerkkarte ausgewaehlt.\n");
496 // We have to add here that you can manually add a device
497 errorbox("Es wurden leider keine freien Netzwerkkarten fuer die Schnittstelle in ihrem System gefunden.");
502 /* Manual entry for gurus. */
503 int manualdriver(char *driver
, char *driveroptions
)
505 char *values
[] = { NULL
, NULL
}; /* pointers for the values. */
506 struct newtWinEntry entries
[] =
507 { { "", &values
[0], 0,}, { NULL
, NULL
, 0 } };
509 char commandstring
[STRING_SIZE
];
513 strcpy(driveroptions
, "");
515 rc
= newtWinEntries(ctr
[TR_SELECT_NETWORK_DRIVER
],
516 ctr
[TR_MODULE_PARAMETERS
], 50, 5, 5, 40, entries
,
517 ctr
[TR_OK
], ctr
[TR_CANCEL
], NULL
);
518 if (rc
== 0 || rc
== 1)
520 if (strlen(values
[0]))
522 sprintf(commandstring
, "/sbin/modprobe %s", values
[0]);
523 if (runcommandwithstatus(commandstring
, ctr
[TR_LOADING_MODULE
]) == 0)
525 if ((driverend
= strchr(values
[0], ' ')))
528 strcpy(driver
, values
[0]);
529 strcpy(driveroptions
, driverend
+ 1);
533 strcpy(driver
, values
[0]);
534 strcpy(driveroptions
, "");
538 errorbox(ctr
[TR_UNABLE_TO_LOAD_DRIVER_MODULE
]);
541 errorbox(ctr
[TR_MODULE_NAME_CANNOT_BE_BLANK
]);