Annotation of qemu/roms/SLOF/clients/net-snk/app/netlib/bootp.c, revision 1.1

1.1     ! root        1: /******************************************************************************
        !             2:  * Copyright (c) 2004, 2008 IBM Corporation
        !             3:  * All rights reserved.
        !             4:  * This program and the accompanying materials
        !             5:  * are made available under the terms of the BSD License
        !             6:  * which accompanies this distribution, and is available at
        !             7:  * http://www.opensource.org/licenses/bsd-license.php
        !             8:  *
        !             9:  * Contributors:
        !            10:  *     IBM Corporation - initial implementation
        !            11:  *****************************************************************************/
        !            12: 
        !            13: 
        !            14: #include <stdio.h>
        !            15: #include <string.h>
        !            16: #include <sys/socket.h>
        !            17: #include <time.h>
        !            18: 
        !            19: #include <ethernet.h>
        !            20: #include <ipv4.h>
        !            21: #include <udp.h>
        !            22: #include <dhcp.h>
        !            23: 
        !            24: #define DEBUG 0
        !            25: 
        !            26: static char * response_buffer;
        !            27: 
        !            28: void
        !            29: print_ip(char *ip)
        !            30: {
        !            31:        printf("%d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
        !            32: }
        !            33: 
        !            34: 
        !            35: /* IP header checksum calculation */
        !            36: unsigned short
        !            37: checksum(unsigned short *packet, int words)
        !            38: {
        !            39:        unsigned long checksum;
        !            40:        for (checksum = 0; words > 0; words--)
        !            41:                checksum += *packet++;
        !            42:        checksum = (checksum >> 16) + (checksum & 0xffff);
        !            43:        checksum += (checksum >> 16);
        !            44:        return ~checksum;
        !            45: }
        !            46: 
        !            47: 
        !            48: static int
        !            49: send_bootp(filename_ip_t * fn_ip)
        !            50: {
        !            51: #if DEBUG
        !            52:        int i;
        !            53: #endif
        !            54:        unsigned int packetsize =
        !            55:            sizeof(struct iphdr) + sizeof(struct ethhdr) +
        !            56:            sizeof(struct udphdr) + sizeof(struct btphdr);
        !            57:        unsigned char packet[packetsize];
        !            58:        struct iphdr *iph;
        !            59:        struct udphdr *udph;
        !            60:        struct btphdr *btph;
        !            61: 
        !            62:        iph = (struct iphdr *) packet;
        !            63:        udph = (struct udphdr *) (iph + 1);
        !            64:        btph = (struct btphdr *) (udph + 1);
        !            65: 
        !            66:        memset(packet, 0, packetsize);
        !            67: 
        !            68:        fill_iphdr((uint8_t *) iph, htons(packetsize - sizeof(struct ethhdr)),
        !            69:                   IPTYPE_UDP, 0, fn_ip->server_ip);
        !            70:        fill_udphdr((uint8_t *) udph,
        !            71:                    htons(sizeof(struct udphdr) + sizeof(struct btphdr)),
        !            72:                    htons(UDPPORT_BOOTPC), htons(UDPPORT_BOOTPS));
        !            73:        btph->op = 1;
        !            74:        btph->htype = 1;
        !            75:        btph->hlen = 6;
        !            76:        strcpy((char *) btph->file, "bla");
        !            77:        memcpy(btph->chaddr, get_mac_address(), 6);
        !            78: 
        !            79: #if DEBUG
        !            80:        printf("Sending packet\n");
        !            81:        printf("Packet is ");
        !            82:        for (i = 0; i < packetsize; i++)
        !            83:                printf(" %02x", packet[i]);
        !            84:        printf(".\n");
        !            85: #endif
        !            86: 
        !            87:        send_ipv4(packet, iph->ip_len);
        !            88: #if DEBUG
        !            89:        printf("%d bytes transmitted over socket.\n", i);
        !            90: #endif
        !            91: 
        !            92:        return 0;
        !            93: }
        !            94: 
        !            95: 
        !            96: static int
        !            97: receive_bootp(filename_ip_t * fn_ip)
        !            98: {
        !            99:        int len, old_sum;
        !           100:        unsigned int packetsize = 2000;
        !           101:        unsigned char packet[packetsize];
        !           102:        struct ethhdr *ethh;
        !           103:        struct iphdr *iph;
        !           104:        struct udphdr *udph;
        !           105:        struct btphdr *btph;
        !           106: 
        !           107:        ethh = (struct ethhdr *) packet;
        !           108:        iph = (struct iphdr *) (packet + sizeof(struct ethhdr));
        !           109:        udph = (struct udphdr *) (iph + 1);
        !           110:        btph = (struct btphdr *) (udph + 1);
        !           111: 
        !           112:        memset(packet, 0, packetsize);
        !           113: 
        !           114:        /* setting up a timer with a timeout of one second */
        !           115:        set_timer(TICKS_SEC);
        !           116: 
        !           117:        do {
        !           118: 
        !           119:                /* let's receive a packet */
        !           120:                len = recv(0, packet, packetsize, 0);
        !           121: 
        !           122: #if DEBUG
        !           123:                int j;
        !           124:                printf("%d bytes received, %d expected \n", len, packetsize);
        !           125:                if (len == 346) {
        !           126:                        printf("Rec packet\n");
        !           127:                        printf("Packet is ");
        !           128:                        for (j = 0; j < len; j++) {
        !           129:                                if (j % 16 == 0)
        !           130:                                        printf("\n");
        !           131:                                printf(" %02x", packet[j]);
        !           132:                        }
        !           133:                        printf(".\n");
        !           134:                }
        !           135: #endif
        !           136:                /* check if the ip checksum is correct */
        !           137:                old_sum = iph->ip_sum;
        !           138:                iph->ip_sum = 0x00;
        !           139:                if (old_sum !=
        !           140:                    checksum((unsigned short *) iph, sizeof(struct iphdr) >> 1))
        !           141:                        /* checksum failed */
        !           142:                        continue;
        !           143:                /* is it a udp packet */
        !           144:                if (iph->ip_p != IPTYPE_UDP)
        !           145:                        continue;
        !           146:                /* check if the source port and destination port and the packet
        !           147:                 * say that it is a bootp answer */
        !           148:                if (udph->uh_dport != htons(UDPPORT_BOOTPC) || udph->uh_sport != htons(UDPPORT_BOOTPS))
        !           149:                        continue;
        !           150:                /* check if it is a Boot Reply */
        !           151:                if (btph->op != 2)
        !           152:                        continue;
        !           153:                /* Comparing our mac address with the one in the bootp reply */ 
        !           154:                if (memcmp(get_mac_address(), btph->chaddr, ETH_ALEN))
        !           155:                        continue;
        !           156: 
        !           157:                if(response_buffer)
        !           158:                        memcpy(response_buffer, btph, 1720);
        !           159: 
        !           160:                fn_ip->own_ip = btph->yiaddr;
        !           161:                fn_ip->server_ip = btph->siaddr;
        !           162:                strcpy((char *) fn_ip->filename, (char *) btph->file);
        !           163: 
        !           164: #if DEBUG
        !           165:                printf("\nThese are the details of the bootp reply:\n");
        !           166:                printf("Our IP address: ");
        !           167:                print_ip((char*) &fn_ip->own_ip);
        !           168:                printf("Next server IP address: ");
        !           169:                print_ip((char*) &fn_ip->server_ip);
        !           170:                printf("Boot file name: %s\n", btph->file);
        !           171:                printf("Packet is: %s\n", btph->file);
        !           172:                for (j = 0; j < len; j++) {
        !           173:                        if (j % 16 == 0)
        !           174:                                printf("\n");
        !           175:                        printf(" %02x", packet[j]);
        !           176:                }
        !           177:                printf(".\n");
        !           178:                printf("fn_ip->own_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", 
        !           179:                        get_mac_address()[0], get_mac_address()[1],
        !           180:                        get_mac_address()[2], get_mac_address()[3],
        !           181:                        get_mac_address()[4], get_mac_address()[5]);
        !           182:                printf("Header ethh->dest_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", 
        !           183:                       ethh->dest_mac[0], ethh->dest_mac[1], ethh->dest_mac[2], 
        !           184:                       ethh->dest_mac[3], ethh->dest_mac[4], ethh->dest_mac[5]);
        !           185:                printf("Header ethh->src_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", 
        !           186:                       ethh->src_mac[0], ethh->src_mac[1], ethh->src_mac[2], 
        !           187:                       ethh->src_mac[3], ethh->src_mac[4], ethh->src_mac[5]);
        !           188:                printf("Header ethh->typ: %x\n",ethh->type); 
        !           189:                printf("Header iph->ip_hlv: %x\n",iph->ip_hlv); 
        !           190:                printf("Header iph->ip_len: %x\n",iph->ip_len); 
        !           191:                printf("Header iph->ip_id: %x\n",iph->ip_id); 
        !           192:                printf("Header iph->ip_off: %x\n",iph->ip_off); 
        !           193:                printf("Header iph->ip_ttl: %x\n",iph->ip_ttl); 
        !           194:                printf("Header iph->ip_p: %x\n",iph->ip_p); 
        !           195:                printf("Header iph->ip_sum: %x\n",iph->ip_sum); 
        !           196:                printf("Header iph->ip_src: %x\n",iph->ip_src); 
        !           197:                printf("Header iph->ip_dst: %x\n",iph->ip_dst); 
        !           198: 
        !           199:                printf("Header btph->op: %x\n",btph->op); 
        !           200:                printf("Header btph->htype: %x\n",btph->htype); 
        !           201:                printf("Header btph->hlen: %x\n",btph->hlen); 
        !           202:                printf("Header btph->hops: %x\n",btph->hops); 
        !           203:                printf("Header btph->xid: %x\n",btph->xid); 
        !           204:                printf("Header btph->secs: %x\n",btph->secs); 
        !           205:                printf("Header btph->ciaddr: %x\n",btph->ciaddr); 
        !           206:                printf("Header btph->yiaddr: %x\n",btph->yiaddr); 
        !           207:                printf("Header btph->siaddr: %x\n",btph->siaddr); 
        !           208:                printf("Header btph->giaddr: %x\n",btph->giaddr); 
        !           209: 
        !           210:                printf("Header btph->chaddr: %02x:%02x:%02x:%02x:%02x:%02x:\n",
        !           211:                       btph->chaddr[0], btph->chaddr[1], btph->chaddr[2],
        !           212:                       btph->chaddr[3], btph->chaddr[4], btph->chaddr[5]);
        !           213: 
        !           214: #endif
        !           215:                return 0;
        !           216: 
        !           217:                /* only do this for the time specified during set_timer() */
        !           218:        } while (get_timer() > 0);
        !           219:        return -1;
        !           220: }
        !           221: 
        !           222: 
        !           223: int
        !           224: bootp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries)
        !           225: {
        !           226:        int i = (int) retries+1;
        !           227:        fn_ip->own_ip = 0;
        !           228: 
        !           229:        printf("   ");
        !           230: 
        !           231:        response_buffer = ret_buffer;
        !           232: 
        !           233:        do {
        !           234:                printf("\b\b%02d", i);
        !           235:                if (!i--) {
        !           236:                        printf("\nGiving up after %d bootp requests\n",
        !           237:                               retries+1);
        !           238:                        return -1;
        !           239:                }
        !           240:                send_bootp(fn_ip);
        !           241:                /* if the timer in receive_bootp expired it will return
        !           242:                 * -1 and we will just send another bootp request just
        !           243:                 * in case the previous one was lost. And because we don't
        !           244:                 * trust the network cable we keep on doing this 30 times */
        !           245:        } while (receive_bootp(fn_ip) != 0);
        !           246:        printf("\b\b\b");
        !           247:        return 0;
        !           248: }

unix.superglobalmegacorp.com

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