Nut/OS  4.10.3
API Reference
icmp-udp.c
Go to the documentation of this file.
00001 
00068 #define MY_MAC          {0x00,0x06,0x98,0x20,0x00,0x00}
00069 #define MY_IP           "192.168.1.100"
00070 #define MY_MASK         "255.255.255.0"
00071 #define MY_GATE         "192.168.1.254"
00072 
00073 #define UDP_ECHO_IP     "192.168.1.103"
00074 #define UDP_ECHO_PORT   7
00075 
00076 #include <string.h>
00077 #include <stdio.h>
00078 #include <io.h>
00079 //#include <inttypes.h>
00080 #include <errno.h>
00081 
00082 #include <dev/board.h>
00083 
00084 #include <sys/thread.h>
00085 #include <sys/timer.h>
00086 #include <sys/socket.h>
00087 #include <sys/confnet.h>
00088 
00089 #include <arpa/inet.h>
00090 #include <net/route.h>
00091 
00092 #define UDP_BUFF_SIZE 256
00093 
00094 static char send_buffer[UDP_BUFF_SIZE];
00095 static char rcv_buffer[UDP_BUFF_SIZE];
00096 static uint8_t my_mac[] = MY_MAC;
00097 
00098 #ifdef DEV_ETHER
00099 
00100 /* Print error message */
00101 void print_udp_icmp_error(uint32_t remote_ip, uint16_t remote_port, int error)
00102 {
00103     printf("ICMP destination unreachable received for remote ip: %s\r\nremote port: %d, errno: %d -- ", 
00104            inet_ntoa(remote_ip), remote_port, error);
00105     
00106     switch (error) {
00107         case ENETUNREACH:
00108             printf("Destination network unreachable\r\n");
00109             break;
00110         case EHOSTUNREACH:
00111             printf("Destination host unreachable\r\n");
00112             break;
00113         case ENOPROTOOPT:
00114             printf("Destination protocol unreachable\r\n");
00115             break;
00116         case ECONNREFUSED:      
00117             printf("Destination port unreachable / connection refused\r\n");
00118             break;
00119         case EMSGSIZE:
00120             printf("Fragmentation required, and DF flag set\r\n");
00121             break;
00122         case EOPNOTSUPP:
00123             printf("Source route failed\r\n");
00124             break;
00125         case EHOSTDOWN:
00126             printf("Destination host unknown or down\r\n");
00127             break;
00128         default:
00129             printf("Other error\r\n");
00130     }
00131 }
00132 
00133 THREAD(UDPReceiver, arg)
00134 {
00135     uint32_t remote_ip;
00136     uint16_t remote_port;
00137     UDPSOCKET *socket = (UDPSOCKET*) arg;
00138     int      rc;
00139     
00140     while (1) {
00141         rc = NutUdpReceiveFrom(socket, &remote_ip, &remote_port, rcv_buffer, UDP_BUFF_SIZE, 2000);
00142         if (rc == 0) {
00143             printf("<-- Timeout (2 sec.) on UDP receive\r\n");
00144         } else 
00145         if (rc < 0) {
00146 #ifdef NUT_UDP_ICMP_SUPPORT             
00147             int error;
00148             error = NutUdpError(socket, &remote_ip, &remote_port);
00149             print_udp_icmp_error(remote_ip, remote_port, error);
00150 #endif            
00151         } else {
00152             printf("<-- Received packet: \"%s\"\r\n", rcv_buffer);
00153         }
00154     }
00155 }
00156 
00157 #endif /* DEV_ETHER */
00158 
00159 /*
00160  * Main application routine. 
00161  *
00162  */
00163 int main(void)
00164 {
00165     uint32_t baud = 115200;
00166     UDPSOCKET *socket;
00167 
00168     uint32_t ip_addr;
00169     uint32_t ip_udp_echo;
00170     int    rc;
00171     int    packet_nr;
00172     uint16_t length;
00173 
00174     /*
00175      * Initialize the uart device.
00176      */
00177     NutRegisterDevice(&DEV_CONSOLE, 0, 0);
00178     freopen(DEV_CONSOLE_NAME, "w", stdout);
00179     _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00180     puts("Demo for ICMP support in UDP sockets...\r\n");
00181 
00182 #ifdef DEV_ETHER
00183 #ifndef NUT_UDP_ICMP_SUPPORT
00184 #warning ICMP support for UDP sockets not enabled in the configurator, please enable NUT_UDP_ICMP_SUPPORT
00185     puts("ICMP support for UDP sockets not enabled in the configurator\r\n");
00186     puts("Please enable NUT_UDP_ICMP_SUPPORT\r\n");
00187 #endif    
00188     /*
00189      * Register the network device.
00190      */
00191     puts("Configuring Ethernet interface");
00192     NutRegisterDevice(&DEV_ETHER, 0, 0);
00193 
00194     ip_addr = inet_addr(MY_IP);
00195     NutNetIfConfig("eth0", my_mac, ip_addr, inet_addr(MY_MASK));
00196     NutIpRouteAdd(0, 0, inet_addr(MY_GATE), &DEV_ETHER);
00197 
00198     printf("%s ready\r\n", inet_ntoa(ip_addr));
00199 
00200 
00201     socket = NutUdpCreateSocket(UDP_ECHO_PORT);
00202     if (socket == 0) {
00203         printf("Could not create UDP socket in port '%d'\r\n", UDP_ECHO_PORT);
00204         puts("Demo halted...\r\n");
00205         while (1);
00206     } else {
00207         printf("Successfully created UDP socket on port '%d'\r\n", UDP_ECHO_PORT);
00208         length = UDP_BUFF_SIZE;
00209         if (NutUdpSetSockOpt(socket, SO_RCVBUF, &length, sizeof(length))) {;
00210             printf("Could not set UDP receive buffer size (%d)\r\n", length);
00211             puts("Demo halted...\r\n");
00212             while (1);
00213         }
00214     }
00215     
00216     if (NutThreadCreate("RCV", UDPReceiver, (void*)socket, 1024) == 0) {
00217             puts("Could not start receiver thread\r\n");
00218             puts("Demo halted...\r\n");
00219             while (1);
00220     } else {
00221         puts("Receiver thread started\r\n");
00222     }
00223     
00224     puts("Starting echo test (1 packet / second)\r\n");
00225     
00226     ip_udp_echo = inet_addr(UDP_ECHO_IP);
00227     packet_nr = 0;
00228     
00229     while (1) {
00230         packet_nr ++;
00231         sprintf(send_buffer, "Packet: %d", packet_nr);
00232         rc = NutUdpSendTo(socket, ip_udp_echo, UDP_ECHO_PORT, send_buffer, length);
00233         printf("--> Sended packet: \"%s\", to %s, rc: %d\r\n", send_buffer, inet_ntoa(ip_udp_echo), rc);
00234         if (rc < 0) {
00235 #ifdef NUT_UDP_ICMP_SUPPORT
00236             int      error;
00237             uint32_t remote_ip;
00238             uint16_t remote_port;             
00239             error = NutUdpError(socket, &remote_ip, &remote_port);
00240             print_udp_icmp_error(remote_ip, remote_port, error);
00241 #endif
00242         }
00243         
00244         NutSleep(1000);
00245     }
00246 #endif /* DEV_ETHER */
00247     return 0;
00248 }