ZealOS/docs/Home/Net/Protocols/DHCP.ZC.html
2021-12-11 06:10:58 -05:00

569 lines
52 KiB
HTML
Executable file

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<meta name="generator" content="ZealOS V1.07">
<style type="text/css">
body {background-color:#1f1f1f;}
.cF0{color:#e3e3e3;background-color:#1f1f1f;}
.cF1{color:#4f84a6;background-color:#1f1f1f;}
.cF2{color:#73a255;background-color:#1f1f1f;}
.cF3{color:#297582;background-color:#1f1f1f;}
.cF4{color:#b34f4b;background-color:#1f1f1f;}
.cF5{color:#8a52c3;background-color:#1f1f1f;}
.cF6{color:#b7822f;background-color:#1f1f1f;}
.cF7{color:#444444;background-color:#1f1f1f;}
.cF8{color:#6d6d6d;background-color:#1f1f1f;}
.cF9{color:#94bfde;background-color:#1f1f1f;}
.cFA{color:#a1ce97;background-color:#1f1f1f;}
.cFB{color:#6db4be;background-color:#1f1f1f;}
.cFC{color:#e88e88;background-color:#1f1f1f;}
.cFD{color:#ca94e8;background-color:#1f1f1f;}
.cFE{color:#d4b475;background-color:#1f1f1f;}
.cFF{color:#1f1f1f;background-color:#1f1f1f;}
</style>
</head>
<body>
<pre style="font-family:monospace;font-size:12pt">
<a name="l1"></a><span class=cF2>//www.networksorcery.com/enp/protocol/dhcp.htm</span><span class=cF0>
<a name="l2"></a>
<a name="l3"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPCODE_BOOTREQUEST </span><span class=cFE>0x01</span><span class=cF0>
<a name="l4"></a>
<a name="l5"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPTION_SUBNET_MASK </span><span class=cFE>1</span><span class=cF0>
<a name="l6"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPTION_ROUTER </span><span class=cFE>3</span><span class=cF0>
<a name="l7"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPTION_DNS </span><span class=cFE>6</span><span class=cF0>
<a name="l8"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPTION_DOMAIN_NAME </span><span class=cFE>15</span><span class=cF0>
<a name="l9"></a>
<a name="l10"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPTION_REQUESTED_IP </span><span class=cFE>50</span><span class=cF0>
<a name="l11"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPTION_MESSAGETYPE </span><span class=cFE>53</span><span class=cF0>
<a name="l12"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPTION_SERVER_ID </span><span class=cFE>54</span><span class=cF0>
<a name="l13"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_OPTION_PARAMLIST </span><span class=cFE>55</span><span class=cF0>
<a name="l14"></a>
<a name="l15"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_MESSAGETYPE_DISCOVER </span><span class=cFE>0x01</span><span class=cF0>
<a name="l16"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_MESSAGETYPE_OFFER </span><span class=cFE>0x02</span><span class=cF0>
<a name="l17"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_MESSAGETYPE_REQUEST </span><span class=cFE>0x03</span><span class=cF0>
<a name="l18"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_MESSAGETYPE_ACK </span><span class=cFE>0x05</span><span class=cF0>
<a name="l19"></a>
<a name="l20"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_COOKIE </span><span class=cFE>0x63825363</span><span class=cF0>
<a name="l21"></a>
<a name="l22"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_STATE_CLIENT_START </span><span class=cFE>0</span><span class=cF0>
<a name="l23"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_STATE_CLIENT_DISCOVER </span><span class=cFE>1</span><span class=cF0>
<a name="l24"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_STATE_CLIENT_REQUEST </span><span class=cFE>2</span><span class=cF0>
<a name="l25"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_STATE_CLIENT_REQ_ACCEPTED </span><span class=cFE>3</span><span class=cF0>
<a name="l26"></a>
<a name="l27"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_TIMEOUT </span><span class=cFE>3000</span><span class=cF0>
<a name="l28"></a>#</span><span class=cF1>define</span><span class=cF0> DHCP_MAX_RETRIES </span><span class=cFE>5</span><span class=cF0> </span><span class=cF2>// shrine has 3, why not 5 :^)</span><span class=cF0>
<a name="l29"></a>
<a name="l30"></a></span><span class=cF1>class</span><span class=cF0> CDHCPHeader
<a name="l31"></a>{
<a name="l32"></a> </span><span class=cF1>U8</span><span class=cF0> opcode; </span><span class=cF2>// Opcode</span><span class=cF0>
<a name="l33"></a> </span><span class=cF1>U8</span><span class=cF0> hw_type; </span><span class=cF2>// Hardware Type</span><span class=cF0>
<a name="l34"></a> </span><span class=cF1>U8</span><span class=cF0> hw_addr_len; </span><span class=cF2>// Hardware Address Length</span><span class=cF0>
<a name="l35"></a> </span><span class=cF1>U8</span><span class=cF0> hops; </span><span class=cF2>// Hop Count</span><span class=cF0>
<a name="l36"></a> </span><span class=cF9>U32</span><span class=cF0> xid; </span><span class=cF2>// Transaction ID</span><span class=cF0>
<a name="l37"></a> </span><span class=cF9>U16</span><span class=cF0> seconds; </span><span class=cF2>// Elapsed time in seconds since client began address acquisition or renewal process</span><span class=cF0>
<a name="l38"></a> </span><span class=cF9>U16</span><span class=cF0> flags; </span><span class=cF2>// Flags</span><span class=cF0>
<a name="l39"></a> </span><span class=cF9>U32</span><span class=cF0> client_ip; </span><span class=cF2>// Client IP Address</span><span class=cF0>
<a name="l40"></a> </span><span class=cF9>U32</span><span class=cF0> your_ip; </span><span class=cF2>// Your IP Address</span><span class=cF0>
<a name="l41"></a> </span><span class=cF9>U32</span><span class=cF0> server_ip; </span><span class=cF2>// Server IP Address</span><span class=cF0>
<a name="l42"></a> </span><span class=cF9>U32</span><span class=cF0> gateway_ip; </span><span class=cF2>// Gateway IP Address</span><span class=cF0>
<a name="l43"></a> </span><span class=cF1>U8</span><span class=cF0> client_hw_addr[</span><span class=cFE>16</span><span class=cF0>]; </span><span class=cF2>// Client Hardware Address</span><span class=cF0>
<a name="l44"></a> </span><span class=cF1>U8</span><span class=cF0> server_name[</span><span class=cFE>64</span><span class=cF0>]; </span><span class=cF2>// Server Hostname</span><span class=cF0>
<a name="l45"></a> </span><span class=cF1>U8</span><span class=cF0> boot_file[</span><span class=cFE>128</span><span class=cF0>]; </span><span class=cF2>// Boot Filename</span><span class=cF0>
<a name="l46"></a>};
<a name="l47"></a>
<a name="l48"></a></span><span class=cF1>class</span><span class=cF0> CDHCPDiscoverOptions
<a name="l49"></a>{
<a name="l50"></a> </span><span class=cF9>U32</span><span class=cF0> cookie;
<a name="l51"></a> </span><span class=cF1>U8</span><span class=cF0> message_type;
<a name="l52"></a> </span><span class=cF1>U8</span><span class=cF0> message_length;
<a name="l53"></a> </span><span class=cF1>U8</span><span class=cF0> message; </span><span class=cF2>// dmt</span><span class=cF0>
<a name="l54"></a> </span><span class=cF1>U8</span><span class=cF0> param_req_list_type;
<a name="l55"></a> </span><span class=cF1>U8</span><span class=cF0> param_req_list_length;
<a name="l56"></a> </span><span class=cF1>U8</span><span class=cF0> param_req_list[</span><span class=cFE>4</span><span class=cF0>];
<a name="l57"></a> </span><span class=cF1>U8</span><span class=cF0> </span><span class=cF1>end</span><span class=cF0>;
<a name="l58"></a>};
<a name="l59"></a>
<a name="l60"></a></span><span class=cF1>class</span><span class=cF0> CDHCPRequestOptions
<a name="l61"></a>{
<a name="l62"></a> </span><span class=cF9>U32</span><span class=cF0> cookie;
<a name="l63"></a> </span><span class=cF1>U8</span><span class=cF0> message_type;
<a name="l64"></a> </span><span class=cF1>U8</span><span class=cF0> message_length;
<a name="l65"></a> </span><span class=cF1>U8</span><span class=cF0> message; </span><span class=cF2>// dmt</span><span class=cF0>
<a name="l66"></a> </span><span class=cF1>U8</span><span class=cF0> requested_ip_type;
<a name="l67"></a> </span><span class=cF1>U8</span><span class=cF0> requested_ip_length;
<a name="l68"></a> </span><span class=cF9>U32</span><span class=cF0> requested_ip;
<a name="l69"></a> </span><span class=cF1>U8</span><span class=cF0> server_id_type;
<a name="l70"></a> </span><span class=cF1>U8</span><span class=cF0> server_id_length;
<a name="l71"></a> </span><span class=cF9>U32</span><span class=cF0> server_id;
<a name="l72"></a> </span><span class=cF1>U8</span><span class=cF0> </span><span class=cF1>end</span><span class=cF0>;
<a name="l73"></a>};
<a name="l74"></a>
<a name="l75"></a></span><span class=cF9>U32</span><span class=cF0> DHCPTransactionBegin()
<a name="l76"></a>{
<a name="l77"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF5>RandU32</span><span class=cF0>;
<a name="l78"></a>}
<a name="l79"></a>
<a name="l80"></a></span><span class=cF9>I64</span><span class=cF0> DHCPDiscoverSend(</span><span class=cF9>U32</span><span class=cF0> xid)
<a name="l81"></a>{
<a name="l82"></a> </span><span class=cF1>U8</span><span class=cF0> *dhcp_frame;
<a name="l83"></a> </span><span class=cF9>I64</span><span class=cF0> de_index;
<a name="l84"></a> CDHCPHeader *dhcp;
<a name="l85"></a> CDHCPDiscoverOptions *opts;
<a name="l86"></a>
<a name="l87"></a>
<a name="l88"></a> de_index = UDPPacketAllocate(&amp;dhcp_frame,
<a name="l89"></a> </span><span class=cFE>0x00000000</span><span class=cF0>,
<a name="l90"></a> </span><span class=cFE>68</span><span class=cF0>,
<a name="l91"></a> </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>,
<a name="l92"></a> </span><span class=cFE>67</span><span class=cF0>,
<a name="l93"></a> </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CDHCPHeader</span><span class=cF7>)</span><span class=cF0> + </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CDHCPDiscoverOptions</span><span class=cF7>)</span><span class=cF0>);
<a name="l94"></a> </span><span class=cF1>if</span><span class=cF0> (de_index &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l95"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l96"></a> NetErr(</span><span class=cF6>&quot;DHCP SEND DISCOVER: Failed, UDP Packet Allocate error.&quot;</span><span class=cF0>);
<a name="l97"></a> </span><span class=cF1>return</span><span class=cF0> de_index;
<a name="l98"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l99"></a>
<a name="l100"></a> dhcp = dhcp_frame;
<a name="l101"></a> </span><span class=cF5>MemSet</span><span class=cF0>(dhcp, </span><span class=cFE>0</span><span class=cF0>, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CDHCPHeader</span><span class=cF7>)</span><span class=cF0>);
<a name="l102"></a>
<a name="l103"></a> dhcp-&gt;opcode = DHCP_OPCODE_BOOTREQUEST;
<a name="l104"></a> dhcp-&gt;hw_type = HTYPE_ETHERNET;
<a name="l105"></a> dhcp-&gt;hw_addr_len = HLEN_ETHERNET;
<a name="l106"></a> dhcp-&gt;hops = </span><span class=cFE>0</span><span class=cF0>;
<a name="l107"></a> dhcp-&gt;xid = </span><span class=cF5>EndianU32</span><span class=cF0>(xid);
<a name="l108"></a> dhcp-&gt;seconds = </span><span class=cFE>0</span><span class=cF0>;
<a name="l109"></a> dhcp-&gt;flags = </span><span class=cF5>EndianU16</span><span class=cF0>(</span><span class=cFE>0x8000</span><span class=cF0>); </span><span class=cF2>// DHCP flag: accept Offer from Broadcast.</span><span class=cF0>
<a name="l110"></a> dhcp-&gt;client_ip = </span><span class=cFE>0</span><span class=cF0>;
<a name="l111"></a> dhcp-&gt;your_ip = </span><span class=cFE>0</span><span class=cF0>;
<a name="l112"></a> dhcp-&gt;server_ip = </span><span class=cFE>0</span><span class=cF0>;
<a name="l113"></a> dhcp-&gt;gateway_ip = </span><span class=cFE>0</span><span class=cF0>;
<a name="l114"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(dhcp-&gt;client_hw_addr, EthernetMACGet, MAC_ADDRESS_LENGTH);
<a name="l115"></a>
<a name="l116"></a> opts = dhcp_frame + </span><span class=cF1>sizeof</span><span class=cF0>(CDHCPHeader);
<a name="l117"></a>
<a name="l118"></a> opts-&gt;cookie = </span><span class=cF5>EndianU32</span><span class=cF0>(DHCP_COOKIE);
<a name="l119"></a> opts-&gt;message_type = DHCP_OPTION_MESSAGETYPE;
<a name="l120"></a> opts-&gt;message_length = </span><span class=cFE>1</span><span class=cF0>;
<a name="l121"></a> opts-&gt;message = DHCP_MESSAGETYPE_DISCOVER;
<a name="l122"></a> opts-&gt;param_req_list_type = DHCP_OPTION_PARAMLIST;
<a name="l123"></a> opts-&gt;param_req_list_length = </span><span class=cFE>4</span><span class=cF0>;
<a name="l124"></a> opts-&gt;param_req_list[</span><span class=cFE>0</span><span class=cF0>] = DHCP_OPTION_SUBNET_MASK;
<a name="l125"></a> opts-&gt;param_req_list[</span><span class=cFE>1</span><span class=cF0>] = DHCP_OPTION_ROUTER;
<a name="l126"></a> opts-&gt;param_req_list[</span><span class=cFE>2</span><span class=cF0>] = DHCP_OPTION_DNS;
<a name="l127"></a> opts-&gt;param_req_list[</span><span class=cFE>3</span><span class=cF0>] = DHCP_OPTION_DOMAIN_NAME;
<a name="l128"></a> opts-&gt;</span><span class=cF1>end</span><span class=cF0> = </span><span class=cFE>0xFF</span><span class=cF0>; </span><span class=cF2>// ??</span><span class=cF0>
<a name="l129"></a>
<a name="l130"></a> UDPPacketFinish(de_index);
<a name="l131"></a> </span><span class=cF1>return</span><span class=cF0> de_index;
<a name="l132"></a>}
<a name="l133"></a>
<a name="l134"></a></span><span class=cF9>I64</span><span class=cF0> DHCPRequestSend(</span><span class=cF9>U32</span><span class=cF0> xid, </span><span class=cF9>U32</span><span class=cF0> requested_ip, </span><span class=cF9>U32</span><span class=cF0> server_ip)
<a name="l135"></a>{
<a name="l136"></a> </span><span class=cF1>U8</span><span class=cF0> *dhcp_frame;
<a name="l137"></a> </span><span class=cF9>I64</span><span class=cF0> de_index;
<a name="l138"></a> CDHCPHeader *dhcp;
<a name="l139"></a> CDHCPRequestOptions *opts;
<a name="l140"></a>
<a name="l141"></a> de_index = UDPPacketAllocate(&amp;dhcp_frame,
<a name="l142"></a> </span><span class=cFE>0x00000000</span><span class=cF0>,
<a name="l143"></a> </span><span class=cFE>68</span><span class=cF0>,
<a name="l144"></a> </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>,
<a name="l145"></a> </span><span class=cFE>67</span><span class=cF0>,
<a name="l146"></a> </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CDHCPHeader</span><span class=cF7>)</span><span class=cF0> + </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CDHCPRequestOptions</span><span class=cF7>)</span><span class=cF0>);
<a name="l147"></a> </span><span class=cF1>if</span><span class=cF0> (de_index &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l148"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l149"></a> NetErr(</span><span class=cF6>&quot;DHCP SEND REQUEST: Failed, UDP Packet Allocate error.&quot;</span><span class=cF0>);
<a name="l150"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l151"></a>
<a name="l152"></a> dhcp = dhcp_frame;
<a name="l153"></a> </span><span class=cF5>MemSet</span><span class=cF0>(dhcp, </span><span class=cFE>0</span><span class=cF0>, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CDHCPHeader</span><span class=cF7>)</span><span class=cF0>);
<a name="l154"></a>
<a name="l155"></a> dhcp-&gt;opcode = DHCP_OPCODE_BOOTREQUEST;
<a name="l156"></a> dhcp-&gt;hw_type = HTYPE_ETHERNET;
<a name="l157"></a> dhcp-&gt;hw_addr_len = HLEN_ETHERNET;
<a name="l158"></a> dhcp-&gt;hops = </span><span class=cFE>0</span><span class=cF0>;
<a name="l159"></a> dhcp-&gt;xid = </span><span class=cF5>EndianU32</span><span class=cF0>(xid);
<a name="l160"></a> dhcp-&gt;seconds = </span><span class=cFE>0</span><span class=cF0>;
<a name="l161"></a> dhcp-&gt;flags = </span><span class=cF5>EndianU16</span><span class=cF0>(</span><span class=cFE>0x0000</span><span class=cF0>); </span><span class=cF2>// DHCP flag: accept ACK from Unicast.</span><span class=cF0>
<a name="l162"></a> dhcp-&gt;client_ip = </span><span class=cFE>0</span><span class=cF0>;
<a name="l163"></a> dhcp-&gt;your_ip = </span><span class=cFE>0</span><span class=cF0>;
<a name="l164"></a> dhcp-&gt;server_ip = </span><span class=cF5>EndianU32</span><span class=cF0>(server_ip);
<a name="l165"></a> dhcp-&gt;gateway_ip = </span><span class=cFE>0</span><span class=cF0>;
<a name="l166"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(dhcp-&gt;client_hw_addr, EthernetMACGet, MAC_ADDRESS_LENGTH);
<a name="l167"></a>
<a name="l168"></a> opts = dhcp_frame + </span><span class=cF1>sizeof</span><span class=cF0>(CDHCPHeader);
<a name="l169"></a>
<a name="l170"></a> opts-&gt;cookie = </span><span class=cF5>EndianU32</span><span class=cF0>(DHCP_COOKIE);
<a name="l171"></a> opts-&gt;message_type = DHCP_OPTION_MESSAGETYPE;
<a name="l172"></a> opts-&gt;message_length = </span><span class=cFE>1</span><span class=cF0>;
<a name="l173"></a> opts-&gt;message = DHCP_MESSAGETYPE_REQUEST;
<a name="l174"></a> opts-&gt;requested_ip_type = DHCP_OPTION_REQUESTED_IP;
<a name="l175"></a> opts-&gt;requested_ip_length = </span><span class=cFE>4</span><span class=cF0>;
<a name="l176"></a> opts-&gt;requested_ip = </span><span class=cF5>EndianU32</span><span class=cF0>(requested_ip);
<a name="l177"></a> opts-&gt;server_id_type = DHCP_OPTION_SERVER_ID;
<a name="l178"></a> opts-&gt;server_id_length = </span><span class=cFE>4</span><span class=cF0>;
<a name="l179"></a> opts-&gt;server_id = </span><span class=cF5>EndianU32</span><span class=cF0>(server_ip);
<a name="l180"></a> opts-&gt;</span><span class=cF1>end</span><span class=cF0> = </span><span class=cFE>0xFF</span><span class=cF0>;
<a name="l181"></a>
<a name="l182"></a> UDPPacketFinish(de_index);
<a name="l183"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
<a name="l184"></a>}
<a name="l185"></a>
<a name="l186"></a></span><span class=cF9>I64</span><span class=cF0> DHCPBeginParse(</span><span class=cF1>U8</span><span class=cF0> **data_inout, </span><span class=cF9>I64</span><span class=cF0> *length_inout, CDHCPHeader **header_out)
<a name="l187"></a>{
<a name="l188"></a> </span><span class=cF1>U8</span><span class=cF0> *data = *data_inout;
<a name="l189"></a> </span><span class=cF9>I64</span><span class=cF0> length = *length_inout;
<a name="l190"></a> </span><span class=cF9>U32</span><span class=cF0> *cookie;
<a name="l191"></a>
<a name="l192"></a> </span><span class=cF1>if</span><span class=cF0> (length &lt; </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CDHCPHeader</span><span class=cF7>)</span><span class=cF0> + </span><span class=cFE>4</span><span class=cF0>) </span><span class=cF2>// + 4?</span><span class=cF0>
<a name="l193"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l194"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE BEGIN: Failed, length too short.&quot;</span><span class=cF0>);
<a name="l195"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l196"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l197"></a>
<a name="l198"></a> cookie = data + </span><span class=cF1>sizeof</span><span class=cF0>(CDHCPHeader);
<a name="l199"></a>
<a name="l200"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>EndianU32</span><span class=cF7>(</span><span class=cF0>*cookie</span><span class=cF7>)</span><span class=cF0> != DHCP_COOKIE)
<a name="l201"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l202"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE BEGIN: Failed, cookie doesn't match DHCP-cookie.&quot;</span><span class=cF0>);
<a name="l203"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l204"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l205"></a>
<a name="l206"></a> *header_out = data;
<a name="l207"></a> *data_inout = data + </span><span class=cF1>sizeof</span><span class=cF0>(CDHCPHeader) + </span><span class=cFE>4</span><span class=cF0>; </span><span class=cF2>// ?</span><span class=cF0>
<a name="l208"></a> *length_inout = length - </span><span class=cF1>sizeof</span><span class=cF0>(CDHCPHeader) + </span><span class=cFE>4</span><span class=cF0>; </span><span class=cF2>// ?..</span><span class=cF0>
<a name="l209"></a>
<a name="l210"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
<a name="l211"></a>}
<a name="l212"></a>
<a name="l213"></a></span><span class=cF9>I64</span><span class=cF0> DHCPOptionParse(</span><span class=cF1>U8</span><span class=cF0> **data_inout, </span><span class=cF9>I64</span><span class=cF0> *length_inout, </span><span class=cF1>U8</span><span class=cF0> *type_out, </span><span class=cF1>U8</span><span class=cF0> *value_length_out, </span><span class=cF1>U8</span><span class=cF0> **value_out)
<a name="l214"></a>{
<a name="l215"></a> </span><span class=cF1>U8</span><span class=cF0> *data = *data_inout;
<a name="l216"></a> </span><span class=cF9>I64</span><span class=cF0> length = *length_inout;
<a name="l217"></a>
<a name="l218"></a> </span><span class=cF1>if</span><span class=cF0> (length &lt; </span><span class=cFE>2</span><span class=cF0> || length &lt; </span><span class=cFE>2</span><span class=cF0> + data[</span><span class=cFE>1</span><span class=cF0>]) </span><span class=cF2>// ??? what is the 1</span><span class=cF0>
<a name="l219"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l220"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE OPTION: Failed, length too short.&quot;</span><span class=cF0>);
<a name="l221"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l222"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l223"></a>
<a name="l224"></a> </span><span class=cF1>if</span><span class=cF0> (data[</span><span class=cFE>0</span><span class=cF0>] == </span><span class=cFE>0xFF</span><span class=cF0>) </span><span class=cF2>// ahead, data[0] is type_out, so data[0] is perhaps usually type?</span><span class=cF0>
<a name="l225"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l226"></a> NetLog(</span><span class=cF6>&quot;DHCP PARSE OPTION: Saw 0xFF, returning 0.&quot;</span><span class=cF0>);
<a name="l227"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
<a name="l228"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l229"></a>
<a name="l230"></a> *type_out = data[</span><span class=cFE>0</span><span class=cF0>];
<a name="l231"></a> *value_length_out = data[</span><span class=cFE>1</span><span class=cF0>];
<a name="l232"></a> *value_out = data + </span><span class=cFE>2</span><span class=cF0>;
<a name="l233"></a>
<a name="l234"></a> *data_inout = data + </span><span class=cFE>2</span><span class=cF0> + *value_length_out;
<a name="l235"></a> *length_inout = length - </span><span class=cFE>2</span><span class=cF0> + *value_length_out;
<a name="l236"></a>
<a name="l237"></a> </span><span class=cF1>return</span><span class=cF0> data[</span><span class=cFE>0</span><span class=cF0>]; </span><span class=cF2>// returns ... type?</span><span class=cF0>
<a name="l238"></a>}
<a name="l239"></a>
<a name="l240"></a></span><span class=cF9>I64</span><span class=cF0> DHCPOfferParse(</span><span class=cF9>U32</span><span class=cF0> xid, </span><span class=cF1>U8</span><span class=cF0> *data, </span><span class=cF9>I64</span><span class=cF0> length,
<a name="l241"></a> </span><span class=cF9>U32</span><span class=cF0> *your_ip_out,
<a name="l242"></a> </span><span class=cF9>U32</span><span class=cF0> *dns_ip_out,
<a name="l243"></a> </span><span class=cF9>U32</span><span class=cF0> *router_ip_out,
<a name="l244"></a> </span><span class=cF9>U32</span><span class=cF0> *subnet_mask_out)
<a name="l245"></a>{
<a name="l246"></a> CDHCPHeader *header;
<a name="l247"></a> </span><span class=cF9>I64</span><span class=cF0> error = DHCPBeginParse(&amp;data, &amp;length, &amp;header);
<a name="l248"></a> </span><span class=cF1>Bool</span><span class=cF0> have_type = </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l249"></a> </span><span class=cF1>Bool</span><span class=cF0> have_dns = </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l250"></a> </span><span class=cF1>Bool</span><span class=cF0> have_router = </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l251"></a> </span><span class=cF1>Bool</span><span class=cF0> have_subnet = </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l252"></a> </span><span class=cF1>U8</span><span class=cF0> type;
<a name="l253"></a> </span><span class=cF1>U8</span><span class=cF0> value_length;
<a name="l254"></a> </span><span class=cF1>U8</span><span class=cF0> *value;
<a name="l255"></a> </span><span class=cF9>U32</span><span class=cF0> address;
<a name="l256"></a>
<a name="l257"></a>
<a name="l258"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>EndianU32</span><span class=cF7>(</span><span class=cF0>header-&gt;xid</span><span class=cF7>)</span><span class=cF0> != xid)
<a name="l259"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l260"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE OFFER: Failed, parsed and parameter Transaction IDs do not match.&quot;</span><span class=cF0>);
<a name="l261"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l262"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l263"></a>
<a name="l264"></a> </span><span class=cF1>while</span><span class=cF0> (length)
<a name="l265"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l266"></a> error = DHCPOptionParse(&amp;data, &amp;length, &amp;type, &amp;value_length, &amp;value);
<a name="l267"></a>
<a name="l268"></a> </span><span class=cF1>if</span><span class=cF0> (error &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l269"></a> {
<a name="l270"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE OFFER: Failed at DHCP Parse Option.&quot;</span><span class=cF0>);
<a name="l271"></a> </span><span class=cF1>return</span><span class=cF0> error;
<a name="l272"></a> }
<a name="l273"></a> </span><span class=cF1>if</span><span class=cF0> (error == </span><span class=cFE>0</span><span class=cF0>)
<a name="l274"></a> {
<a name="l275"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l276"></a> }
<a name="l277"></a>
<a name="l278"></a> address = </span><span class=cF5>EndianU32</span><span class=cF0>(*value</span><span class=cF7>(</span><span class=cF9>U32</span><span class=cF0> *</span><span class=cF7>)</span><span class=cF0>);
<a name="l279"></a>
<a name="l280"></a> </span><span class=cF1>switch</span><span class=cF0> (type)
<a name="l281"></a> {
<a name="l282"></a> </span><span class=cF1>case</span><span class=cF0> DHCP_OPTION_MESSAGETYPE:
<a name="l283"></a> NetLog(</span><span class=cF6>&quot;DHCP PARSE OFFER: Parsed Option, Type MESSAGETYPE.&quot;</span><span class=cF0>);
<a name="l284"></a> </span><span class=cF1>if</span><span class=cF0> (value_length == </span><span class=cFE>1</span><span class=cF0> &amp;&amp; value[</span><span class=cFE>0</span><span class=cF0>] == DHCP_MESSAGETYPE_OFFER)
<a name="l285"></a> have_type = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l286"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l287"></a>
<a name="l288"></a> </span><span class=cF1>case</span><span class=cF0> DHCP_OPTION_DNS:
<a name="l289"></a> NetLog(</span><span class=cF6>&quot;DHCP PARSE OFFER: Parsed Option, Type DNS.&quot;</span><span class=cF0>);
<a name="l290"></a> </span><span class=cF1>if</span><span class=cF0> (value_length == </span><span class=cFE>4</span><span class=cF0>)
<a name="l291"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l292"></a> *dns_ip_out = address;
<a name="l293"></a> have_dns = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l294"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l295"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l296"></a>
<a name="l297"></a> </span><span class=cF1>case</span><span class=cF0> DHCP_OPTION_ROUTER:
<a name="l298"></a> NetLog(</span><span class=cF6>&quot;DHCP PARSE OFFER: Parsed Option, Type ROUTER.&quot;</span><span class=cF0>);
<a name="l299"></a> </span><span class=cF1>if</span><span class=cF0> (value_length == </span><span class=cFE>4</span><span class=cF0>)
<a name="l300"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l301"></a> *router_ip_out = address;
<a name="l302"></a> have_router = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l303"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l304"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l305"></a>
<a name="l306"></a> </span><span class=cF1>case</span><span class=cF0> DHCP_OPTION_SUBNET_MASK:
<a name="l307"></a> NetLog(</span><span class=cF6>&quot;DHCP PARSE OFFER: Parsed Option, Type SUBNET MASK.&quot;</span><span class=cF0>);
<a name="l308"></a> </span><span class=cF1>if</span><span class=cF0> (value_length == </span><span class=cFE>4</span><span class=cF0>)
<a name="l309"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l310"></a> *subnet_mask_out = address;
<a name="l311"></a> have_subnet = </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l312"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l313"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l314"></a> }
<a name="l315"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l316"></a>
<a name="l317"></a> </span><span class=cF1>if</span><span class=cF0> (have_type &amp;&amp; have_dns &amp;&amp; have_subnet &amp;&amp; have_router)
<a name="l318"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l319"></a> *your_ip_out = </span><span class=cF5>EndianU32</span><span class=cF0>(header-&gt;your_ip);
<a name="l320"></a> NetLog(</span><span class=cF6>&quot;DHCP PARSE OFFER: Success, got your-ip from DHCP Header.&quot;</span><span class=cF0>);
<a name="l321"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
<a name="l322"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l323"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l324"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l325"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE OFFER: Failed, did not have needed Options.&quot;</span><span class=cF0>);
<a name="l326"></a> NetErr(</span><span class=cF6>&quot; have_type: %Z&quot;</span><span class=cF0>, have_type, </span><span class=cF6>&quot;ST_FALSE_TRUE&quot;</span><span class=cF0>);
<a name="l327"></a> NetErr(</span><span class=cF6>&quot; have_dns: %Z&quot;</span><span class=cF0>, have_dns, </span><span class=cF6>&quot;ST_FALSE_TRUE&quot;</span><span class=cF0>);
<a name="l328"></a> NetErr(</span><span class=cF6>&quot; have_router: %Z&quot;</span><span class=cF0>, have_router, </span><span class=cF6>&quot;ST_FALSE_TRUE&quot;</span><span class=cF0>);
<a name="l329"></a> NetErr(</span><span class=cF6>&quot; have_subnet: %Z&quot;</span><span class=cF0>, have_subnet, </span><span class=cF6>&quot;ST_FALSE_TRUE&quot;</span><span class=cF0>);
<a name="l330"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l331"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l332"></a>}
<a name="l333"></a>
<a name="l334"></a></span><span class=cF9>I64</span><span class=cF0> DHCPAckParse(</span><span class=cF9>U32</span><span class=cF0> xid, </span><span class=cF1>U8</span><span class=cF0> *data, </span><span class=cF9>I64</span><span class=cF0> length)
<a name="l335"></a>{
<a name="l336"></a> CDHCPHeader *header;
<a name="l337"></a> </span><span class=cF9>I64</span><span class=cF0> error = DHCPBeginParse(&amp;data, &amp;length, &amp;header);
<a name="l338"></a> </span><span class=cF1>U8</span><span class=cF0> type;
<a name="l339"></a> </span><span class=cF1>U8</span><span class=cF0> value_length;
<a name="l340"></a> </span><span class=cF1>U8</span><span class=cF0> *value;
<a name="l341"></a>
<a name="l342"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>EndianU32</span><span class=cF7>(</span><span class=cF0>header-&gt;xid</span><span class=cF7>)</span><span class=cF0> != xid)
<a name="l343"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l344"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE ACK: Failed, parsed and parameter Transaction IDs do not match.&quot;</span><span class=cF0>);
<a name="l345"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l346"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l347"></a>
<a name="l348"></a> </span><span class=cF1>while</span><span class=cF0> (length)
<a name="l349"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l350"></a> error = DHCPOptionParse(&amp;data, &amp;length, &amp;type, &amp;value_length, &amp;value);
<a name="l351"></a>
<a name="l352"></a> </span><span class=cF1>if</span><span class=cF0> (error &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l353"></a> {
<a name="l354"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE ACK: Failed at DHCP Parse Option.&quot;</span><span class=cF0>);
<a name="l355"></a> </span><span class=cF1>return</span><span class=cF0> error;
<a name="l356"></a> }
<a name="l357"></a> </span><span class=cF1>if</span><span class=cF0> (error == </span><span class=cFE>0</span><span class=cF0>)
<a name="l358"></a> {
<a name="l359"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l360"></a> }
<a name="l361"></a>
<a name="l362"></a> </span><span class=cF1>switch</span><span class=cF0> (type)
<a name="l363"></a> {
<a name="l364"></a> </span><span class=cF1>case</span><span class=cF0> DHCP_OPTION_MESSAGETYPE:
<a name="l365"></a> </span><span class=cF1>if</span><span class=cF0> (value_length == </span><span class=cFE>1</span><span class=cF0> &amp;&amp; value[</span><span class=cFE>0</span><span class=cF0>] == DHCP_MESSAGETYPE_ACK)
<a name="l366"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
<a name="l367"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l368"></a> }
<a name="l369"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l370"></a>
<a name="l371"></a> NetErr(</span><span class=cF6>&quot;DHCP PARSE ACK: Failed.&quot;</span><span class=cF0>);
<a name="l372"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l373"></a>}
<a name="l374"></a>
<a name="l375"></a></span><span class=cF9>I64</span><span class=cF0> DHCPInnerConfigure(CUDPSocket *udp_socket,
<a name="l376"></a> </span><span class=cF9>U32</span><span class=cF0> *your_ip_out,
<a name="l377"></a> </span><span class=cF9>U32</span><span class=cF0> *dns_ip_out,
<a name="l378"></a> </span><span class=cF9>U32</span><span class=cF0> *router_ip_out,
<a name="l379"></a> </span><span class=cF9>U32</span><span class=cF0> *subnet_mask_out)
<a name="l380"></a>{
<a name="l381"></a> </span><span class=cF9>I64</span><span class=cF0> state = DHCP_STATE_CLIENT_START;
<a name="l382"></a> </span><span class=cF9>I64</span><span class=cF0> retries = </span><span class=cFE>0</span><span class=cF0>;
<a name="l383"></a> </span><span class=cF9>I64</span><span class=cF0> timeout = DHCP_TIMEOUT;
<a name="l384"></a> </span><span class=cF9>I64</span><span class=cF0> error = </span><span class=cFE>0</span><span class=cF0>;
<a name="l385"></a> </span><span class=cF9>U32</span><span class=cF0> xid;
<a name="l386"></a> </span><span class=cF9>U32</span><span class=cF0> dhcp_addr;
<a name="l387"></a> </span><span class=cF1>U8</span><span class=cF0> buffer[</span><span class=cFE>2048</span><span class=cF0>];
<a name="l388"></a> </span><span class=cF9>I64</span><span class=cF0> count;
<a name="l389"></a>
<a name="l390"></a> CSocketAddressIPV4 ipv4_addr;
<a name="l391"></a> CSocketAddressIPV4 ipv4_addr_in;
<a name="l392"></a>
<a name="l393"></a> </span><span class=cF2>//Shrine: setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO_MS, &amp;timeout, sizeof(timeout)))</span><span class=cF0>
<a name="l394"></a> udp_socket-&gt;receive_timeout_ms = timeout;
<a name="l395"></a>
<a name="l396"></a> ipv4_addr.family = AF_INET;
<a name="l397"></a> ipv4_addr.port = </span><span class=cF5>EndianU16</span><span class=cF0>(</span><span class=cFE>68</span><span class=cF0>);
<a name="l398"></a> ipv4_addr.address.address = INADDR_ANY;
<a name="l399"></a>
<a name="l400"></a> </span><span class=cF1>if</span><span class=cF0> (UDPSocketBind</span><span class=cF7>(</span><span class=cF0>udp_socket, &amp;ipv4_addr</span><span class=cF7>)</span><span class=cF0> &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l401"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l402"></a> NetErr(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Failed to Bind UDP Socket.&quot;</span><span class=cF0>);
<a name="l403"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l404"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l405"></a>
<a name="l406"></a> xid = DHCPTransactionBegin;
<a name="l407"></a>
<a name="l408"></a> </span><span class=cF1>while</span><span class=cF0> (state != DHCP_STATE_CLIENT_REQ_ACCEPTED)
<a name="l409"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l410"></a> </span><span class=cF1>switch</span><span class=cF0> (state)
<a name="l411"></a> {
<a name="l412"></a> </span><span class=cF1>case</span><span class=cF0> DHCP_STATE_CLIENT_START:
<a name="l413"></a> state = DHCP_STATE_CLIENT_DISCOVER;
<a name="l414"></a> retries = </span><span class=cFE>0</span><span class=cF0>;
<a name="l415"></a>
<a name="l416"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l417"></a>
<a name="l418"></a> </span><span class=cF1>case</span><span class=cF0> DHCP_STATE_CLIENT_DISCOVER:
<a name="l419"></a> NetLog(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Trying Discover.&quot;</span><span class=cF0>);
<a name="l420"></a> error = DHCPDiscoverSend(xid);
<a name="l421"></a> </span><span class=cF1>if</span><span class=cF0> (error &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l422"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l423"></a> NetErr(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Failed, DHCP Send Discover error.&quot;</span><span class=cF0>);
<a name="l424"></a> </span><span class=cF1>return</span><span class=cF0> error;
<a name="l425"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l426"></a>
<a name="l427"></a> count = UDPSocketReceiveFrom(udp_socket, buffer, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>buffer</span><span class=cF7>)</span><span class=cF0>, &amp;ipv4_addr_in);
<a name="l428"></a>
<a name="l429"></a> </span><span class=cF1>if</span><span class=cF0> (count &gt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l430"></a> </span><span class=cF7>{</span><span class=cF0> </span><span class=cF2>// 'Try a parse offer'</span><span class=cF0>
<a name="l431"></a> NetLog(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Trying Parse Offer.&quot;</span><span class=cF0>);
<a name="l432"></a> error = DHCPOfferParse(xid, buffer, count, your_ip_out, dns_ip_out, router_ip_out, subnet_mask_out);
<a name="l433"></a>
<a name="l434"></a> </span><span class=cF1>if</span><span class=cF0> (error &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l435"></a> NetWarn(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Unsuccessful DHCP Parse Offer.&quot;</span><span class=cF0>);
<a name="l436"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l437"></a>
<a name="l438"></a> </span><span class=cF1>if</span><span class=cF0> (count &gt; </span><span class=cFE>0</span><span class=cF0> &amp;&amp; error &gt;= </span><span class=cFE>0</span><span class=cF0>)
<a name="l439"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l440"></a> dhcp_addr = </span><span class=cF5>EndianU32</span><span class=cF0>(ipv4_addr_in.address.address);
<a name="l441"></a> state = DHCP_STATE_CLIENT_REQUEST;
<a name="l442"></a> retries = </span><span class=cFE>0</span><span class=cF0>;
<a name="l443"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l444"></a> </span><span class=cF1>else</span><span class=cF0> </span><span class=cF1>if</span><span class=cF0> (++retries == DHCP_MAX_RETRIES)
<a name="l445"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l446"></a> NetErr(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Failed, hit max retries in DHCP DISCOVER state.&quot;</span><span class=cF0>);
<a name="l447"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l448"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l449"></a>
<a name="l450"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l451"></a>
<a name="l452"></a> </span><span class=cF1>case</span><span class=cF0> DHCP_STATE_CLIENT_REQUEST:
<a name="l453"></a> NetLog(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Trying Send Request.&quot;</span><span class=cF0>);
<a name="l454"></a> error = DHCPRequestSend(xid, *your_ip_out, dhcp_addr);
<a name="l455"></a>
<a name="l456"></a> </span><span class=cF1>if</span><span class=cF0> (error &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l457"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l458"></a> NetErr(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Failed, unsuccessful DHCP Send Request.&quot;</span><span class=cF0>);
<a name="l459"></a> </span><span class=cF1>return</span><span class=cF0> error;
<a name="l460"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l461"></a>
<a name="l462"></a> count = UDPSocketReceiveFrom(udp_socket, buffer, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>buffer</span><span class=cF7>)</span><span class=cF0>, &amp;ipv4_addr_in);
<a name="l463"></a>
<a name="l464"></a> </span><span class=cF1>if</span><span class=cF0> (count &gt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l465"></a> </span><span class=cF7>{</span><span class=cF0> </span><span class=cF2>// 'Try parse Ack'</span><span class=cF0>
<a name="l466"></a> error = DHCPAckParse(xid, buffer, count);
<a name="l467"></a>
<a name="l468"></a> </span><span class=cF1>if</span><span class=cF0> (error &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l469"></a> NetWarn(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Unsuccessful DHCP Parse Ack.&quot;</span><span class=cF0>);
<a name="l470"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l471"></a>
<a name="l472"></a> </span><span class=cF1>if</span><span class=cF0> (count &gt; </span><span class=cFE>0</span><span class=cF0> &amp;&amp; error &gt;= </span><span class=cFE>0</span><span class=cF0>)
<a name="l473"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l474"></a> dhcp_addr = </span><span class=cF5>EndianU32</span><span class=cF0>(ipv4_addr_in.address.address);
<a name="l475"></a> state = DHCP_STATE_CLIENT_REQ_ACCEPTED;
<a name="l476"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l477"></a> </span><span class=cF1>else</span><span class=cF0> </span><span class=cF1>if</span><span class=cF0> (++retries == DHCP_MAX_RETRIES)
<a name="l478"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l479"></a> NetErr(</span><span class=cF6>&quot;DHCP CONFIGURE INNER: Failed, hit max retries in DHCP REQUEST state.&quot;</span><span class=cF0>);
<a name="l480"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l481"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l482"></a>
<a name="l483"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l484"></a> }
<a name="l485"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l486"></a>
<a name="l487"></a> </span><span class=cF1>return</span><span class=cF0> state;
<a name="l488"></a>}
<a name="l489"></a>
<a name="l490"></a></span><span class=cF9>I64</span><span class=cF0> DHCPConfigure()
<a name="l491"></a>{
<a name="l492"></a> CUDPSocket *udp_socket = UDPSocket(AF_INET);
<a name="l493"></a> CIPV4Address address;
<a name="l494"></a> </span><span class=cF9>U32</span><span class=cF0> your_ip;
<a name="l495"></a> </span><span class=cF9>U32</span><span class=cF0> dns_ip;
<a name="l496"></a> </span><span class=cF9>U32</span><span class=cF0> router_ip;
<a name="l497"></a> </span><span class=cF9>U32</span><span class=cF0> subnet_mask;
<a name="l498"></a> </span><span class=cF9>I64</span><span class=cF0> state = DHCPInnerConfigure(udp_socket, &amp;your_ip, &amp;dns_ip, &amp;router_ip, &amp;subnet_mask);
<a name="l499"></a>
<a name="l500"></a> UDPSocketClose(udp_socket);
<a name="l501"></a>
<a name="l502"></a> </span><span class=cF1>if</span><span class=cF0> (state == DHCP_STATE_CLIENT_REQ_ACCEPTED)
<a name="l503"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l504"></a> address.address = </span><span class=cF5>EndianU32</span><span class=cF0>(your_ip);
<a name="l505"></a> NetLog(</span><span class=cF6>&quot;$BG,2$$FG,15$DHCP CONFIGURE: Obtained IPV4 Address! : %s $BG$$FG$&quot;</span><span class=cF0>, NetworkToPresentation</span><span class=cF7>(</span><span class=cF0>AF_INET, &amp;address</span><span class=cF7>)</span><span class=cF0>);
<a name="l506"></a>
<a name="l507"></a> IPV4AddressSet(your_ip);
<a name="l508"></a> IPV4SubnetSet(router_ip, subnet_mask);
<a name="l509"></a> DNSResolverIPV4Set(dns_ip);
<a name="l510"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
<a name="l511"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l512"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l513"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l514"></a> NetErr(</span><span class=cF6>&quot;$BG,4$DHCP CONFIGURE: Failed, incorrect state.$BG$&quot;</span><span class=cF0>);
<a name="l515"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l516"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l517"></a>}
<a name="l518"></a>
<a name="l519"></a>
<a name="l520"></a></span><span class=cF1>U0</span><span class=cF0> NetConfigure()
<a name="l521"></a>{
<a name="l522"></a> </span><span class=cF9>I64</span><span class=cF0> error;
<a name="l523"></a>
<a name="l524"></a> NetLog(</span><span class=cF6>&quot;\n==== Configuring Network. ====\n&quot;</span><span class=cF0>);
<a name="l525"></a> error = DHCPConfigure;
<a name="l526"></a>
<a name="l527"></a> </span><span class=cF1>if</span><span class=cF0> (error &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l528"></a> NetErr(</span><span class=cF6>&quot;==== Network Configure Failed ====&quot;</span><span class=cF0>);
<a name="l529"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l530"></a> NetLog(</span><span class=cF6>&quot;$BG,2$$FG,15$==== Network Configure Success ====$FG$$BG$&quot;</span><span class=cF0>);
<a name="l531"></a>}
<a name="l532"></a>
<a name="l533"></a></span><span class=cF1>U0</span><span class=cF0> NetRep()
<a name="l534"></a>{
<a name="l535"></a> </span><span class=cF6>&quot;\n$LTGREEN$Network Report:$FG$\n\n&quot;</span><span class=cF0>;
<a name="l536"></a> UDPRep;
<a name="l537"></a> TCPRep;
<a name="l538"></a> DNSRep;
<a name="l539"></a> ARPRep;
<a name="l540"></a> IPV4Rep;
<a name="l541"></a>}</span></pre></body>
</html>