00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 #ifndef __LWIP_TCP_H__
00036 #define __LWIP_TCP_H__
00037 
00038 #include "net/sys.h"
00039 #include "net/mem.h"
00040 
00041 #include "net/pbuf.h"
00042 #include "net/opt.h"
00043 
00044 #include "net/ipv4/ip.h"
00045 
00046 #include "net/ipv4/icmp.h"
00047 
00048 #include "net/sys.h"
00049 
00050 #include "net/err.h"
00051 
00052 struct tcp_pcb;
00053 
00054 
00055 
00056 
00057 void             tcp_init    (void);  
00058 
00059 void             tcp_tmr     (void);  
00060 
00061 
00062 
00063 struct tcp_pcb * tcp_new     (void);
00064 
00065 void             tcp_arg     (struct tcp_pcb *pcb, void *arg);
00066 void             tcp_accept  (struct tcp_pcb *pcb,
00067                               err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
00068                                                err_t err));
00069 void             tcp_recv    (struct tcp_pcb *pcb,
00070                               err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
00071                                   struct pbuf *p, err_t err));
00072 void             tcp_sent    (struct tcp_pcb *pcb,
00073                               err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
00074                                              uInt16 len));
00075 void             tcp_poll    (struct tcp_pcb *pcb,
00076                               err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
00077                               uInt8 interval);
00078 void             tcp_err     (struct tcp_pcb *pcb,
00079                               void (* err)(void *arg, err_t err));
00080 
00081 #define          tcp_sndbuf(pcb)   ((pcb)->snd_buf)
00082 
00083 void             tcp_recved  (struct tcp_pcb *pcb, uInt16 len);
00084 err_t            tcp_bind    (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
00085                               uInt16 port);
00086 err_t            tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr,
00087                               uInt16 port, err_t (* connected)(void *arg,
00088                                                               struct tcp_pcb *tpcb,
00089                                                               err_t err));
00090 struct tcp_pcb * tcp_listen  (struct tcp_pcb *pcb);
00091 void             tcp_abort   (struct tcp_pcb *pcb);
00092 err_t            tcp_close   (struct tcp_pcb *pcb);
00093 err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, uInt16 len,
00094                               uInt8 copy);
00095 
00096 
00097 
00098 void             tcp_slowtmr (void);
00099 void             tcp_fasttmr (void);
00100 
00101 
00102 
00103 void             tcp_input   (struct pbuf *p, struct netif *inp);
00104 
00105 err_t            tcp_output  (struct tcp_pcb *pcb);
00106 
00107 
00108 
00109 
00110 #define TCP_SEQ_LT(a,b)     ((Int32)((a)-(b)) < 0)
00111 #define TCP_SEQ_LEQ(a,b)    ((Int32)((a)-(b)) <= 0)
00112 #define TCP_SEQ_GT(a,b)     ((Int32)((a)-(b)) > 0)
00113 #define TCP_SEQ_GEQ(a,b)    ((Int32)((a)-(b)) >= 0)
00114 
00115 #define TCP_FIN 0x01
00116 #define TCP_SYN 0x02
00117 #define TCP_RST 0x04
00118 #define TCP_PSH 0x08
00119 #define TCP_ACK 0x10
00120 #define TCP_URG 0x20
00121 
00122 
00123 #define TCP_HLEN 20
00124 
00125 #define TCP_TMR_INTERVAL       100  
00126 
00127 
00128 #define TCP_FAST_INTERVAL      200  
00129 
00130 #define TCP_SLOW_INTERVAL      500  
00131 
00132 #define TCP_FIN_WAIT_TIMEOUT 20000 
00133 #define TCP_SYN_RCVD_TIMEOUT 20000 
00134 
00135 #define TCP_OOSEQ_TIMEOUT        6 
00136 
00137 #define TCP_MSL 60000  
00138 
00139 struct tcp_hdr {
00140   PACK_STRUCT_FIELD(uInt16 src);
00141   PACK_STRUCT_FIELD(uInt16 dest);
00142   PACK_STRUCT_FIELD(uInt32 seqno);
00143   PACK_STRUCT_FIELD(uInt32 ackno);
00144   PACK_STRUCT_FIELD(uInt16 _offset_flags);
00145   PACK_STRUCT_FIELD(uInt16 wnd);
00146   PACK_STRUCT_FIELD(uInt16 chksum);
00147   PACK_STRUCT_FIELD(uInt16 urgp);
00148 } PACK_STRUCT_STRUCT;
00149 
00150 #define TCPH_OFFSET(hdr) (NTOHS((hdr)->_offset_flags) >> 8)
00151 #define TCPH_FLAGS(hdr) (NTOHS((hdr)->_offset_flags) & 0xff)
00152 
00153 #define TCPH_OFFSET_SET(hdr, offset) (hdr)->_offset_flags = HTONS(((offset) << 8) | TCPH_FLAGS(hdr))
00154 #define TCPH_FLAGS_SET(hdr, flags) (hdr)->_offset_flags = HTONS((TCPH_OFFSET(hdr) << 8) | (flags))
00155 
00156 #define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
00157                                         TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
00158 
00159 enum tcp_state {
00160   CLOSED      = 0,
00161   LISTEN      = 1,
00162   SYN_SENT    = 2,
00163   SYN_RCVD    = 3,
00164   ESTABLISHED = 4,
00165   FIN_WAIT_1  = 5,
00166   FIN_WAIT_2  = 6,
00167   CLOSE_WAIT  = 7,
00168   CLOSING     = 8,
00169   LAST_ACK    = 9,
00170   TIME_WAIT   = 10
00171 };
00172 
00173 
00174 
00175 struct tcp_pcb {
00176   struct tcp_pcb *next;   
00177 
00178   enum tcp_state state;   
00179 
00180   void *callback_arg;
00181   
00182   
00183   err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
00184 
00185   struct ip_addr local_ip;
00186   uInt16 local_port;
00187   
00188   struct ip_addr remote_ip;
00189   uInt16 remote_port;
00190   
00191   
00192   uInt32 rcv_nxt;   
00193   uInt16 rcv_wnd;   
00194 
00195   
00196   uInt16 tmr;
00197 
00198   
00199   uInt8 rtime;
00200   
00201   uInt16 mss;   
00202 
00203   uInt8 flags;
00204 #define TF_ACK_DELAY 0x01   
00205 #define TF_ACK_NOW   0x02   
00206 #define TF_INFR      0x04   
00207 #define TF_RESET     0x08   
00208 #define TF_CLOSED    0x10   
00209 #define TF_GOT_FIN   0x20   
00210   
00211   
00212   uInt16 rttest; 
00213   uInt32 rtseq;  
00214   Int32 sa, sv;
00215 
00216   uInt16 rto;    
00217   uInt8 nrtx;    
00218 
00219   
00220   uInt32 lastack; 
00221   uInt8 dupacks;
00222   
00223   
00224   uInt16 cwnd;  
00225   uInt16 ssthresh;
00226 
00227   
00228   uInt32 snd_nxt,       
00229     snd_max,       
00230     snd_wnd,       
00231     snd_wl1, snd_wl2,
00232     snd_lbb;      
00233 
00234   uInt16 snd_buf;   
00235   uInt8 snd_queuelen;
00236 
00237   
00238   err_t (* sent)(void *arg, struct tcp_pcb *pcb, uInt16 space);
00239   uInt16 acked;
00240   
00241   
00242   err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
00243   struct pbuf *recv_data;
00244 
00245   
00246   err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err);
00247 
00248   
00249   err_t (* poll)(void *arg, struct tcp_pcb *pcb);
00250 
00251   
00252   void (* errf)(void *arg, err_t err);
00253   
00254   uInt8 polltmr, pollinterval;
00255   
00256   
00257   struct tcp_seg *unsent;   
00258   struct tcp_seg *unacked;  
00259 #if TCP_QUEUE_OOSEQ  
00260   struct tcp_seg *ooseq;    
00261 #endif 
00262 
00263 };
00264 
00265 struct tcp_pcb_listen {  
00266   struct tcp_pcb_listen *next;   
00267   
00268   enum tcp_state state;   
00269 
00270   void *callback_arg;
00271   
00272   
00273   void (* accept)(void *arg, struct tcp_pcb *newpcb);
00274 
00275   struct ip_addr local_ip;
00276   uInt16 local_port;
00277 };
00278 
00279 
00280 struct tcp_seg {
00281   struct tcp_seg *next;    
00282   struct pbuf *p;          
00283   void *dataptr;           
00284   uInt16 len;               
00285   struct tcp_hdr *tcphdr;  
00286 };
00287 
00288 
00289 struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
00290 void tcp_pcb_purge(struct tcp_pcb *pcb);
00291 void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
00292 
00293 uInt8 tcp_segs_free(struct tcp_seg *seg);
00294 uInt8 tcp_seg_free(struct tcp_seg *seg);
00295 struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
00296 
00297 #define tcp_ack(pcb)     if((pcb)->flags & TF_ACK_DELAY) { \
00298                             (pcb)->flags |= TF_ACK_NOW; \
00299                             tcp_output(pcb); \
00300                          } else { \
00301                             (pcb)->flags |= TF_ACK_DELAY; \
00302                          }
00303 
00304 #define tcp_ack_now(pcb) (pcb)->flags |= TF_ACK_NOW; \
00305                          tcp_output(pcb)
00306 
00307 err_t tcp_send_ctrl(struct tcp_pcb *pcb, uInt8 flags);
00308 err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, uInt16 len,
00309                 uInt8 flags, uInt8 copy,
00310                 uInt8 *optdata, uInt8 optlen);
00311 
00312 void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
00313 
00314 void tcp_rst(uInt32 seqno, uInt32 ackno,
00315              struct ip_addr *local_ip, struct ip_addr *remote_ip,
00316              uInt16 local_port, uInt16 remote_port);
00317 
00318 uInt32 tcp_next_iss(void);
00319 
00320 extern uInt32 tcp_ticks;
00321 
00322 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
00323 void tcp_debug_print(struct tcp_hdr *tcphdr);
00324 void tcp_debug_print_flags(uInt8 flags);
00325 void tcp_debug_print_state(enum tcp_state s);
00326 void tcp_debug_print_pcbs(void);
00327 int tcp_pcbs_sane(void);
00328 #else
00329 #define tcp_pcbs_sane() 1
00330 #endif 
00331 
00332 
00333 
00334 extern struct tcp_pcb_listen *tcp_listen_pcbs;  
00335 extern struct tcp_pcb *tcp_active_pcbs;  
00336 
00337 
00338 extern struct tcp_pcb *tcp_tw_pcbs;      
00339 
00340 extern struct tcp_pcb *tcp_tmp_pcb;      
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 #ifdef LWIP_DEBUG
00352 #define TCP_REG(pcbs, npcb) do {\
00353                             DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \
00354                             for(tcp_tmp_pcb = *pcbs; \
00355                                   tcp_tmp_pcb != NULL; \
00356                                 tcp_tmp_pcb = tcp_tmp_pcb->next) { \
00357                                 ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \
00358                             } \
00359                             ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \
00360                             npcb->next = *pcbs; \
00361                             ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \
00362                             *pcbs = npcb; \
00363                             ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
00364                             } while(0)
00365 #define TCP_RMV(pcbs, npcb) do { \
00366                             ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \
00367                             DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \
00368                             if(*pcbs == npcb) { \
00369                                *pcbs = (*pcbs)->next; \
00370                             } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
00371                                if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
00372                                   tcp_tmp_pcb->next = npcb->next; \
00373                                   break; \
00374                                } \
00375                             } \
00376                             npcb->next = NULL; \
00377                             ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
00378                             DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \
00379                             } while(0)
00380 
00381 #else 
00382 #define TCP_REG(pcbs, npcb) do { \
00383                             npcb->next = *pcbs; \
00384                             *pcbs = npcb; \
00385                             } while(0)
00386 #define TCP_RMV(pcbs, npcb) do { \
00387                             if(*pcbs == npcb) { \
00388                                *pcbs = (*pcbs)->next; \
00389                             } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
00390                                if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
00391                                   tcp_tmp_pcb->next = npcb->next; \
00392                                   break; \
00393                                } \
00394                             } \
00395                             npcb->next = NULL; \
00396                             } while(0)
00397 #endif 
00398 #endif 
00399 
00400 
00401