52
#define error(fmt, args...) do { if (debug) \
53
syslog(LOG_KERN | LOG_ERR, "%s(%d): " fmt "\n", \
54
__FUNCTION__, __LINE__, ## args); \
56
#define info(fmt, args...) do { if (debug) \
57
syslog(LOG_KERN | LOG_ERR, "%s(%d): " fmt "\n", \
58
__FUNCTION__, __LINE__, ## args); \
62
static int get_filesize(int fd)
65
if(!fstat(fd, &statbuf))
67
return statbuf.st_size;
75
static int dotaint(void)
77
FILE *f = fopen("/proc/sys/kernel/tainted", "w");
85
static int put_file(int device, char *filename, int ioctl_nr)
88
struct put_file put_file;
51
#define error(fmt, ...) do { \
52
syslog(LOG_KERN | LOG_ERR, "%s: %s(%d): " fmt "\n", \
53
PROG_NAME, __FUNCTION__, __LINE__ , ## __VA_ARGS__); \
55
#define info(fmt, ...) do { \
56
syslog(LOG_KERN | LOG_INFO, "%s: %s(%d): " fmt "\n", \
57
PROG_NAME, __FUNCTION__, __LINE__ , ## __VA_ARGS__); \
60
#define dbg(fmt, ...) do { if (debug) \
61
syslog(LOG_KERN | LOG_DEBUG, "%s: %s(%d): " fmt "\n", \
62
PROG_NAME, __FUNCTION__, __LINE__ , ## __VA_ARGS__); \
65
/* read system file (either .sys or .bin) */
66
static int read_file(char *filename, struct load_driver_file *driver_file)
89
70
void * image = NULL;
91
char *file_basename = basename(strdup(filename));
73
char *file_basename = basename(filename);
93
75
fd = open(filename, O_RDONLY);
96
perror("Unable to open file");
99
size = get_filesize(fd);
100
image = mmap(0, size, PROT_READ, MAP_PRIVATE,
104
perror("Unable to mmap driver");
109
strncpy(put_file.name, file_basename, sizeof(put_file.name));
110
put_file.name[sizeof(put_file.name)-1] = 0;
111
put_file.size = size;
114
error("Unable to locate file %s", filename);
118
put_file.data = image;
119
if (ioctl(device, ioctl_nr, &put_file))
121
perror("Unable to put file (check dmesg for more info)");
128
static int confname_to_put_device(const char *name_orig,
129
struct put_device *put_device)
132
char *name = strdup(name_orig);
139
sscanf(s, "%04x:%04x", &put_device->vendor,
140
&put_device->device);
141
put_device->pci_subdevice = -1;
142
put_device->pci_subvendor = -1;
144
else if(strlen(s) == 19)
146
sscanf(s, "%04x:%04x:%04x:%04x", &put_device->vendor,
147
&put_device->device, &put_device->pci_subvendor,
148
&put_device->pci_subdevice);
77
error("unable to open file: %s", strerror(errno));
81
if (fstat(fd, &statbuf)) {
82
error("incorrect driver file '%s'", filename);
86
size = statbuf.st_size;
88
image = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
89
if (image == MAP_FAILED) {
90
error("unable to mmap driver: %s", strerror(errno));
95
strncpy(driver_file->name, file_basename, sizeof(driver_file->name));
96
driver_file->name[sizeof(driver_file->name)-1] = 0;
97
driver_file->size = size;
98
driver_file->data = image;
102
/* split setting into name and value pair */
156
103
static int parse_setting_line(const char *setting_line, char *setting_name,
157
104
char *setting_val)
207
static int put_device(int device, char *conf_file_name)
148
/* read .conf file and store info in device */
149
static int read_conf_file(char *conf_file_name, struct load_device *device)
210
struct put_device put_device;
211
151
char setting_line[SETTING_LEN];
212
152
struct stat statbuf;
214
char setting_name[NAME_LEN], setting_val[VAL_LEN];
217
if(lstat(conf_file_name, &statbuf))
219
perror("unable to open config file");
223
put_device.fuzzy = 0;
224
if(S_ISLNK(statbuf.st_mode))
225
put_device.fuzzy = 1;
227
if ((config = fopen(conf_file_name, "r")) == NULL)
229
perror("unable to open config file");
233
confname_to_put_device(conf_file_name, &put_device);
235
put_device.bustype = -1;
236
while (fgets(setting_line, SETTING_LEN-1, config))
238
setting_line[SETTING_LEN-1] = 0;
239
ret = parse_setting_line(setting_line, setting_name,
246
if (strcmp(setting_name, "BusType") == 0)
248
put_device.bustype = strtol(setting_val, NULL, 10);
249
if (put_device.bustype != 0 &&
250
put_device.bustype != 5)
252
perror("invalid bustype");
255
if (ioctl(device, NDIS_PUTDEVICE, &put_device))
257
perror("Unable to put device "
258
"(check dmesg for more info)");
266
if (put_device.bustype == -1)
269
while (fgets(setting_line, SETTING_LEN-1, config))
271
struct put_setting setting;
273
setting_line[SETTING_LEN-1] = 0;
274
ret = parse_setting_line(setting_line, setting_name,
281
setting.name_len = strlen(setting_name);
282
setting.val_str_len = strlen(setting_val);
283
setting.name = setting_name;
284
setting.value = setting_val;
286
if (ioctl(device, NDIS_PUTSETTING, &setting))
288
error("Error adding setting: %s", setting_name);
154
char setting_name[MAX_NDIS_SETTING_NAME_LEN];
155
char setting_value[MAX_NDIS_SETTING_VALUE_LEN];
156
int ret, nr_settings;
159
if (lstat(conf_file_name, &statbuf)) {
160
error("unable to open config file: %s", strerror(errno));
164
if (S_ISLNK(statbuf.st_mode))
169
if ((config = fopen(conf_file_name, "r")) == NULL) {
170
error("unable to open config file: %s", strerror(errno));
174
file_name = strdup(conf_file_name);
175
s = basename(file_name);
179
if (strlen(s) == 9) {
180
sscanf(s, "%04x:%04x", &device->vendor, &device->device);
181
device->pci_subdevice = -1;
182
device->pci_subvendor = -1;
183
} else if (strlen(s) == 19) {
184
sscanf(s, "%04x:%04x:%04x:%04x", &device->vendor,
185
&device->device, &device->pci_subvendor,
186
&device->pci_subdevice);
192
device->bustype = -1;
195
while (fgets(setting_line, SETTING_LEN-1, config)) {
196
struct load_device_setting *setting;
198
setting_line[SETTING_LEN-1] = 0;
199
ret = parse_setting_line(setting_line, setting_name,
206
if (strcmp(setting_name, "BusType") == 0) {
207
device->bustype = strtol(setting_value, NULL, 10);
208
if (device->bustype != NDIS_PCI_BUS &&
209
device->bustype != NDIS_USB_BUS) {
210
error("invalid bustype: %d", device->bustype);
214
setting = &device->settings[nr_settings];
215
strncpy(setting->name, setting_name,
216
MAX_NDIS_SETTING_NAME_LEN);
217
strncpy(setting->value, setting_value,
218
MAX_NDIS_SETTING_VALUE_LEN);
221
if (nr_settings >= MAX_NDIS_SETTINGS) {
222
error("too many settings");
229
if (device->bustype == -1) {
230
error("coudn't find device type in settings");
234
device->nr_settings = nr_settings;
237
device->nr_settings = 0;
298
* Open a windows driver and pass it to the kernel module.
242
* open a windows driver and pass it to the kernel module.
243
* returns 0: on success, -1 on error
300
static int load(int device, char *confdir)
245
static int load_driver(int ioctl_device, DIR *dir, char *driver_name)
303
248
struct dirent *dirent;
308
error("Unable to open config dir %s", confdir);
315
error("Unable to open config dir %s", confdir);
320
/* Locate the .sys first */
321
while((dirent = readdir(dir)))
324
len = strlen(dirent->d_name);
325
if(len > 4 && strcmp(&dirent->d_name[len-4], ".sys") == 0)
327
if((err = put_file(device, dirent->d_name,
328
NDIS_PUTDRIVER)) != 0)
338
/* Now add all .conf and other files */
339
while((dirent = readdir(dir)))
342
len = strlen(dirent->d_name);
343
if(len > 5 && strcmp(&dirent->d_name[len-5], ".conf") == 0)
345
put_device(device, dirent->d_name);
349
if(strcmp(dirent->d_name, ".") == 0)
351
if(strcmp(dirent->d_name, "..") == 0)
353
if(len > 4 && !strcmp(&dirent->d_name[len-4], ".sys"))
355
if(len > 4 && !strcmp(&dirent->d_name[len-4], ".inf"))
357
if(len > 4 && !strcmp(&dirent->d_name[len-4], ".dll"))
359
if(len > 4 && !strcmp(&dirent->d_name[len-4], ".exe"))
361
put_file(device, dirent->d_name, NDIS_PUTFILE);
365
if(ioctl(device, NDIS_STARTDRIVER, 0))
367
perror("Unable to start driver (check dmesg for more info)");
249
struct load_driver *driver;
250
int nr_sys_files, nr_devices, nr_bin_files;
252
if (!dir || !driver_name) {
253
error("invalid driver");
257
if ((driver = malloc(sizeof(*driver))) == NULL) {
258
error("couldn't allocate memory for driver %s", driver_name);
261
memset(driver, 0, sizeof(*driver));
262
strncpy(driver->name, driver_name, MAX_DRIVER_NAME_LEN);
269
dbg("loading driver %s", driver_name);
270
while ((dirent = readdir(dir))) {
273
if (strcmp(dirent->d_name, ".") == 0 ||
274
strcmp(dirent->d_name, "..") == 0)
277
len = strlen(dirent->d_name);
279
strcmp(&dirent->d_name[len-4], ".inf") == 0)
282
if (len > 4 && strcmp(&dirent->d_name[len-4], ".sys") == 0) {
283
if (read_file(dirent->d_name,
284
&driver->sys_files[nr_sys_files])) {
285
error("couldn't load .sys file %s",
290
} else if (len > 5 &&
291
strcmp(&dirent->d_name[len-5], ".conf") == 0) {
292
if (read_conf_file(dirent->d_name,
293
&driver->devices[nr_devices])) {
294
error("couldn't load .conf file %s",
299
} else if (len > 4 &&
300
strcmp(&dirent->d_name[len-4], ".bin") == 0) {
301
if (read_file(dirent->d_name,
302
&driver->bin_files[nr_bin_files])) {
303
error("coudln't load .bin file %s",
309
error("file %s is ignored", dirent->d_name);
311
if (nr_sys_files == MAX_PE_IMAGES) {
312
error("too many .sys files for driver %s",
316
if (nr_devices == MAX_NDIS_DEVICES) {
317
error("too many .conf files for driver %s",
321
if (nr_bin_files == MAX_NDIS_BIN_FILES) {
322
error("too many .bin files for driver %s",
328
if (nr_sys_files == 0 || nr_devices == 0) {
329
error("coudln't find valid drivers files for driver %s",
333
driver->nr_sys_files = nr_sys_files;
334
driver->nr_devices = nr_devices;
335
driver->nr_bin_files = nr_bin_files;
337
if (ioctl(ioctl_device, NDIS_ADD_DRIVER, driver))
340
dbg("driver %s loaded", driver_name);
345
for (i = 0; i < nr_sys_files; i++)
346
free(driver->sys_files[i].data);
347
for (i = 0; i < nr_bin_files; i++)
348
free(driver->bin_files[i].data);
349
error("couldn't load driver %s", driver_name);
376
* Load all installed drivers
355
* load all installed drivers
356
* returns: number of drivers loadeed successfully
378
static int loadall(int device)
358
static int load_all_drivers(int ioctl_device)
380
360
struct stat statbuf;
381
361
struct dirent *dirent;
383
DIR *dir = opendir(".");
385
while((dirent = readdir(dir)))
387
if(strcmp(dirent->d_name, ".") == 0)
389
if(strcmp(dirent->d_name, "..") == 0)
392
if(stat(dirent->d_name, &statbuf))
395
if(!S_ISDIR(statbuf.st_mode))
398
load(device, dirent->d_name);
365
if (chdir(confdir)) {
366
error("directory %s is not valid: %s",
367
confdir, strerror(errno));
370
if ((dir = opendir(confdir)) == NULL) {
371
error("directory %s is not valid: %s",
372
confdir, strerror(errno));
377
while((dirent = readdir(dir))) {
378
if (strcmp(dirent->d_name, ".") == 0 ||
379
strcmp(dirent->d_name, "..") == 0 ||
380
strcmp(dirent->d_name, "modules.ndiswrapper") == 0)
383
if (stat(dirent->d_name, &statbuf) ||
384
(!S_ISDIR(statbuf.st_mode)) ||
385
((driver = opendir(dirent->d_name)) == NULL)) {
386
error("directory %s is not valid: %s",
387
dirent->d_name, strerror(errno));
390
if (chdir(dirent->d_name)) {
391
error("directory %s is not valid: %s",
392
dirent->d_name, strerror(errno));
396
if (!load_driver(ioctl_device, driver, dirent->d_name))
406
* Open a misc device without having a /dev/ entry
408
static int open_misc_device(int minor)
406
* we need a device to use ioctl to communicate with ndiswrapper module
407
* we create a device in /dev instead of /tmp as some distributions don't
408
* allow creation of devices in /tmp
410
static int get_ioctl_device()
410
char tmp[] = {"/tmp/ndiswrapperXXXXXX"};
411
int fd = mkstemp(tmp);
414
if(mknod(tmp, S_IFCHR | 0600, 10 << 8 | minor) == -1)
417
fd = open(tmp, O_RDONLY);
416
/* get minor device number used by ndiswrapper driver */
417
proc_misc = fopen("/proc/misc", "r");
421
while (fgets(line, sizeof(line), proc_misc)) {
422
if (strstr(line, "ndiswrapper")) {
423
long i = strtol(line, 0, 10);
424
if (i != LONG_MAX && i != LONG_MIN) {
432
if (minor_dev == -1) {
433
error("couldn't find ndiswrapper in /proc/misc; "
434
"is ndiswrapper module loaded?");
439
if (mknod(ioctl_file, S_IFCHR | 0600, 10 << 8 | minor_dev) == -1) {
440
error("couldn't create file %s: %s",
441
ioctl_file, strerror(errno));
445
fd = open(ioctl_file, O_RDONLY);
449
error("couldn't open file %s: %s",
450
ioctl_file, strerror(errno));
425
* Parse /proc/misc to get the minor of out kernel driver
427
static int get_misc_minor()
430
FILE *misc = fopen("/proc/misc", "r");
435
while(fgets(line, sizeof(line), misc))
437
if(strstr(line, "ndiswrapper"))
439
int i = strtol(line, 0, 10);
440
if(i != LONG_MAX && i != LONG_MIN)
452
456
int main(int argc, char *argv[0])
454
int i, device, misc_minor, res;
459
openlog("loadndisdriver", LOG_PERROR | LOG_CONS, LOG_KERN);
458
int i, ioctl_device, res;
460
openlog(PROG_NAME, LOG_PERROR | LOG_CONS, LOG_KERN | LOG_DEBUG);
462
info("version %s started", NDISWRAPPER_VERSION);
463
465
error("Usage: %s <debug> <version> [-a] [driver]", argv[0]);
469
471
i = atoi(argv[1]);
472
473
error("invalid debug value %d", i);
479
if ((res = chdir(confdir)))
481
error("%s does not exist", confdir);
485
misc_minor = get_misc_minor();
486
if (misc_minor == -1)
488
error("%s: cannot find minor for kernel module."
489
"Module loaded?", argv[0]);
494
device = open_misc_device(misc_minor);
497
error("Unable to open kernel driver (%d)", errno);
504
if (strcmp(argv[2], NDISWRAPPER_VERSION))
510
if (strcmp(argv[3], "-a") == 0)
511
res = loadall(device);
513
res = load(device, argv[3]);
517
info("%s", "Drivers loaded successfully");
479
ioctl_device = get_ioctl_device();
480
if (ioctl_device == -1) {
481
error("unable to open ioctl device %s", ioctl_file);
486
if (strcmp(argv[2], NDISWRAPPER_VERSION)) {
487
error("version %s doesn't match driver version %s",
488
NDISWRAPPER_VERSION, argv[2]);
493
if (strcmp(argv[3], "-a") == 0) {
494
if (load_all_drivers(ioctl_device) > 0)
497
error("no useable drivers found, aborting");
502
if (chdir(confdir)) {
503
error("directory %s is not valid: %s",
504
confdir, strerror(errno));
508
if ((driver_dir = opendir(argv[3])) == NULL) {
509
error("couldn't open driver directory %s: %s",
510
argv[3], strerror(errno));
514
if (chdir(argv[3])) {
515
error("directory %s is not valid: %s",
516
argv[3], strerror(errno));
520
res = load_driver(ioctl_device, driver_dir,
522
closedir(driver_dir);
526
if (ioctl_device != -1)