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.
9 * $Id: netstuff.c,v 1.19.2.7 2004/11/05 23:40:17 alanh Exp $
13 #include "libsmooth.h"
21 newtComponent networkform
;
22 newtComponent addressentry
;
23 newtComponent netmaskentry
;
24 newtComponent statictyperadio
;
25 newtComponent dhcptyperadio
;
26 newtComponent pppoetyperadio
;
27 newtComponent pptptyperadio
;
28 newtComponent dhcphostnameentry
;
30 /* acceptable character filter for IP and netmaks entry boxes */
31 static int ip_input_filter(newtComponent entry
, void * data
, int ch
, int cursor
)
33 if ((ch
>= '0' && ch
<= '9') || ch
== '.' || ch
== '\r' || ch
>= NEWT_KEY_EXTRA_BASE
)
38 /* This is a groovie dialog for showing network info. Takes a keyvalue list,
39 * a colour and a dhcp flag. Shows the current settings, and rewrites them
40 * if necessary. DHCP flag sets wether to show the dhcp checkbox. */
41 int changeaddress(struct keyvalue
*kv
, char *colour
, int typeflag
,
42 char *defaultdhcphostname
)
46 char *dhcphostnameresult
;
47 struct newtExitStruct es
;
49 newtComponent addresslabel
;
50 newtComponent netmasklabel
;
51 newtComponent dhcphostnamelabel
;
52 newtComponent ok
, cancel
;
54 char temp
[STRING_SIZE
];
55 char addressfield
[STRING_SIZE
];
56 char netmaskfield
[STRING_SIZE
];
57 char typefield
[STRING_SIZE
];
58 char dhcphostnamefield
[STRING_SIZE
];
61 char type
[STRING_SIZE
];
62 int startstatictype
= 0;
63 int startdhcptype
= 0;
64 int startpppoetype
= 0;
65 int startpptptype
= 0;
67 /* Build some key strings. */
68 sprintf(addressfield
, "%s_ADDRESS", colour
);
69 sprintf(netmaskfield
, "%s_NETMASK", colour
);
70 sprintf(typefield
, "%s_TYPE", colour
);
71 sprintf(dhcphostnamefield
, "%s_DHCP_HOSTNAME", colour
);
73 sprintf(message
, ctr
[TR_INTERFACE
], colour
);
74 newtCenteredWindow(44, (typeflag
? 18 : 12), message
);
76 networkform
= newtForm(NULL
, NULL
, 0);
78 sprintf(message
, ctr
[TR_ENTER_THE_IP_ADDRESS_INFORMATION
], colour
);
79 header
= newtTextboxReflowed(1, 1, message
, 42, 0, 0, 0);
80 newtFormAddComponent(networkform
, header
);
82 /* See if we need a dhcp checkbox. If we do, then we shift the contents
83 * of the window down two rows to make room. */
86 strcpy(temp
, "STATIC"); findkey(kv
, typefield
, temp
);
87 if (strcmp(temp
, "STATIC") == 0) startstatictype
= 1;
88 if (strcmp(temp
, "DHCP") == 0) startdhcptype
= 1;
89 if (strcmp(temp
, "PPPOE") == 0) startpppoetype
= 1;
90 if (strcmp(temp
, "PPTP") == 0) startpptptype
= 1;
91 statictyperadio
= newtRadiobutton(2, 4, ctr
[TR_STATIC
], startstatictype
, NULL
);
92 dhcptyperadio
= newtRadiobutton(2, 5, "DHCP", startdhcptype
, statictyperadio
);
93 pppoetyperadio
= newtRadiobutton(2, 6, "PPPOE", startpppoetype
, dhcptyperadio
);
94 pptptyperadio
= newtRadiobutton(2, 7, "PPTP", startpptptype
, pppoetyperadio
);
95 newtFormAddComponents(networkform
, statictyperadio
, dhcptyperadio
,
96 pppoetyperadio
, pptptyperadio
, NULL
);
97 newtComponentAddCallback(statictyperadio
, networkdialogcallbacktype
, NULL
);
98 newtComponentAddCallback(dhcptyperadio
, networkdialogcallbacktype
, NULL
);
99 newtComponentAddCallback(pppoetyperadio
, networkdialogcallbacktype
, NULL
);
100 newtComponentAddCallback(pptptyperadio
, networkdialogcallbacktype
, NULL
);
101 dhcphostnamelabel
= newtTextbox(2, 9, 18, 1, 0);
102 newtTextboxSetText(dhcphostnamelabel
, ctr
[TR_DHCP_HOSTNAME
]);
103 strcpy(temp
, defaultdhcphostname
);
104 findkey(kv
, dhcphostnamefield
, temp
);
105 dhcphostnameentry
= newtEntry(20, 9, temp
, 20, &dhcphostnameresult
, 0);
106 newtFormAddComponent(networkform
, dhcphostnamelabel
);
107 newtFormAddComponent(networkform
, dhcphostnameentry
);
108 if (startdhcptype
== 0)
109 newtEntrySetFlags(dhcphostnameentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
112 addresslabel
= newtTextbox(2, (typeflag
? 11 : 4) + 0, 18, 1, 0);
113 newtTextboxSetText(addresslabel
, ctr
[TR_IP_ADDRESS_PROMPT
]);
115 findkey(kv
, addressfield
, temp
);
116 addressentry
= newtEntry(20, (typeflag
? 11 : 4) + 0, temp
, 20, &addressresult
, 0);
117 newtEntrySetFilter(addressentry
, ip_input_filter
, NULL
);
118 if (typeflag
== 1 && startstatictype
== 0 && startpptptype
== 0 )
119 newtEntrySetFlags(addressentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
120 newtFormAddComponent(networkform
, addresslabel
);
121 newtFormAddComponent(networkform
, addressentry
);
124 netmasklabel
= newtTextbox(2, (typeflag
? 11 : 4) + 1, 18, 1, 0);
125 newtTextboxSetText(netmasklabel
, ctr
[TR_NETMASK_PROMPT
]);
126 strcpy(temp
, "255.255.255.0"); findkey(kv
, netmaskfield
, temp
);
127 netmaskentry
= newtEntry(20, (typeflag
? 11 : 4) + 1, temp
, 20, &netmaskresult
, 0);
128 newtEntrySetFilter(netmaskentry
, ip_input_filter
, NULL
);
129 if (typeflag
== 1 && startstatictype
== 0 && startpptptype
== 0 )
130 newtEntrySetFlags(netmaskentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
132 newtFormAddComponent(networkform
, netmasklabel
);
133 newtFormAddComponent(networkform
, netmaskentry
);
136 ok
= newtButton(8, (typeflag
? 14 : 7), ctr
[TR_OK
]);
137 cancel
= newtButton(26, (typeflag
? 14 : 7), ctr
[TR_CANCEL
]);
139 newtFormAddComponents(networkform
, ok
, cancel
, NULL
);
142 newtDrawForm(networkform
);
147 newtFormRun(networkform
, &es
);
151 /* OK was pressed; verify the contents of each entry. */
152 strcpy(message
, ctr
[TR_INVALID_FIELDS
]);
154 strcpy(type
, "STATIC");
157 if (strcmp(type
, "STATIC") == 0 || strcmp(type
, "PPTP") == 0 )
159 if (inet_addr(addressresult
) == INADDR_NONE
)
161 strcat(message
, ctr
[TR_IP_ADDRESS_CR
]);
164 if (inet_addr(netmaskresult
) == INADDR_NONE
)
166 strcat(message
, ctr
[TR_NETWORK_MASK_CR
]);
170 if (strcmp(type
, "DHCP") == 0)
172 if (!strlen(dhcphostnameresult
))
174 strcat(message
, ctr
[TR_DHCP_HOSTNAME_CR
]);
182 /* No errors! Set new values, depending on dhcp flag etc. */
185 replacekeyvalue(kv
, dhcphostnamefield
, dhcphostnameresult
);
186 if (strcmp(type
, "STATIC") != 0 && strcmp(type
, "PPTP") != 0)
188 replacekeyvalue(kv
, addressfield
, "0.0.0.0");
189 replacekeyvalue(kv
, netmaskfield
, "0.0.0.0");
193 replacekeyvalue(kv
, addressfield
, addressresult
);
194 replacekeyvalue(kv
, netmaskfield
, netmaskresult
);
196 replacekeyvalue(kv
, typefield
, type
);
200 replacekeyvalue(kv
, addressfield
, addressresult
);
201 replacekeyvalue(kv
, netmaskfield
, netmaskresult
);
204 setnetaddress(kv
, colour
);
211 newtFormDestroy(networkform
);
217 /* for pppoe: return string thats type STATIC, DHCP or PPPOE */
218 int gettype(char *type
)
220 newtComponent selected
= newtRadioGetCurrent(statictyperadio
);
222 if (selected
== statictyperadio
)
223 strcpy(type
, "STATIC");
224 else if (selected
== dhcptyperadio
)
225 strcpy(type
, "DHCP");
226 else if (selected
== pppoetyperadio
)
227 strcpy(type
, "PPPOE");
228 else if (selected
== pptptyperadio
)
229 strcpy(type
, "PPTP");
231 strcpy(type
, "ERROR");
236 /* 0.9.9: calculates broadcast too. */
237 int setnetaddress(struct keyvalue
*kv
, char *colour
)
239 char addressfield
[STRING_SIZE
];
240 char netaddressfield
[STRING_SIZE
];
241 char netmaskfield
[STRING_SIZE
];
242 char broadcastfield
[STRING_SIZE
];
243 char address
[STRING_SIZE
];
244 char netmask
[STRING_SIZE
];
245 unsigned long int intaddress
;
246 unsigned long int intnetaddress
;
247 unsigned long int intnetmask
;
248 unsigned long int intbroadcast
;
253 /* Build some key strings. */
254 sprintf(addressfield
, "%s_ADDRESS", colour
);
255 sprintf(netaddressfield
, "%s_NETADDRESS", colour
);
256 sprintf(netmaskfield
, "%s_NETMASK", colour
);
257 sprintf(broadcastfield
, "%s_BROADCAST", colour
);
259 strcpy(address
, ""); findkey(kv
, addressfield
, address
);
260 strcpy(netmask
, ""); findkey(kv
, netmaskfield
, netmask
);
262 /* Calculate netaddress. Messy.. */
263 intaddress
= inet_addr(address
);
264 intnetmask
= inet_addr(netmask
);
266 intnetaddress
= intaddress
& intnetmask
;
267 temp
.s_addr
= intnetaddress
;
268 netaddress
= inet_ntoa(temp
);
270 replacekeyvalue(kv
, netaddressfield
, netaddress
);
272 intbroadcast
= intnetaddress
| ~intnetmask
;
273 temp
.s_addr
= intbroadcast
;
274 broadcast
= inet_ntoa(temp
);
276 replacekeyvalue(kv
, broadcastfield
, broadcast
);
281 /* Called when dhcp flag is toggled. Toggle disabled state of other 3
283 void networkdialogcallbacktype(newtComponent cm
, void *data
)
285 char type
[STRING_SIZE
];
289 if (strcmp(type
, "STATIC") != 0 && strcmp(type
, "PPTP") != 0 )
291 newtEntrySetFlags(addressentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
292 newtEntrySetFlags(netmaskentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
296 newtEntrySetFlags(addressentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_RESET
);
297 newtEntrySetFlags(netmaskentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_RESET
);
299 if (strcmp(type
, "DHCP") == 0)
300 newtEntrySetFlags(dhcphostnameentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_RESET
);
302 newtEntrySetFlags(dhcphostnameentry
, NEWT_FLAG_DISABLED
, NEWT_FLAGS_SET
);
305 newtDrawForm(networkform
);
308 int interfacecheck(struct keyvalue
*kv
, char *colour
)
310 char temp
[STRING_SIZE
];
311 char colourfields
[NETCHANGE_TOTAL
][STRING_SIZE
];
314 sprintf(colourfields
[ADDRESS
], "%s_ADDRESS", colour
);
315 sprintf(colourfields
[NETADDRESS
], "%s_NETADDRESS", colour
);
316 sprintf(colourfields
[NETMASK
], "%s_NETMASK", colour
);
318 for (c
= 0; c
< 3; c
++)
320 strcpy(temp
, ""); findkey(kv
, colourfields
[c
], temp
);
321 if (!(strlen(temp
))) return 0;
326 /* Network probing! */
327 struct nic nics
[] = {
328 { "100VG-AnyLan Network Adapters, HP J2585B, J2585A, etc", "hp100" },
329 { "3Com EtherLink III", "3c509" },
330 { "3Com 3c501", "3c501" },
331 { "3Com ISA EtherLink XL", "3c515" },
332 { "3Com 3c503 and 3c503/16", "3c503" },
333 { "3Com EtherLink MC (3c523)", "3c523" },
334 { "3Com EtherLink MC/32 (3c527)", "3c527" },
335 { "3Com EtherLink Plus (3c505)", "3c505" },
336 { "3Com EtherLink 16", "3c507" },
337 { "3Com \"Corkscrew\" EtherLink PCI III/XL, etc.", "3c59x" },
338 { "3Com Typhoon Family (3C990, 3CR990, and variants)", "typhoon" },
339 { "Adaptec Starfire/DuraLAN", "starfire" },
340 { "Alteon AceNIC/3Com 3C985/Netgear GA620 Gigabit", "acenic" },
341 { "AMD8111 based 10/100 Ethernet Controller", "amd8111e" },
342 { "AMD LANCE/PCnetAllied Telesis AT1500, J2405A, etc", "lance" },
343 { "AMD PCnet32 and AMD PCnetPCI", "pcnet32" },
344 { "Ansel Communications EISA 3200", "ac3200" },
345 { "Apricot 680x0 VME, 82596 chipset", "82596" },
346 { "AT1700/1720", "at1700" },
347 { "Broadcom 4400", "b44" },
348 { "Broadcom Tigon3", "tg3" },
349 { "Cabletron E2100 series ethercards", "e2100" },
350 { "CATC USB NetMate-based Ethernet", "catc" },
351 { "CDC USB Ethernet", "CDCEther" },
352 { "Crystal LAN CS8900/CS8920", "cs89x0" },
353 { "Compaq Netelligent 10/100 TX PCI UTP, etc", "tlan" },
354 { "D-Link DL2000-based Gigabit Ethernet", "dl2k" },
355 { "Digi Intl. RightSwitch SE-X EISA and PCI", "dgrs" },
356 { "Digital 21x4x Tulip PCI ethernet cards, etc.", "tulip" },
357 { "Digital DEPCA & EtherWORKS,DEPCA, DE100, etc", "depca" },
358 { "DM9102 PCI Fast Ethernet Adapter", "dmfe", },
359 { "Dummy Network Card (testing)", "dummy", },
360 { "EtherWORKS DE425 TP/COAX EISA, DE434 TP PCI, etc.", "de4x5" },
361 { "EtherWORKS 3 (DE203, DE204 and DE205)", "ewrk3" },
362 { "HP PCLAN/plus", "hp-plus" },
363 { "HP LAN ethernet", "hp" },
364 { "IBM LANA", "ibmlana" },
365 { "ICL EtherTeam 16i/32" ,"eth16i" },
366 { "Intel i82557/i82558 PCI EtherExpressPro", "e100" },
367 { "Intel EtherExpress Cardbus Ethernet", "eepro100_cb" },
368 { "Intel i82595 ISA EtherExpressPro10/10+ driver" ,"eepro" },
369 { "Intel EtherExpress 16 (i82586)", "eexpress" },
370 { "Intel Panther onboard i82596 driver", "lp486e" },
371 { "Intel PRO/1000 Gigabit Ethernet", "e1000" },
372 { "KLSI USB KL5USB101-based", "kaweth" },
373 { "MiCom-Interlan NI5010 ethercard", "ni5010" },
374 { "Mylex EISA LNE390A/B", "lne390", },
375 { "Myson MTD-8xx PCI Ethernet", "fealnx" },
376 { "National Semiconductor DP8381x" , "natsemi" },
377 { "National Semiconductor DP83820" , "ns83820" },
378 { "NE/2 MCA", "ne2" },
379 { "NE2000 PCI cards, RealTEk RTL-8029, etc", "ne2k-pci" },
380 { "NE1000 / NE2000 (non-pci)", "ne" },
381 { "NI50 card (i82586 Ethernet chip)", "ni52" },
382 { "NI6510, ni6510 EtherBlaster", "ni65" },
383 { "Novell/Eagle/Microdyne NE3210 EISA", "ne3210" },
384 { "NVidia Nforce2 Driver", "forcedeth" },
385 { "Packet Engines Hamachi GNIC-II", "hamachi" },
386 { "Packet Engines Yellowfin Gigabit-NIC", "yellowfin" },
387 { "Pegasus/Pegasus-II USB ethernet", "pegasus" },
388 { "PureData PDUC8028,WD8003 and WD8013 compatibles", "wd" },
389 { "Racal-Interlan EISA ES3210", "es3210" },
390 { "RealTek RTL-8139 Fast Ethernet", "8139too" },
391 { "RealTek RTL-8139C+ series 10/100 PCI Ethernet", "8139cp" },
392 { "RealTek RTL-8150 USB ethernet", "rtl8150" },
393 { "RealTek RTL-8169 Gigabit Ethernet", "r8169" },
394 { "SiS 900 PCI", "sis900" },
395 { "SKnet MCA", "sk_mca" },
396 { "SMC 9000 series of ethernet cards", "smc9194" },
397 { "SMC EtherPower II", "epic100" },
398 { "SMC Ultra/EtherEZ ISA/PnP Ethernet", "smc-ultra" },
399 { "SMC Ultra32 EISA Ethernet", "smc-ultra32" },
400 { "SMC Ultra MCA Ethernet", "smc-mca" },
401 { "Sundance Alta", "sundance" },
402 { "SysKonnect SK-98xx", "sk98lin" },
403 { "Toshiba TC35815 Ethernet", "tc35815" },
404 { "Tulip chipset Cardbus Ethernet", "tulip_cb" },
405 { "USB Ethernet", "usbnet" },
406 { "VIA Rhine PCI Fast Ethernet, etc", "via-rhine" },
407 { "Winbond W89c840 Ethernet", "winbond-840" },
408 { "Xircom Cardbus Ethernet", "xircom_cb" },
409 { "Xircom (tulip-like) Cardbus Ethernet", "xircom_tulip_cb" },
413 /* Funky routine for loading all drivers (cept those are already loaded.). */
414 int probecards(char *driver
, char *driveroptions
)
419 char commandstring
[STRING_SIZE
];
423 /* PCMCIA Detection */
424 runcommandwithstatus("cardmgr -o",
425 ctr
[TR_LOADING_PCMCIA
]);
427 if (countcards() > n
)
429 strcpy(driver
, "pcmcia");
430 strcpy(driveroptions
,"");
434 /* Regular module detection */
435 while (nics
[c
].modulename
)
437 /* Skip dummy driver during autoprobe as it always succeeds */
438 if (strncmp(nics
[c
].modulename
, "dummy", strlen("dummy")))
440 if (!checkformodule(nics
[c
].modulename
)) {
441 sprintf(commandstring
, "/sbin/modprobe %s", nics
[c
].modulename
);
442 sprintf(message
, ctr
[TR_LOOKING_FOR_NIC
], nics
[c
].description
);
443 if (runcommandwithstatus(commandstring
, message
) == 0)
445 if (countcards() > n
) {
446 strcpy(driver
, nics
[c
].modulename
);
447 strcpy(driveroptions
, "");
456 strcpy(driveroptions
, "");
461 /* A listbox for selected the card... with a * MANUAL * entry at top for
462 * manual module names. */
463 int choosecards(char *driver
, char *driveroptions
)
470 char commandstring
[STRING_SIZE
];
471 char message
[STRING_SIZE
];
475 c
= 0; drivercount
= 0;
476 while (nics
[c
].modulename
)
482 sections
= malloc((drivercount
+ 1) * sizeof(char *));
486 sections
[c
] = ctr
[TR_MANUAL
];
488 while (nics
[c
- 1].modulename
)
490 sections
[c
] = nics
[c
- 1].description
;
496 strcpy(driveroptions
, "");
498 done
= 0; choice
= 1;
501 rc
= newtWinMenu(ctr
[TR_SELECT_NETWORK_DRIVER
],
502 ctr
[TR_SELECT_NETWORK_DRIVER_LONG
], 50, 5, 5, 6,
503 sections
, &choice
, ctr
[TR_OK
], ctr
[TR_CANCEL
], NULL
);
504 if (rc
== 0 || rc
== 1)
508 /* Find module number, load module. */
511 if (!checkformodule(nics
[c
].modulename
))
513 sprintf(commandstring
, "/sbin/modprobe %s", nics
[c
].modulename
);
514 sprintf(message
, ctr
[TR_LOOKING_FOR_NIC
], nics
[c
].description
);
515 if (runcommandwithstatus(commandstring
, message
) == 0)
517 strcpy(driver
, nics
[c
].modulename
);
518 strcpy(driveroptions
, "");
522 errorbox(ctr
[TR_UNABLE_TO_LOAD_DRIVER_MODULE
]);
525 errorbox(ctr
[TR_THIS_DRIVER_MODULE_IS_ALREADY_LOADED
]);
529 manualdriver(driver
, driveroptions
);
541 /* Manual entry for gurus. */
542 int manualdriver(char *driver
, char *driveroptions
)
544 char *values
[] = { NULL
, NULL
}; /* pointers for the values. */
545 struct newtWinEntry entries
[] =
546 { { "", &values
[0], 0,}, { NULL
, NULL
, 0 } };
548 char commandstring
[STRING_SIZE
];
552 strcpy(driveroptions
, "");
554 rc
= newtWinEntries(ctr
[TR_SELECT_NETWORK_DRIVER
],
555 ctr
[TR_MODULE_PARAMETERS
], 50, 5, 5, 40, entries
,
556 ctr
[TR_OK
], ctr
[TR_CANCEL
], NULL
);
557 if (rc
== 0 || rc
== 1)
559 if (strlen(values
[0]))
561 sprintf(commandstring
, "/sbin/modprobe %s", values
[0]);
562 if (runcommandwithstatus(commandstring
, ctr
[TR_LOADING_MODULE
]) == 0)
564 if ((driverend
= strchr(values
[0], ' ')))
567 strcpy(driver
, values
[0]);
568 strcpy(driveroptions
, driverend
+ 1);
572 strcpy(driver
, values
[0]);
573 strcpy(driveroptions
, "");
577 errorbox(ctr
[TR_UNABLE_TO_LOAD_DRIVER_MODULE
]);
580 errorbox(ctr
[TR_MODULE_NAME_CANNOT_BE_BLANK
]);
587 /* Returns the total number of nics current available as ethX devices. */
591 char buffer
[STRING_SIZE
];
595 if (!(file
= fopen("/proc/net/dev", "r")))
597 fprintf(flog
, "Unable to open /proc/net/dev in countnics()\n");
601 while (fgets(buffer
, STRING_SIZE
, file
))
604 while (*start
== ' ') start
++;
605 if (strncmp(start
, "eth", strlen("eth")) == 0)
607 if (strncmp(start
, "dummy", strlen("dummy")) == 0)
616 /* Finds the listed module name and copies the card description back. */
617 int findnicdescription(char *modulename
, char *description
)
621 if (strcmp(modulename
, "pcmcia") == 0) {
622 strcpy(description
, "PCMCIA Ethernet card");
626 while (nics
[c
].description
)
628 if (strcmp(nics
[c
].modulename
, modulename
) == 0)
630 strcpy(description
, nics
[c
].description
);
636 strcpy(description
, "UNKNOWN");