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

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 iphdr *iph;
                    103:        struct udphdr *udph;
                    104:        struct btphdr *btph;
                    105: 
1.1.1.2 ! root      106: #if DEBUG
        !           107:        struct ethhdr *ethh;
1.1       root      108:        ethh = (struct ethhdr *) packet;
1.1.1.2 ! root      109: #endif
        !           110: 
1.1       root      111:        iph = (struct iphdr *) (packet + sizeof(struct ethhdr));
                    112:        udph = (struct udphdr *) (iph + 1);
                    113:        btph = (struct btphdr *) (udph + 1);
                    114: 
                    115:        memset(packet, 0, packetsize);
                    116: 
                    117:        /* setting up a timer with a timeout of one second */
                    118:        set_timer(TICKS_SEC);
                    119: 
                    120:        do {
                    121: 
                    122:                /* let's receive a packet */
                    123:                len = recv(0, packet, packetsize, 0);
                    124: 
                    125: #if DEBUG
                    126:                int j;
                    127:                printf("%d bytes received, %d expected \n", len, packetsize);
                    128:                if (len == 346) {
                    129:                        printf("Rec packet\n");
                    130:                        printf("Packet is ");
                    131:                        for (j = 0; j < len; j++) {
                    132:                                if (j % 16 == 0)
                    133:                                        printf("\n");
                    134:                                printf(" %02x", packet[j]);
                    135:                        }
                    136:                        printf(".\n");
                    137:                }
                    138: #endif
1.1.1.2 ! root      139:                if (len == 0)
        !           140:                        continue;
        !           141: 
1.1       root      142:                /* check if the ip checksum is correct */
                    143:                old_sum = iph->ip_sum;
                    144:                iph->ip_sum = 0x00;
                    145:                if (old_sum !=
                    146:                    checksum((unsigned short *) iph, sizeof(struct iphdr) >> 1))
                    147:                        /* checksum failed */
                    148:                        continue;
                    149:                /* is it a udp packet */
                    150:                if (iph->ip_p != IPTYPE_UDP)
                    151:                        continue;
                    152:                /* check if the source port and destination port and the packet
                    153:                 * say that it is a bootp answer */
                    154:                if (udph->uh_dport != htons(UDPPORT_BOOTPC) || udph->uh_sport != htons(UDPPORT_BOOTPS))
                    155:                        continue;
                    156:                /* check if it is a Boot Reply */
                    157:                if (btph->op != 2)
                    158:                        continue;
                    159:                /* Comparing our mac address with the one in the bootp reply */ 
                    160:                if (memcmp(get_mac_address(), btph->chaddr, ETH_ALEN))
                    161:                        continue;
                    162: 
                    163:                if(response_buffer)
                    164:                        memcpy(response_buffer, btph, 1720);
                    165: 
                    166:                fn_ip->own_ip = btph->yiaddr;
                    167:                fn_ip->server_ip = btph->siaddr;
                    168:                strcpy((char *) fn_ip->filename, (char *) btph->file);
                    169: 
                    170: #if DEBUG
                    171:                printf("\nThese are the details of the bootp reply:\n");
                    172:                printf("Our IP address: ");
                    173:                print_ip((char*) &fn_ip->own_ip);
                    174:                printf("Next server IP address: ");
                    175:                print_ip((char*) &fn_ip->server_ip);
                    176:                printf("Boot file name: %s\n", btph->file);
                    177:                printf("Packet is: %s\n", btph->file);
                    178:                for (j = 0; j < len; j++) {
                    179:                        if (j % 16 == 0)
                    180:                                printf("\n");
                    181:                        printf(" %02x", packet[j]);
                    182:                }
                    183:                printf(".\n");
                    184:                printf("fn_ip->own_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", 
                    185:                        get_mac_address()[0], get_mac_address()[1],
                    186:                        get_mac_address()[2], get_mac_address()[3],
                    187:                        get_mac_address()[4], get_mac_address()[5]);
                    188:                printf("Header ethh->dest_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", 
                    189:                       ethh->dest_mac[0], ethh->dest_mac[1], ethh->dest_mac[2], 
                    190:                       ethh->dest_mac[3], ethh->dest_mac[4], ethh->dest_mac[5]);
                    191:                printf("Header ethh->src_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", 
                    192:                       ethh->src_mac[0], ethh->src_mac[1], ethh->src_mac[2], 
                    193:                       ethh->src_mac[3], ethh->src_mac[4], ethh->src_mac[5]);
                    194:                printf("Header ethh->typ: %x\n",ethh->type); 
                    195:                printf("Header iph->ip_hlv: %x\n",iph->ip_hlv); 
                    196:                printf("Header iph->ip_len: %x\n",iph->ip_len); 
                    197:                printf("Header iph->ip_id: %x\n",iph->ip_id); 
                    198:                printf("Header iph->ip_off: %x\n",iph->ip_off); 
                    199:                printf("Header iph->ip_ttl: %x\n",iph->ip_ttl); 
                    200:                printf("Header iph->ip_p: %x\n",iph->ip_p); 
                    201:                printf("Header iph->ip_sum: %x\n",iph->ip_sum); 
                    202:                printf("Header iph->ip_src: %x\n",iph->ip_src); 
                    203:                printf("Header iph->ip_dst: %x\n",iph->ip_dst); 
                    204: 
                    205:                printf("Header btph->op: %x\n",btph->op); 
                    206:                printf("Header btph->htype: %x\n",btph->htype); 
                    207:                printf("Header btph->hlen: %x\n",btph->hlen); 
                    208:                printf("Header btph->hops: %x\n",btph->hops); 
                    209:                printf("Header btph->xid: %x\n",btph->xid); 
                    210:                printf("Header btph->secs: %x\n",btph->secs); 
                    211:                printf("Header btph->ciaddr: %x\n",btph->ciaddr); 
                    212:                printf("Header btph->yiaddr: %x\n",btph->yiaddr); 
                    213:                printf("Header btph->siaddr: %x\n",btph->siaddr); 
                    214:                printf("Header btph->giaddr: %x\n",btph->giaddr); 
                    215: 
                    216:                printf("Header btph->chaddr: %02x:%02x:%02x:%02x:%02x:%02x:\n",
                    217:                       btph->chaddr[0], btph->chaddr[1], btph->chaddr[2],
                    218:                       btph->chaddr[3], btph->chaddr[4], btph->chaddr[5]);
                    219: #endif
                    220:                return 0;
                    221: 
                    222:                /* only do this for the time specified during set_timer() */
                    223:        } while (get_timer() > 0);
                    224:        return -1;
                    225: }
                    226: 
                    227: 
                    228: int
                    229: bootp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries)
                    230: {
                    231:        int i = (int) retries+1;
                    232:        fn_ip->own_ip = 0;
                    233: 
                    234:        printf("   ");
                    235: 
                    236:        response_buffer = ret_buffer;
                    237: 
                    238:        do {
                    239:                printf("\b\b%02d", i);
                    240:                if (!i--) {
                    241:                        printf("\nGiving up after %d bootp requests\n",
                    242:                               retries+1);
                    243:                        return -1;
                    244:                }
                    245:                send_bootp(fn_ip);
                    246:                /* if the timer in receive_bootp expired it will return
                    247:                 * -1 and we will just send another bootp request just
                    248:                 * in case the previous one was lost. And because we don't
                    249:                 * trust the network cable we keep on doing this 30 times */
                    250:        } while (receive_bootp(fn_ip) != 0);
                    251:        printf("\b\b\b");
                    252:        return 0;
                    253: }

unix.superglobalmegacorp.com

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