ipoput4()

ipoput4()

概要

  • /sys/src/9/ip/ip.c?にて定義

引数

実装

  223: int
  224: ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos, Conv *c)
  225: {
  226:         Ipifc *ifc;
  227:         uchar *gate;
  228:         ulong fragoff;
  229:         Block *xp, *nb;
  230:         Ip4hdr *eh, *feh;
  231:         int lid, len, seglen, chunk, dlen, blklen, offset, medialen;
  232:         Route *r, *sr;
  233:         IP *ip;
  234:         int rv = 0;
  235: 
  236:         ip = f->ip;
  237: 
  238:         /* Fill out the ip header */
  239:         eh = (Ip4hdr*)(bp->rp);
  240: 
  241:         ip->stats[OutRequests]++;
  242: 
  243:         /* Number of uchars in data and ip header to write */
  244:         len = blocklen(bp);
  245: 
  246:         if(gating){
  247:                 chunk = nhgets(eh->length);
  • 詳細はnhgets()?にて定義
  248:                 if(chunk > len){
  249:                         ip->stats[OutDiscards]++;
  250:                         netlog(f, Logip, "short gated packet\n");
  251:                         goto free;
  252:                 }
  253:                 if(chunk < len)
  254:                         len = chunk;
  255:         }
  256:         if(len >= IP_MAX){
  257:                 ip->stats[OutDiscards]++;
  258:                 netlog(f, Logip, "exceeded ip max size %V\n", eh->dst);
  259:                 goto free;
  260:         }
  261: 
  262:         r = v4lookup(f, eh->dst, c);
  263:         if(r == nil){
  264:                 ip->stats[OutNoRoutes]++;
  265:                 netlog(f, Logip, "no interface %V\n", eh->dst);
  266:                 rv = -1;
  267:                 goto free;
  268:         }
  269: 
  270:         ifc = r->ifc;
  271:         if(r->type & (Rifc|Runi))
  272:                 gate = eh->dst;
  273:         else
  274:         if(r->type & (Rbcast|Rmulti)) {
  275:                 gate = eh->dst;
  276:                 sr = v4lookup(f, eh->src, nil);
  277:                 if(sr != nil && (sr->type & Runi))
  278:                         ifc = sr->ifc;
  279:         }
  280:         else
  281:                 gate = r->v4.gate;
  282: 
  283:         if(!gating)
  284:                 eh->vihl = IP_VER4|IP_HLEN4;
  285:         eh->ttl = ttl;
  286:         if(!gating)
  287:                 eh->tos = tos;
  288: 
  289:         if(!canrlock(ifc))
  • 詳細はcanrlock()?にて定義
  290:                 goto free;
  291:         if(waserror()){
  • 詳細はwaserror()?にて定義
  292:                 runlock(ifc);
  293:                 nexterror();
  • 詳細はrunlock()?にて定義
  • 詳細はnexterrror()?にて定義
  294:         }
  295:         if(ifc->m == nil)
  296:                 goto raise;
  297: 
  298:         /* If we dont need to fragment just send it */
  299:         medialen = ifc->maxtu - ifc->m->hsize;
  300:         if(len <= medialen) {
  301:                 if(!gating)
  302:                         hnputs(eh->id, incref(&ip->id4));
  303:                 hnputs(eh->length, len);
  304:                 if(!gating){
  305:                         eh->frag[0] = 0;
  306:                         eh->frag[1] = 0;
  307:                 }
  308:                 eh->cksum[0] = 0;
  309:                 eh->cksum[1] = 0;
  310:                 hnputs(eh->cksum, ipcsum(&eh->vihl));
  311:                 ifc->m->bwrite(ifc, bp, V4, gate);
  312:                 runlock(ifc);
  313:                 poperror();
  • 詳細はpoperror()?にて定義
  314:                 return 0;
  315:         }