* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#)ns_input.c 7.6 (Berkeley) %G%
+ * @(#)ns_input.c 7.4 (Berkeley) 6/29/88
*/
#include "param.h"
#include "systm.h"
-#include "malloc.h"
#include "mbuf.h"
#include "domain.h"
#include "protosw.h"
union ns_host ns_broadhost;
union ns_net ns_zeronet;
union ns_net ns_broadnet;
-struct sockaddr_ns ns_netmask, ns_hostmask;
static u_short allones[] = {-1, -1, -1};
nsrawpcb.nsp_next = nsrawpcb.nsp_prev = &nsrawpcb;
nsintrq.ifq_maxlen = nsqmaxlen;
ns_pexseq = time.tv_usec;
- ns_netmask.sns_len = 6;
- ns_netmask.sns_addr.x_net = ns_broadnet;
- ns_hostmask.sns_len = 12;
- ns_hostmask.sns_addr.x_net = ns_broadnet;
- ns_hostmask.sns_addr.x_host = ns_broadhost;
}
/*
register struct idp *idp;
register struct mbuf *m;
register struct nspcb *nsp;
+ struct ifnet *ifp;
+ struct mbuf *m0;
register int i;
int len, s, error;
char oddpacketp;
* in first mbuf.
*/
s = splimp();
- IF_DEQUEUE(&nsintrq, m);
+ IF_DEQUEUEIF(&nsintrq, m, ifp);
splx(s);
nsintr_getpck++;
if (m == 0)
return;
- if ((m->m_flags & M_EXT || m->m_len < sizeof (struct idp)) &&
+ if ((m->m_off > MMAXOFF || m->m_len < sizeof (struct idp)) &&
(m = m_pullup(m, sizeof (struct idp))) == 0) {
idpstat.idps_toosmall++;
goto next;
*/
for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
struct mbuf *m1 = m_copy(m, 0, (int)M_COPYALL);
- if (m1) idp_input(m1, nsp);
+ if (m1) idp_input(m1, nsp, ifp);
}
idp = mtod(m, struct idp *);
* Trim mbufs if longer than we expect.
* Drop packet if shorter than we expect.
*/
- if (m->m_pkthdr.len < len) {
- idpstat.idps_tooshort++;
- goto bad;
+ i = -len;
+ m0 = m;
+ for (;;) {
+ i += m->m_len;
+ if (m->m_next == 0)
+ break;
+ m = m->m_next;
}
- if (m->m_pkthdr.len > len) {
- if (m->m_len == m->m_pkthdr.len) {
- m->m_len = len;
- m->m_pkthdr.len = len;
- } else
- m_adj(m, len - m->m_pkthdr.len);
+ if (i != 0) {
+ if (i < 0) {
+ idpstat.idps_tooshort++;
+ m = m0;
+ goto bad;
+ }
+ if (i <= m->m_len)
+ m->m_len -= i;
+ else
+ m_adj(m0, -i);
}
+ m = m0;
if (idpcksum && ((i = idp->idp_sum)!=0xffff)) {
idp->idp_sum = 0;
- if (i != (idp->idp_sum = ns_cksum(m, len))) {
+ if (i != (idp->idp_sum = ns_cksum(m,len))) {
idpstat.idps_badsum++;
idp->idp_sum = i;
if (ns_hosteqnh(ns_thishost, idp->idp_dna.x_host))
* Suggestion of Bill Nesheim, Cornell U.
*/
if (idp->idp_tc < NS_MAXHOPS) {
- idp_forward(m);
+ idp_forward(idp);
goto next;
}
}
* Is this our packet? If not, forward.
*/
} else if (!ns_hosteqnh(ns_thishost,idp->idp_dna.x_host)) {
- idp_forward(m);
+ idp_forward(idp);
goto next;
}
/*
nsintr_swtch++;
if (nsp) {
if (oddpacketp) {
- m_adj(m, -1);
+ m_adj(m0, -1);
}
if ((nsp->nsp_flags & NSP_ALL_PACKETS)==0)
switch (idp->idp_pt) {
case NSPROTO_SPP:
- spp_input(m, nsp);
+ spp_input(m, nsp, ifp);
goto next;
case NSPROTO_ERROR:
ns_err_input(m);
goto next;
}
- idp_input(m, nsp);
+ idp_input(m, nsp, ifp);
} else {
ns_error(m, NS_ERR_NOSOCK, 0);
}
case PRC_HOSTDEAD:
case PRC_HOSTUNREACH:
sns = (struct sockaddr_ns *)arg;
- if (sns->sns_family != AF_NS)
+ if (sns->sns_family != AF_INET)
return;
ns = &sns->sns_addr;
break;
struct route idp_droute;
struct route idp_sroute;
-idp_forward(m)
-struct mbuf *m;
+idp_forward(idp)
+ register struct idp *idp;
{
- register struct idp *idp = mtod(m, struct idp *);
register int error, type, code;
struct mbuf *mcopy = NULL;
int agedelta = 1;
* Save at most 42 bytes of the packet in case
* we need to generate an NS error message to the src.
*/
- mcopy = m_copy(m, 0, imin((int)ntohs(idp->idp_len), 42));
+ mcopy = m_copy(dtom(idp), 0, imin((int)ntohs(idp->idp_len), 42));
if ((ok_there = idp_do_route(&idp->idp_dna,&idp_droute))==0) {
type = NS_ERR_UNREACH_HOST, code = 0;
}
if ((ok_back = idp_do_route(&idp->idp_sna,&idp_sroute))==0) {
/* error = ENETUNREACH; He'll never get it! */
- m_freem(m);
+ m_freem(dtom(idp));
goto cleanup;
}
if (idp_droute.ro_rt &&
x.l = x.s[0] + x.s[1];
if (x.l==0xffff) idp->idp_sum = 0; else idp->idp_sum = x.l;
}
- if ((error = ns_output(m, &idp_droute, flags)) &&
+ if ((error = ns_output(dtom(idp), &idp_droute, flags)) &&
(mcopy!=NULL)) {
idp = mtod(mcopy, struct idp *);
type = NS_ERR_UNSPEC_T, code = 0;
}
mcopy = NULL;
senderror:
- ns_error(m, type, code);
+ ns_error(dtom(idp), type, code);
}
cleanup:
if (ok_there)
bzero((caddr_t)ro, sizeof (*ro));
dst = (struct sockaddr_ns *)&ro->ro_dst;
- dst->sns_len = sizeof(*dst);
dst->sns_family = AF_NS;
dst->sns_addr = *src;
dst->sns_addr.x_port = 0;
struct ifnet *ifp;
{
register struct nspcb *nsp;
- register struct ifaddr *ifa;
+ register struct ifaddr *ia;
/*
* Give any raw listeners a crack at the packet
*/
for (nsp = nsrawpcb.nsp_next; nsp != &nsrawpcb; nsp = nsp->nsp_next) {
struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
if (m0) {
- register struct idp *idp;
-
- M_PREPEND(m0, sizeof (*idp), M_DONTWAIT);
- if (m0 == NULL)
- continue;
- idp = mtod(m0, struct idp *);
- idp->idp_sna.x_net = ns_zeronet;
- idp->idp_sna.x_host = ns_thishost;
- if (ifp && (ifp->if_flags & IFF_POINTOPOINT))
- for(ifa = ifp->if_addrlist; ifa;
- ifa = ifa->ifa_next) {
- if (ifa->ifa_addr->sa_family==AF_NS) {
- idp->idp_sna = IA_SNS(ifa)->sns_addr;
- break;
- }
- }
- idp->idp_len = ntohl(m0->m_pkthdr.len);
- idp_input(m0, nsp);
+ struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
+
+ if(m1 == NULL)
+ m_freem(m0);
+ else {
+ register struct idp *idp;
+
+ m1->m_off = MMINOFF;
+ m1->m_len = sizeof (*idp);
+ m1->m_next = m0;
+ idp = mtod(m1, struct idp *);
+ idp->idp_sna.x_net = ns_zeronet;
+ idp->idp_sna.x_host = ns_thishost;
+ if (ifp && (ifp->if_flags & IFF_POINTOPOINT))
+ for(ia = ifp->if_addrlist; ia;
+ ia = ia->ifa_next) {
+ if (ia->ifa_addr.sa_family==AF_NS) {
+ idp->idp_sna =
+ satons_addr(ia->ifa_dstaddr);
+ break;
+ }
+ }
+ idp->idp_len = 0xffff;
+ idp_input(m1, nsp, ifp);
+ }
}
}
}