Annotation of qemu/roms/SLOF/clients/net-snk/app/netlib/bootp.c, revision 1.1.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.