-/* raw_cb.c 4.4 82/03/05 */
+/* raw_cb.c 4.8 82/04/11 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../net/in_systm.h"
#include "../net/if.h"
#include "../net/raw_cb.h"
+#include "../net/pup.h"
#include "../errno.h"
/*
*
* TODO:
* hash lookups by protocol family/protocol + address family
- * take care of unique address problems per AF
+ * take care of unique address problems per AF?
* redo address binding to allow wildcards
*/
{
struct mbuf *m;
register struct rawcb *rp;
- struct ifnet *ifp = ifnet;
COUNT(RAW_ATTACH);
+ if (ifnet == 0)
+ return (EADDRNOTAVAIL);
/*
* Should we verify address not already in use?
* Some say yes, others no.
if (addr) switch (addr->sa_family) {
case AF_IMPLINK:
- case AF_INET: {
- register struct sockaddr_in *sin = (struct sockaddr_in *)addr;
-
- if (ifnet && sin->sin_addr.s_addr == 0)
- sin->sin_addr = ifnet->if_addr;
- ifp = if_ifwithaddr(sin->sin_addr);
+ case AF_INET:
+ if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
+ if_ifwithaddr(addr) == 0)
+ return (EADDRNOTAVAIL);
break;
- }
- case AF_PUP:
- ifp = ifnet;
+#ifdef PUP
+ /*
+ * Curious, we convert PUP address format to internet
+ * to allow us to verify we're asking for an Ethernet
+ * interface. This is wrong, but things are heavily
+ * oriented towards the internet addressing scheme, and
+ * converting internet to PUP would be very expensive.
+ */
+ case AF_PUP: {
+ struct sockaddr_pup *spup = (struct sockaddr_pup *)addr;
+ struct sockaddr_in inpup;
+
+ bzero((caddr_t)&inpup, sizeof(inpup));
+ inpup.sin_family = AF_INET;
+ inpup.sin_addr.s_net = spup->sp_net;
+ inpup.sin_addr.s_impno = spup->sp_host;
+ if (inpup.sin_addr.s_addr &&
+ if_ifwithaddr((struct sockaddr *)&inpup) == 0)
+ return (EADDRNOTAVAIL);
break;
+ }
+#endif
default:
return (EAFNOSUPPORT);
}
- if (ifp == 0)
- return (EADDRNOTAVAIL);
m = m_getclr(M_DONTWAIT);
if (m == 0)
return (ENOBUFS);
insque(rp, &rawcb);
so->so_pcb = (caddr_t)rp;
rp->rcb_pcb = 0;
-
- if (addr)
- bcopy(addr, &so->so_addr, sizeof(*addr));
+ if (addr) {
+ bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof(*addr));
+ rp->rcb_flags |= RAW_LADDR;
+ }
return (0);
bad2:
sbrelease(&so->so_snd);
struct rawcb *rp;
{
COUNT(RAW_DISCONNECT);
- rp->rcb_flags &= ~RAW_ADDR;
+ rp->rcb_flags &= ~RAW_FADDR;
if (rp->rcb_socket->so_state & SS_USERGONE)
raw_detach(rp);
}
struct sockaddr *addr;
{
COUNT(RAW_CONNADDR);
- bcopy(addr, &rp->rcb_addr, sizeof(struct sockaddr));
- rp->rcb_flags |= RAW_ADDR;
+ bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
+ rp->rcb_flags |= RAW_FADDR;
}