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

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

unix.superglobalmegacorp.com

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