in.c (229621) | in.c (230207) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (C) 2001 WIDE Project. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * @(#)in.c 8.4 (Berkeley) 1/9/95 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (C) 2001 WIDE Project. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * @(#)in.c 8.4 (Berkeley) 1/9/95 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/in.c 229621 2012-01-05 19:00:36Z jhb $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/in.c 230207 2012-01-16 09:53:24Z glebius $"); |
35 36#include "opt_mpath.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/sockio.h> 41#include <sys/malloc.h> 42#include <sys/priv.h> --- 25 unchanged lines hidden (view full) --- 68 69static int in_mask2len(struct in_addr *); 70static void in_len2mask(struct in_addr *, int); 71static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, 72 struct ifnet *, struct thread *); 73 74static void in_socktrim(struct sockaddr_in *); 75static int in_ifinit(struct ifnet *, struct in_ifaddr *, | 35 36#include "opt_mpath.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/sockio.h> 41#include <sys/malloc.h> 42#include <sys/priv.h> --- 25 unchanged lines hidden (view full) --- 68 69static int in_mask2len(struct in_addr *); 70static void in_len2mask(struct in_addr *, int); 71static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, 72 struct ifnet *, struct thread *); 73 74static void in_socktrim(struct sockaddr_in *); 75static int in_ifinit(struct ifnet *, struct in_ifaddr *, |
76 struct sockaddr_in *, int, int, int); | 76 struct sockaddr_in *, int, int); |
77static void in_purgemaddrs(struct ifnet *); 78 79static VNET_DEFINE(int, nosameprefix); 80#define V_nosameprefix VNET(nosameprefix) 81SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, no_same_prefix, CTLFLAG_RW, 82 &VNET_NAME(nosameprefix), 0, 83 "Refuse to create same prefixes on different interfaces"); 84 --- 130 unchanged lines hidden (view full) --- 215{ 216 register struct ifreq *ifr = (struct ifreq *)data; 217 register struct in_ifaddr *ia, *iap; 218 register struct ifaddr *ifa; 219 struct in_addr allhosts_addr; 220 struct in_addr dst; 221 struct in_ifinfo *ii; 222 struct in_aliasreq *ifra = (struct in_aliasreq *)data; | 77static void in_purgemaddrs(struct ifnet *); 78 79static VNET_DEFINE(int, nosameprefix); 80#define V_nosameprefix VNET(nosameprefix) 81SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, no_same_prefix, CTLFLAG_RW, 82 &VNET_NAME(nosameprefix), 0, 83 "Refuse to create same prefixes on different interfaces"); 84 --- 130 unchanged lines hidden (view full) --- 215{ 216 register struct ifreq *ifr = (struct ifreq *)data; 217 register struct in_ifaddr *ia, *iap; 218 register struct ifaddr *ifa; 219 struct in_addr allhosts_addr; 220 struct in_addr dst; 221 struct in_ifinfo *ii; 222 struct in_aliasreq *ifra = (struct in_aliasreq *)data; |
223 struct sockaddr_in oldaddr; | |
224 int error, hostIsNew, iaIsNew, maskIsNew; 225 int iaIsFirst; 226 u_long ocmd = cmd; 227 228 /* 229 * Pre-10.x compat: OSIOCAIFADDR passes a shorter 230 * struct in_aliasreq, without ifra_vhid. 231 */ --- 41 unchanged lines hidden (view full) --- 273 ifra->ifra_mask.sin_family != AF_INET)) 274 return (EINVAL); 275#endif 276 break; 277 case SIOCSIFADDR: 278 case SIOCSIFBRDADDR: 279 case SIOCSIFDSTADDR: 280 case SIOCSIFNETMASK: | 223 int error, hostIsNew, iaIsNew, maskIsNew; 224 int iaIsFirst; 225 u_long ocmd = cmd; 226 227 /* 228 * Pre-10.x compat: OSIOCAIFADDR passes a shorter 229 * struct in_aliasreq, without ifra_vhid. 230 */ --- 41 unchanged lines hidden (view full) --- 272 ifra->ifra_mask.sin_family != AF_INET)) 273 return (EINVAL); 274#endif 275 break; 276 case SIOCSIFADDR: 277 case SIOCSIFBRDADDR: 278 case SIOCSIFDSTADDR: 279 case SIOCSIFNETMASK: |
281 if (ifr->ifr_addr.sa_family != AF_INET || 282 ifr->ifr_addr.sa_len != sizeof(struct sockaddr_in)) 283 return (EINVAL); 284 break; | 280 /* We no longer support that old commands. */ 281 return (EINVAL); |
285 286 case SIOCALIFADDR: 287 if (td != NULL) { 288 error = priv_check(td, PRIV_NET_ADDIFADDR); 289 if (error) 290 return (error); 291 } 292 if (ifp == NULL) --- 24 unchanged lines hidden (view full) --- 317 if (ifp == NULL) 318 return (EADDRNOTAVAIL); 319 320 /* 321 * Security checks before we get involved in any work. 322 */ 323 switch (cmd) { 324 case SIOCAIFADDR: | 282 283 case SIOCALIFADDR: 284 if (td != NULL) { 285 error = priv_check(td, PRIV_NET_ADDIFADDR); 286 if (error) 287 return (error); 288 } 289 if (ifp == NULL) --- 24 unchanged lines hidden (view full) --- 314 if (ifp == NULL) 315 return (EADDRNOTAVAIL); 316 317 /* 318 * Security checks before we get involved in any work. 319 */ 320 switch (cmd) { 321 case SIOCAIFADDR: |
325 case SIOCSIFADDR: 326 case SIOCSIFBRDADDR: 327 case SIOCSIFNETMASK: 328 case SIOCSIFDSTADDR: | |
329 if (td != NULL) { 330 error = priv_check(td, PRIV_NET_ADDIFADDR); 331 if (error) 332 return (error); 333 } 334 break; 335 336 case SIOCDIFADDR: --- 71 unchanged lines hidden (view full) --- 408 error = EDESTADDRREQ; 409 goto out; 410 } 411 } 412 if (cmd == SIOCDIFADDR && ia == NULL) { 413 error = EADDRNOTAVAIL; 414 goto out; 415 } | 322 if (td != NULL) { 323 error = priv_check(td, PRIV_NET_ADDIFADDR); 324 if (error) 325 return (error); 326 } 327 break; 328 329 case SIOCDIFADDR: --- 71 unchanged lines hidden (view full) --- 401 error = EDESTADDRREQ; 402 goto out; 403 } 404 } 405 if (cmd == SIOCDIFADDR && ia == NULL) { 406 error = EADDRNOTAVAIL; 407 goto out; 408 } |
416 /* FALLTHROUGH */ 417 case SIOCSIFADDR: 418 case SIOCSIFNETMASK: 419 case SIOCSIFDSTADDR: | |
420 if (ia == NULL) { 421 ia = (struct in_ifaddr *) 422 malloc(sizeof *ia, M_IFADDR, M_NOWAIT | 423 M_ZERO); 424 if (ia == NULL) { 425 error = ENOBUFS; 426 goto out; 427 } --- 19 unchanged lines hidden (view full) --- 447 ifa_ref(ifa); /* in_ifaddrhead */ 448 IN_IFADDR_WLOCK(); 449 TAILQ_INSERT_TAIL(&V_in_ifaddrhead, ia, ia_link); 450 IN_IFADDR_WUNLOCK(); 451 iaIsNew = 1; 452 } 453 break; 454 | 409 if (ia == NULL) { 410 ia = (struct in_ifaddr *) 411 malloc(sizeof *ia, M_IFADDR, M_NOWAIT | 412 M_ZERO); 413 if (ia == NULL) { 414 error = ENOBUFS; 415 goto out; 416 } --- 19 unchanged lines hidden (view full) --- 436 ifa_ref(ifa); /* in_ifaddrhead */ 437 IN_IFADDR_WLOCK(); 438 TAILQ_INSERT_TAIL(&V_in_ifaddrhead, ia, ia_link); 439 IN_IFADDR_WUNLOCK(); 440 iaIsNew = 1; 441 } 442 break; 443 |
455 case SIOCSIFBRDADDR: | |
456 case SIOCGIFADDR: 457 case SIOCGIFNETMASK: 458 case SIOCGIFDSTADDR: 459 case SIOCGIFBRDADDR: 460 if (ia == NULL) { 461 error = EADDRNOTAVAIL; 462 goto out; 463 } --- 24 unchanged lines hidden (view full) --- 488 } 489 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr; 490 goto out; 491 492 case SIOCGIFNETMASK: 493 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask; 494 goto out; 495 | 444 case SIOCGIFADDR: 445 case SIOCGIFNETMASK: 446 case SIOCGIFDSTADDR: 447 case SIOCGIFBRDADDR: 448 if (ia == NULL) { 449 error = EADDRNOTAVAIL; 450 goto out; 451 } --- 24 unchanged lines hidden (view full) --- 476 } 477 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr; 478 goto out; 479 480 case SIOCGIFNETMASK: 481 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask; 482 goto out; 483 |
496 case SIOCSIFDSTADDR: 497 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 498 error = EINVAL; 499 goto out; 500 } 501 oldaddr = ia->ia_dstaddr; 502 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr; 503 if (ifp->if_ioctl != NULL) { 504 error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, 505 (caddr_t)ia); 506 if (error) { 507 ia->ia_dstaddr = oldaddr; 508 goto out; 509 } 510 } 511 if (ia->ia_flags & IFA_ROUTE) { 512 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr; 513 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 514 ia->ia_ifa.ifa_dstaddr = 515 (struct sockaddr *)&ia->ia_dstaddr; 516 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 517 } 518 goto out; 519 520 case SIOCSIFBRDADDR: 521 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 522 error = EINVAL; 523 goto out; 524 } 525 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr; 526 goto out; 527 528 case SIOCSIFADDR: 529 error = in_ifinit(ifp, ia, 530 (struct sockaddr_in *) &ifr->ifr_addr, 1, 0, 0); 531 if (error != 0 && iaIsNew) 532 break; 533 if (error == 0) { 534 ii = ((struct in_ifinfo *)ifp->if_afdata[AF_INET]); 535 if (iaIsFirst && 536 (ifp->if_flags & IFF_MULTICAST) != 0) { 537 error = in_joingroup(ifp, &allhosts_addr, 538 NULL, &ii->ii_allhosts); 539 } 540 EVENTHANDLER_INVOKE(ifaddr_event, ifp); 541 } 542 error = 0; 543 goto out; 544 545 case SIOCSIFNETMASK: 546 ia->ia_sockmask.sin_addr = ((struct sockaddr_in *) 547 &ifr->ifr_addr)->sin_addr; 548 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr); 549 goto out; 550 | |
551 case SIOCAIFADDR: 552 maskIsNew = 0; 553 hostIsNew = 1; 554 error = 0; 555 if (ifra->ifra_addr.sin_addr.s_addr == 556 ia->ia_addr.sin_addr.s_addr) 557 hostIsNew = 0; 558 if (ifra->ifra_mask.sin_len) { --- 15 unchanged lines hidden (view full) --- 574 } 575 if ((ifp->if_flags & IFF_POINTOPOINT) && 576 (ifra->ifra_dstaddr.sin_family == AF_INET)) { 577 in_ifscrub(ifp, ia, LLE_STATIC); 578 ia->ia_dstaddr = ifra->ifra_dstaddr; 579 maskIsNew = 1; /* We lie; but the effect's the same */ 580 } 581 if (hostIsNew || maskIsNew) | 484 case SIOCAIFADDR: 485 maskIsNew = 0; 486 hostIsNew = 1; 487 error = 0; 488 if (ifra->ifra_addr.sin_addr.s_addr == 489 ia->ia_addr.sin_addr.s_addr) 490 hostIsNew = 0; 491 if (ifra->ifra_mask.sin_len) { --- 15 unchanged lines hidden (view full) --- 507 } 508 if ((ifp->if_flags & IFF_POINTOPOINT) && 509 (ifra->ifra_dstaddr.sin_family == AF_INET)) { 510 in_ifscrub(ifp, ia, LLE_STATIC); 511 ia->ia_dstaddr = ifra->ifra_dstaddr; 512 maskIsNew = 1; /* We lie; but the effect's the same */ 513 } 514 if (hostIsNew || maskIsNew) |
582 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0, 583 maskIsNew, (ocmd == cmd ? ifra->ifra_vhid : 0)); | 515 error = in_ifinit(ifp, ia, &ifra->ifra_addr, maskIsNew, 516 (ocmd == cmd ? ifra->ifra_vhid : 0)); |
584 if (error != 0 && iaIsNew) 585 break; 586 587 if ((ifp->if_flags & IFF_BROADCAST) && 588 ifra->ifra_broadaddr.sin_len) 589 ia->ia_broadaddr = ifra->ifra_broadaddr; 590 if (error == 0) { 591 ii = ((struct in_ifinfo *)ifp->if_afdata[AF_INET]); --- 266 unchanged lines hidden (view full) --- 858} 859 860/* 861 * Initialize an interface's internet address 862 * and routing table entry. 863 */ 864static int 865in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, | 517 if (error != 0 && iaIsNew) 518 break; 519 520 if ((ifp->if_flags & IFF_BROADCAST) && 521 ifra->ifra_broadaddr.sin_len) 522 ia->ia_broadaddr = ifra->ifra_broadaddr; 523 if (error == 0) { 524 ii = ((struct in_ifinfo *)ifp->if_afdata[AF_INET]); --- 266 unchanged lines hidden (view full) --- 791} 792 793/* 794 * Initialize an interface's internet address 795 * and routing table entry. 796 */ 797static int 798in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, |
866 int scrub, int masksupplied, int vhid) | 799 int masksupplied, int vhid) |
867{ 868 register u_long i = ntohl(sin->sin_addr.s_addr); 869 int flags = RTF_UP, error = 0; 870 | 800{ 801 register u_long i = ntohl(sin->sin_addr.s_addr); 802 int flags = RTF_UP, error = 0; 803 |
871 if (scrub) 872 in_scrubprefix(ia, LLE_STATIC); 873 | |
874 IN_IFADDR_WLOCK(); 875 if (ia->ia_addr.sin_family == AF_INET) 876 LIST_REMOVE(ia, ia_hash); 877 ia->ia_addr = *sin; 878 LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), 879 ia, ia_hash); 880 IN_IFADDR_WUNLOCK(); 881 --- 789 unchanged lines hidden --- | 804 IN_IFADDR_WLOCK(); 805 if (ia->ia_addr.sin_family == AF_INET) 806 LIST_REMOVE(ia, ia_hash); 807 ia->ia_addr = *sin; 808 LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), 809 ia, ia_hash); 810 IN_IFADDR_WUNLOCK(); 811 --- 789 unchanged lines hidden --- |