mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-01-04 19:56:30 +00:00
1b75d91002
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.
392 lines
34 KiB
HTML
Executable file
392 lines
34 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=cF1>Bool</span><span class=cF0> TCPHandleValidSEQ(CTCPSocket *tcp_socket, CTCPHeader *header, </span><span class=cF9>U32</span><span class=cF0> segment_seq_num, </span><span class=cF9>I64</span><span class=cF0> length, </span><span class=cF1>U8</span><span class=cF0> *data)
|
|
<a name="l2"></a>{</span><span class=cF2>// returns the value of must_ack, used later in TCPHandleSocket. Copies data to receive buffer.</span><span class=cF0>
|
|
<a name="l3"></a> </span><span class=cF1>Bool</span><span class=cF0> must_ack = </span><span class=cF3>FALSE</span><span class=cF0>;
|
|
<a name="l4"></a> </span><span class=cF9>I64</span><span class=cF0> write_position;
|
|
<a name="l5"></a> </span><span class=cF9>I64</span><span class=cF0> next_position;
|
|
<a name="l6"></a> </span><span class=cF9>I64</span><span class=cF0> i;
|
|
<a name="l7"></a>
|
|
<a name="l8"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>tcp_socket->send_window = header->window_size;</span><span class=cF0>
|
|
<a name="l9"></a> tcp_socket->send_window = </span><span class=cF5>EndianU16</span><span class=cF0>(header->window_size);
|
|
<a name="l10"></a> </span><span class=cF2>// Shrine doesn't use EndianU16 (ntohs)? are these all being stored network byte order? ...</span><span class=cF0>
|
|
<a name="l11"></a>
|
|
<a name="l12"></a> </span><span class=cF1>switch</span><span class=cF0> (tcp_socket->state)
|
|
<a name="l13"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l14"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_ESTABLISHED:
|
|
<a name="l15"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_FIN_WAIT1:
|
|
<a name="l16"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_FIN_WAIT2: </span><span class=cF2>// FIN2 check is ommitted in Shrine, yet used in below logic. Adding.</span><span class=cF0>
|
|
<a name="l17"></a>
|
|
<a name="l18"></a> NetDebug(</span><span class=cF6>"TCP HANDLE VALID SEQ: Updating data in receive buffer."</span><span class=cF0>);
|
|
<a name="l19"></a>
|
|
<a name="l20"></a> </span><span class=cF2>// TODO: review while loops, make sure we DO NOT HANG INTERRUPT HANDLER.</span><span class=cF0>
|
|
<a name="l21"></a> write_position = tcp_socket->write_position;
|
|
<a name="l22"></a>
|
|
<a name="l23"></a> </span><span class=cF1>while</span><span class=cF0> (length && segment_seq_num != tcp_socket->next_recv_seq_num)
|
|
<a name="l24"></a> {
|
|
<a name="l25"></a> segment_seq_num = (segment_seq_num + </span><span class=cFE>1</span><span class=cF0>) & </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>;
|
|
<a name="l26"></a> data++;
|
|
<a name="l27"></a> length--;
|
|
<a name="l28"></a> }
|
|
<a name="l29"></a>
|
|
<a name="l30"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i < length; i++)
|
|
<a name="l31"></a> {
|
|
<a name="l32"></a></span><span class=cF2>//</span><span class=cF0> </span><span class=cF2>next_position = (write_position + 1) & (tcp_socket->receive_buffer_size - 1);</span><span class=cF0>
|
|
<a name="l33"></a> next_position = (write_position + </span><span class=cFE>1</span><span class=cF0>) % tcp_socket->receive_buffer_size;
|
|
<a name="l34"></a>
|
|
<a name="l35"></a> </span><span class=cF1>if</span><span class=cF0> (next_position == tcp_socket->read_position)
|
|
<a name="l36"></a> </span><span class=cF1>break</span><span class=cF0>; </span><span class=cF2>// ...?</span><span class=cF0>
|
|
<a name="l37"></a>
|
|
<a name="l38"></a> tcp_socket->receive_buffer[write_position] = data[i];
|
|
<a name="l39"></a> write_position = next_position;
|
|
<a name="l40"></a> }
|
|
<a name="l41"></a>
|
|
<a name="l42"></a> tcp_socket->write_position = write_position;
|
|
<a name="l43"></a> tcp_socket->next_recv_seq_num += i;
|
|
<a name="l44"></a>
|
|
<a name="l45"></a> </span><span class=cF1>if</span><span class=cF0> (i > </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l46"></a> must_ack = </span><span class=cF3>TRUE</span><span class=cF0>;
|
|
<a name="l47"></a>
|
|
<a name="l48"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&header->flags, TCPf_FIN</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l49"></a> {
|
|
<a name="l50"></a> must_ack = </span><span class=cF3>TRUE</span><span class=cF0>;
|
|
<a name="l51"></a> tcp_socket->next_recv_seq_num++;
|
|
<a name="l52"></a>
|
|
<a name="l53"></a> </span><span class=cF1>switch</span><span class=cF0> (tcp_socket->state)
|
|
<a name="l54"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l55"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_ESTABLISHED:
|
|
<a name="l56"></a> tcp_socket->state = TCP_STATE_CLOSE_WAIT;
|
|
<a name="l57"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l58"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_FIN_WAIT1:
|
|
<a name="l59"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_FIN_WAIT2:
|
|
<a name="l60"></a> tcp_socket->state = TCP_STATE_TIME_WAIT;
|
|
<a name="l61"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l62"></a> </span><span class=cF7>}</span><span class=cF0> </span><span class=cF2>// review RFC, whether more state checks needed here.</span><span class=cF0>
|
|
<a name="l63"></a> }
|
|
<a name="l64"></a>
|
|
<a name="l65"></a>
|
|
<a name="l66"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l67"></a>
|
|
<a name="l68"></a> </span><span class=cF1>default</span><span class=cF0>:
|
|
<a name="l69"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l70"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l71"></a>
|
|
<a name="l72"></a> </span><span class=cF1>return</span><span class=cF0> must_ack;
|
|
<a name="l73"></a>}
|
|
<a name="l74"></a>
|
|
<a name="l75"></a>
|
|
<a name="l76"></a></span><span class=cF1>Bool</span><span class=cF0> TCPHandleACK(CTCPSocket *tcp_socket, CIPV4Packet *packet, CTCPHeader *header,
|
|
<a name="l77"></a> </span><span class=cF9>U32</span><span class=cF0> segment_seq_num, </span><span class=cF9>U32</span><span class=cF0> segment_ack_num, </span><span class=cF9>U32</span><span class=cF0> segment_length)
|
|
<a name="l78"></a>{ </span><span class=cF2>// returns the value of must_ack, used later in TCPHandleSocket</span><span class=cF0>
|
|
<a name="l79"></a> </span><span class=cF9>I64</span><span class=cF0> ack_relative;
|
|
<a name="l80"></a> </span><span class=cF9>I64</span><span class=cF0> ack_next_relative;
|
|
<a name="l81"></a>
|
|
<a name="l82"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&header->flags, TCPf_ACK</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l83"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l84"></a> ack_relative = (segment_ack_num - tcp_socket->first_unacked_seq) & </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>;
|
|
<a name="l85"></a> ack_next_relative = (tcp_socket->next_send_seq_num - tcp_socket->first_unacked_seq) & </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>;
|
|
<a name="l86"></a>
|
|
<a name="l87"></a> </span><span class=cF2>// Shrine has comments here about RFC poor wording,</span><span class=cF0>
|
|
<a name="l88"></a> </span><span class=cF2>// TODO: review RFC and implement more refined approach.</span><span class=cF0>
|
|
<a name="l89"></a> </span><span class=cF1>if</span><span class=cF0> (ack_relative <= ack_next_relative)
|
|
<a name="l90"></a> {
|
|
<a name="l91"></a> TCPAcknowledgePacket(tcp_socket, segment_ack_num);
|
|
<a name="l92"></a>
|
|
<a name="l93"></a> </span><span class=cF2>// "Accept ACK"</span><span class=cF0>
|
|
<a name="l94"></a> tcp_socket->first_unacked_seq = segment_ack_num;
|
|
<a name="l95"></a>
|
|
<a name="l96"></a> </span><span class=cF1>switch</span><span class=cF0> (tcp_socket->state)
|
|
<a name="l97"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l98"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_SYN_SENT:
|
|
<a name="l99"></a> NetDebug(</span><span class=cF6>"TCP HANDLE ACK: Acceptable ACK; state: SYN_SENT"</span><span class=cF0>);
|
|
<a name="l100"></a> </span><span class=cF1>if</span><span class=cF0> (!</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&header->flags, TCPf_SYN</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l101"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l102"></a> </span><span class=cF2>// else, fall-through</span><span class=cF0>
|
|
<a name="l103"></a>
|
|
<a name="l104"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_SYN_RECEIVED:
|
|
<a name="l105"></a> tcp_socket->state = TCP_STATE_ESTABLISHED;
|
|
<a name="l106"></a> tcp_socket->srtt = </span><span class=cF5>tS</span><span class=cF0> - tcp_socket->connection_time;
|
|
<a name="l107"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l108"></a>
|
|
<a name="l109"></a> </span><span class=cF1>default</span><span class=cF0>:
|
|
<a name="l110"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l111"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l112"></a> NetDebug(</span><span class=cF6>"TCP HANDLE ACK: Acceptable ACK returning; state: 0x%0X"</span><span class=cF0>, tcp_socket->state);
|
|
<a name="l113"></a> }
|
|
<a name="l114"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l115"></a> {
|
|
<a name="l116"></a> NetWarn(</span><span class=cF6>"TCP HANDLE SOCKET: Invalid ACK."</span><span class=cF0>);
|
|
<a name="l117"></a>
|
|
<a name="l118"></a> </span><span class=cF1>switch</span><span class=cF0> (tcp_socket->state)
|
|
<a name="l119"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l120"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_LISTEN:
|
|
<a name="l121"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_SYN_SENT:
|
|
<a name="l122"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_SYN_RECEIVED:
|
|
<a name="l123"></a> TCPSend(packet->destination_ip_address,
|
|
<a name="l124"></a> </span><span class=cF5>EndianU16</span><span class=cF7>(</span><span class=cF0>header->destination_port</span><span class=cF7>)</span><span class=cF0>,
|
|
<a name="l125"></a> packet->source_ip_address,
|
|
<a name="l126"></a> </span><span class=cF5>EndianU16</span><span class=cF7>(</span><span class=cF0>header->source_port</span><span class=cF7>)</span><span class=cF0>,
|
|
<a name="l127"></a> segment_ack_num,
|
|
<a name="l128"></a> segment_seq_num + segment_length,
|
|
<a name="l129"></a> TCPF_ACK | TCPF_RST);
|
|
<a name="l130"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l131"></a>
|
|
<a name="l132"></a> </span><span class=cF1>default</span><span class=cF0>:
|
|
<a name="l133"></a> </span><span class=cF1>if</span><span class=cF0> (IsTCPStateSync</span><span class=cF7>(</span><span class=cF0>tcp_socket</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l134"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>; </span><span class=cF2>// must ACK the packet.</span><span class=cF0>
|
|
<a name="l135"></a>
|
|
<a name="l136"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l137"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l138"></a> }
|
|
<a name="l139"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l140"></a>
|
|
<a name="l141"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>; </span><span class=cF2>// do not need to ACK the packet.</span><span class=cF0>
|
|
<a name="l142"></a>}
|
|
<a name="l143"></a>
|
|
<a name="l144"></a></span><span class=cF1>Bool</span><span class=cF0> TCPHandleReset(CTCPSocket *tcp_socket, CTCPHeader *header, </span><span class=cF1>Bool</span><span class=cF0> is_seq_valid)
|
|
<a name="l145"></a>{ </span><span class=cF2>// returns whether or not to stop overall TCP procedure.</span><span class=cF0>
|
|
<a name="l146"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&header->flags, TCPf_RST</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l147"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l148"></a> </span><span class=cF1>switch</span><span class=cF0> (tcp_socket->state)
|
|
<a name="l149"></a> {
|
|
<a name="l150"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_SYN_SENT:
|
|
<a name="l151"></a> </span><span class=cF1>if</span><span class=cF0> (tcp_socket->first_unacked_seq == tcp_socket->next_send_seq_num)
|
|
<a name="l152"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l153"></a> NetWarn(</span><span class=cF6>"TCP HANDLE SOCKET: Got RST, socket state SYN_SENT. Connection refused."</span><span class=cF0>);
|
|
<a name="l154"></a> tcp_socket->state = TCP_STATE_CLOSED;
|
|
<a name="l155"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
|
|
<a name="l156"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l157"></a> </span><span class=cF1>break</span><span class=cF0>;
|
|
<a name="l158"></a>
|
|
<a name="l159"></a> </span><span class=cF1>default</span><span class=cF0>:
|
|
<a name="l160"></a> </span><span class=cF1>if</span><span class=cF0> (is_seq_valid)
|
|
<a name="l161"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l162"></a> NetWarn(</span><span class=cF6>"TCP HANDLE SOCKET: Got RST, connection refused by remote host."</span><span class=cF0>);
|
|
<a name="l163"></a> tcp_socket->state = TCP_STATE_CLOSED;
|
|
<a name="l164"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
|
|
<a name="l165"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l166"></a> }
|
|
<a name="l167"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l168"></a>
|
|
<a name="l169"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
|
|
<a name="l170"></a>}
|
|
<a name="l171"></a>
|
|
<a name="l172"></a></span><span class=cF1>U0</span><span class=cF0> TCPHandleSocketListen(CTCPSocket *tcp_socket, CIPV4Packet *packet, CTCPHeader *header, </span><span class=cF9>U32</span><span class=cF0> segment_seq_num)
|
|
<a name="l173"></a>{ </span><span class=cF2>// if SYN and socket listening, queue up the connection in the socket's accept queue.</span><span class=cF0>
|
|
<a name="l174"></a> CTCPAcceptQueue *new_connection;
|
|
<a name="l175"></a>
|
|
<a name="l176"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&header->flags, TCPf_SYN</span><span class=cF7>)</span><span class=cF0> && </span><span class=cF5>QueueSize</span><span class=cF7>(</span><span class=cF0>tcp_socket->accept_queue</span><span class=cF7>)</span><span class=cF0> < tcp_socket->accept_queue_limit)
|
|
<a name="l177"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l178"></a> NetDebug(</span><span class=cF6>"TCP HANDLE SOCKET LISTEN: Adding new connection to Socket accept queue"</span><span class=cF0>);
|
|
<a name="l179"></a> new_connection = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>CTCPAcceptQueue</span><span class=cF7>)</span><span class=cF0>);
|
|
<a name="l180"></a>
|
|
<a name="l181"></a> new_connection->segment_seq_num = segment_seq_num;
|
|
<a name="l182"></a> new_connection->ipv4_address = packet->source_ip_address;
|
|
<a name="l183"></a> new_connection->port = header->source_port;
|
|
<a name="l184"></a>
|
|
<a name="l185"></a> </span><span class=cF5>QueueInsertRev</span><span class=cF0>(new_connection, tcp_socket->accept_queue);
|
|
<a name="l186"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l187"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l188"></a> </span><span class=cF7>{</span><span class=cF0> </span><span class=cF2>// refuse</span><span class=cF0>
|
|
<a name="l189"></a> NetDebug(</span><span class=cF6>"TCP HANDLE SOCKET LISTEN: Header flags not SYN or Queue full, REFUSING CONNECTION"</span><span class=cF0>);
|
|
<a name="l190"></a> TCPSend(packet->destination_ip_address,
|
|
<a name="l191"></a> </span><span class=cF5>EndianU16</span><span class=cF7>(</span><span class=cF0>header->destination_port</span><span class=cF7>)</span><span class=cF0>,
|
|
<a name="l192"></a> packet->source_ip_address,
|
|
<a name="l193"></a> </span><span class=cF5>EndianU16</span><span class=cF7>(</span><span class=cF0>header->source_port</span><span class=cF7>)</span><span class=cF0>,
|
|
<a name="l194"></a> segment_seq_num + </span><span class=cFE>1</span><span class=cF0>,
|
|
<a name="l195"></a> segment_seq_num + </span><span class=cFE>1</span><span class=cF0>,
|
|
<a name="l196"></a> TCPF_ACK | TCPF_RST);
|
|
<a name="l197"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l198"></a>}
|
|
<a name="l199"></a>
|
|
<a name="l200"></a></span><span class=cF1>U0</span><span class=cF0> TCPHandleSocket(CTCPSocket *tcp_socket, CIPV4Packet *packet, CTCPHeader *header, </span><span class=cF1>U8</span><span class=cF0> *data, </span><span class=cF9>I64</span><span class=cF0> length)
|
|
<a name="l201"></a>{
|
|
<a name="l202"></a> </span><span class=cF9>U32</span><span class=cF0> segment_length = length;
|
|
<a name="l203"></a> </span><span class=cF9>U32</span><span class=cF0> segment_seq_num = </span><span class=cF5>EndianU32</span><span class=cF0>(header->seq_num);
|
|
<a name="l204"></a> </span><span class=cF9>U32</span><span class=cF0> segment_ack_num = </span><span class=cF5>EndianU32</span><span class=cF0>(header->ack_num);
|
|
<a name="l205"></a> </span><span class=cF1>Bool</span><span class=cF0> must_ack = </span><span class=cF3>FALSE</span><span class=cF0>;
|
|
<a name="l206"></a> </span><span class=cF1>Bool</span><span class=cF0> is_seq_valid = </span><span class=cF3>FALSE</span><span class=cF0>;
|
|
<a name="l207"></a> </span><span class=cF9>I64</span><span class=cF0> seq_relative;
|
|
<a name="l208"></a> </span><span class=cF9>I64</span><span class=cF0> seq_end_relative;
|
|
<a name="l209"></a>
|
|
<a name="l210"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&header->flags, TCPf_FIN</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l211"></a> segment_length++;
|
|
<a name="l212"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&header->flags, TCPf_SYN</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l213"></a> segment_length++;
|
|
<a name="l214"></a>
|
|
<a name="l215"></a> </span><span class=cF1>switch</span><span class=cF0> (tcp_socket->state)
|
|
<a name="l216"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l217"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_LISTEN:
|
|
<a name="l218"></a> NetDebug(</span><span class=cF6>"TCP HANDLE SOCKET: Running TCP HANDLE SOCKET LISTEN"</span><span class=cF0>);
|
|
<a name="l219"></a> TCPHandleSocketListen(tcp_socket, packet, header, segment_seq_num);
|
|
<a name="l220"></a> </span><span class=cF1>return</span><span class=cF0>;
|
|
<a name="l221"></a>
|
|
<a name="l222"></a> </span><span class=cF1>case</span><span class=cF0> TCP_STATE_CLOSED:
|
|
<a name="l223"></a> NetErr(</span><span class=cF6>"TCP HANDLE SOCKET: Received packet but TCP Socket is CLOSED."</span><span class=cF0>);
|
|
<a name="l224"></a> </span><span class=cF1>return</span><span class=cF0>;
|
|
<a name="l225"></a>
|
|
<a name="l226"></a> </span><span class=cF1>default</span><span class=cF0>:
|
|
<a name="l227"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>&header->flags, TCPf_SYN</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l228"></a> {
|
|
<a name="l229"></a> tcp_socket->next_recv_seq_num = ++segment_seq_num;
|
|
<a name="l230"></a>
|
|
<a name="l231"></a> must_ack = </span><span class=cF3>TRUE</span><span class=cF0>;
|
|
<a name="l232"></a> }
|
|
<a name="l233"></a>
|
|
<a name="l234"></a> </span><span class=cF1>if</span><span class=cF0> (segment_length == </span><span class=cFE>0</span><span class=cF0> && tcp_socket->receive_window == </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l235"></a> {
|
|
<a name="l236"></a> NetDebug(</span><span class=cF6>"TCP HANDLE SOCKET: segment length == 0 && receive window == 0, SEQ valid if seq == next recv seq"</span><span class=cF0>);
|
|
<a name="l237"></a> is_seq_valid = (segment_seq_num == tcp_socket->next_recv_seq_num);
|
|
<a name="l238"></a> }
|
|
<a name="l239"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l240"></a> {
|
|
<a name="l241"></a> seq_relative = (segment_seq_num - tcp_socket->next_recv_seq_num) & </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>;
|
|
<a name="l242"></a> seq_end_relative = (segment_seq_num + segment_length - </span><span class=cFE>1</span><span class=cF0> - tcp_socket->next_recv_seq_num) & </span><span class=cFE>0xFFFFFFFF</span><span class=cF0>;
|
|
<a name="l243"></a>
|
|
<a name="l244"></a> is_seq_valid = (seq_relative < tcp_socket->receive_window ||
|
|
<a name="l245"></a> seq_end_relative < tcp_socket->receive_window);
|
|
<a name="l246"></a> }
|
|
<a name="l247"></a>
|
|
<a name="l248"></a> </span><span class=cF1>if</span><span class=cF0> (!is_seq_valid)
|
|
<a name="l249"></a> NetWarn(</span><span class=cF6>"TCP HANDLE SOCKET: Invalid SEQ."</span><span class=cF0>);
|
|
<a name="l250"></a>
|
|
<a name="l251"></a> must_ack |= TCPHandleACK(tcp_socket, packet, header, segment_seq_num, segment_ack_num, segment_length);
|
|
<a name="l252"></a>
|
|
<a name="l253"></a>
|
|
<a name="l254"></a> </span><span class=cF1>if</span><span class=cF0> (TCPHandleReset</span><span class=cF7>(</span><span class=cF0>tcp_socket, header, is_seq_valid</span><span class=cF7>)</span><span class=cF0>)
|
|
<a name="l255"></a> </span><span class=cF1>return</span><span class=cF0>;
|
|
<a name="l256"></a>
|
|
<a name="l257"></a> </span><span class=cF1>if</span><span class=cF0> (is_seq_valid)
|
|
<a name="l258"></a> must_ack |= TCPHandleValidSEQ(tcp_socket, header, segment_seq_num, length, data);
|
|
<a name="l259"></a>
|
|
<a name="l260"></a> </span><span class=cF1>if</span><span class=cF0> (must_ack)
|
|
<a name="l261"></a> TCPSendFlags(tcp_socket, TCPF_ACK);
|
|
<a name="l262"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l263"></a>
|
|
<a name="l264"></a>}
|
|
<a name="l265"></a>
|
|
<a name="l266"></a></span><span class=cF9>I64</span><span class=cF0> TCPHandleRefuse(CIPV4Packet *packet, CTCPHeader *header, </span><span class=cF9>I64</span><span class=cF0> length)
|
|
<a name="l267"></a>{
|
|
<a name="l268"></a> </span><span class=cF9>I64</span><span class=cF0> de_index;
|
|
<a name="l269"></a> </span><span class=cF9>U32</span><span class=cF0> ack_num = </span><span class=cF5>EndianU32</span><span class=cF0>(header->ack_num);
|
|
<a name="l270"></a> </span><span class=cF9>U32</span><span class=cF0> seq_num = </span><span class=cF5>EndianU32</span><span class=cF0>(header->seq_num);
|
|
<a name="l271"></a>
|
|
<a name="l272"></a> </span><span class=cF1>no_warn</span><span class=cF0> length; </span><span class=cF2>// TODO: Will reset generation need length ?</span><span class=cF0>
|
|
<a name="l273"></a>
|
|
<a name="l274"></a> ack_num = ++seq_num;
|
|
<a name="l275"></a> seq_num = </span><span class=cFE>0</span><span class=cF0>;
|
|
<a name="l276"></a>
|
|
<a name="l277"></a> </span><span class=cF2>// review RFC Reset-Generation ...</span><span class=cF0>
|
|
<a name="l278"></a>
|
|
<a name="l279"></a> de_index = TCPSend(packet->destination_ip_address,
|
|
<a name="l280"></a> </span><span class=cF5>EndianU16</span><span class=cF7>(</span><span class=cF0>header->destination_port</span><span class=cF7>)</span><span class=cF0>,
|
|
<a name="l281"></a> packet->source_ip_address,
|
|
<a name="l282"></a> </span><span class=cF5>EndianU16</span><span class=cF7>(</span><span class=cF0>header->source_port</span><span class=cF7>)</span><span class=cF0>,
|
|
<a name="l283"></a> seq_num,
|
|
<a name="l284"></a> ack_num,
|
|
<a name="l285"></a> TCPF_RST | TCPF_ACK);
|
|
<a name="l286"></a> </span><span class=cF1>if</span><span class=cF0> (de_index < </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l287"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l288"></a> NetErr(</span><span class=cF6>"TCP Handler Refuse: TCP Send failed."</span><span class=cF0>);
|
|
<a name="l289"></a> </span><span class=cF1>return</span><span class=cF0> de_index;
|
|
<a name="l290"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l291"></a>
|
|
<a name="l292"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>0</span><span class=cF0>;
|
|
<a name="l293"></a>}
|
|
<a name="l294"></a>
|
|
<a name="l295"></a></span><span class=cF9>I64</span><span class=cF0> TCPHandler(CIPV4Packet *packet)
|
|
<a name="l296"></a>{
|
|
<a name="l297"></a> CTCPHeader *header;
|
|
<a name="l298"></a> </span><span class=cF9>U16</span><span class=cF0> destination_port;
|
|
<a name="l299"></a> </span><span class=cF1>U8</span><span class=cF0> *data;
|
|
<a name="l300"></a> </span><span class=cF9>I64</span><span class=cF0> length;
|
|
<a name="l301"></a> CTCPTreeNode *head = tcp_globals.bound_socket_tree;
|
|
<a name="l302"></a> CTCPTreeNode *node;
|
|
<a name="l303"></a> CTCPTreeQueue *queue;
|
|
<a name="l304"></a> CTCPSocket *tcp_socket;
|
|
<a name="l305"></a> </span><span class=cF9>I64</span><span class=cF0> error = TCPPacketParse(&header, &data, &length, packet);
|
|
<a name="l306"></a>
|
|
<a name="l307"></a> </span><span class=cF1>if</span><span class=cF0> (error < </span><span class=cFE>0</span><span class=cF0>)
|
|
<a name="l308"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l309"></a> NetErr(</span><span class=cF6>"TCP HANDLER: Packet Parse Error."</span><span class=cF0>);
|
|
<a name="l310"></a> </span><span class=cF1>return</span><span class=cF0> error;
|
|
<a name="l311"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l312"></a>
|
|
<a name="l313"></a> NetDebug(</span><span class=cF6>"TCP HANDLER: Caught packet with dest port of %0X (B.E.)"</span><span class=cF0>, header->destination_port);
|
|
<a name="l314"></a>
|
|
<a name="l315"></a> destination_port = </span><span class=cF5>EndianU16</span><span class=cF0>(header->destination_port); </span><span class=cF2>// B.E. -> L.E.</span><span class=cF0>
|
|
<a name="l316"></a> NetDebug(</span><span class=cF6>"TCP HANDLER: Caught packet with dest port of %0X (L.E.)"</span><span class=cF0>, destination_port);
|
|
<a name="l317"></a>
|
|
<a name="l318"></a> </span><span class=cF1>if</span><span class=cF0> (head)
|
|
<a name="l319"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l320"></a> node = TCPTreeNodeFind(destination_port, head);
|
|
<a name="l321"></a>
|
|
<a name="l322"></a> </span><span class=cF1>if</span><span class=cF0> (node)
|
|
<a name="l323"></a> {
|
|
<a name="l324"></a> NetDebug(</span><span class=cF6>"TCP HANDLER: Found node for port, looking for address %0X (L.E.)"</span><span class=cF0>, packet->source_ip_address);
|
|
<a name="l325"></a> queue = TCPTreeNodeQueueIPV4Find(packet->source_ip_address, node); </span><span class=cF2>// TODO: make sure bit order is correct here!!</span><span class=cF0>
|
|
<a name="l326"></a> </span><span class=cF1>if</span><span class=cF0> (queue)
|
|
<a name="l327"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l328"></a> tcp_socket = queue->socket;
|
|
<a name="l329"></a> NetLog(</span><span class=cF6>"TCP HANDLER: Port and Address are in bound tree."</span><span class=cF0>);
|
|
<a name="l330"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l331"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l332"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l333"></a> NetWarn(</span><span class=cF6>"TCP HANDLER: Found node for port, but address is not in node queue."</span><span class=cF0>);
|
|
<a name="l334"></a> NetWarn(</span><span class=cF6>" TCP source ip: 0x%0X."</span><span class=cF0>, packet->source_ip_address);
|
|
<a name="l335"></a>
|
|
<a name="l336"></a> NetWarn(</span><span class=cF6>"TCP HANDLER: Sending TCP RST ACK packet. Refusing connection."</span><span class=cF0>);
|
|
<a name="l337"></a> TCPHandleRefuse(packet, header, length);
|
|
<a name="l338"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l339"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l340"></a> }
|
|
<a name="l341"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l342"></a> {
|
|
<a name="l343"></a> NetDebug(</span><span class=cF6>"TCP HANDLER: NODE SEARCH FAILURE: PORT %0X"</span><span class=cF0>, destination_port);
|
|
<a name="l344"></a> NetWarn(</span><span class=cF6>"TCP HANDLER: Node for Port is not in tree."</span><span class=cF0>);
|
|
<a name="l345"></a> NetWarn(</span><span class=cF6>"TCP HANDLER: Sending TCP RST ACK packet. Refusing connection."</span><span class=cF0>);
|
|
<a name="l346"></a> TCPHandleRefuse(packet, header, length);
|
|
<a name="l347"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l348"></a> }
|
|
<a name="l349"></a>
|
|
<a name="l350"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l351"></a> </span><span class=cF1>else</span><span class=cF0>
|
|
<a name="l352"></a> </span><span class=cF7>{</span><span class=cF0>
|
|
<a name="l353"></a> NetWarn(</span><span class=cF6>"TCP HANDLER: Socket tree is currently empty."</span><span class=cF0>);
|
|
<a name="l354"></a> NetWarn(</span><span class=cF6>"TCP HANDLER: Sending TCP RST ACK packet. Refusing connection."</span><span class=cF0>);
|
|
<a name="l355"></a> TCPHandleRefuse(packet, header, length);
|
|
<a name="l356"></a> </span><span class=cF1>return</span><span class=cF0> -</span><span class=cFE>1</span><span class=cF0>;
|
|
<a name="l357"></a> </span><span class=cF7>}</span><span class=cF0>
|
|
<a name="l358"></a>
|
|
<a name="l359"></a> </span><span class=cF2>// at this point, tcp_socket is set, otherwise has already returned -1.</span><span class=cF0>
|
|
<a name="l360"></a>
|
|
<a name="l361"></a> NetDebug(</span><span class=cF6>"TCP HANDLER: Running TCP HANDLE SOCKET"</span><span class=cF0>);
|
|
<a name="l362"></a> TCPHandleSocket(tcp_socket, packet, header, data, length);
|
|
<a name="l363"></a>
|
|
<a name="l364"></a>}</span></pre></body>
|
|
</html>
|