uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
test_etharp.c
Go to the documentation of this file.
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;
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 
254 Suite *
256 {
257  TFun tests[] = {
258  test_etharp_table,
259  };
260  return create_suite("ETHARP", tests, sizeof(tests)/sizeof(TFun), etharp_setup, etharp_teardown);
261 }