static char *udpannounce(struct conv *c, char **argv, int argc) { char *e; Udppriv *upriv; upriv = c->p->priv; e = Fsstdannounce(c, argv, argc); if (e != NULL) return e; Fsconnected(c, NULL); iphtadd(&upriv->ht, c); return NULL; }
static char* rudpconnect(Conv *c, char **argv, int argc) { char *e; Rudppriv *upriv; upriv = c->p->priv; rudpstartackproc(c->p); e = Fsstdconnect(c, argv, argc); Fsconnected(c, e); iphtadd(&upriv->ht, c); return e; }
static char* udpannounce(Conv *c, char** argv, int argc) { char *e; Udppriv *upriv; upriv = c->p->priv; e = Fsstdannounce(c, argv, argc); if(e != nil) return e; Fsconnected(c, nil); iphtadd(&upriv->ht, c); return nil; }
void udpiput(struct Proto *udp, struct Ipifc *ifc, struct block *bp) { int len; Udp4hdr *uh4; Udp6hdr *uh6; struct conv *c; Udpcb *ucb; uint8_t raddr[IPaddrlen], laddr[IPaddrlen]; uint16_t rport, lport; Udppriv *upriv; struct Fs *f; int version; int ottl, oviclfl, olen; uint8_t *p; upriv = udp->priv; f = udp->f; upriv->ustats.udpInDatagrams++; uh4 = (Udp4hdr *) (bp->rp); version = ((uh4->vihl & 0xF0) == IP_VER6) ? V6 : V4; /* * Put back pseudo header for checksum * (remember old values for icmpnoconv()) */ switch (version) { case V4: ottl = uh4->Unused; uh4->Unused = 0; len = nhgets(uh4->udplen); olen = nhgets(uh4->udpplen); hnputs(uh4->udpplen, len); v4tov6(raddr, uh4->udpsrc); v4tov6(laddr, uh4->udpdst); lport = nhgets(uh4->udpdport); rport = nhgets(uh4->udpsport); if (!(bp->flag & Budpck) && (uh4->udpcksum[0] || uh4->udpcksum[1]) && ptclcsum(bp, UDP4_PHDR_OFF, len + UDP4_PHDR_SZ)) { upriv->ustats.udpInErrors++; netlog(f, Logudp, "udp: checksum error %I\n", raddr); printd("udp: checksum error %I\n", raddr); freeblist(bp); return; } uh4->Unused = ottl; hnputs(uh4->udpplen, olen); break; case V6: uh6 = (Udp6hdr *) (bp->rp); len = nhgets(uh6->udplen); oviclfl = nhgetl(uh6->viclfl); olen = nhgets(uh6->len); ottl = uh6->hoplimit; ipmove(raddr, uh6->udpsrc); ipmove(laddr, uh6->udpdst); lport = nhgets(uh6->udpdport); rport = nhgets(uh6->udpsport); memset(uh6, 0, 8); hnputl(uh6->viclfl, len); uh6->hoplimit = IP_UDPPROTO; if (ptclcsum(bp, UDP6_PHDR_OFF, len + UDP6_PHDR_SZ)) { upriv->ustats.udpInErrors++; netlog(f, Logudp, "udp: checksum error %I\n", raddr); printd("udp: checksum error %I\n", raddr); freeblist(bp); return; } hnputl(uh6->viclfl, oviclfl); hnputs(uh6->len, olen); uh6->nextheader = IP_UDPPROTO; uh6->hoplimit = ottl; break; default: panic("udpiput: version %d", version); return; /* to avoid a warning */ } qlock(&udp->qlock); c = iphtlook(&upriv->ht, raddr, rport, laddr, lport); if (c == NULL) { /* no converstation found */ upriv->ustats.udpNoPorts++; qunlock(&udp->qlock); netlog(f, Logudp, "udp: no conv %I!%d -> %I!%d\n", raddr, rport, laddr, lport); switch (version) { case V4: icmpnoconv(f, bp); break; case V6: icmphostunr(f, ifc, bp, icmp6_port_unreach, 0); break; default: panic("udpiput2: version %d", version); } freeblist(bp); return; } ucb = (Udpcb *) c->ptcl; if (c->state == Announced) { if (ucb->headers == 0) { /* create a new conversation */ if (ipforme(f, laddr) != Runi) { switch (version) { case V4: v4tov6(laddr, ifc->lifc->local); break; case V6: ipmove(laddr, ifc->lifc->local); break; default: panic("udpiput3: version %d", version); } } c = Fsnewcall(c, raddr, rport, laddr, lport, version); if (c == NULL) { qunlock(&udp->qlock); freeblist(bp); return; } iphtadd(&upriv->ht, c); ucb = (Udpcb *) c->ptcl; } } qlock(&c->qlock); qunlock(&udp->qlock); /* * Trim the packet down to data size */ len -= UDP_UDPHDR_SZ; switch (version) { case V4: bp = trimblock(bp, UDP4_IPHDR_SZ + UDP_UDPHDR_SZ, len); break; case V6: bp = trimblock(bp, UDP6_IPHDR_SZ + UDP_UDPHDR_SZ, len); break; default: bp = NULL; panic("udpiput4: version %d", version); } if (bp == NULL) { qunlock(&c->qlock); netlog(f, Logudp, "udp: len err %I.%d -> %I.%d\n", raddr, rport, laddr, lport); upriv->lenerr++; return; } netlog(f, Logudpmsg, "udp: %I.%d -> %I.%d l %d\n", raddr, rport, laddr, lport, len); switch (ucb->headers) { case 7: /* pass the src address */ bp = padblock(bp, UDP_USEAD7); p = bp->rp; ipmove(p, raddr); p += IPaddrlen; ipmove(p, laddr); p += IPaddrlen; ipmove(p, ifc->lifc->local); p += IPaddrlen; hnputs(p, rport); p += 2; hnputs(p, lport); break; case 6: /* pass the src address */ bp = padblock(bp, UDP_USEAD6); p = bp->rp; ipmove(p, raddr); p += IPaddrlen; ipmove(p, ipforme(f, laddr) == Runi ? laddr : ifc->lifc->local); p += IPaddrlen; hnputs(p, rport); p += 2; hnputs(p, lport); break; } if (bp->next) bp = concatblock(bp); if (qfull(c->rq)) { qunlock(&c->qlock); netlog(f, Logudp, "udp: qfull %I.%d -> %I.%d\n", raddr, rport, laddr, lport); freeblist(bp); return; } qpass(c->rq, bp); qunlock(&c->qlock); }