* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)if.c 6.13 (Berkeley) %G%
int ifqmaxlen
= IFQ_MAXLEN
;
* Network interface utility routines.
* Routines with ifa_ifwith* names take sockaddr *'s as
register struct ifnet
*ifp
;
for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
)
if (ifp
->if_snd
.ifq_maxlen
== 0)
ifp
->if_snd
.ifq_maxlen
= ifqmaxlen
;
* Call each interface on a Unibus reset.
register struct ifnet
*ifp
;
for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
)
(*ifp
->if_reset
)(ifp
->if_unit
, uban
);
* Attach an interface to the
* list of "active" interfaces.
register struct ifnet
**p
= &ifnet
;
* Locate an interface based on a complete address.
register struct ifnet
*ifp
;
register struct ifaddr
*ifa
;
(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
)
for (ifa
= ifp
->if_addrlist
; ifa
; ifa
= ifa
->ifa_next
) {
if (ifa
->ifa_addr
.sa_family
!= addr
->sa_family
)
if (equal(&ifa
->ifa_addr
, addr
))
if ((ifp
->if_flags
& IFF_BROADCAST
) &&
equal(&ifa
->ifa_broadaddr
, addr
))
return ((struct ifaddr
*)0);
* Locate the point to point interface with a given destination address.
register struct ifnet
*ifp
;
register struct ifaddr
*ifa
;
for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
)
if (ifp
->if_flags
& IFF_POINTOPOINT
)
for (ifa
= ifp
->if_addrlist
; ifa
; ifa
= ifa
->ifa_next
) {
if (ifa
->ifa_addr
.sa_family
!= addr
->sa_family
)
if (equal(&ifa
->ifa_dstaddr
, addr
))
return ((struct ifaddr
*)0);
* Find an interface on a specific network. If many, choice
register struct sockaddr
*addr
;
register struct ifnet
*ifp
;
register struct ifaddr
*ifa
;
register u_int af
= addr
->sa_family
;
register int (*netmatch
)();
netmatch
= afswitch
[af
].af_netmatch
;
for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
)
for (ifa
= ifp
->if_addrlist
; ifa
; ifa
= ifa
->ifa_next
) {
if (ifa
->ifa_addr
.sa_family
!= addr
->sa_family
)
if ((*netmatch
)(&ifa
->ifa_addr
, addr
))
return ((struct ifaddr
*)0);
* Find an interface using a specific address family
register struct ifnet
*ifp
;
register struct ifaddr
*ifa
;
for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
)
for (ifa
= ifp
->if_addrlist
; ifa
; ifa
= ifa
->ifa_next
)
if (ifa
->ifa_addr
.sa_family
== af
)
return ((struct ifaddr
*)0);
* Mark an interface down and notify protocols of
* NOTE: must be called at splnet or eqivalent.
register struct ifnet
*ifp
;
register struct ifaddr
*ifa
;
ifp
->if_flags
&= ~IFF_UP
;
for (ifa
= ifp
->if_addrlist
; ifa
; ifa
= ifa
->ifa_next
)
pfctlinput(PRC_IFDOWN
, &ifa
->ifa_addr
);
* Handle interface watchdog timer routines. Called
* from softclock, we decrement timers (if set) and
* call the appropriate interface routine on expiration.
register struct ifnet
*ifp
;
for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
) {
if (ifp
->if_timer
== 0 || --ifp
->if_timer
)
(*ifp
->if_watchdog
)(ifp
->if_unit
);
timeout(if_slowtimo
, (caddr_t
)0, hz
/ IFNET_SLOWHZ
);
* interface structure pointer.
register struct ifnet
*ifp
;
for (cp
= name
; cp
< name
+ IFNAMSIZ
&& *cp
; cp
++)
if (*cp
>= '0' && *cp
<= '9')
if (*cp
== '\0' || cp
== name
+ IFNAMSIZ
)
return ((struct ifnet
*)0);
for (ifp
= ifnet
; ifp
; ifp
= ifp
->if_next
) {
if (bcmp(ifp
->if_name
, name
, (unsigned)(cp
- name
)))
if (unit
== ifp
->if_unit
)
register struct ifnet
*ifp
;
register struct ifreq
*ifr
;
return (ifconf(cmd
, data
));
#if defined(INET) && NETHER > 0
return (arpioctl(cmd
, data
));
ifr
= (struct ifreq
*)data
;
ifp
= ifunit(ifr
->ifr_name
);
ifr
->ifr_flags
= ifp
->if_flags
;
ifr
->ifr_metric
= ifp
->if_metric
;
if (ifp
->if_flags
& IFF_UP
&& (ifr
->ifr_flags
& IFF_UP
) == 0) {
ifp
->if_flags
= (ifp
->if_flags
& IFF_CANTCHANGE
) |
(ifr
->ifr_flags
&~ IFF_CANTCHANGE
);
(void) (*ifp
->if_ioctl
)(ifp
, cmd
, data
);
ifp
->if_metric
= ifr
->ifr_metric
;
return ((*so
->so_proto
->pr_usrreq
)(so
, PRU_CONTROL
,
* Return interface configuration
* of system. List may be used
* in later ioctl's (above) to get
register struct ifconf
*ifc
= (struct ifconf
*)data
;
register struct ifnet
*ifp
= ifnet
;
register struct ifaddr
*ifa
;
int space
= ifc
->ifc_len
, error
= 0;
ep
= ifr
.ifr_name
+ sizeof (ifr
.ifr_name
) - 2;
for (; space
> sizeof (ifr
) && ifp
; ifp
= ifp
->if_next
) {
bcopy(ifp
->if_name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
) - 2);
for (cp
= ifr
.ifr_name
; cp
< ep
&& *cp
; cp
++)
*cp
++ = '0' + ifp
->if_unit
; *cp
= '\0';
if ((ifa
= ifp
->if_addrlist
) == 0) {
bzero((caddr_t
)&ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
error
= copyout((caddr_t
)&ifr
, (caddr_t
)ifrp
, sizeof (ifr
));
space
-= sizeof (ifr
), ifrp
++;
for ( ; space
> sizeof (ifr
) && ifa
; ifa
= ifa
->ifa_next
) {
ifr
.ifr_addr
= ifa
->ifa_addr
;
error
= copyout((caddr_t
)&ifr
, (caddr_t
)ifrp
, sizeof (ifr
));
space
-= sizeof (ifr
), ifrp
++;