1 /******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation
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
10 * IBM Corporation - initial implementation
11 *****************************************************************************/
16 #include <sys/socket.h>
26 static char * response_buffer;
32 printf("%d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
36 /* IP header checksum calculation */
38 checksum(unsigned short *packet, int words)
40 unsigned long checksum;
41 for (checksum = 0; words > 0; words--)
42 checksum += *packet++;
43 checksum = (checksum >> 16) + (checksum & 0xffff);
44 checksum += (checksum >> 16);
50 send_bootp(filename_ip_t * fn_ip)
55 unsigned int packetsize =
56 sizeof(struct iphdr) + sizeof(struct ethhdr) +
57 sizeof(struct udphdr) + sizeof(struct btphdr);
58 unsigned char packet[packetsize];
63 iph = (struct iphdr *) packet;
64 udph = (struct udphdr *) (iph + 1);
65 btph = (struct btphdr *) (udph + 1);
67 memset(packet, 0, packetsize);
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));
77 strcpy((char *) btph->file, "bla");
78 memcpy(btph->chaddr, get_mac_address(), 6);
81 printf("Sending packet\n");
83 for (i = 0; i < packetsize; i++)
84 printf(" %02x", packet[i]);
88 send_ipv4(fn_ip->fd, packet, iph->ip_len);
90 printf("%d bytes transmitted over socket.\n", i);
98 receive_bootp(filename_ip_t * fn_ip)
101 unsigned int packetsize = 2000;
102 unsigned char packet[packetsize];
109 ethh = (struct ethhdr *) packet;
112 iph = (struct iphdr *) (packet + sizeof(struct ethhdr));
113 udph = (struct udphdr *) (iph + 1);
114 btph = (struct btphdr *) (udph + 1);
116 memset(packet, 0, packetsize);
118 /* setting up a timer with a timeout of one second */
119 set_timer(TICKS_SEC);
123 /* let's receive a packet */
124 len = recv(fn_ip->fd, packet, packetsize, 0);
128 printf("%d bytes received, %d expected \n", len, packetsize);
130 printf("Rec packet\n");
131 printf("Packet is ");
132 for (j = 0; j < len; j++) {
135 printf(" %02x", packet[j]);
143 /* check if the ip checksum is correct */
144 old_sum = iph->ip_sum;
147 checksum((unsigned short *) iph, sizeof(struct iphdr) >> 1))
148 /* checksum failed */
150 /* is it a udp packet */
151 if (iph->ip_p != IPTYPE_UDP)
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))
157 /* check if it is a Boot Reply */
160 /* Comparing our mac address with the one in the bootp reply */
161 if (memcmp(get_mac_address(), btph->chaddr, ETH_ALEN))
165 memcpy(response_buffer, btph, 1720);
167 fn_ip->own_ip = btph->yiaddr;
168 fn_ip->server_ip = btph->siaddr;
169 strcpy((char *) fn_ip->filename, (char *) btph->file);
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++) {
182 printf(" %02x", packet[j]);
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);
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);
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]);
223 /* only do this for the time specified during set_timer() */
224 } while (get_timer() > 0);
230 bootp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries)
232 int i = (int) retries+1;
237 response_buffer = ret_buffer;
240 printf("\b\b%02d", i);
242 printf("\nGiving up after %d bootp requests\n",
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);