20 typedef struct Tftp Tftp;
21 typedef struct Dhcp Dhcp;
38 char pkt[2+2+Segsize];
61 int pxecall(int op, void *buf);
64 unfar(ulong seg, ulong off)
66 return (void*)((off & 0xFFFF) + (seg & 0xFFFF)*16);
70 puts(void *x, ushort v)
83 return p[1]<<8 | p[0];
87 hnputs(void *x, ushort v)
100 return p[0]<<8 | p[1];
106 memmove(d, s, sizeof(d));
116 static uchar shutdown[] = { 0x05, 0x070, 0x02, 0 };
119 for(o = shutdown; *o; o++){
120 memset(&buf, 0, sizeof(buf));
121 if(pxecall(*o, &buf))
127 getip(IP4 yip, IP4 sip, IP4 gip, char mac[16])
140 memset(&buf, 0, sizeof(buf));
141 puts(buf.pkttype, 3);
143 if(r = pxecall(0x71, &buf))
145 if((p = unfar(gets(buf.seg), gets(buf.off))) == 0)
152 mac[i*2] = hex[p->mac[i]>>4];
153 mac[i*2+1] = hex[p->mac[i]&15];
167 moveip(buf.sip, sip);
168 return pxecall(0x30, &buf);
176 return pxecall(0x31, status);
180 udpread(IP4 sip, IP4 dip, int *sport, int dport, int *len, void *data)
195 moveip(buf.sip, sip);
196 moveip(buf.dip, dip);
197 hnputs(buf.sport, *sport);
198 hnputs(buf.dport, dport);
200 puts(buf.off, (long)data);
202 if(r = pxecall(0x32, &buf))
204 moveip(sip, buf.sip);
205 *sport = nhgets(buf.sport);
206 *len = gets(buf.len);
211 udpwrite(IP4 ip, IP4 gw, int sport, int dport, int len, void *data)
227 hnputs(buf.sport, sport);
228 hnputs(buf.dport, dport);
230 puts(buf.off, (long)data);
232 return pxecall(0x33, &buf);
236 read(void *f, void *data, int len)
241 while(!t->eof && t->rp >= t->ep){
244 if(udpread(t->dip, t->sip, &t->dport, t->sport, &n, t->pkt))
249 switch(nhgets(t->pkt)){
251 seq = nhgets(t->pkt+2);
256 hnputs(t->pkt, Tftp_ACK);
257 while(udpwrite(t->dip, t->gip, t->sport, t->dport, 4, t->pkt))
262 t->eof = n < Segsize;
276 memmove(data, t->rp, len);
291 tftpopen(Tftp *t, char *path, IP4 sip, IP4 dip, IP4 gip)
293 static ushort xport = 6666;
299 memset(t->dip, 0, sizeof(t->dip));
306 if(r = udpopen(t->sip))
309 hnputs(p, Tftp_READ); p += 2;
311 memmove(p, path, n); p += n;
312 memmove(p, "octet", 6); p += 6;
315 if(r = udpwrite(dip, t->gip, t->sport, TftpPort, n, t->pkt))
317 if(r = read(t, 0, 0))
328 char mac[16], path[Maxpath], *kern;
334 print("pxe init\r\n");
337 if(getip(yip, sip, gip, mac)){
338 print("bad dhcp\r\n");
341 memmove(path, "/cfg/pxe/", 9);
342 memmove(path+9, mac, 13);
343 if(tftpopen(f = &t, path, yip, sip, gip)){
344 print("no config\r\n");
348 kern = configure(f, path); f = 0;
349 if(tftpopen(&t, kern, yip, sip, gip)){
350 print("not found\r\n");