1/* 2 * Copyright (C) 2002-2003 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 */ 6#if defined(KERNEL) || defined(_KERNEL) 7# undef KERNEL 8# undef _KERNEL --- 20 unchanged lines hidden (view full) --- 29# ifdef __OpenBSD__ 30struct file; 31# endif 32# include <sys/uio.h> 33# undef _KERNEL 34#endif 35#include <sys/socket.h> 36#if (defined(__osf__) || defined(AIX) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) |
37# include "radix_ipf_local.h" 38# define _RADIX_H_ 39#endif 40#include <net/if.h> 41#if defined(__FreeBSD__) 42# include <sys/cdefs.h> 43# include <sys/proc.h> 44#endif --- 8 unchanged lines hidden (view full) --- 53#include "netinet/ip_compat.h" 54#include "netinet/ip_fil.h" 55#include "netinet/ip_pool.h" 56#include "netinet/ip_htable.h" 57#include "netinet/ip_lookup.h" 58/* END OF INCLUDES */ 59 60#if !defined(lint) |
61static const char rcsid[] = "@(#)$Id: ip_lookup.c,v 2.35.2.15 2007/05/26 13:05:13 darrenr Exp $"; |
62#endif 63 64#ifdef IPFILTER_LOOKUP 65int ip_lookup_inited = 0; 66 67static int iplookup_addnode __P((caddr_t)); 68static int iplookup_delnode __P((caddr_t data)); 69static int iplookup_addtable __P((caddr_t)); --- 51 unchanged lines hidden (view full) --- 121/* space. */ 122/* cmd(I) - ioctl command number */ 123/* mode(I) - file mode bits used with open */ 124/* */ 125/* Handle ioctl commands sent to the ioctl device. For the most part, this */ 126/* involves just calling another function to handle the specifics of each */ 127/* command. */ 128/* ------------------------------------------------------------------------ */ |
129int ip_lookup_ioctl(data, cmd, mode, uid, ctx) |
130caddr_t data; 131ioctlcmd_t cmd; |
132int mode, uid; 133void *ctx; |
134{ 135 int err; 136 SPL_INT(s); 137 138 mode = mode; /* LINT */ 139 140 SPL_NET(s); 141 --- 33 unchanged lines hidden (view full) --- 175 break; 176 177 case SIOCLOOKUPFLUSH : 178 WRITE_ENTER(&ip_poolrw); 179 err = iplookup_flush(data); 180 RWLOCK_EXIT(&ip_poolrw); 181 break; 182 |
183 case SIOCLOOKUPITER : 184 err = ip_lookup_iterate(data, uid, ctx); 185 break; 186 |
187 default : 188 err = EINVAL; 189 break; 190 } 191 SPL_X(s); 192 return err; 193} 194 --- 12 unchanged lines hidden (view full) --- 207{ 208 ip_pool_node_t node, *m; 209 iplookupop_t op; 210 iphtable_t *iph; 211 iphtent_t hte; 212 ip_pool_t *p; 213 int err; 214 |
215 err = BCOPYIN(data, &op, sizeof(op)); 216 if (err != 0) 217 return EFAULT; 218 219 if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) 220 return EINVAL; 221 |
222 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 223 224 switch (op.iplo_type) 225 { 226 case IPLT_POOL : 227 if (op.iplo_size != sizeof(node)) 228 return EINVAL; 229 --- 55 unchanged lines hidden (view full) --- 285 iphtable_t *iph; 286 iphtent_t hte; 287 ip_pool_t *p; 288 int err; 289 290 err = 0; 291 BCOPYIN(data, &op, sizeof(op)); 292 |
293 if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) 294 return EINVAL; 295 |
296 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 297 298 switch (op.iplo_type) 299 { 300 case IPLT_POOL : 301 if (op.iplo_size != sizeof(node)) 302 return EINVAL; 303 --- 42 unchanged lines hidden (view full) --- 346/* for this one. */ 347/* ------------------------------------------------------------------------ */ 348static int iplookup_addtable(data) 349caddr_t data; 350{ 351 iplookupop_t op; 352 int err; 353 |
354 err = BCOPYIN(data, &op, sizeof(op)); 355 if (err != 0) 356 return EFAULT; |
357 |
358 if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) 359 return EINVAL; 360 |
361 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 362 363 switch (op.iplo_type) 364 { 365 case IPLT_POOL : 366 if (ip_pool_find(op.iplo_unit, op.iplo_name) != NULL) 367 err = EEXIST; 368 else --- 11 unchanged lines hidden (view full) --- 380 err = EINVAL; 381 break; 382 } 383 384 /* 385 * For anonymous pools, copy back the operation struct because in the 386 * case of success it will contain the new table's name. 387 */ |
388 if ((err == 0) && ((op.iplo_arg & LOOKUP_ANON) != 0)) { 389 err = BCOPYOUT(&op, data, sizeof(op)); 390 if (err != 0) 391 err = EFAULT; |
392 } 393 394 return err; 395} 396 397 398/* ------------------------------------------------------------------------ */ 399/* Function: iplookup_deltable */ --- 4 unchanged lines hidden (view full) --- 404/* calls the relevant function to do the cleanup. */ 405/* ------------------------------------------------------------------------ */ 406static int iplookup_deltable(data) 407caddr_t data; 408{ 409 iplookupop_t op; 410 int err; 411 |
412 err = BCOPYIN(data, &op, sizeof(op)); 413 if (err != 0) 414 return EFAULT; |
415 |
416 if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) 417 return EINVAL; |
418 |
419 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 420 |
421 /* 422 * create a new pool - fail if one already exists with 423 * the same # 424 */ 425 switch (op.iplo_type) 426 { 427 case IPLT_POOL : |
428 err = ip_pool_destroy(op.iplo_unit, op.iplo_name); |
429 break; 430 431 case IPLT_HASH : |
432 err = fr_removehtable(op.iplo_unit, op.iplo_name); |
433 break; 434 435 default : 436 err = EINVAL; 437 break; 438 } 439 return err; 440} --- 7 unchanged lines hidden (view full) --- 448/* Copy statistical information from inside the kernel back to user space. */ 449/* ------------------------------------------------------------------------ */ 450static int iplookup_stats(data) 451caddr_t data; 452{ 453 iplookupop_t op; 454 int err; 455 |
456 err = BCOPYIN(data, &op, sizeof(op)); 457 if (err != 0) 458 return EFAULT; |
459 |
460 if (op.iplo_unit < 0 || op.iplo_unit > IPL_LOGMAX) 461 return EINVAL; 462 |
463 switch (op.iplo_type) 464 { 465 case IPLT_POOL : 466 err = ip_pool_statistics(&op); 467 break; 468 469 case IPLT_HASH : 470 err = fr_gethtablestat(&op); --- 16 unchanged lines hidden (view full) --- 487/* entry in the hash table/pool or want to remove all groups from those. */ 488/* ------------------------------------------------------------------------ */ 489static int iplookup_flush(data) 490caddr_t data; 491{ 492 int err, unit, num, type; 493 iplookupflush_t flush; 494 |
495 err = BCOPYIN(data, &flush, sizeof(flush)); 496 if (err != 0) 497 return EFAULT; |
498 |
499 unit = flush.iplf_unit; 500 if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) 501 return EINVAL; 502 |
503 flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; 504 |
505 type = flush.iplf_type; 506 err = EINVAL; 507 num = 0; 508 509 if (type == IPLT_POOL || type == IPLT_ALL) { 510 err = 0; 511 num = ip_pool_flush(&flush); 512 } 513 514 if (type == IPLT_HASH || type == IPLT_ALL) { 515 err = 0; 516 num += fr_flushhtable(&flush); 517 } 518 519 if (err == 0) { 520 flush.iplf_count = num; |
521 err = BCOPYOUT(&flush, data, sizeof(flush)); 522 if (err != 0) 523 err = EFAULT; |
524 } 525 return err; 526} 527 528 |
529/* ------------------------------------------------------------------------ */ 530/* Function: ip_lookup_delref */ 531/* Returns: void */ 532/* Parameters: type(I) - table type to operate on */ 533/* ptr(I) - pointer to object to remove reference for */ 534/* */ 535/* This function organises calling the correct deref function for a given */ 536/* type of object being passed into it. */ 537/* ------------------------------------------------------------------------ */ |
538void ip_lookup_deref(type, ptr) 539int type; 540void *ptr; 541{ 542 if (ptr == NULL) 543 return; 544 545 WRITE_ENTER(&ip_poolrw); --- 6 unchanged lines hidden (view full) --- 552 case IPLT_HASH : 553 fr_derefhtable(ptr); 554 break; 555 } 556 RWLOCK_EXIT(&ip_poolrw); 557} 558 559 |
560/* ------------------------------------------------------------------------ */ 561/* Function: ip_lookup_iterate */ 562/* Returns: int - 0 = success, else error */ 563/* Parameters: data(I) - pointer to data from ioctl call */ 564/* */ 565/* Decodes ioctl request to step through either hash tables or pools. */ 566/* ------------------------------------------------------------------------ */ 567int ip_lookup_iterate(data, uid, ctx) 568void *data; 569int uid; 570void *ctx; 571{ 572 ipflookupiter_t iter; 573 ipftoken_t *token; 574 int err; 575 SPL_INT(s); 576 577 err = fr_inobj(data, &iter, IPFOBJ_LOOKUPITER); 578 if (err != 0) 579 return err; 580 581 if (iter.ili_unit < 0 || iter.ili_unit > IPL_LOGMAX) 582 return EINVAL; 583 584 if (iter.ili_ival != IPFGENITER_LOOKUP) 585 return EINVAL; 586 587 SPL_SCHED(s); 588 token = ipf_findtoken(iter.ili_key, uid, ctx); 589 if (token == NULL) { 590 RWLOCK_EXIT(&ipf_tokens); 591 SPL_X(s); 592 return ESRCH; 593 } 594 595 switch (iter.ili_type) 596 { 597 case IPLT_POOL : 598 err = ip_pool_getnext(token, &iter); 599 break; 600 case IPLT_HASH : 601 err = fr_htable_getnext(token, &iter); 602 break; 603 default : 604 err = EINVAL; 605 break; 606 } 607 RWLOCK_EXIT(&ipf_tokens); 608 SPL_X(s); 609 610 return err; 611} 612 613 614/* ------------------------------------------------------------------------ */ 615/* Function: iplookup_iterderef */ 616/* Returns: int - 0 = success, else error */ 617/* Parameters: data(I) - pointer to data from ioctl call */ 618/* */ 619/* Decodes ioctl request to remove a particular hash table or pool and */ 620/* calls the relevant function to do the cleanup. */ 621/* ------------------------------------------------------------------------ */ 622void ip_lookup_iterderef(type, data) 623u_32_t type; 624void *data; 625{ 626 iplookupiterkey_t key; 627 628 key.ilik_key = type; 629 630 if (key.ilik_unstr.ilik_ival != IPFGENITER_LOOKUP) 631 return; 632 633 switch (key.ilik_unstr.ilik_type) 634 { 635 case IPLT_HASH : 636 fr_htable_iterderef((u_int)key.ilik_unstr.ilik_otype, 637 (int)key.ilik_unstr.ilik_unit, data); 638 break; 639 case IPLT_POOL : 640 ip_pool_iterderef((u_int)key.ilik_unstr.ilik_otype, 641 (int)key.ilik_unstr.ilik_unit, data); 642 break; 643 } 644} 645 646 647 |
648#else /* IPFILTER_LOOKUP */ 649 650/*ARGSUSED*/ |
651int ip_lookup_ioctl(data, cmd, mode, uid, ctx) |
652caddr_t data; 653ioctlcmd_t cmd; |
654int mode, uid; 655void *ctx; |
656{ 657 return EIO; 658} 659#endif /* IPFILTER_LOOKUP */ |