Annotation of researchv9/sys/boot/stand/inet.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)inet.c     1.1 86/02/03    Copyr 1984 Sun Micro";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
        !             7:  */
        !             8: 
        !             9: /*
        !            10:  * Standalone IP send and receive - specific to Ethernet
        !            11:  * Includes ARP and Reverse ARP
        !            12:  */
        !            13: #include "saio.h"
        !            14: #include "../h/socket.h"
        !            15: #include "../net/if.h"
        !            16: #include "../netinet/in.h"
        !            17: #include "../netinet/if_ether.h"
        !            18: #include "../netinet/in_systm.h"
        !            19: #include "../netinet/ip.h"
        !            20: #include "sainet.h"
        !            21: #include "../mon/sunromvec.h"
        !            22: #include "../mon/idprom.h"
        !            23: 
        !            24: #define millitime() (*romp->v_nmiclock)
        !            25: 
        !            26: struct ether_addr etherbroadcastaddr = { 
        !            27:        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        !            28: };
        !            29: 
        !            30: struct arp_packet {
        !            31:        struct ether_header     arp_eh;
        !            32:        struct ether_arp        arp_ea;
        !            33: #define        used_size (sizeof (struct ether_header)+sizeof(struct ether_arp))
        !            34:        char    filler[ETHERMIN - sizeof(struct ether_arp)];
        !            35: };
        !            36: 
        !            37: #define WAITCNT        2       /* 4 seconds before bitching about arp/revarp */
        !            38: 
        !            39: /*
        !            40:  * Fetch our Ethernet address from the ID prom
        !            41:  */
        !            42: myetheraddr(ea)
        !            43:        struct ether_addr *ea;
        !            44: {
        !            45:        struct idprom id;
        !            46: 
        !            47:        if (idprom(IDFORM_1, &id) != IDFORM_1) {
        !            48:                printf("ERROR: missing or invalid ID prom\n");
        !            49:                return;
        !            50:        }
        !            51:        *ea = *(struct ether_addr *)id.id_ether;
        !            52: }
        !            53: 
        !            54: /*
        !            55:  * Initialize IP state
        !            56:  * Find out our Ethernet address and call Reverse ARP
        !            57:  * to find out our Internet address
        !            58:  * Set the ARP cache to the broadcast host
        !            59:  */
        !            60: inet_init(sip, sain, tmpbuf)
        !            61:        register struct saioreq *sip;
        !            62:        register struct sainet *sain;
        !            63:        char *tmpbuf;
        !            64: {
        !            65:        myetheraddr(&sain->sain_myether);
        !            66:        sain->sain_hisaddr.s_addr = 0;
        !            67:        sain->sain_hisether = etherbroadcastaddr;
        !            68:        revarp(sip, sain, tmpbuf);
        !            69: }
        !            70: 
        !            71: 
        !            72: /*
        !            73:  * Output an IP packet
        !            74:  * Cause ARP to be invoked if necessary
        !            75:  */
        !            76: ip_output(sip, buf, len, sain, tmpbuf)
        !            77:        register struct saioreq *sip;
        !            78:        caddr_t buf, tmpbuf;
        !            79:        short len;
        !            80:        register struct sainet *sain;
        !            81: {
        !            82:        register struct ether_header *eh;
        !            83:        register struct ip *ip;
        !            84: 
        !            85:        eh = (struct ether_header *)buf;
        !            86:        ip = (struct ip *)(buf + sizeof(struct ether_header));
        !            87:        if (ip->ip_dst.s_addr != sain->sain_hisaddr.s_addr) {
        !            88:                sain->sain_hisaddr.s_addr = ip->ip_dst.s_addr;
        !            89:                arp(sip, sain, tmpbuf);
        !            90:        }
        !            91:        eh->ether_type = ETHERPUP_IPTYPE;
        !            92:        eh->ether_shost = sain->sain_myether;
        !            93:        eh->ether_dhost = sain->sain_hisether;
        !            94:        /* checksum the packet */
        !            95:        ip->ip_sum = 0;
        !            96:        ip->ip_sum = ipcksum((caddr_t)ip, sizeof (struct ip));
        !            97:        if (len < ETHERMIN+sizeof(struct ether_header))
        !            98:                len = ETHERMIN+sizeof(struct ether_header);
        !            99:        return (*sip->si_sif->sif_xmit)(sip->si_devdata, buf, len);
        !           100: }
        !           101: 
        !           102: /*
        !           103:  * Check incoming packets for IP packets
        !           104:  * addressed to us. Also, respond to ARP packets
        !           105:  * that wish to know about us.
        !           106:  * Returns a length for any IP packet addressed to us, 0 otherwise.
        !           107:  */
        !           108: ip_input(sip, buf, sain)
        !           109:        register struct saioreq *sip;
        !           110:        caddr_t buf;
        !           111:        register struct sainet *sain;
        !           112: {
        !           113:        register short len;
        !           114:        register struct ether_header *eh;
        !           115:        register struct ip *ip;
        !           116:        register struct ether_arp *ea;
        !           117: 
        !           118:        len = (*sip->si_sif->sif_poll)(sip->si_devdata, buf);
        !           119:        eh = (struct ether_header *)buf;
        !           120:        if (eh->ether_type == ETHERPUP_IPTYPE &&
        !           121:            len >= sizeof(struct ether_header)+sizeof(struct ip)) {
        !           122:                ip = (struct ip *)(buf + sizeof(struct ether_header));
        !           123: #ifdef NOREVARP
        !           124:                if ((sain->sain_hisaddr.s_addr & 0xFF000000) == 0 &&
        !           125:                    bcmp((caddr_t)&etherbroadcastaddr,
        !           126:                                (caddr_t)&eh->ether_dhost, 6) != 0 &&
        !           127:                    (in_broadaddr(sain->sain_hisaddr) ||
        !           128:                    in_lnaof(ip->ip_src) == in_lnaof(sain->sain_hisaddr))) {
        !           129:                        sain->sain_myaddr = ip->ip_dst;
        !           130:                        sain->sain_hisaddr = ip->ip_src;
        !           131:                        sain->sain_hisether = eh->ether_shost;
        !           132:                }
        !           133: #endif
        !           134:                if (ip->ip_dst.s_addr != sain->sain_myaddr.s_addr) 
        !           135:                        return (0);
        !           136:                return (len);
        !           137:        }
        !           138:        if (eh->ether_type == ETHERPUP_ARPTYPE &&
        !           139:            len >= sizeof(struct ether_header)+sizeof(struct ether_arp)) {
        !           140:                ea = (struct ether_arp *)(buf + sizeof(struct ether_header));
        !           141:                if (ea->arp_pro != ETHERPUP_IPTYPE)
        !           142:                        return (0);
        !           143:                if (arp_spa(ea).s_addr == sain->sain_hisaddr.s_addr)
        !           144:                        sain->sain_hisether = arp_sha(ea);
        !           145:                if (ea->arp_op == ARPOP_REQUEST &&
        !           146:                    arp_tpa(ea).s_addr == sain->sain_myaddr.s_addr) {
        !           147:                        ea->arp_op = ARPOP_REPLY;
        !           148:                        eh->ether_dhost = arp_sha(ea);
        !           149:                        eh->ether_shost = sain->sain_myether;
        !           150:                        arp_tha(ea) = arp_sha(ea);
        !           151:                        arp_tpa(ea) = arp_spa(ea);
        !           152:                        arp_sha(ea) = sain->sain_myether;
        !           153:                        arp_spa(ea) = sain->sain_myaddr;
        !           154:                        (*sip->si_sif->sif_xmit)(sip->si_devdata, buf, 
        !           155:                                                sizeof(struct arp_packet));
        !           156:                }
        !           157:                return (0);
        !           158:        }
        !           159:        return (0);
        !           160: }
        !           161: 
        !           162: /*
        !           163:  * arp
        !           164:  * Broadcasts to determine Ethernet address given IP address
        !           165:  * See RFC 826
        !           166:  */
        !           167: arp(sip, sain, tmpbuf)
        !           168:        register struct saioreq *sip;
        !           169:        register struct sainet *sain;
        !           170:        char *tmpbuf;
        !           171: {
        !           172:        struct arp_packet out;
        !           173: 
        !           174:        if (in_broadaddr(sain->sain_hisaddr)
        !           175: #ifdef NOREVARP
        !           176:            || (sain->sain_hisaddr.s_addr & 0xFF000000) == 0
        !           177: #endif
        !           178:            ) {
        !           179:                sain->sain_hisether = etherbroadcastaddr;
        !           180:                return;
        !           181:        }
        !           182:        out.arp_eh.ether_type = ETHERPUP_ARPTYPE;
        !           183:        out.arp_ea.arp_op = ARPOP_REQUEST;
        !           184:        arp_tha(&out.arp_ea) = etherbroadcastaddr;      /* what we want */
        !           185:        arp_tpa(&out.arp_ea).s_addr = sain->sain_hisaddr.s_addr;
        !           186:        comarp(sip, sain, &out, tmpbuf);
        !           187: }
        !           188: 
        !           189: /*
        !           190:  * Reverse ARP client side
        !           191:  * Determine our Internet address given our Ethernet address
        !           192:  * See RFC 903
        !           193:  */
        !           194: revarp(sip, sain, tmpbuf)
        !           195:        register struct saioreq *sip;
        !           196:        register struct sainet *sain;
        !           197:        char *tmpbuf;
        !           198: {
        !           199:        struct arp_packet out;
        !           200: 
        !           201: #ifdef NOREVARP
        !           202:        sain->sain_myaddr.s_addr = 0;
        !           203:        bcopy((caddr_t)&sain->sain_myether.ether_addr_octet[3],
        !           204:                (caddr_t)(&sain->sain_myaddr)+1, 3);
        !           205: #else
        !           206:        out.arp_eh.ether_type = ETHERPUP_REVARPTYPE;
        !           207:        out.arp_ea.arp_op = REVARP_REQUEST;
        !           208:        arp_tha(&out.arp_ea) = sain->sain_myether;
        !           209:        arp_tpa(&out.arp_ea).s_addr = 0;/* what we want to find out */
        !           210:        comarp(sip, sain, &out, tmpbuf);
        !           211: #endif
        !           212: }
        !           213: 
        !           214: /*
        !           215:  * Common ARP code 
        !           216:  * Broadcast the packet and wait for the right response.
        !           217:  * Fills in *sain with the results
        !           218:  */
        !           219: comarp(sip, sain, out, tmpbuf)
        !           220:        register struct saioreq *sip;
        !           221:        register struct sainet *sain;
        !           222:        register struct arp_packet *out;
        !           223:        char *tmpbuf;
        !           224: {
        !           225:        register struct arp_packet *in = (struct arp_packet *)tmpbuf;
        !           226:        register int e, count, time, feedback,len, delay = 2;
        !           227:        char    *ind = "-\|/";
        !           228: 
        !           229:        out->arp_eh.ether_dhost = etherbroadcastaddr;
        !           230:        out->arp_eh.ether_shost = sain->sain_myether;
        !           231:        out->arp_ea.arp_hrd =  ARPHRD_ETHER;
        !           232:        out->arp_ea.arp_pro = ETHERPUP_IPTYPE;
        !           233:        out->arp_ea.arp_hln = sizeof(struct ether_addr);
        !           234:        out->arp_ea.arp_pln = sizeof(struct in_addr);
        !           235:        arp_sha(&out->arp_ea) = sain->sain_myether;
        !           236:        arp_spa(&out->arp_ea).s_addr = sain->sain_myaddr.s_addr;
        !           237:        feedback = 0;
        !           238: 
        !           239:        for (count=0; ; count++) {
        !           240:                if (count == WAITCNT) {
        !           241:                        if (out->arp_ea.arp_op == ARPOP_REQUEST) {
        !           242:                                printf("\nRequesting Ethernet address for ");
        !           243:                                inet_print(arp_tpa(&out->arp_ea));
        !           244:                        } else {
        !           245:                                printf("\nRequesting Internet address for ");
        !           246:                                ether_print(&arp_tha(&out->arp_ea));
        !           247:                        }
        !           248:                }
        !           249:                e = (*sip->si_sif->sif_xmit)(sip->si_devdata, (caddr_t)out,
        !           250:                        sizeof *out);
        !           251:                if (e)
        !           252:                        printf("X\b");
        !           253:                else
        !           254:                        printf("%c\b", ind[feedback++ % 4]); /* Show activity */
        !           255: 
        !           256:                time = millitime() + (delay * 1000);    /* broadcast delay */
        !           257:                while (millitime() <= time) {
        !           258:                        len = (*sip->si_sif->sif_poll)(sip->si_devdata, tmpbuf);
        !           259:                        if (len < used_size)
        !           260:                                continue;
        !           261:                        if (in->arp_ea.arp_pro != ETHERPUP_IPTYPE)
        !           262:                                continue;
        !           263:                        if (out->arp_ea.arp_op == ARPOP_REQUEST) {
        !           264:                                if (in->arp_eh.ether_type != ETHERPUP_ARPTYPE)
        !           265:                                        continue;
        !           266:                                if (in->arp_ea.arp_op != ARPOP_REPLY)
        !           267:                                        continue;
        !           268:                                if (arp_spa(&in->arp_ea).s_addr !=
        !           269:                                    arp_tpa(&out->arp_ea).s_addr)
        !           270:                                        continue;
        !           271:                                if (count >= WAITCNT) {
        !           272:                                        printf("Found at ");
        !           273:                                        ether_print(&arp_sha(&in->arp_ea));
        !           274:                                }
        !           275:                                sain->sain_hisether = arp_sha(&in->arp_ea);
        !           276:                                return;
        !           277:                        } else {                /* Reverse ARP */
        !           278:                                if (in->arp_eh.ether_type !=ETHERPUP_REVARPTYPE)
        !           279:                                        continue;
        !           280:                                if (in->arp_ea.arp_op != REVARP_REPLY)
        !           281:                                        continue;
        !           282:                                if (bcmp((caddr_t)&arp_tha(&in->arp_ea),
        !           283:                                    (caddr_t)&arp_tha(&out->arp_ea), 
        !           284:                                    sizeof (struct ether_addr)) != 0)
        !           285:                                        continue;
        !           286: 
        !           287:                                if (count >= WAITCNT) {
        !           288:                                        printf("Internet address is ");
        !           289:                                        inet_print(arp_tpa(&in->arp_ea));
        !           290:                                }
        !           291:                                sain->sain_myaddr = arp_tpa(&in->arp_ea);
        !           292:                                /* short circuit first ARP */
        !           293:                                sain->sain_hisaddr = arp_spa(&in->arp_ea);
        !           294:                                sain->sain_hisether = arp_sha(&in->arp_ea);
        !           295:                                return;
        !           296:                        }
        !           297:                }
        !           298: 
        !           299:                delay = delay * 2;      /* Double the request delay */
        !           300:                if (delay > 64)         /* maximum delay is 64 seconds */
        !           301:                        delay = 64;
        !           302: 
        !           303:                (*sip->si_sif->sif_reset)(sip->si_devdata);
        !           304:        }
        !           305:        /* NOTREACHED */
        !           306: }
        !           307: 
        !           308: /*
        !           309:  * Return the host portion of an internet address.
        !           310:  */
        !           311: in_lnaof(in)
        !           312:        struct in_addr in;
        !           313: {
        !           314:        register u_long i = ntohl(in.s_addr);
        !           315: 
        !           316:        if (IN_CLASSA(i))
        !           317:                return ((i)&IN_CLASSA_HOST);
        !           318:        else if (IN_CLASSB(i))
        !           319:                return ((i)&IN_CLASSB_HOST);
        !           320:        else
        !           321:                return ((i)&IN_CLASSC_HOST);
        !           322: }
        !           323: 
        !           324: /*
        !           325:  * Test for broadcast IP address
        !           326:  */
        !           327: in_broadaddr(in)
        !           328:        struct in_addr in;
        !           329: {
        !           330:        register u_long i = ntohl(in.s_addr);
        !           331: 
        !           332:        if (IN_CLASSA(i)) {
        !           333:                i &= IN_CLASSA_HOST;
        !           334:                return (i == 0 || i == 0xFFFFFF);
        !           335:        } else if (IN_CLASSB(i)) {
        !           336:                i &= IN_CLASSB_HOST;
        !           337:                return (i == 0 || i == 0xFFFF);
        !           338:        } else if (IN_CLASSC(i)) {
        !           339:                i &= IN_CLASSC_HOST;
        !           340:                return (i == 0 || i == 0xFF);
        !           341:        }
        !           342:        /* NOTREACHED */
        !           343: }
        !           344: 
        !           345: /*
        !           346:  * Compute one's complement checksum
        !           347:  * for IP packet headers 
        !           348:  */
        !           349: ipcksum(cp, count)
        !           350:        caddr_t cp;
        !           351:        register unsigned short count;
        !           352: {
        !           353:        register unsigned short *sp = (unsigned short *)cp;
        !           354:        register unsigned long  sum = 0;
        !           355:        register unsigned long  oneword = 0x00010000;
        !           356: 
        !           357:        count >>= 1;
        !           358:        while (count--) {
        !           359:                sum += *sp++;
        !           360:                if (sum >= oneword) {           /* Wrap carries into low bit */
        !           361:                        sum -= oneword;
        !           362:                        sum++;
        !           363:                }
        !           364:        }
        !           365:        return (~sum);
        !           366: }
        !           367: 
        !           368: inet_print(s)
        !           369:        struct in_addr s;
        !           370: {
        !           371:        printf("%d.%d.%d.%d\n",
        !           372:                s.S_un.S_un_b.s_b1, s.S_un.S_un_b.s_b2, 
        !           373:                s.S_un.S_un_b.s_b3, s.S_un.S_un_b.s_b4);
        !           374: }
        !           375: 
        !           376: ether_print(ea)
        !           377:        struct ether_addr *ea;
        !           378: {
        !           379:        register u_char *p = &ea->ether_addr_octet[0];
        !           380: 
        !           381:        printf("%x:%x:%x:%x:%x:%x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
        !           382: }

unix.superglobalmegacorp.com

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