Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/in.c
Show First 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | |||||
#include <netinet/ip_var.h> | #include <netinet/ip_var.h> | ||||
#include <netinet/ip_carp.h> | #include <netinet/ip_carp.h> | ||||
#include <netinet/igmp_var.h> | #include <netinet/igmp_var.h> | ||||
#include <netinet/udp.h> | #include <netinet/udp.h> | ||||
#include <netinet/udp_var.h> | #include <netinet/udp_var.h> | ||||
static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *); | static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *); | ||||
static int in_difaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *); | static int in_difaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *); | ||||
static int in_gifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *); | |||||
static void in_socktrim(struct sockaddr_in *); | static void in_socktrim(struct sockaddr_in *); | ||||
static void in_purgemaddrs(struct ifnet *); | static void in_purgemaddrs(struct ifnet *); | ||||
VNET_DEFINE_STATIC(int, nosameprefix); | VNET_DEFINE_STATIC(int, nosameprefix); | ||||
#define V_nosameprefix VNET(nosameprefix) | #define V_nosameprefix VNET(nosameprefix) | ||||
SYSCTL_INT(_net_inet_ip, OID_AUTO, no_same_prefix, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_ip, OID_AUTO, no_same_prefix, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(nosameprefix), 0, | &VNET_NAME(nosameprefix), 0, | ||||
▲ Show 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, | ||||
* to specific functions and ifp->if_ioctl(). | * to specific functions and ifp->if_ioctl(). | ||||
*/ | */ | ||||
switch (cmd) { | switch (cmd) { | ||||
case SIOCGIFADDR: | case SIOCGIFADDR: | ||||
case SIOCGIFBRDADDR: | case SIOCGIFBRDADDR: | ||||
case SIOCGIFDSTADDR: | case SIOCGIFDSTADDR: | ||||
case SIOCGIFNETMASK: | case SIOCGIFNETMASK: | ||||
break; | break; | ||||
case SIOCGIFALIAS: | |||||
sx_xlock(&in_control_sx); | |||||
error = in_gifaddr_ioctl(cmd, data, ifp, td); | |||||
sx_xunlock(&in_control_sx); | |||||
return (error); | |||||
case SIOCDIFADDR: | case SIOCDIFADDR: | ||||
sx_xlock(&in_control_sx); | sx_xlock(&in_control_sx); | ||||
error = in_difaddr_ioctl(cmd, data, ifp, td); | error = in_difaddr_ioctl(cmd, data, ifp, td); | ||||
sx_xunlock(&in_control_sx); | sx_xunlock(&in_control_sx); | ||||
return (error); | return (error); | ||||
case OSIOCAIFADDR: /* 9.x compat */ | case OSIOCAIFADDR: /* 9.x compat */ | ||||
case SIOCAIFADDR: | case SIOCAIFADDR: | ||||
sx_xlock(&in_control_sx); | sx_xlock(&in_control_sx); | ||||
▲ Show 20 Lines • Show All 393 Lines • ▼ Show 20 Lines | if (callout_stop(&ia->ia_garp_timer) == 1) { | ||||
ifa_free(&ia->ia_ifa); | ifa_free(&ia->ia_ifa); | ||||
} | } | ||||
IF_ADDR_WUNLOCK(ifp); | IF_ADDR_WUNLOCK(ifp); | ||||
EVENTHANDLER_INVOKE(ifaddr_event_ext, ifp, &ia->ia_ifa, | EVENTHANDLER_INVOKE(ifaddr_event_ext, ifp, &ia->ia_ifa, | ||||
IFADDR_EVENT_DEL); | IFADDR_EVENT_DEL); | ||||
ifa_free(&ia->ia_ifa); /* in_ifaddrhead */ | ifa_free(&ia->ia_ifa); /* in_ifaddrhead */ | ||||
return (0); | |||||
} | |||||
static int | |||||
in_gifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td) | |||||
{ | |||||
struct in_aliasreq *ifra = (struct in_aliasreq *)data; | |||||
const struct sockaddr_in *addr = &ifra->ifra_addr; | |||||
struct epoch_tracker et; | |||||
struct ifaddr *ifa; | |||||
struct in_ifaddr *ia; | |||||
/* | |||||
* ifra_addr must be present and be of INET family. | |||||
*/ | |||||
if (addr->sin_len != sizeof(struct sockaddr_in) || | |||||
addr->sin_family != AF_INET) | |||||
return (EINVAL); | |||||
/* | |||||
* See whether address exist. | |||||
*/ | |||||
ia = NULL; | |||||
NET_EPOCH_ENTER(et); | |||||
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { | |||||
struct in_ifaddr *it; | |||||
if (ifa->ifa_addr->sa_family != AF_INET) | |||||
continue; | |||||
it = (struct in_ifaddr *)ifa; | |||||
if (it->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr && | |||||
prison_check_ip4(td->td_ucred, &addr->sin_addr) == 0) { | |||||
ia = it; | |||||
break; | |||||
} | |||||
} | |||||
if (ia == NULL) { | |||||
NET_EPOCH_EXIT(et); | |||||
return (EADDRNOTAVAIL); | |||||
} | |||||
ifra->ifra_mask = ia->ia_sockmask; | |||||
if ((ifp->if_flags & IFF_POINTOPOINT) && | |||||
ia->ia_dstaddr.sin_family == AF_INET) | |||||
ifra->ifra_dstaddr = ia->ia_dstaddr; | |||||
else if ((ifp->if_flags & IFF_BROADCAST) && | |||||
ia->ia_broadaddr.sin_family == AF_INET) | |||||
ifra->ifra_broadaddr = ia->ia_broadaddr; | |||||
else | |||||
memset(&ifra->ifra_broadaddr, 0, | |||||
sizeof(ifra->ifra_broadaddr)); | |||||
NET_EPOCH_EXIT(et); | |||||
return (0); | return (0); | ||||
} | } | ||||
#define rtinitflags(x) \ | #define rtinitflags(x) \ | ||||
((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \ | ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \ | ||||
? RTF_HOST : 0) | ? RTF_HOST : 0) | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 853 Lines • Show Last 20 Lines |