* Copyright (c) 1982 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)ns.c 6.4 (Berkeley) %G%
#include "../net/route.h"
struct ns_ifaddr
*ns_ifaddr
;
register struct sockaddr_ns
*sns
;
register u_short
*s
= sns
->sns_addr
.x_host
.s_host
;
hp
->afh_nethash
= ns_netof(sns
->sns_addr
);
hash
= *s
++; hash
<<= 8; hash
+= *s
++; hash
<<= 8; hash
+= *s
;
struct sockaddr_ns
*sns1
, *sns2
;
return (ns_netof(sns1
->sns_addr
) == ns_netof(sns2
->sns_addr
));
* Generic internet control operations (ioctl's).
ns_control(so
, cmd
, data
, ifp
)
register struct ifnet
*ifp
;
register struct ifreq
*ifr
= (struct ifreq
*)data
;
register struct ns_ifaddr
*ia
;
* Find address for this interface, if it exists.
for (ia
= ns_ifaddr
; ia
; ia
= ia
->ia_next
)
if (ia
== (struct ns_ifaddr
*)0)
ifr
->ifr_addr
= ia
->ia_addr
;
if (ia
== (struct ns_ifaddr
*)0)
if ((ifp
->if_flags
& IFF_BROADCAST
) == 0)
ifr
->ifr_dstaddr
= ia
->ia_broadaddr
;
if (ia
== (struct ns_ifaddr
*)0)
if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0)
ifr
->ifr_dstaddr
= ia
->ia_dstaddr
;
if (ia
== (struct ns_ifaddr
*)0) {
m
= m_getclr(M_WAIT
, MT_IFADDR
);
if (m
== (struct mbuf
*)NULL
)
for ( ; ia
->ia_next
; ia
= ia
->ia_next
)
ia
->ia_next
= mtod(m
, struct ns_ifaddr
*);
ns_ifaddr
= mtod(m
, struct ns_ifaddr
*);
ia
= mtod(m
, struct ns_ifaddr
*);
if (ifa
= ifp
->if_addrlist
) {
for ( ; ifa
->ifa_next
; ifa
= ifa
->ifa_next
)
ifa
->ifa_next
= (struct ifaddr
*) ia
;
ifp
->if_addrlist
= (struct ifaddr
*) ia
;
IA_SNS(ia
)->sns_family
= AF_NS
;
(ns_ifinit(ifp
, ia
, (struct sockaddr_ns
*)&ifr
->ifr_addr
));
return ((*ifp
->if_ioctl
)(ifp
, cmd
, data
));
* Initialize an interface's internet address
* and routing table entry.
register struct ifnet
*ifp
;
register struct ns_ifaddr
*ia
;
struct sockaddr_ns netaddr
;
register union ns_host
*h
= &(IA_SNS(ia
)->sns_addr
.x_host
);
* The convention we shall adopt for naming is that
* a supplied address of zero means that "we don't care".
* if there is a single interface, use the address of that
* interface as our 6 byte host address.
* if there are multiple interfaces, use any address already
* If we have gotten into trouble and want to reset back to
* virginity, we recognize a request of the broadcast address.
if (ns_hosteqnh(sns
->sns_addr
.x_host
, ns_broadhost
)) {
ns_thishost
= ns_zerohost
;
* Delete any previous route for an old address.
bzero((caddr_t
)&netaddr
, sizeof (netaddr
));
netaddr
.sns_family
= AF_NS
;
netaddr
.sns_addr
.x_host
= ns_broadhost
;
netaddr
.sns_addr
.x_net
= ia
->ia_net
;
if (ia
->ia_flags
& IFA_ROUTE
) {
if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0) {
rtinit((struct sockaddr
*)&netaddr
, &ia
->ia_addr
, -1);
rtinit((struct sockaddr
*)&ia
->ia_dstaddr
, &ia
->ia_addr
, -1);
ia
->ia_addr
= *(struct sockaddr
*)sns
;
ia
->ia_net
= sns
->sns_addr
.x_net
;
netaddr
.sns_addr
.x_net
= ia
->ia_net
;
if (ifp
->if_flags
& IFF_BROADCAST
) {
ia
->ia_broadaddr
= * (struct sockaddr
*) &netaddr
;
* Point to point links are a little touchier --
* We have to have an address of our own first,
* and will use the supplied address as that of the other end.
if (ifp
->if_flags
& IFF_POINTOPOINT
) {
struct sockaddr_ns
*sns2
= IA_SNS(ia
);
if (ns_hosteqnh(ns_zerohost
,ns_thishost
))
ia
->ia_dstaddr
= ia
->ia_addr
;
sns2
->sns_addr
.x_host
= ns_thishost
;
sns
->sns_addr
.x_host
= ns_thishost
;
* Give the interface a chance to initialize
* if this is its first address,
* and to validate the address if necessary.
if (ns_hosteqnh(ns_thishost
, ns_zerohost
)) {
(error
= (*ifp
->if_ioctl
)(ifp
, SIOCSIFADDR
, ia
))) {
} else if (ns_hosteqnh(sns
->sns_addr
.x_host
, ns_zerohost
)
|| ns_hosteqnh(sns
->sns_addr
.x_host
, ns_thishost
)) {
(error
= (*ifp
->if_ioctl
)(ifp
, SIOCSIFADDR
, ia
))) {
if(!ns_hosteqnh(ns_thishost
,*h
)) {
* Add route for the network.
if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0) {
rtinit((struct sockaddr
*)&netaddr
, &ia
->ia_addr
, RTF_UP
);
rtinit((struct sockaddr
*)&ia
->ia_dstaddr
, &ia
->ia_addr
,
ia
->ia_flags
|= IFA_ROUTE
;
* Return address info for specified internet network.
register struct ns_ifaddr
*ia
;
#define NtoL(x) (*(long *)(&(x)))
for (ia
= ns_ifaddr
; ia
; ia
= ia
->ia_next
)
if (NtoL(ia
->ia_net
) == NtoL(net
))
return ((struct ns_ifaddr
*)0);