@@ -102,6 +102,56 @@ static void reset_heap(void) {
102102 heap .size = 0 ;
103103}
104104
105+ static void setup_stack_with_two_ifaces (struct wolfIP * s , ip4 primary_ip , ip4 secondary_ip )
106+ {
107+ wolfIP_init (s );
108+ mock_link_init (s );
109+ mock_link_init_idx (s , TEST_SECOND_IF , NULL );
110+ wolfIP_ipconfig_set (s , primary_ip , 0xFFFFFF00U , 0 );
111+ wolfIP_ipconfig_set_ex (s , TEST_SECOND_IF , secondary_ip , 0xFFFFFF00U , 0 );
112+ }
113+
114+ static void inject_tcp_syn (struct wolfIP * s , unsigned int if_idx , ip4 dst_ip , uint16_t dst_port )
115+ {
116+ struct wolfIP_tcp_seg syn ;
117+ struct wolfIP_ll_dev * ll = wolfIP_getdev_ex (s , if_idx );
118+ union transport_pseudo_header ph ;
119+ static const uint8_t src_mac [6 ] = {0x10 , 0x20 , 0x30 , 0x40 , 0x50 , 0x60 };
120+
121+ ck_assert_ptr_nonnull (ll );
122+ memset (& syn , 0 , sizeof (syn ));
123+ memcpy (syn .ip .eth .dst , ll -> mac , 6 );
124+ memcpy (syn .ip .eth .src , src_mac , 6 );
125+ syn .ip .eth .type = ee16 (ETH_TYPE_IP );
126+ syn .ip .ver_ihl = 0x45 ;
127+ syn .ip .ttl = 64 ;
128+ syn .ip .proto = WI_IPPROTO_TCP ;
129+ syn .ip .len = ee16 (IP_HEADER_LEN + TCP_HEADER_LEN );
130+ syn .ip .src = ee32 (0x0A0000A1U );
131+ syn .ip .dst = ee32 (dst_ip );
132+ syn .ip .csum = 0 ;
133+ iphdr_set_checksum (& syn .ip );
134+
135+ syn .src_port = ee16 (40000 );
136+ syn .dst_port = ee16 (dst_port );
137+ syn .seq = ee32 (1 );
138+ syn .ack = 0 ;
139+ syn .hlen = TCP_HEADER_LEN << 2 ;
140+ syn .flags = 0x02 ;
141+ syn .win = ee16 (65535 );
142+ syn .csum = 0 ;
143+ syn .urg = 0 ;
144+
145+ memset (& ph , 0 , sizeof (ph ));
146+ ph .ph .src = syn .ip .src ;
147+ ph .ph .dst = syn .ip .dst ;
148+ ph .ph .proto = WI_IPPROTO_TCP ;
149+ ph .ph .len = ee16 (TCP_HEADER_LEN );
150+ syn .csum = ee16 (transport_checksum (& ph , & syn .src_port ));
151+
152+ tcp_input (s , if_idx , & syn , sizeof (struct wolfIP_eth_frame ) + IP_HEADER_LEN + TCP_HEADER_LEN );
153+ }
154+
105155
106156START_TEST (test_fifo_init )
107157{
@@ -934,6 +984,155 @@ START_TEST(test_loopback_dest_not_forwarded)
934984}
935985END_TEST
936986
987+ START_TEST (test_tcp_listen_rejects_wrong_interface )
988+ {
989+ struct wolfIP s ;
990+ const ip4 primary_ip = 0xC0A80001U ;
991+ const ip4 secondary_ip = 0xC0A80101U ;
992+ const uint16_t listen_port = 12345 ;
993+ int listen_fd ;
994+ struct wolfIP_sockaddr_in addr ;
995+ struct tsocket * listener ;
996+
997+ setup_stack_with_two_ifaces (& s , primary_ip , secondary_ip );
998+
999+ listen_fd = wolfIP_sock_socket (& s , AF_INET , IPSTACK_SOCK_STREAM , 0 );
1000+ ck_assert_int_ge (listen_fd , 0 );
1001+ listener = & s .tcpsockets [listen_fd & ~MARK_TCP_SOCKET ];
1002+
1003+ memset (& addr , 0 , sizeof (addr ));
1004+ addr .sin_family = AF_INET ;
1005+ addr .sin_port = ee16 (listen_port );
1006+ addr .sin_addr .s_addr = ee32 (primary_ip );
1007+ ck_assert_int_eq (wolfIP_sock_bind (& s , listen_fd , (struct wolfIP_sockaddr * )& addr , sizeof (addr )), 0 );
1008+ ck_assert_int_eq (wolfIP_sock_listen (& s , listen_fd , 1 ), 0 );
1009+
1010+ inject_tcp_syn (& s , TEST_SECOND_IF , secondary_ip , listen_port );
1011+
1012+ ck_assert_int_eq (listener -> sock .tcp .state , TCP_LISTEN );
1013+ ck_assert_int_eq (listener -> events & CB_EVENT_READABLE , 0 );
1014+ }
1015+ END_TEST
1016+
1017+ START_TEST (test_tcp_listen_accepts_bound_interface )
1018+ {
1019+ struct wolfIP s ;
1020+ const ip4 primary_ip = 0xC0A80002U ;
1021+ const ip4 secondary_ip = 0xC0A80101U ;
1022+ const uint16_t listen_port = 23456 ;
1023+ int listen_fd ;
1024+ int client_fd ;
1025+ struct wolfIP_sockaddr_in addr ;
1026+ struct tsocket * listener ;
1027+ struct tsocket * client ;
1028+
1029+ setup_stack_with_two_ifaces (& s , primary_ip , secondary_ip );
1030+
1031+ listen_fd = wolfIP_sock_socket (& s , AF_INET , IPSTACK_SOCK_STREAM , 0 );
1032+ ck_assert_int_ge (listen_fd , 0 );
1033+ listener = & s .tcpsockets [listen_fd & ~MARK_TCP_SOCKET ];
1034+
1035+ memset (& addr , 0 , sizeof (addr ));
1036+ addr .sin_family = AF_INET ;
1037+ addr .sin_port = ee16 (listen_port );
1038+ addr .sin_addr .s_addr = ee32 (secondary_ip );
1039+ ck_assert_int_eq (wolfIP_sock_bind (& s , listen_fd , (struct wolfIP_sockaddr * )& addr , sizeof (addr )), 0 );
1040+ ck_assert_int_eq (wolfIP_sock_listen (& s , listen_fd , 1 ), 0 );
1041+
1042+ inject_tcp_syn (& s , TEST_SECOND_IF , secondary_ip , listen_port );
1043+
1044+ ck_assert_int_eq (listener -> sock .tcp .state , TCP_SYN_RCVD );
1045+ ck_assert_uint_eq (listener -> local_ip , secondary_ip );
1046+ ck_assert_uint_eq (listener -> if_idx , TEST_SECOND_IF );
1047+
1048+ client_fd = wolfIP_sock_accept (& s , listen_fd , NULL , NULL );
1049+ ck_assert_int_ge (client_fd , 0 );
1050+ client = & s .tcpsockets [client_fd & ~MARK_TCP_SOCKET ];
1051+ ck_assert_uint_eq (client -> local_ip , secondary_ip );
1052+ ck_assert_uint_eq (client -> bound_local_ip , secondary_ip );
1053+ ck_assert_int_eq (client -> sock .tcp .state , TCP_ESTABLISHED );
1054+ }
1055+ END_TEST
1056+
1057+ START_TEST (test_tcp_listen_accepts_any_interface )
1058+ {
1059+ struct wolfIP s ;
1060+ const ip4 primary_ip = 0xC0A80005U ;
1061+ const ip4 secondary_ip = 0xC0A80105U ;
1062+ const uint16_t listen_port = 34567 ;
1063+ int listen_fd ;
1064+ int client_fd ;
1065+ struct wolfIP_sockaddr_in addr ;
1066+ struct tsocket * listener ;
1067+ struct tsocket * client ;
1068+
1069+ setup_stack_with_two_ifaces (& s , primary_ip , secondary_ip );
1070+
1071+ listen_fd = wolfIP_sock_socket (& s , AF_INET , IPSTACK_SOCK_STREAM , 0 );
1072+ ck_assert_int_ge (listen_fd , 0 );
1073+ listener = & s .tcpsockets [listen_fd & ~MARK_TCP_SOCKET ];
1074+
1075+ memset (& addr , 0 , sizeof (addr ));
1076+ addr .sin_family = AF_INET ;
1077+ addr .sin_port = ee16 (listen_port );
1078+ addr .sin_addr .s_addr = ee32 (IPADDR_ANY );
1079+ ck_assert_int_eq (wolfIP_sock_bind (& s , listen_fd , (struct wolfIP_sockaddr * )& addr , sizeof (addr )), 0 );
1080+ ck_assert_int_eq (wolfIP_sock_listen (& s , listen_fd , 1 ), 0 );
1081+
1082+ inject_tcp_syn (& s , TEST_SECOND_IF , secondary_ip , listen_port );
1083+
1084+ ck_assert_int_eq (listener -> sock .tcp .state , TCP_SYN_RCVD );
1085+ ck_assert_uint_eq (listener -> local_ip , secondary_ip );
1086+ ck_assert_uint_eq (listener -> if_idx , TEST_SECOND_IF );
1087+
1088+ client_fd = wolfIP_sock_accept (& s , listen_fd , NULL , NULL );
1089+ ck_assert_int_ge (client_fd , 0 );
1090+ client = & s .tcpsockets [client_fd & ~MARK_TCP_SOCKET ];
1091+ ck_assert_uint_eq (client -> local_ip , secondary_ip );
1092+ ck_assert_int_eq (client -> sock .tcp .state , TCP_ESTABLISHED );
1093+ }
1094+ END_TEST
1095+
1096+ START_TEST (test_sock_connect_selects_local_ip_multi_if )
1097+ {
1098+ struct wolfIP s ;
1099+ const ip4 primary_ip = 0xC0A80009U ;
1100+ const ip4 secondary_ip = 0xC0A80109U ;
1101+ const ip4 remote_primary = 0xC0A800AAU ;
1102+ const ip4 remote_secondary = 0xC0A801A1U ;
1103+ int udp_fd ;
1104+ int tcp_fd ;
1105+ struct wolfIP_sockaddr_in dst ;
1106+ struct tsocket * ts ;
1107+ int ret ;
1108+
1109+ setup_stack_with_two_ifaces (& s , primary_ip , secondary_ip );
1110+
1111+ udp_fd = wolfIP_sock_socket (& s , AF_INET , IPSTACK_SOCK_DGRAM , 0 );
1112+ ck_assert_int_ge (udp_fd , 0 );
1113+ memset (& dst , 0 , sizeof (dst ));
1114+ dst .sin_family = AF_INET ;
1115+ dst .sin_port = ee16 (5555 );
1116+ dst .sin_addr .s_addr = ee32 (remote_secondary );
1117+ ck_assert_int_eq (wolfIP_sock_connect (& s , udp_fd , (struct wolfIP_sockaddr * )& dst , sizeof (dst )), 0 );
1118+ ts = & s .udpsockets [udp_fd & ~MARK_UDP_SOCKET ];
1119+ ck_assert_uint_eq (ts -> local_ip , secondary_ip );
1120+ ck_assert_uint_eq (ts -> if_idx , TEST_SECOND_IF );
1121+
1122+ tcp_fd = wolfIP_sock_socket (& s , AF_INET , IPSTACK_SOCK_STREAM , 0 );
1123+ ck_assert_int_ge (tcp_fd , 0 );
1124+ memset (& dst , 0 , sizeof (dst ));
1125+ dst .sin_family = AF_INET ;
1126+ dst .sin_port = ee16 (8080 );
1127+ dst .sin_addr .s_addr = ee32 (remote_primary );
1128+ ret = wolfIP_sock_connect (& s , tcp_fd , (struct wolfIP_sockaddr * )& dst , sizeof (dst ));
1129+ ck_assert_int_eq (ret , - WOLFIP_EAGAIN );
1130+ ts = & s .tcpsockets [tcp_fd & ~MARK_TCP_SOCKET ];
1131+ ck_assert_uint_eq (ts -> local_ip , primary_ip );
1132+ ck_assert_uint_eq (ts -> if_idx , TEST_PRIMARY_IF );
1133+ }
1134+ END_TEST
1135+
9371136
9381137// Test for `transport_checksum` calculation
9391138START_TEST (test_transport_checksum ) {
@@ -1136,6 +1335,14 @@ Suite *wolf_suite(void)
11361335 suite_add_tcase (s , tc_proto );
11371336 tcase_add_test (tc_proto , test_loopback_dest_not_forwarded );
11381337 suite_add_tcase (s , tc_proto );
1338+ tcase_add_test (tc_proto , test_tcp_listen_rejects_wrong_interface );
1339+ suite_add_tcase (s , tc_proto );
1340+ tcase_add_test (tc_proto , test_tcp_listen_accepts_bound_interface );
1341+ suite_add_tcase (s , tc_proto );
1342+ tcase_add_test (tc_proto , test_tcp_listen_accepts_any_interface );
1343+ suite_add_tcase (s , tc_proto );
1344+ tcase_add_test (tc_proto , test_sock_connect_selects_local_ip_multi_if );
1345+ suite_add_tcase (s , tc_proto );
11391346
11401347 tcase_add_test (tc_utils , test_transport_checksum );
11411348 suite_add_tcase (s , tc_proto );
0 commit comments