t_stat udp_create (DEVICE *dptr, char *premote, int32 *pln) { // Create a logical UDP link to the specified remote system. The "remote" // string specifies both the remote host name or IP and a port number. The // port number is both the port we send datagrams to, and also the port we // listen on for incoming datagrams. UDP doesn't have any real concept of a // "connection" of course, and this routine simply creates the necessary // sockets in this host. We have no way of knowing whether the remote host is // listening or even if it exists. // // We return SCPE_OK if we're successful and an error code if we aren't. If // we are successful, then the ln parameter is assigned the link number, // which is a handle used to identify this connection to all future udp_xyz() // calls. t_stat ret; int32 link = udp_find_free_link(); if (link < 0) return SCPE_MEM; // Make sure WINSOCK is initialized ... if ((ret = udp_startup(dptr)) != SCPE_OK) return ret; // Parse the remote name and set up the ipaddr and port ... if ((ret = udp_parse_remote(link, premote)) != SCPE_OK) return ret; // Create the sockets for the transmitter and receiver ... if ((ret = udp_create_rx_socket(link)) != SCPE_OK) return ret; if ((ret = udp_create_tx_socket(link)) != SCPE_OK) return ret; // All done - mark the TCP_LINK data as "used" and return the index. udp_links[link].used = TRUE; *pln = link; sim_debug(IMP_DBG_UDP, dptr, "link %d - listening on port %d and sending to %s\n", link, udp_links[link].rxport, udp_format_remote(link)); return SCPE_OK; }
int udp_create (char * premote, int * pln) { int rc; // Create a logical UDP link to the specified remote system. The "remote" // string specifies both the remote host name or IP and a port number. The // port number is both the port we send datagrams to, and also the port we // listen on for incoming datagrams. UDP doesn't have any real concept of a // "connection" of course, and this routine simply creates the necessary // sockets in this host. We have no way of knowing whether the remote host is // listening or even if it exists. // // We return SCPE_OK if we're successful and an error code if we aren't. If // we are successful, then the ln parameter is assigned the link number, // which is a handle used to identify this connection to all future udp_xyz() // calls. int link = udp_find_free_link (); if (link < 0) return -1; // out of links // Parse the remote name and set up the ipaddr and port ... if (udp_parse_remote (link, premote) != 0) return -2; #if 0 // Create the socket connection to the destination ... sprintf(linkinfo, "Buffer=%d,Line=%d,%s,UDP,Connect=%s", (int)(sizeof(UDP_PACKET)+sizeof(int32_t)), link, udp_links[link].lport, udp_links[link].rhostport); ret = tmxr_open_master (&udp_tmxr, linkinfo); if (ret != SCPE_OK) return ret; #endif int sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock == -1) return -3; rc = fcntl (sock, F_SETFL, fcntl (sock, F_GETFL, 0) | O_NONBLOCK); if (sock == -1) return -4; struct sockaddr_in si_me; memset ((char *) & si_me, 0, sizeof (si_me)); si_me . sin_family = AF_INET; si_me . sin_port = udp_links [link] . lportno; si_me . sin_addr . s_addr = INADDR_ANY; rc = bind (sock, (struct sockaddr *) & si_me, sizeof (si_me)); if (rc == -1) return -5; // As I understand it, a connect on UDP sets the send address and limits // recieving to the specifed address; creating a 'connection'; I am not // sure the udplib wants that. The alternative is to use sendto(). struct addrinfo * ai; rc = getaddrinfo (udp_links [link] . rhost, udp_links [link] . rport, NULL, & ai); if (rc == -1) return -6; rc = connect (sock, ai -> ai_addr, sizeof (struct sockaddr)); if (rc == -1) return -7; freeaddrinfo (ai); udp_links [link] . sock = sock; // All done - mark the TCP_LINK data as "used" and return the index. udp_links [link] . used = true; * pln = link; printf ("link %d - listening on port %s and sending to %s:%s\n", link, udp_links [link] . lport, udp_links [link] . rhost, udp_links [link] . rport); return 0; }