Annotation of researchv10no/ipc/mgrs/icmpmgr/icmpmgr.c, revision 1.1

1.1     ! root        1: #include <sys/param.h>
        !             2: #include <sys/inet/ip.h>
        !             3: #include <ipc.h>
        !             4: 
        !             5: int printip();
        !             6: 
        !             7: typedef struct {
        !             8:        int code;
        !             9:        char *meaning;
        !            10:        int (*action)();
        !            11:        int needid;
        !            12: } Code;
        !            13: 
        !            14: typedef struct {
        !            15:        int type;
        !            16:        Code *c;
        !            17: } Msg;
        !            18: 
        !            19: typedef struct {
        !            20:        int type;
        !            21:        int inuse;
        !            22:        int id;
        !            23: } Client;
        !            24: 
        !            25: /* Destination Unreachable Message
        !            26: 
        !            27:     0                   1                   2                   3
        !            28:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !            29:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            30:    |     Type      |     Code      |          Checksum             |
        !            31:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            32:    |                             unused                            |
        !            33:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            34:    |      Internet Header + 64 bits of Original Data Datagram      |
        !            35:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            36: 
        !            37: */
        !            38: 
        !            39: Code unreachc[] = {
        !            40:        { 0, "net unreachable", printip, 0 },
        !            41:        { 1, "host unreachable", printip, 0 },
        !            42:        { 2, "protocol unreachable", printip, 0 },
        !            43:        { 3, "port unreachable", printip, 0 },
        !            44:        { 4, "fragment needed and DF set", printip, 0 },
        !            45:        { 5, "source route failed", printip, 0 },
        !            46:        { -1, 0, 0 }
        !            47: };
        !            48: 
        !            49: typedef struct {
        !            50:        u_char param[4];
        !            51:        struct ip ip;
        !            52: } IpMsg;
        !            53: 
        !            54: 
        !            55: /* Time Exceeded Message
        !            56: 
        !            57:     0                   1                   2                   3
        !            58:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !            59:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            60:    |     Type      |     Code      |          Checksum             |
        !            61:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            62:    |                             unused                            |
        !            63:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            64:    |      Internet Header + 64 bits of Original Data Datagram      |
        !            65:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            66: */
        !            67: 
        !            68: Code timec[] = {
        !            69:        { 0, "time to live exceeded in transit", printip, 0 },
        !            70:        { 1, "fragment reassembly time exceeded", printip, 0 },
        !            71:        { -1, 0, 0 }
        !            72: };
        !            73: 
        !            74: 
        !            75: 
        !            76: /* Parameter Problem Message
        !            77: 
        !            78:     0                   1                   2                   3
        !            79:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !            80:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            81:    |     Type      |     Code      |          Checksum             |
        !            82:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            83:    |    Pointer    |                   unused                      |
        !            84:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            85:    |      Internet Header + 64 bits of Original Data Datagram      |
        !            86:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            87: */
        !            88: 
        !            89: Code paramc[] = {
        !            90:        { 0, "parameter problem", printip, 0 },
        !            91:        { -1, 0, 0 }
        !            92: };
        !            93: 
        !            94: /* Source Quench Message
        !            95: 
        !            96:     0                   1                   2                   3
        !            97:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !            98:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            99:    |     Type      |     Code      |          Checksum             |
        !           100:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           101:    |                             unused                            |
        !           102:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           103:    |      Internet Header + 64 bits of Original Data Datagram      |
        !           104:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           105: */
        !           106: 
        !           107: Code quenchc[] = {
        !           108:        { 0, "source quench", printip, 0 },
        !           109:        { -1, 0, 0 }
        !           110: };
        !           111: 
        !           112: 
        !           113: /* Redirect Message
        !           114: 
        !           115:     0                   1                   2                   3
        !           116:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !           117:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           118:    |     Type      |     Code      |          Checksum             |
        !           119:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           120:    |                 Gateway Internet Address                      |
        !           121:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           122:    |      Internet Header + 64 bits of Original Data Datagram      |
        !           123:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           124: */
        !           125: 
        !           126: Code redirectc[] = {
        !           127:        { 0, "redirect datagrams for the network", printip, 0 },
        !           128:        { 1, "redirect datagrams for the host", printip, 0 },
        !           129:        { 2, "redirect datagrams for the type of service and network", printip, 0},
        !           130:        { 3, "redirect datagrams for the type of service and host", printip, 0 },
        !           131:        { -1, 0, 0 }
        !           132: };
        !           133: 
        !           134: 
        !           135: /* Echo or Echo Reply Message
        !           136: 
        !           137:     0                   1                   2                   3
        !           138:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !           139:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           140:    |     Type      |     Code      |          Checksum             |
        !           141:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           142:    |           Identifier          |        Sequence Number        |
        !           143:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           144:    |     Data ...
        !           145:    +-+-+-+-+-
        !           146: */
        !           147: 
        !           148: int echo();
        !           149: Code echoc[] = {
        !           150:        { 0, "echo", echo, 1 },
        !           151:        { -1, 0, 0 }
        !           152: };
        !           153: Code echorc[] = {
        !           154:        { 0, "echo reply", 0, 1 },
        !           155:        { -1, 0, 0 }
        !           156: };
        !           157: 
        !           158: typedef struct {
        !           159:        u_char id[2];
        !           160:        u_char seqno[2];
        !           161: } EchoMsg;
        !           162: 
        !           163: /* Timestamp or Timestamp Reply Message
        !           164: 
        !           165:     0                   1                   2                   3
        !           166:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !           167:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           168:    |     Type      |      Code     |          Checksum             |
        !           169:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           170:    |           Identifier          |        Sequence Number        |
        !           171:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           172:    |     Originate Timestamp                                       |
        !           173:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           174:    |     Receive Timestamp                                         |
        !           175:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           176:    |     Transmit Timestamp                                        |
        !           177:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           178: */
        !           179: 
        !           180: Code timestampc[] = {
        !           181:        { 0, "timestamp", 0, 1 },
        !           182:        { -1, 0, 0 }
        !           183: };
        !           184: Code timestamprc[] = {
        !           185:        { 0, "timestamp reply", 0, 1 },
        !           186:        { -1, 0, 0 }
        !           187: };
        !           188: 
        !           189: typedef struct {
        !           190:        u_char id[2];
        !           191:        u_char seqno[2];
        !           192:        u_char orig[4];
        !           193:        u_char recv[4];
        !           194:        u_char xmit[4];
        !           195: } TsMsg;
        !           196: 
        !           197: 
        !           198: /* Information Request or Information Reply Message
        !           199: 
        !           200:     0                   1                   2                   3
        !           201:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !           202:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           203:    |     Type      |      Code     |          Checksum             |
        !           204:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           205:    |           Identifier          |        Sequence Number        |
        !           206:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           207: */
        !           208: 
        !           209: Code infoc[] = {
        !           210:        { 0, "info", 0, 1 },
        !           211:        { -1, 0, 0 }
        !           212: };
        !           213: Code inforc[] = {
        !           214:        { 0, "info reply", 0, 1 },
        !           215:        { -1, 0, 0 }
        !           216: };
        !           217: 
        !           218: Msg msgs[] = {
        !           219:         { 0, echorc },
        !           220:         { 3, unreachc },
        !           221:         { 4, quenchc },
        !           222:         { 5, redirectc },
        !           223:         { 8, echoc },
        !           224:         { 11, timec },
        !           225:         { 12, paramc },
        !           226:         { 13, timestampc },
        !           227:         { 14, timestamprc },
        !           228:         { 15, infoc },
        !           229:         { 16, inforc },
        !           230: };
        !           231: 
        !           232: typedef struct {
        !           233:        struct ip ip;
        !           234:        u_char type;
        !           235:        u_char code;
        !           236:        u_char cksum[2];
        !           237:        union {
        !           238:                IpMsg i;
        !           239:                EchoMsg e;
        !           240:                TsMsg t;
        !           241:        } u;
        !           242:        u_char buffer[4096];
        !           243: } IcmpMsg;
        !           244: 
        !           245: /*
        !           246:  *  globals
        !           247:  */
        !           248: char *av0;
        !           249: Client clients[NOFILE];
        !           250: fd_set cfds;
        !           251: int debug;
        !           252: 
        !           253: ding()
        !           254: {
        !           255:        signal(SIGALRM, ding);
        !           256:        alarm(10);
        !           257: }
        !           258: 
        !           259: /*
        !           260:  *  icmp mgr
        !           261:  */
        !           262: main(ac, av)
        !           263:        int ac;
        !           264:        char *av[];
        !           265: {
        !           266:        char *mtpt="icmp", *cp;
        !           267:        int i;
        !           268:        int ipfd, fsfd;
        !           269:        fd_set fds;
        !           270: 
        !           271:        av0 = av[0];
        !           272:        chdir("/cs");
        !           273:        for (i=1; i<ac; i++) {
        !           274:                if (av[i][0] == '-') {
        !           275:                        for (cp=&av[i][1]; *cp; cp++) {
        !           276:                                switch(*cp) {
        !           277:                                case 'd':
        !           278:                                        debug = 1;
        !           279:                                        break;
        !           280:                                case 'm':
        !           281:                                        if (i+1>=ac)
        !           282:                                                usage(av0);
        !           283:                                        mtpt = av[++i];
        !           284:                                        break;
        !           285:                                default:
        !           286:                                        usage(av0);
        !           287:                                }
        !           288:                        }
        !           289:                }
        !           290:        }
        !           291: 
        !           292:        /*
        !           293:         * open the ip protocol
        !           294:         */
        !           295:        ipfd = open("/dev/ipicmp", 2);
        !           296:        if(ipfd < 0){
        !           297:                logevent("error opening ip device\n");
        !           298:                exit(1);
        !           299:        };
        !           300: 
        !           301:        /*
        !           302:         * plug ourselves into the file system
        !           303:         */
        !           304:        fsfd = ipccreat(mtpt, "");
        !           305:        if(ipfd < 0){
        !           306:                logevent("error mounting into fs\n");
        !           307:                exit(1);
        !           308:        };
        !           309: 
        !           310:        if(!debug)
        !           311:                detach(mtpt);
        !           312: 
        !           313:        /*
        !           314:         * clear out the clients
        !           315:         */
        !           316:        for(i=0; i<NOFILE; i++){
        !           317:                clients[i].id = i;
        !           318:                clients[i].inuse = 0;
        !           319:        }
        !           320: 
        !           321:        /*
        !           322:         * spin honoring requests
        !           323:         */
        !           324:        FD_ZERO(fds);
        !           325:        for(;;) {
        !           326:                int n;
        !           327: 
        !           328:                fds = cfds;
        !           329:                FD_SET(ipfd, fds);
        !           330:                FD_SET(fsfd, fds);
        !           331:                switch(n = select(NOFILE, &fds, 0, 10000)){
        !           332:                case -1:
        !           333:                        logevent("select failed\n");
        !           334:                        exit(1);
        !           335:                case 0:
        !           336:                        continue;
        !           337:                }
        !           338:                signal(SIGALRM, ding);
        !           339:                alarm(10);
        !           340:                if(FD_ISSET(ipfd, fds)) {
        !           341:                        readnet(ipfd);
        !           342:                        n--;
        !           343:                }
        !           344:                if(n && FD_ISSET(fsfd, fds)) {
        !           345:                        newclient(fsfd);
        !           346:                        n--;
        !           347:                }
        !           348:                for(i = 0; n && i<NOFILE; i++){
        !           349:                        if(FD_ISSET(i, fds)){
        !           350:                                readclient(i, ipfd);
        !           351:                                n--;
        !           352:                        }
        !           353:                }
        !           354:                alarm(0);
        !           355:        }
        !           356: }
        !           357: 
        !           358: /*
        !           359:  * read an icmp message from the network
        !           360:  */
        !           361: readnet(fd)
        !           362: {
        !           363:        Msg *mp;
        !           364:        IcmpMsg m;
        !           365:        int n;
        !           366:        char fromsys[32], tosys[32];
        !           367:        u_char c[2];
        !           368:        Code *cp;
        !           369: 
        !           370:        if((n = read(fd, &m, sizeof(m))) > 0){
        !           371:                strcpy(fromsys, in_ntoa(m.ip.ip_src));
        !           372:                strcpy(tosys, in_ntoa(m.ip.ip_dst));
        !           373:                logevent("in %s -> %s, type %d code %d\n", fromsys, tosys,
        !           374:                        m.type, m.code);
        !           375:                c[0] = m.cksum[0];
        !           376:                c[1] = m.cksum[1];
        !           377:                cksum(&m, n);
        !           378:                if(c[0] != m.cksum[0] || c[1] != m.cksum[1]){
        !           379:                        fprint(2, "checksum error %.2x%.2x/%.2x%.2x\n", c[0],
        !           380:                                c[1], m.cksum[0], m.cksum[1]);
        !           381:                        return;
        !           382:                }
        !           383:                for(mp = msgs; mp->type >= 0; mp++){
        !           384:                        if(mp->type == m.type){
        !           385:                                for(cp = mp->c; cp->code >= 0; cp++)
        !           386:                                        if(cp->code == m.code)
        !           387:                                                break;
        !           388:                                if(cp->code < 0)
        !           389:                                        fprint(2, "undefined code\n");
        !           390:                                else if(cp->action)
        !           391:                                        (*cp->action)(fd, &m, n);
        !           392:                                break;
        !           393:                        }
        !           394:                }
        !           395:                if(mp->type < 0)
        !           396:                        fprint(2, "undefined type\n");
        !           397:        } else {
        !           398:                logevent("error reading from network %d\n", errno);
        !           399:                exit(1);
        !           400:        }
        !           401: }
        !           402: 
        !           403: /*
        !           404:  * a call from a new client
        !           405:  */
        !           406: newclient(fd)
        !           407: {
        !           408:        int cfd;
        !           409:        ipcinfo *ipc;
        !           410: 
        !           411:        /*
        !           412:         *  get the new call (protected by a timeout)
        !           413:         */
        !           414:        ipc = ipclisten(fd);
        !           415:        if(fd==0)
        !           416:                return;
        !           417:        cfd = ipcaccept(ipc);
        !           418:        if(cfd<0)
        !           419:                return;
        !           420: 
        !           421:        /*
        !           422:         *  set up a new id (for echo/timestamp/etc)
        !           423:         */
        !           424:        clients[cfd].id += NOFILE;
        !           425:        clients[cfd].inuse = 1;
        !           426:        FD_SET(cfd, cfds);
        !           427:        logevent("new client %d %s!%s\n", cfd, ipc->machine, ipc->user);
        !           428: }
        !           429: 
        !           430: /*
        !           431:  * read an icmp message from a client (protected by an timeout).
        !           432:  * if this is a message that requires an id, put one in.
        !           433:  */
        !           434: readclient(fd, ipfd)
        !           435: {
        !           436:        IcmpMsg m;
        !           437:        int n;
        !           438:        char fromsys[32], tosys[32];
        !           439:        Msg *mp;
        !           440:        Code *cp;
        !           441: 
        !           442:        if((n = read(fd, &m, sizeof(m))) > 0){
        !           443:                strcpy(fromsys, in_ntoa(m.ip.ip_src));
        !           444:                strcpy(tosys, in_ntoa(m.ip.ip_dst));
        !           445:                logevent("out(%d) %s -> %s, type %d code %d\n", fd, fromsys,
        !           446:                        tosys, m.type, m.code);
        !           447:                for(mp = msgs; mp->type >= 0; mp++){
        !           448:                        if(mp->type == m.type){
        !           449:                                for(cp = mp->c; cp->code >= 0; cp++)
        !           450:                                        if(cp->code == m.code)
        !           451:                                                break;
        !           452:                                if(cp->code < 0)
        !           453:                                        fprint(2, "undefined code\n");
        !           454:                                else {
        !           455:                                        if(cp->needid){
        !           456:                                                m.u.e.id[0] = clients[fd].id;
        !           457:                                                m.u.e.id[1] = clients[fd].id>>8;
        !           458:                                        }
        !           459:                                        ipsend(ipfd, &m, n, m.ip.ip_src,
        !           460:                                                m.ip.ip_dst);
        !           461:                                }
        !           462:                                break;
        !           463:                        }
        !           464:                }
        !           465:                if(mp->type < 0)
        !           466:                        fprint(2, "undefined type\n");
        !           467:        } else {
        !           468:                logevent("losing client %d\n", fd);
        !           469:                FD_CLR(fd, cfds);
        !           470:                close(fd);
        !           471:        }
        !           472: }
        !           473: 
        !           474: /*
        !           475:  * print a message with an ip body
        !           476:  */
        !           477: printip(fd, mp, len)
        !           478:        IcmpMsg *mp;
        !           479: {
        !           480: }
        !           481: 
        !           482: /*
        !           483:  * send an ip datagram
        !           484:  */
        !           485: ipsend(fd, mp, len, src, dst)
        !           486:        IcmpMsg *mp;
        !           487:        u_long src;
        !           488:        u_long dst;
        !           489: {
        !           490:        mp->ip.ip_dst = dst;
        !           491:        mp->ip.ip_src = src;
        !           492:        mp->ip.ip_len = len;
        !           493:        mp->ip.ip_hl = sizeof(struct ip)>>2;
        !           494:        mp->ip.ip_off = 0;
        !           495:        mp->ip.ip_ttl = 255;
        !           496:        mp->ip.ip_p = 1;
        !           497:        cksum(mp, len);
        !           498:        return write(fd, mp, len)!=len ? -1 : 0;
        !           499: }
        !           500: 
        !           501: /*
        !           502:  * echo a datagram
        !           503:  */
        !           504: echo(fd, mp, len)
        !           505:        IcmpMsg *mp;
        !           506: {
        !           507:        mp->type = 0;
        !           508:        if(ipsend(fd, mp, len, mp->ip.ip_dst, mp->ip.ip_src) < 0)
        !           509:                perror("sending echo");
        !           510: }
        !           511: 
        !           512: usage(name)
        !           513:        char *name;
        !           514: {
        !           515:        fprint(2, "usage: %s [-d] [-m mount-pt]\n", name);
        !           516:        exit(1);
        !           517: }
        !           518: 
        !           519: /*
        !           520:  * internet checksum routine
        !           521:  */
        !           522: cksum(mp, len)
        !           523:        IcmpMsg *mp;
        !           524: {
        !           525:        u_char *cp;
        !           526:        u_short *sp;
        !           527:        u_long sum;
        !           528: 
        !           529:        sp = (u_short *)&mp->type;
        !           530:        len -= sizeof(struct ip);
        !           531:        mp->cksum[0] = mp->cksum[1] = 0;
        !           532:        for(sum = 0; len >=2; len-=2)
        !           533:                sum += *sp++;
        !           534:        if(len){
        !           535:                cp = (u_char *)sp;
        !           536:                sum += *cp;
        !           537:        }
        !           538:        while(sum & 0xffff0000)
        !           539:                sum = (sum & 0xffff) + (sum>>16);
        !           540:        sum ^= 0xffff;
        !           541:        mp->cksum[1] = sum>>8;
        !           542:        mp->cksum[0] = sum;
        !           543: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.