]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/blob - test/unit/etharp/test_etharp.c
7eedc764971459dd5104250771a78a95798d6fd1
[pes-rpp/rpp-lwip.git] / test / unit / etharp / test_etharp.c
1 #include "test_etharp.h"
2
3 #include "lwip/udp.h"
4 #include "netif/etharp.h"
5 #include "lwip/stats.h"
6
7 #if !LWIP_STATS || !UDP_STATS || !MEMP_STATS || !ETHARP_STATS
8 #error "This tests needs UDP-, MEMP- and ETHARP-statistics enabled"
9 #endif
10 #if !ETHARP_SUPPORT_STATIC_ENTRIES
11 #error "This test needs ETHARP_SUPPORT_STATIC_ENTRIES enabled"
12 #endif
13
14 static struct netif test_netif;
15 static ip_addr_t test_ipaddr, test_netmask, test_gw;
16 struct eth_addr test_ethaddr = {1,1,1,1,1,1};
17 struct eth_addr test_ethaddr2 = {1,1,1,1,1,2};
18 struct eth_addr test_ethaddr3 = {1,1,1,1,1,3};
19 struct eth_addr test_ethaddr4 = {1,1,1,1,1,4};
20 static int linkoutput_ctr;
21
22 /* Helper functions */
23 static void
24 etharp_remove_all(void)
25 {
26   int i;
27   /* call etharp_tmr often enough to have all entries cleaned */
28   for(i = 0; i < 0xff; i++) {
29     etharp_tmr();
30   }
31 }
32
33 static err_t
34 default_netif_linkoutput(struct netif *netif, struct pbuf *p)
35 {
36   fail_unless(netif == &test_netif);
37   fail_unless(p != NULL);
38   linkoutput_ctr++;
39   return ERR_OK;
40 }
41
42 static err_t
43 default_netif_init(struct netif *netif)
44 {
45   fail_unless(netif != NULL);
46   netif->linkoutput = default_netif_linkoutput;
47   netif->output = etharp_output;
48   netif->mtu = 1500;
49   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
50   netif->hwaddr_len = ETHARP_HWADDR_LEN;
51   return ERR_OK;
52 }
53
54 static void
55 default_netif_add(void)
56 {
57   IP4_ADDR(&test_gw, 192,168,0,1);
58   IP4_ADDR(&test_ipaddr, 192,168,0,1);
59   IP4_ADDR(&test_netmask, 255,255,0,0);
60
61   fail_unless(netif_default == NULL);
62   netif_set_default(netif_add(&test_netif, &test_ipaddr, &test_netmask,
63                               &test_gw, NULL, default_netif_init, NULL));
64   netif_set_up(&test_netif);
65 }
66
67 static void
68 default_netif_remove(void)
69 {
70   fail_unless(netif_default == &test_netif);
71   netif_remove(&test_netif);
72 }
73
74 static void
75 create_arp_response(ip_addr_t *adr)
76 {
77   int k;
78   struct eth_hdr *ethhdr;
79   struct etharp_hdr *etharphdr;
80   struct pbuf *p = pbuf_alloc(PBUF_RAW, sizeof(struct eth_hdr) + sizeof(struct etharp_hdr), PBUF_RAM);
81   if(p == NULL) {
82     FAIL_RET();
83   }
84   ethhdr = (struct eth_hdr*)p->payload;
85   etharphdr = (struct etharp_hdr*)(ethhdr + 1);
86
87   ethhdr->dest = test_ethaddr;
88   ethhdr->src = test_ethaddr2;
89   ethhdr->type = htons(ETHTYPE_ARP);
90
91   etharphdr->hwtype = htons(/*HWTYPE_ETHERNET*/ 1);
92   etharphdr->proto = htons(ETHTYPE_IP);
93   etharphdr->_hwlen_protolen = htons((ETHARP_HWADDR_LEN << 8) | sizeof(ip_addr_t));
94   etharphdr->opcode = htons(ARP_REPLY);
95
96   SMEMCPY(&etharphdr->sipaddr, adr, sizeof(ip_addr_t));
97   SMEMCPY(&etharphdr->dipaddr, &test_ipaddr, sizeof(ip_addr_t));
98
99   k = 6;
100   while(k > 0) {
101     k--;
102     /* Write the ARP MAC-Addresses */
103     etharphdr->shwaddr.addr[k] = test_ethaddr2.addr[k];
104     etharphdr->dhwaddr.addr[k] = test_ethaddr.addr[k];
105     /* Write the Ethernet MAC-Addresses */
106     ethhdr->dest.addr[k] = test_ethaddr.addr[k];
107     ethhdr->src.addr[k]  = test_ethaddr2.addr[k];
108   }
109
110   ethernet_input(p, &test_netif);
111 }
112
113 /* Setups/teardown functions */
114
115 static void
116 etharp_setup(void)
117 {
118   etharp_remove_all();
119   default_netif_add();
120 }
121
122 static void
123 etharp_teardown(void)
124 {
125   etharp_remove_all();
126   default_netif_remove();
127 }
128
129
130 /* Test functions */
131
132 START_TEST(test_etharp_table)
133 {
134 #if ETHARP_SUPPORT_STATIC_ENTRIES
135   err_t err;
136 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
137   s8_t idx;
138   ip_addr_t *unused_ipaddr;
139   struct eth_addr *unused_ethaddr;
140   struct udp_pcb* pcb;
141   LWIP_UNUSED_ARG(_i);
142
143   if (netif_default != &test_netif) {
144     fail("This test needs a default netif");
145   }
146
147   linkoutput_ctr = 0;
148
149   pcb = udp_new();
150   fail_unless(pcb != NULL);
151   if (pcb != NULL) {
152     ip_addr_t adrs[ARP_TABLE_SIZE + 2];
153     int i;
154     for(i = 0; i < ARP_TABLE_SIZE + 2; i++) {
155       IP4_ADDR(&adrs[i], 192,168,0,i+2);
156     }
157     /* fill ARP-table with dynamic entries */
158     for(i = 0; i < ARP_TABLE_SIZE; i++) {
159       struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM);
160       fail_unless(p != NULL);
161       if (p != NULL) {
162         err_t err = udp_sendto(pcb, p, &adrs[i], 123);
163         fail_unless(err == ERR_OK);
164         /* etharp request sent? */
165         fail_unless(linkoutput_ctr == (2*i) + 1);
166         pbuf_free(p);
167
168         /* create an ARP response */
169         create_arp_response(&adrs[i]);
170         /* queued UDP packet sent? */
171         fail_unless(linkoutput_ctr == (2*i) + 2);
172
173         idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr);
174         fail_unless(idx == i);
175         etharp_tmr();
176       }
177     }
178     linkoutput_ctr = 0;
179 #if ETHARP_SUPPORT_STATIC_ENTRIES
180     /* create one static entry */
181     err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE], &test_ethaddr3);
182     fail_unless(err == ERR_OK);
183     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
184     fail_unless(idx == 0);
185     fail_unless(linkoutput_ctr == 0);
186 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
187
188     linkoutput_ctr = 0;
189     /* fill ARP-table with dynamic entries */
190     for(i = 0; i < ARP_TABLE_SIZE; i++) {
191       struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM);
192       fail_unless(p != NULL);
193       if (p != NULL) {
194         err_t err = udp_sendto(pcb, p, &adrs[i], 123);
195         fail_unless(err == ERR_OK);
196         /* etharp request sent? */
197         fail_unless(linkoutput_ctr == (2*i) + 1);
198         pbuf_free(p);
199
200         /* create an ARP response */
201         create_arp_response(&adrs[i]);
202         /* queued UDP packet sent? */
203         fail_unless(linkoutput_ctr == (2*i) + 2);
204
205         idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr);
206         if (i < ARP_TABLE_SIZE - 1) {
207           fail_unless(idx == i+1);
208         } else {
209           /* the last entry must not overwrite the static entry! */
210           fail_unless(idx == 1);
211         }
212         etharp_tmr();
213       }
214     }
215 #if ETHARP_SUPPORT_STATIC_ENTRIES
216     /* create a second static entry */
217     err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE+1], &test_ethaddr4);
218     fail_unless(err == ERR_OK);
219     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
220     fail_unless(idx == 0);
221     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
222     fail_unless(idx == 2);
223     /* and remove it again */
224     err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE+1]);
225     fail_unless(err == ERR_OK);
226     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
227     fail_unless(idx == 0);
228     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
229     fail_unless(idx == -1);
230 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
231
232     /* check that static entries don't time out */
233     etharp_remove_all();
234     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
235     fail_unless(idx == 0);
236
237 #if ETHARP_SUPPORT_STATIC_ENTRIES
238     /* remove the first static entry */
239     err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE]);
240     fail_unless(err == ERR_OK);
241     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
242     fail_unless(idx == -1);
243     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
244     fail_unless(idx == -1);
245 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
246
247     udp_remove(pcb);
248   }
249 }
250 END_TEST
251
252
253 /** Create the suite including all tests for this module */
254 Suite *
255 etharp_suite(void)
256 {
257   TFun tests[] = {
258     test_etharp_table,
259   };
260   return create_suite("ETHARP", tests, sizeof(tests)/sizeof(TFun), etharp_setup, etharp_teardown);
261 }