ZealOS/docs/Home/Net/Protocols/Sockets.CC.html
TomAwezome 1b75d91002 Fix Mount AHCI Port selection.
Add arg to SATARep to specify drive types to show.
Add checks in AHCIPortInit to verify port signatures, add helper method to get signatures from port.
2021-08-02 16:40:05 -04:00

515 lines
42 KiB
HTML
Executable file

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<meta name="generator" content="ZealOS V0.13">
<style type="text/css">
body {background-color:#fef1f0;}
.cF0{color:#000000;background-color:#fef1f0;}
.cF1{color:#0148a4;background-color:#fef1f0;}
.cF2{color:#3b7901;background-color:#fef1f0;}
.cF3{color:#057c7e;background-color:#fef1f0;}
.cF4{color:#bb2020;background-color:#fef1f0;}
.cF5{color:#9e42ae;background-color:#fef1f0;}
.cF6{color:#b57901;background-color:#fef1f0;}
.cF7{color:#b2b6af;background-color:#fef1f0;}
.cF8{color:#555753;background-color:#fef1f0;}
.cF9{color:#678fbb;background-color:#fef1f0;}
.cFA{color:#82bc49;background-color:#fef1f0;}
.cFB{color:#0097a2;background-color:#fef1f0;}
.cFC{color:#e26a6a;background-color:#fef1f0;}
.cFD{color:#c671bc;background-color:#fef1f0;}
.cFE{color:#c7ab00;background-color:#fef1f0;}
.cFF{color:#fef1f0;background-color:#fef1f0;}
</style>
</head>
<body>
<pre style="font-family:monospace;font-size:12pt">
<a name="l1"></a><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>docs.idris-lang.org/en/latest/st/examples.html</span><span class=cF0>
<a name="l2"></a> </span><span class=cF2>beej.us/guide/bgnet/html/</span><span class=cF0>
<a name="l3"></a>
<a name="l4"></a> </span><span class=cF2>Sockets are non-standard, a simple</span><span class=cF0>
<a name="l5"></a> </span><span class=cF2>Finite State Machine. The functions'</span><span class=cF0>
<a name="l6"></a> </span><span class=cF2>only args are the socket. Socket functions</span><span class=cF0>
<a name="l7"></a> </span><span class=cF2>requiring more parameters should be</span><span class=cF0>
<a name="l8"></a> </span><span class=cF2>defined at the protocol level. </span><span class=cF0>
<a name="l9"></a>
<a name="l10"></a> </span><span class=cF2>The state machine exists to allow</span><span class=cF0>
<a name="l11"></a> </span><span class=cF2>protocol code to execute code in</span><span class=cF0>
<a name="l12"></a> </span><span class=cF2>the appropriate order. When calling</span><span class=cF0>
<a name="l13"></a> </span><span class=cF2>a socket function, code can use</span><span class=cF0>
<a name="l14"></a> </span><span class=cF2>the modified/unmodified states to</span><span class=cF0>
<a name="l15"></a> </span><span class=cF2>determine next procedure. </span><span class=cF0>
<a name="l16"></a>
<a name="l17"></a> </span><span class=cF2>Some code is inclded for IPV6, currently</span><span class=cF0>
<a name="l18"></a> </span><span class=cF2>unused. */</span><span class=cF0>
<a name="l19"></a>
<a name="l20"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_READY </span><span class=cFE>0</span><span class=cF0>
<a name="l21"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_BIND_REQ </span><span class=cFE>1</span><span class=cF0>
<a name="l22"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_CONNECT_REQ </span><span class=cFE>2</span><span class=cF0>
<a name="l23"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_BOUND </span><span class=cFE>3</span><span class=cF0>
<a name="l24"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_LISTEN_REQ </span><span class=cFE>4</span><span class=cF0>
<a name="l25"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_LISTENING </span><span class=cFE>5</span><span class=cF0>
<a name="l26"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_OPEN </span><span class=cFE>6</span><span class=cF0>
<a name="l27"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_CLOSE_REQ </span><span class=cFE>7</span><span class=cF0>
<a name="l28"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STATE_CLOSED </span><span class=cFE>8</span><span class=cF0>
<a name="l29"></a>
<a name="l30"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_STREAM </span><span class=cFE>1</span><span class=cF0>
<a name="l31"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_DATAGRAM </span><span class=cFE>2</span><span class=cF0>
<a name="l32"></a>#</span><span class=cF1>define</span><span class=cF0> SOCKET_RAW </span><span class=cFE>3</span><span class=cF0>
<a name="l33"></a>
<a name="l34"></a>#</span><span class=cF1>define</span><span class=cF0> AF_UNSPEC </span><span class=cFE>0</span><span class=cF0>
<a name="l35"></a>#</span><span class=cF1>define</span><span class=cF0> AF_INET </span><span class=cFE>2</span><span class=cF0>
<a name="l36"></a>#</span><span class=cF1>define</span><span class=cF0> AF_INET6 </span><span class=cFE>10</span><span class=cF0>
<a name="l37"></a>
<a name="l38"></a>#</span><span class=cF1>define</span><span class=cF0> INADDR_ANY </span><span class=cFE>0</span><span class=cF0>
<a name="l39"></a>
<a name="l40"></a>#</span><span class=cF1>define</span><span class=cF0> INET_ADDRSTRLEN </span><span class=cFE>16</span><span class=cF0> </span><span class=cF2>//pubs.opengroup.com netinit/in.h</span><span class=cF0>
<a name="l41"></a>#</span><span class=cF1>define</span><span class=cF0> INET6_ADDRSTRLEN </span><span class=cFE>46</span><span class=cF0>
<a name="l42"></a>
<a name="l43"></a>#</span><span class=cF1>define</span><span class=cF0> INET_MIN_ADDRSTRLEN </span><span class=cFE>7</span><span class=cF0> </span><span class=cF2>// ex: len of 0.0.0.0</span><span class=cF0>
<a name="l44"></a>#</span><span class=cF1>define</span><span class=cF0> INET6_MIN_ADDRSTRLEN </span><span class=cFE>2</span><span class=cF0> </span><span class=cF2>// ie: len of ::</span><span class=cF0>
<a name="l45"></a>
<a name="l46"></a>
<a name="l47"></a>#</span><span class=cF1>define</span><span class=cF0> IP_PARSE_STATE_NUM </span><span class=cFE>0</span><span class=cF0>
<a name="l48"></a>#</span><span class=cF1>define</span><span class=cF0> IP_PARSE_STATE_DOT </span><span class=cFE>1</span><span class=cF0>
<a name="l49"></a>
<a name="l50"></a></span><span class=cF1>class</span><span class=cF0> CIPV4Address
<a name="l51"></a>{
<a name="l52"></a> </span><span class=cF9>U32</span><span class=cF0> address; </span><span class=cF2>// 'in Network Byte order' ... Big Endian</span><span class=cF0>
<a name="l53"></a>};
<a name="l54"></a>
<a name="l55"></a></span><span class=cF1>class</span><span class=cF0> CIPV6Address
<a name="l56"></a>{
<a name="l57"></a> </span><span class=cF1>U8</span><span class=cF0> address[</span><span class=cFE>16</span><span class=cF0>]; </span><span class=cF2>// a clear #define would be nice</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> CIPAddressStorage
<a name="l61"></a>{</span><span class=cF2>// class specifically meant to be generic casted either IPV4 or IPV6 Address.</span><span class=cF0>
<a name="l62"></a> </span><span class=cF1>U8</span><span class=cF0> padding[</span><span class=cFE>16</span><span class=cF0>];
<a name="l63"></a>};
<a name="l64"></a>
<a name="l65"></a></span><span class=cF1>class</span><span class=cF0> CSocketAddressIPV4
<a name="l66"></a>{
<a name="l67"></a> </span><span class=cF9>U16</span><span class=cF0> family; </span><span class=cF2>// 'AF_INET'</span><span class=cF0>
<a name="l68"></a> </span><span class=cF9>U16</span><span class=cF0> port; </span><span class=cF2>// 'in Network Byte order' ... Big Endian</span><span class=cF0>
<a name="l69"></a> CIPV4Address address;
<a name="l70"></a> </span><span class=cF1>U8</span><span class=cF0> zeroes[</span><span class=cFE>8</span><span class=cF0>]; </span><span class=cF2>// 'same size as socket address'</span><span class=cF0>
<a name="l71"></a>};
<a name="l72"></a>
<a name="l73"></a></span><span class=cF1>class</span><span class=cF0> CSocketAddressIPV6
<a name="l74"></a>{
<a name="l75"></a> </span><span class=cF9>U16</span><span class=cF0> family; </span><span class=cF2>// 'AF_INET6'</span><span class=cF0>
<a name="l76"></a> </span><span class=cF9>U16</span><span class=cF0> port; </span><span class=cF2>// 'in Network Byte order'... Big Endian</span><span class=cF0>
<a name="l77"></a> </span><span class=cF9>U32</span><span class=cF0> flow_info;
<a name="l78"></a> CIPV6Address address;
<a name="l79"></a> </span><span class=cF9>U32</span><span class=cF0> scope_id;
<a name="l80"></a>};
<a name="l81"></a>
<a name="l82"></a></span><span class=cF1>class</span><span class=cF0> CSocketAddressStorage
<a name="l83"></a>{</span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>'designed to be large enough to</span><span class=cF0>
<a name="l84"></a> </span><span class=cF2>hold both IPV4 and IPV6 structures.' */</span><span class=cF0>
<a name="l85"></a>
<a name="l86"></a> </span><span class=cF9>U16</span><span class=cF0> family;
<a name="l87"></a> </span><span class=cF1>U8</span><span class=cF0> padding[</span><span class=cFE>26</span><span class=cF0>];
<a name="l88"></a>};
<a name="l89"></a>
<a name="l90"></a></span><span class=cF1>class</span><span class=cF0> CAddressInfo
<a name="l91"></a>{
<a name="l92"></a> </span><span class=cF9>I32</span><span class=cF0> flags;
<a name="l93"></a> </span><span class=cF9>I32</span><span class=cF0> family;
<a name="l94"></a> </span><span class=cF9>I32</span><span class=cF0> socket_type;
<a name="l95"></a> </span><span class=cF9>I32</span><span class=cF0> protocol;
<a name="l96"></a> </span><span class=cF9>I64</span><span class=cF0> address_length;
<a name="l97"></a> CSocketAddressStorage *address;
<a name="l98"></a> </span><span class=cF1>U8</span><span class=cF0> *canonical_name;
<a name="l99"></a> CAddressInfo *next;
<a name="l100"></a>};
<a name="l101"></a>
<a name="l102"></a></span><span class=cF1>class</span><span class=cF0> CSocket
<a name="l103"></a>{
<a name="l104"></a> </span><span class=cF1>U8</span><span class=cF0> state;
<a name="l105"></a>
<a name="l106"></a> </span><span class=cF9>U16</span><span class=cF0> type;
<a name="l107"></a> </span><span class=cF9>U16</span><span class=cF0> domain;
<a name="l108"></a>};
<a name="l109"></a>
<a name="l110"></a></span><span class=cF1>U0</span><span class=cF0> AddressInfoCopy(CAddressInfo *out, CAddressInfo *in)
<a name="l111"></a>{ </span><span class=cF2>// assumes *out already exists</span><span class=cF0>
<a name="l112"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(out, in, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CAddressInfo</span><span class=cF7>)</span><span class=cF0>);
<a name="l113"></a>
<a name="l114"></a> </span><span class=cF1>if</span><span class=cF0> (in-&gt;address)
<a name="l115"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l116"></a> out-&gt;address = </span><span class=cF5>CAlloc</span><span class=cF0>(in-&gt;address_length);
<a name="l117"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(out-&gt;address, in-&gt;address, in-&gt;address_length);
<a name="l118"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l119"></a>
<a name="l120"></a> </span><span class=cF1>if</span><span class=cF0> (in-&gt;canonical_name)
<a name="l121"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l122"></a> out-&gt;canonical_name = </span><span class=cF5>StrNew</span><span class=cF0>(in-&gt;canonical_name);
<a name="l123"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l124"></a>}
<a name="l125"></a>
<a name="l126"></a></span><span class=cF1>U0</span><span class=cF0> AddressInfoFree(CAddressInfo *info)
<a name="l127"></a>{
<a name="l128"></a> CAddressInfo *next;
<a name="l129"></a>
<a name="l130"></a> </span><span class=cF1>while</span><span class=cF0> (info)
<a name="l131"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l132"></a> next = info-&gt;next;
<a name="l133"></a>
<a name="l134"></a> </span><span class=cF5>Free</span><span class=cF0>(info-&gt;address);
<a name="l135"></a> </span><span class=cF5>Free</span><span class=cF0>(info-&gt;canonical_name);
<a name="l136"></a> </span><span class=cF5>Free</span><span class=cF0>(info);
<a name="l137"></a>
<a name="l138"></a> info = next;
<a name="l139"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l140"></a>}
<a name="l141"></a>
<a name="l142"></a></span><span class=cF1>Bool</span><span class=cF0> IPV4AddressParse(</span><span class=cF1>U8</span><span class=cF0> *string, </span><span class=cF9>U32</span><span class=cF0> *destination)
<a name="l143"></a>{
<a name="l144"></a> </span><span class=cF1>U8</span><span class=cF0> *lexable_string = </span><span class=cF5>StrNew</span><span class=cF0>(string);
<a name="l145"></a>
<a name="l146"></a> lexable_string = </span><span class=cF5>StrReplace</span><span class=cF0>(lexable_string, </span><span class=cF6>&quot;.&quot;</span><span class=cF0>, </span><span class=cF6>&quot;,&quot;</span><span class=cF0>); </span><span class=cF2>// swap dots with commas since Lex is easier with them.</span><span class=cF0>
<a name="l147"></a>
<a name="l148"></a> </span><span class=cF9>CCompCtrl</span><span class=cF0> *cc = </span><span class=cF5>CompCtrlNew</span><span class=cF0>(lexable_string);
<a name="l149"></a> </span><span class=cF2>//Bts(&amp;cc-&gt;opts, OPTf_DECIMAL_ONLY);</span><span class=cF0>
<a name="l150"></a>
<a name="l151"></a> cc-&gt;opts |= </span><span class=cFE>1</span><span class=cF0> &lt;&lt; </span><span class=cF3>OPTf_DECIMAL_ONLY</span><span class=cF0>;
<a name="l152"></a>
<a name="l153"></a> </span><span class=cF9>I64</span><span class=cF0> tk;
<a name="l154"></a>
<a name="l155"></a> </span><span class=cF9>I64</span><span class=cF0> state = IP_PARSE_STATE_NUM;
<a name="l156"></a> </span><span class=cF9>U32</span><span class=cF0> temp_destination = </span><span class=cFE>0</span><span class=cF0>;
<a name="l157"></a>
<a name="l158"></a> </span><span class=cF9>I64</span><span class=cF0> current_section = </span><span class=cFE>0</span><span class=cF0>; </span><span class=cF2>// IPV4 address has 4 total sections</span><span class=cF0>
<a name="l159"></a>
<a name="l160"></a> </span><span class=cF1>while</span><span class=cF0> (tk = </span><span class=cF5>Lex</span><span class=cF7>(</span><span class=cF0>cc</span><span class=cF7>)</span><span class=cF0>)
<a name="l161"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l162"></a> </span><span class=cF1>switch</span><span class=cF0> (state)
<a name="l163"></a> {
<a name="l164"></a> </span><span class=cF1>case</span><span class=cF0> IP_PARSE_STATE_NUM:
<a name="l165"></a> </span><span class=cF1>switch</span><span class=cF0> (tk)
<a name="l166"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l167"></a> </span><span class=cF1>case</span><span class=cF0> </span><span class=cF3>TK_I64</span><span class=cF0>:
<a name="l168"></a> </span><span class=cF1>if</span><span class=cF0> (cc-&gt;cur_i64 &gt; </span><span class=cFE>255</span><span class=cF0> || cc-&gt;cur_i64 &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l169"></a> {
<a name="l170"></a> NetErr(</span><span class=cF6>&quot;IPV4 ADDRESS PARSE: Invalid value, must be 0 - 255.&quot;</span><span class=cF0>);
<a name="l171"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l172"></a> }
<a name="l173"></a> </span><span class=cF1>if</span><span class=cF0> (current_section &gt; </span><span class=cFE>3</span><span class=cF0>)
<a name="l174"></a> {
<a name="l175"></a> NetErr(</span><span class=cF6>&quot;IPV4 ADDRESS PARSE: IP Address can only have 4 sections.&quot;</span><span class=cF0>);
<a name="l176"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l177"></a> }
<a name="l178"></a>
<a name="l179"></a> temp_destination |= cc-&gt;cur_i64 &lt;&lt; (current_section * </span><span class=cFE>8</span><span class=cF0>);
<a name="l180"></a> current_section++;
<a name="l181"></a>
<a name="l182"></a> state = IP_PARSE_STATE_DOT;
<a name="l183"></a>
<a name="l184"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l185"></a>
<a name="l186"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l187"></a> NetErr(</span><span class=cF6>&quot;IPV4 ADDRESS PARSE: Expected decimal. &quot;</span><span class=cF0>);
<a name="l188"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l189"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l190"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l191"></a>
<a name="l192"></a> </span><span class=cF1>case</span><span class=cF0> IP_PARSE_STATE_DOT:
<a name="l193"></a> </span><span class=cF1>switch</span><span class=cF0> (tk)
<a name="l194"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l195"></a> </span><span class=cF1>case</span><span class=cF0> </span><span class=cF6>','</span><span class=cF0>:
<a name="l196"></a> state = IP_PARSE_STATE_NUM;
<a name="l197"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l198"></a>
<a name="l199"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l200"></a> NetErr(</span><span class=cF6>&quot;IPV4 ADDRESS PARSE: Expected dot. &quot;</span><span class=cF0>);
<a name="l201"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l202"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l203"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l204"></a> }
<a name="l205"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l206"></a>
<a name="l207"></a> </span><span class=cF5>CompCtrlDel</span><span class=cF0>(cc);
<a name="l208"></a>
<a name="l209"></a> temp_destination = </span><span class=cF5>EndianU32</span><span class=cF0>(temp_destination); </span><span class=cF2>// store the address in Network Byte Order (Big-Endian)</span><span class=cF0>
<a name="l210"></a> *destination = temp_destination;
<a name="l211"></a>
<a name="l212"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l213"></a>}
<a name="l214"></a>
<a name="l215"></a></span><span class=cF9>I64</span><span class=cF0> PresentationToNetwork(</span><span class=cF9>I64</span><span class=cF0> address_family, </span><span class=cF1>U8</span><span class=cF0> *string, CIPAddressStorage *destination)
<a name="l216"></a>{
<a name="l217"></a></span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Converts IP string to internet address class, our inet_pton().</span><span class=cF0>
<a name="l218"></a> </span><span class=cF2>Destination written as CIPV4Address or CIPV6Address depending</span><span class=cF0>
<a name="l219"></a> </span><span class=cF2>on value of address_family.</span><span class=cF0>
<a name="l220"></a> </span><span class=cF2>The destination address is the generic class, functions</span><span class=cF0>
<a name="l221"></a> </span><span class=cF2>calling this method must cast their classes in the params. */</span><span class=cF0>
<a name="l222"></a>
<a name="l223"></a> CIPV4Address *ipv4_address;
<a name="l224"></a> CIPV6Address *ipv6_address;
<a name="l225"></a>
<a name="l226"></a> </span><span class=cF9>I64</span><span class=cF0> string_length = </span><span class=cF5>StrLen</span><span class=cF0>(string);
<a name="l227"></a>
<a name="l228"></a> </span><span class=cF1>switch</span><span class=cF0> (address_family)
<a name="l229"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l230"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET:
<a name="l231"></a> </span><span class=cF1>if</span><span class=cF0> (string_length &gt; INET_ADDRSTRLEN || string_length &lt; INET_MIN_ADDRSTRLEN)
<a name="l232"></a> {
<a name="l233"></a> NetErr(</span><span class=cF6>&quot;IP to Socket Address failed: Invalid Input String Size.&quot;</span><span class=cF0>);
<a name="l234"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l235"></a> }
<a name="l236"></a> ipv4_address = destination;
<a name="l237"></a>
<a name="l238"></a> </span><span class=cF1>if</span><span class=cF0> (!IPV4AddressParse</span><span class=cF7>(</span><span class=cF0>string, &amp;ipv4_address-&gt;address</span><span class=cF7>)</span><span class=cF0>)
<a name="l239"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l240"></a>
<a name="l241"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l242"></a>
<a name="l243"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET6:
<a name="l244"></a> </span><span class=cF1>if</span><span class=cF0> (string_length &gt; INET6_ADDRSTRLEN || string_length &lt; INET6_MIN_ADDRSTRLEN)
<a name="l245"></a> {
<a name="l246"></a> NetErr(</span><span class=cF6>&quot;IP to Socket Address failed: Invalid Input String Size.&quot;</span><span class=cF0>);
<a name="l247"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l248"></a> }
<a name="l249"></a> ipv6_address = destination;
<a name="l250"></a>
<a name="l251"></a>
<a name="l252"></a> NetErr(</span><span class=cF6>&quot;IP to Socket Address failed: FIXME, IPV6 support not implemented yet.\n&quot;</span><span class=cF0>);
<a name="l253"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l254"></a>
<a name="l255"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l256"></a> NetErr(</span><span class=cF6>&quot;IP to Socket Address failed: Invalid Address Family.&quot;</span><span class=cF0>);
<a name="l257"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l258"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l259"></a>
<a name="l260"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
<a name="l261"></a>
<a name="l262"></a>}
<a name="l263"></a>
<a name="l264"></a></span><span class=cF1>U8</span><span class=cF0> *NetworkToPresentation(</span><span class=cF9>I64</span><span class=cF0> address_family, CIPAddressStorage *source)
<a name="l265"></a>{ </span><span class=cF2>// converts socket address to IP string, our inet_ntop. Taking Shrine approach of function returns U8* .</span><span class=cF0>
<a name="l266"></a>
<a name="l267"></a>
<a name="l268"></a> </span><span class=cF1>U8</span><span class=cF0> *ip_string = </span><span class=cF3>NULL</span><span class=cF0>;
<a name="l269"></a> CIPV4Address *ipv4_source;
<a name="l270"></a> CIPV4Address *ipv6_source;
<a name="l271"></a>
<a name="l272"></a> </span><span class=cF1>switch</span><span class=cF0> (address_family)
<a name="l273"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l274"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET:
<a name="l275"></a>
<a name="l276"></a> ipv4_source = source;
<a name="l277"></a>
<a name="l278"></a> ip_string = </span><span class=cF5>MStrPrint</span><span class=cF0>(</span><span class=cF6>&quot;%d.%d.%d.%d&quot;</span><span class=cF0>,
<a name="l279"></a> ipv4_source-&gt;address.u8[</span><span class=cFE>0</span><span class=cF0>],
<a name="l280"></a> ipv4_source-&gt;address.u8[</span><span class=cFE>1</span><span class=cF0>],
<a name="l281"></a> ipv4_source-&gt;address.u8[</span><span class=cFE>2</span><span class=cF0>],
<a name="l282"></a> ipv4_source-&gt;address.u8[</span><span class=cFE>3</span><span class=cF0>]);
<a name="l283"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l284"></a>
<a name="l285"></a> </span><span class=cF1>case</span><span class=cF0> AF_INET6:
<a name="l286"></a>
<a name="l287"></a> ipv6_source = source;
<a name="l288"></a>
<a name="l289"></a> NetErr(</span><span class=cF6>&quot;Socket Address to IP failed: FIXME, IPV6 support not implemented yet.\n&quot;</span><span class=cF0>);
<a name="l290"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
<a name="l291"></a>
<a name="l292"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l293"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l294"></a> NetErr(</span><span class=cF6>&quot;Socket Address to IP failed: Invalid Address Family.&quot;</span><span class=cF0>);
<a name="l295"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l296"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l297"></a>
<a name="l298"></a> </span><span class=cF1>return</span><span class=cF0> ip_string;
<a name="l299"></a>}
<a name="l300"></a>
<a name="l301"></a>
<a name="l302"></a>CSocket *Socket(</span><span class=cF9>U16</span><span class=cF0> domain, </span><span class=cF9>U16</span><span class=cF0> type)
<a name="l303"></a>{
<a name="l304"></a> CSocket *socket = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CSocket</span><span class=cF7>)</span><span class=cF0>);
<a name="l305"></a>
<a name="l306"></a> socket-&gt;domain = domain;
<a name="l307"></a> socket-&gt;type = type;
<a name="l308"></a>
<a name="l309"></a> socket-&gt;state = SOCKET_STATE_READY;
<a name="l310"></a>
<a name="l311"></a> </span><span class=cF1>return</span><span class=cF0> socket;
<a name="l312"></a>}
<a name="l313"></a>
<a name="l314"></a></span><span class=cF1>U0</span><span class=cF0> SocketStateErr(</span><span class=cF1>U8</span><span class=cF0> *request, </span><span class=cF1>U8</span><span class=cF0> state)
<a name="l315"></a>{
<a name="l316"></a> </span><span class=cF1>U8</span><span class=cF0> *state_string;
<a name="l317"></a> </span><span class=cF1>switch</span><span class=cF0> (state)
<a name="l318"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l319"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_READY:
<a name="l320"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;READY&quot;</span><span class=cF0>);
<a name="l321"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l322"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_BIND_REQ:
<a name="l323"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;BIND REQUEST&quot;</span><span class=cF0>);
<a name="l324"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l325"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_CONNECT_REQ:
<a name="l326"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;CONNECT REQUEST&quot;</span><span class=cF0>);
<a name="l327"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l328"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_BOUND:
<a name="l329"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;BOUND&quot;</span><span class=cF0>);
<a name="l330"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l331"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_LISTEN_REQ:
<a name="l332"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;LISTEN REQUEST&quot;</span><span class=cF0>);
<a name="l333"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l334"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_LISTENING:
<a name="l335"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;LISTENING&quot;</span><span class=cF0>);
<a name="l336"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l337"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_OPEN:
<a name="l338"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;OPEN&quot;</span><span class=cF0>);
<a name="l339"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l340"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_CLOSE_REQ:
<a name="l341"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;CLOSE REQUEST&quot;</span><span class=cF0>);
<a name="l342"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l343"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_CLOSED:
<a name="l344"></a> state_string = </span><span class=cF5>StrNew</span><span class=cF0>(</span><span class=cF6>&quot;CLOSED&quot;</span><span class=cF0>);
<a name="l345"></a> </span><span class=cF1>break</span><span class=cF0>;
<a name="l346"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l347"></a> NetErr(</span><span class=cF6>&quot;Socket attempted %s while in %s state.&quot;</span><span class=cF0>, request, state_string);
<a name="l348"></a>}
<a name="l349"></a>
<a name="l350"></a></span><span class=cF1>Bool</span><span class=cF0> SocketAccept(CSocket *socket)
<a name="l351"></a>{
<a name="l352"></a> </span><span class=cF1>switch</span><span class=cF0> (socket-&gt;state)
<a name="l353"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l354"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_LISTENING:
<a name="l355"></a> </span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Socket expected to stay listening.</span><span class=cF0>
<a name="l356"></a> </span><span class=cF2>At protocol level, a new socket 'connected'</span><span class=cF0>
<a name="l357"></a> </span><span class=cF2>to this one is expected to be made. */</span><span class=cF0>
<a name="l358"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l359"></a>
<a name="l360"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l361"></a> SocketStateErr(</span><span class=cF6>&quot;ACCEPT&quot;</span><span class=cF0>, socket-&gt;state);
<a name="l362"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l363"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l364"></a>}
<a name="l365"></a>
<a name="l366"></a></span><span class=cF1>Bool</span><span class=cF0> SocketClose(CSocket *socket)
<a name="l367"></a>{ </span><span class=cF2>/* Sockets attempting close will enter close</span><span class=cF0>
<a name="l368"></a> </span><span class=cF2>request state before destroying the socket at</span><span class=cF0>
<a name="l369"></a> </span><span class=cF2>the protocol level. */</span><span class=cF0>
<a name="l370"></a> socket-&gt;state = SOCKET_STATE_CLOSE_REQ;
<a name="l371"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l372"></a>}
<a name="l373"></a>
<a name="l374"></a></span><span class=cF1>Bool</span><span class=cF0> SocketBind(CSocket *socket)
<a name="l375"></a>{
<a name="l376"></a> </span><span class=cF1>switch</span><span class=cF0> (socket-&gt;state)
<a name="l377"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l378"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_READY:
<a name="l379"></a> </span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Sockets can only be bound</span><span class=cF0>
<a name="l380"></a> </span><span class=cF2>if they are in initial state. */</span><span class=cF0>
<a name="l381"></a> socket-&gt;state = SOCKET_STATE_BIND_REQ;
<a name="l382"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l383"></a>
<a name="l384"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l385"></a> SocketStateErr(</span><span class=cF6>&quot;BIND&quot;</span><span class=cF0>, socket-&gt;state);
<a name="l386"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l387"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l388"></a>}
<a name="l389"></a>
<a name="l390"></a></span><span class=cF1>Bool</span><span class=cF0> SocketConnect(CSocket *socket)
<a name="l391"></a>{
<a name="l392"></a> </span><span class=cF1>switch</span><span class=cF0> (socket-&gt;state)
<a name="l393"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l394"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_READY:
<a name="l395"></a> </span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Sockets can only be connected</span><span class=cF0>
<a name="l396"></a> </span><span class=cF2>if they are in initial state. */</span><span class=cF0>
<a name="l397"></a> socket-&gt;state = SOCKET_STATE_CONNECT_REQ;
<a name="l398"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l399"></a>
<a name="l400"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l401"></a> SocketStateErr(</span><span class=cF6>&quot;CONNECT&quot;</span><span class=cF0>, socket-&gt;state);
<a name="l402"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l403"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l404"></a>}
<a name="l405"></a>
<a name="l406"></a></span><span class=cF1>Bool</span><span class=cF0> SocketListen(CSocket *socket)
<a name="l407"></a>{
<a name="l408"></a> </span><span class=cF1>switch</span><span class=cF0> (socket-&gt;state)
<a name="l409"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l410"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_BOUND:
<a name="l411"></a> </span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>A socket must be bound to</span><span class=cF0>
<a name="l412"></a> </span><span class=cF2>set it to listening. */</span><span class=cF0>
<a name="l413"></a> socket-&gt;state = SOCKET_STATE_LISTEN_REQ;
<a name="l414"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l415"></a>
<a name="l416"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l417"></a> SocketStateErr(</span><span class=cF6>&quot;LISTEN&quot;</span><span class=cF0>, socket-&gt;state);
<a name="l418"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l419"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l420"></a>}
<a name="l421"></a>
<a name="l422"></a></span><span class=cF1>Bool</span><span class=cF0> SocketReceive(CSocket *socket)
<a name="l423"></a>{
<a name="l424"></a> </span><span class=cF1>switch</span><span class=cF0> (socket-&gt;state)
<a name="l425"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l426"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_OPEN:
<a name="l427"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_BOUND:
<a name="l428"></a> </span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Sockets can only recv when</span><span class=cF0>
<a name="l429"></a> </span><span class=cF2>connected to or bound. */</span><span class=cF0>
<a name="l430"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l431"></a>
<a name="l432"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l433"></a> SocketStateErr(</span><span class=cF6>&quot;RECEIVE&quot;</span><span class=cF0>, socket-&gt;state);
<a name="l434"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l435"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l436"></a>}
<a name="l437"></a>
<a name="l438"></a></span><span class=cF1>Bool</span><span class=cF0> SocketReceiveFrom(CSocket *socket)
<a name="l439"></a>{
<a name="l440"></a> </span><span class=cF1>switch</span><span class=cF0> (socket-&gt;state)
<a name="l441"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l442"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_OPEN:
<a name="l443"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_BOUND:
<a name="l444"></a> </span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Sockets can only recvfrom when</span><span class=cF0>
<a name="l445"></a> </span><span class=cF2>connected to or bound. */</span><span class=cF0>
<a name="l446"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l447"></a>
<a name="l448"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l449"></a> SocketStateErr(</span><span class=cF6>&quot;RECEIVE FROM&quot;</span><span class=cF0>, socket-&gt;state);
<a name="l450"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l451"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l452"></a>}
<a name="l453"></a>
<a name="l454"></a></span><span class=cF1>Bool</span><span class=cF0> SocketSend(CSocket *socket)
<a name="l455"></a>{
<a name="l456"></a> </span><span class=cF1>switch</span><span class=cF0> (socket-&gt;state)
<a name="l457"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l458"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_OPEN:
<a name="l459"></a> </span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Sockets can only send when</span><span class=cF0>
<a name="l460"></a> </span><span class=cF2>they have been connected to. */</span><span class=cF0>
<a name="l461"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l462"></a>
<a name="l463"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l464"></a> SocketStateErr(</span><span class=cF6>&quot;SEND&quot;</span><span class=cF0>, socket-&gt;state);
<a name="l465"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l466"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l467"></a>}
<a name="l468"></a>
<a name="l469"></a></span><span class=cF1>Bool</span><span class=cF0> SocketSendTo(CSocket *socket)
<a name="l470"></a>{
<a name="l471"></a> </span><span class=cF1>switch</span><span class=cF0> (socket-&gt;state)
<a name="l472"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l473"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_OPEN:
<a name="l474"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_BOUND:
<a name="l475"></a> </span><span class=cF1>case</span><span class=cF0> SOCKET_STATE_READY:
<a name="l476"></a> </span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>Sockets can only sendto when</span><span class=cF0>
<a name="l477"></a> </span><span class=cF2>connected to, bound, or in</span><span class=cF0>
<a name="l478"></a> </span><span class=cF2>initial state. Protocol logic</span><span class=cF0>
<a name="l479"></a> </span><span class=cF2>will determine how to change</span><span class=cF0>
<a name="l480"></a> </span><span class=cF2>state based on params. */</span><span class=cF0>
<a name="l481"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l482"></a>
<a name="l483"></a> </span><span class=cF1>default</span><span class=cF0>:
<a name="l484"></a> SocketStateErr(</span><span class=cF6>&quot;SEND TO&quot;</span><span class=cF0>, socket-&gt;state);
<a name="l485"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l486"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l487"></a>}</span></pre></body>
</html>