Why am I getting Debug assertion failed after strcpy_s? - c++

im just starting to learn about sockets and i have been given this code, and i have to make the port lookup logic work. But the problem is i keep getting this run time error and I dont know why?
// portlookup.cpp
// Given a service name, this program displays the corresponding port number.
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
using namespace std;
int main (int argc, char **argv)
{
char service[80]; // This string contains name of desired service
struct servent *pse; // pointer to service information entry
short port; // Port # (in Network Byte Order) of desired service
if (argc < 2)
{
cout << "Please specify a service." << endl;
}
strcpy_s(service, sizeof(service), argv[1]);
WORD wVersion = 0x0202;
WSADATA wsaData;
int iResult = WSAStartup(wVersion, &wsaData); // Returns zero if successful
if (iResult != 0) {
cout << "Insufficient resources to startup WINSOCK." << endl;
return 0;
}
port = htons( (u_short) atoi(service)); // 1st try to convert string to integer
if (port == 0) { // if that doesn't work, call service function
pse = getservbyname(service,NULL);
if (pse) {
port = pse->s_port;
}
else
{
cout << "Invalid service request." << endl;
return INVALID_SOCKET;
}
}
cout << "Service: " << service << endl;
cout << "Port: " << htons(port) << endl;
}

Your problem appears to be that you aren't passing a command line, you check argc < 2, but when it is < 2 you execute the strcpy_s anyway.
In Visual Studio, Got to the Project Properties dialog, from there go to the Debugging page
and add the service name to Command Arguments
And fix your argument checking code
if (argc < 2)
{
//cout << "Please specify a service." << endl;
cerr << "error: no service specified." << endl;
return EXIT_FAILURE; // return some non-zero value to indicate failure.
}

You need to start your program with an argument. The line strcpy_s(service, sizeof(service),argv[1]); assumes you've given the program 1 argument, which will be stored in argv[1].
If you don't run it with any arguments, argv[1] will be NULL and your program will crash.

Make sure to exit if no parameter is specified.
if (argc < 2)
{
cout << "Please specify a service." << endl;
return 0; // exit!
}

also,
port = htons( (u_short) atoi(service));
...
cout << htons(port);

Related

Memory access violation error c++

I'm trying to exchange messages using multiple covert channels.
So, basically, first i need to select the channel that i want to use for communication and then select the "destination_ip" of the user that i want to chat with and after that the
processMessage()
is called. Now, to move from one channel to another I have to close the existing connection and then open a new connection with the new channel that i want to use. My code below is modified to keep using the same channel after closing the connection and contain only the things that you need.
#include <channelmanager.hpp>
#include <thread>
#include <iostream>
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <openssl/hmac.h>
struct CommunicationFixture {
CommunicationFixture() {
channelmanager.setErrorStream(&cout);
channelmanager.setOutputStream(&cout);
destination_ip = "";
channel_id = channelmanager.getChannelIDs()[0];
}
library::ChannelManager channelmanager;
vector<string> last_adapters;
string destination_ip;
string channel_id = "";
int processMessage(string message) {
if (message.compare("exit") == 0) {
channelmanager.closeConnection(destination_ip);
return 1;
}
vector<string> arguments;
boost::split(arguments, message, boost::is_any_of(" "), boost::token_compress_on);
if (arguments[0].compare("argument") == 0) {
if (arguments.size() < 2) {
cout << "Not enough arguments" << endl;
return 0;
}
string argument_list = arguments[1];
for (unsigned int i = 2; i < arguments.size(); i++) {
argument_list += " " + arguments[i];
}
channelmanager.setChannelArguments(destination_ip, argument_list);
cout << "Set channel argument to '" << argument_list << "'." << endl;
return 0;
}
if (message.compare("help") == 0) {
cout << "Help not available in chat mode. Close chat first with 'exit'" << endl;
return 0;
}
channelmanager.openConnection(destination_ip, channel_id);
channelmanager.sendMessage(destination_ip, message);
return 0;
}
int close(string destination){
cout << "closing.." << endl;
channelmanager.closeConnection(destination); //I believe i have the error because of this!
return 0;
}
};
BOOST_FIXTURE_TEST_SUITE(communication, CommunicationFixture)
BOOST_AUTO_TEST_CASE(basic_communication) {
selectAdapterId(0);
cout << "Test" << endl << endl;
printCommands();
cout << "Enter your command:" << endl;
string command;
int code = 0;
while (code != 2) {
std::getline(cin, command);
code = processCommand(command);
if (code == 1) {
// chat
cout << "chat started.." << endl;
int chatCode = 0;
while (chatCode != 1) {
std::getline(cin, message);
close(destination_ip);
chatCode = processMessage(message);
channelmanager.setErrorStream(&cout);
}
cout << "chat ended." << endl;
}
}
}
BOOST_AUTO_TEST_SUITE_END()
Note that, i think that the error happens due to the
function close()
because without it i don't get any errors. and the error doesn't happen immediately but after exchanging some messages. Here's the error:
unknown location(0): fatal error: in
"communication/basic_communication": memory access violation at
address: 0x00000024: no mapping at fault address
communicationTest.cpp(325): last checkpoint: "basic_communication"
test entry
Memory access violation happen when you are trying to access to an unitialized variable, in this case the channelmanager.
I can only see that you initialize channelmanager in the processMessage() method and you are closing the connection before initializing the channelmanager as it happen in:
close(destination_ip);
chatCode = processMessage(message);
Either you change the initialization or do not close it before the processMessage() method.
Memory access violation is also called a segmentation fault (or segfault), occurs when the program tries to access a memory location that doesn't exist, or is otherwise inaccessible. We call this trying to access an illegal memory location. That memory is either non-existent or we aren't aren't allowed to touch it.
If the first input from user is 'exit', which is going to call
if (message.compare("exit") == 0) {
channelmanager.closeConnection(destination_ip);
return 1;
}
In this case, destination_ip isn't initialised.

How do I receive data from NTP server?

I have no idea why send data is 48 bytes 010,0,0..., someone can explain? the problem is buffer for data received, I don't know how big he should be, and even if I receive data, how to make normal time from it?
Here's the code:
#include <iostream>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_MEAN_AND_LEAN
#include <winsock2.h>
#include <windows.h>
#include <time.h>
using namespace std;
class HRException
{
public:
HRException() :
m_pMessage("") {}
virtual ~HRException() {}
HRException(const char *pMessage) :
m_pMessage(pMessage) {}
const char * what() { return m_pMessage; }
private:
const char *m_pMessage;
};
const int REQ_WINSOCK_VER = 2; // Minimum winsock version required
const char DEF_SERVER_NAME[] = "0.pl.pool.ntp.org";
const int SERVER_PORT = 123;
const int TEMP_BUFFER_SIZE = 128;
const char msg[48] = { 010,0,0,0,0,0,0,0,0 };
// IP number typedef for IPv4
typedef unsigned long IPNumber;
IPNumber FindHostIP(const char *pServerName)
{
HOSTENT *pHostent;
// Get hostent structure for hostname:
if (!(pHostent = gethostbyname(pServerName)))
throw HRException("could not resolve hostname.");
// Extract primary IP address from hostent structure:
if (pHostent->h_addr_list && pHostent->h_addr_list[0])
return *reinterpret_cast<IPNumber*>(pHostent->h_addr_list[0]);
return 0;
}
void FillSockAddr(sockaddr_in *pSockAddr, const char *pServerName, int portNumber)
{
// Set family, port and find IP
pSockAddr->sin_family = AF_INET;
pSockAddr->sin_port = htons(portNumber);
pSockAddr->sin_addr.S_un.S_addr = FindHostIP(pServerName);
}
bool RequestHeaders(const char *pServername)
{
SOCKET hSocket = INVALID_SOCKET;
char tempBuffer[TEMP_BUFFER_SIZE];
sockaddr_in sockAddr = { 0 };
bool bSuccess = true;
try
{
// Lookup hostname and fill sockaddr_in structure:
cout << "Looking up hostname " << pServername << "... ";
FillSockAddr(&sockAddr, pServername, SERVER_PORT);
cout << "found.\n";
// Create socket
cout << "Creating socket... ";
if ((hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
throw HRException("could not create socket.");
cout << "created.\n";
// Connect to server
cout << "Attempting to connect to " << inet_ntoa(sockAddr.sin_addr)
<< ":" << SERVER_PORT << "... ";
if (connect(hSocket, reinterpret_cast<sockaddr*>(&sockAddr), sizeof(sockAddr)) != 0)
throw HRException("could not connect.");
cout << "connected.\n";
cout << "Sending request... ";
// send request part 1
if (send(hSocket, msg, sizeof(msg) , 0) == SOCKET_ERROR)
throw HRException("failed to send data.");
cout << "request sent.\n";
cout << "Dumping received data...\n\n";
// Loop to print all data
recv(hSocket, tempBuffer, sizeof(tempBuffer), 0); // <-- the problem
///
//part where we take time out of tempBuffer
///
}
catch (HRException e)
{
cerr << "\nError: " << e.what() << endl;
bSuccess = false;
}
if (hSocket != INVALID_SOCKET)
{
closesocket(hSocket);
}
return bSuccess;
}
int main(int argc, char* argv[])
{
int iRet = 1;
WSADATA wsaData;
cout << "Initializing winsock... ";
if (WSAStartup(MAKEWORD(REQ_WINSOCK_VER, 0), &wsaData) == 0)
{
// Check if major version is at least REQ_WINSOCK_VER
if (LOBYTE(wsaData.wVersion) >= REQ_WINSOCK_VER)
{
cout << "initialized.\n";
// Set default hostname:
const char *pHostname = DEF_SERVER_NAME;
// Set custom hostname if given on the commandline:
if (argc > 1)
pHostname = argv[1];
iRet = !RequestHeaders(pHostname);
}
else
{
cerr << "required version not supported!";
}
cout << "Cleaning up winsock... ";
// Cleanup winsock
if (WSACleanup() != 0)
{
cerr << "cleanup failed!\n";
iRet = 1;
}
cout << "done.\n";
}
else
{
cerr << "startup failed!\n";
}
int x;
cin >> x;
return iRet;
}
Most part of code is from madwizard.org
Ok it works, main part of code:
const char msg[48] = { 010,0,0,0,0,0,0,0,0 };
if (send(hSocket, msg, sizeof(msg) , 0) == SOCKET_ERROR)
throw HRException("failed to send data.");
cout << "request sent.\n";
cout << "Dumping received data...\n\n";
char tempBuffer[1024];
int bytes = recv(hSocket, tempBuffer, sizeof(tempBuffer), 0);
cout << "bytes received: " << bytes << endl;
time_t tmit;
tmit = ntohl(((time_t*)tempBuffer)[4]);
tmit -= 2208988800U;
cout << ctime(&tmit);
No idea why data that we send is
msg[48] = { 010,0,0,0,0,0,0,0,0 };
and why received data contains many numbers? for example if change code to
tmit = ntohl(((time_t*)tempBuffer)[6]);
I will get date 2008y, why?
Guys why so many minuses?, still waiting for an explanation :D
Here's whole code http://pastebin.com/Sv3ERGfV , dont forget to link ws2_32.lib
Similar to my issue when trying to query the time from a self-hostet Windows-NTP-Server with the C++ library NTPClient which uses boost for the network tasks, msg[48] = { 010,0,0,0,0,0,0,0,0 }; configures the ntp.flags.mode. After comparing the network traffic of w32tm /stripchart /computer:10.159.96.65 using Wireshark, flag 27 or 11 seem to be the choices for my usecase:
Comparison of NTP network packages
tmit = ntohl(((time_t*)tempBuffer)[6]); extracts the data from the received package. It looks like
4 yields the reference time (last sync with timeserver I assume),
8 the time when server received request and
10 the transmit time (which should be almost equal).

Why this WinSock code is not connecting to client?

I am new to Winsock programming and came across this code while reading the book "Network Programming For Microsoft Windows " . But it seems that this code is not able to connect to the client. Please tell me how can I fix this problem .
My Server Code :
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main(){
WSADATA wsadata;
int ret;
if ((ret = WSAStartup(MAKEWORD(2, 2), &wsadata)) != 0){
cout << "Wsastartup failed" << endl;
}
else{
cout << "connection made successfully" << endl;
}
SOCKET ListeningSocket, NewConnection;
SOCKADDR_IN ServerAddr, ClientAddr;
int port = 80;
ListeningSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(port);
inet_pton(ServerAddr.sin_family,"127.0.0.1",&ServerAddr.sin_addr.s_addr);
int res= bind(ListeningSocket,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr));
if (res == SOCKET_ERROR){
cout << "binding failed" << endl;
}
res = listen(ListeningSocket,5);
if (res == SOCKET_ERROR){
cout << "Listening failed" << endl;
}
int c = 1;
NewConnection= accept(ListeningSocket,(SOCKADDR*)&ClientAddr,&c);
if (NewConnection == INVALID_SOCKET){
cout << "COULD not CONNECT TO CLIENT . err code : "<<WSAGetLastError() << endl;
}
closesocket(ListeningSocket);
if (WSACleanup() == SOCKET_ERROR){
cout << "WSACleanup failed with error : " << WSAGetLastError() << endl;
}
else{
cout << "WinSock data cleaned successfully" << endl;
}
cin.get();
}
On running this code , it shows "COULD not CONNECT TO CLIENT. err code 10014" .
I've found this Description of the error code on windows dev center :
Bad address.
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).
How can I fix this error ?
When you call accept, the variable that the third parameter points to needs to hold the size of the buffer the second parameter points to. (When accept returns, it will hold the amount of space actually used)
In your code, change:
int c = 1;
to
int c = sizeof(ClientAddr);

editing tcp client/server to create reverse polish notation calculator server [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am trying to create a reverse polish notation calculator server, I was given the source code for a client and server "see below" and asked to modify it to create the server. i have an idea on how to go about creating the calculator but where do i insert my calculator code in this exisiting server source code. or does it go into the existing client source code.
client source code:
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <iostream>
#include <cstring>
#include <stdlib.h>
#define MAX_LINE 100
#define LINE_ARRAY_SIZE (MAX_LINE+1)
using namespace std;
int main()
{
int socketDescriptor;
unsigned short int serverPort;
struct sockaddr_in serverAddress;
struct hostent *hostInfo;
char buf[LINE_ARRAY_SIZE], c;
cout << "Enter server host name or IP address: ";
cin.get(buf, MAX_LINE, '\n');
// gethostbyname() takes a host name or ip address in "numbers and
// dots" notation, and returns a pointer to a hostent structure,
// which we'll need later. It's not important for us what this
// structure is actually composed of.
hostInfo = gethostbyname(buf);
if (hostInfo == NULL) {
cout << "problem interpreting host: " << buf << "\n";
exit(1);
}
cout << "Enter server port number: ";
cin >> serverPort;
cin.get(c); // dispose of the newline
// Create a socket. "AF_INET" means it will use the IPv4 protocol.
// "SOCK_STREAM" means it will be a reliable connection (i.e., TCP;
// for UDP use SOCK_DGRAM), and I'm not sure what the 0 for the last
// parameter means, but it seems to work.
socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
if (socketDescriptor < 0) {
cerr << "cannot create socket\n";
exit(1);
}
// Connect to server. First we have to set some fields in the
// serverAddress structure. The system will assign me an arbitrary
// local port that is not in use.
serverAddress.sin_family = hostInfo->h_addrtype;
memcpy((char *) &serverAddress.sin_addr.s_addr,
hostInfo->h_addr_list[0], hostInfo->h_length);
serverAddress.sin_port = htons(serverPort);
if (connect(socketDescriptor,
(struct sockaddr *) &serverAddress,
sizeof(serverAddress)) < 0) {
cerr << "cannot connect\n";
exit(1);
}
cout << "\nEnter some lines, and the server will modify them and\n";
cout << "send them back. When you are done, enter a line with\n";
cout << "just a dot, and nothing else.\n";
cout << "If a line is more than " << MAX_LINE << " characters, then\n";
cout << "only the first " << MAX_LINE << " characters will be used.\n\n";
// Prompt the user for input, then read in the input, up to MAX_LINE
// charactars, and then dispose of the rest of the line, including
// the newline character.
cout << "Input: ";
cin.get(buf, MAX_LINE, '\n');
while (cin.get(c) && c != '\n')
;
// Stop when the user inputs a line with just a dot.
while (strcmp(buf, ".")) {
// Send the line to the server.
if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) {
cerr << "cannot send data ";
close(socketDescriptor);
exit(1);
}
// Zero out the buffer.
memset(buf, 0x0, LINE_ARRAY_SIZE);
// Read the modified line back from the server.
if (recv(socketDescriptor, buf, MAX_LINE, 0) < 0) {
cerr << "didn't get response from server?";
close(socketDescriptor);
exit(1);
}
cout << "Modified: " << buf << "\n";
// Prompt the user for input, then read in the input, up to MAX_LINE
// charactars, and then dispose of the rest of the line, including
// the newline character. As above.
cout << "Input: ";
cin.get(buf, MAX_LINE, '\n');
while (cin.get(c) && c != '\n')
;
}
close(socketDescriptor);
return 0;
}
server source code:
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <iostream>
#include <cstring>
#include <stdlib.h>
#define MAX_MSG 100
#define LINE_ARRAY_SIZE (MAX_MSG+1)
using namespace std;
int main()
{
int listenSocket, connectSocket, i;
unsigned short int listenPort;
socklen_t clientAddressLength;
struct sockaddr_in clientAddress, serverAddress;
char line[LINE_ARRAY_SIZE];
cout << "Enter port number to listen on (between 1500 and 65000): ";
cin >> listenPort;
// Create socket for listening for client connection requests.
listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket < 0) {
cerr << "cannot create listen socket";
exit(1);
}
// Bind listen socket to listen port. First set various fields in
// the serverAddress structure, then call bind().
// htonl() and htons() convert long integers and short integers
// (respectively) from host byte order (on x86 this is Least
// Significant Byte first) to network byte order (Most Significant
// Byte first).
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(listenPort);
if (bind(listenSocket,
(struct sockaddr *) &serverAddress,
sizeof(serverAddress)) < 0) {
cerr << "cannot bind socket";
exit(1);
}
// Wait for connections from clients.
// This is a non-blocking call; i.e., it registers this program with
// the system as expecting connections on this socket, and then
// this thread of execution continues on.
listen(listenSocket, 5);
while (1) {
cout << "Waiting for TCP connection on port " << listenPort << " ...\n";
// Accept a connection with a client that is requesting one. The
// accept() call is a blocking call; i.e., this thread of
// execution stops until a connection comes in.
// connectSocket is a new socket that the system provides,
// separate from listenSocket. We *could* accept more
// connections on listenSocket, before connectSocket is closed,
// but this program doesn't do that.
clientAddressLength = sizeof(clientAddress);
connectSocket = accept(listenSocket,
(struct sockaddr *) &clientAddress,
&clientAddressLength);
if (connectSocket < 0) {
cerr << "cannot accept connection ";
exit(1);
}
// Show the IP address of the client.
// inet_ntoa() converts an IP address from binary form to the
// standard "numbers and dots" notation.
cout << " connected to " << inet_ntoa(clientAddress.sin_addr);
// Show the client's port number.
// ntohs() converts a short int from network byte order (which is
// Most Significant Byte first) to host byte order (which on x86,
// for example, is Least Significant Byte first).
cout << ":" << ntohs(clientAddress.sin_port) << "\n";
// Read lines from socket, using recv(), storing them in the line
// array. If no messages are currently available, recv() blocks
// until one arrives.
// First set line to all zeroes, so we'll know where the end of
// the string is.
memset(line, 0x0, LINE_ARRAY_SIZE);
while (recv(connectSocket, line, MAX_MSG, 0) > 0) {
cout << " -- " << line << "\n";
// Convert line to upper case.
for (i = 0; line[i] != '\0'; i++)
line[i] = toupper(line[i]);
// Send converted line back to client.
if (send(connectSocket, line, strlen(line) + 1, 0) < 0)
cerr << "Error: cannot send modified data";
memset(line, 0x0, LINE_ARRAY_SIZE); // set line to all zeroes
}
}
}
while (recv(connectSocket, line, MAX_MSG, 0) > 0) {
//process line, so retrieve numbers, operation
//and call calculator(numbers, operation) and
//convert result to string result
// Send result back to client.
if (send(connectSocket, result, strlen(line) + 1, 0) < 0)
cerr << "Error: cannot send modified data";

getting an error associated with WSAIoctl

hey guys i have been trying to make a simple console application to see my network traffic :P im trying to just read it.
anyways im getting an error from the WSAIoctl function and the error code WSAGetLastError is giving me is 10022 and the MSDN tells me that it is associated with this:
Invalid argument.
Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function). In some instances, it also refers to the current state of the socket—for instance, calling accept on a socket that is not listening.
i have tried messing with the arguments without luck :/ please help me :P
here's my code:
WSADATA wsaData;
int startup = WSAStartup(0x0202, &wsaData);
if(startup != 0) {
cout << "Error: could not initalize WSADATA for target socket." << endl;
system("pause");
}
unsigned long BytesReturned;
int InBuffer, OutBuffer, LPCVoid;
int optValue = 1;
SOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
Sleep(await);
cout << "creating and configuring RAW_SOCK" << endl;
int listening = listen(sock, SOMAXCONN); // tried debugging using this.
int sockopt = setsockopt(sock, IPPROTO_IP, 2, (char*)&optValue, sizeof(optValue));
int SockMode = WSAIoctl(sock, SIO_RCVALL, &InBuffer, sizeof(InBuffer), &OutBuffer, sizeof(OutBuffer), &BytesReturned, NULL, NULL);
//0x98000001
if(SockMode == 0) {
Sleep(await);
cout << "RAW_SOCKET created successfully!" << endl << "Trying to listen for incoming network packets..." << endl;
int listeningk = listen(sock, SOMAXCONN);
if(listening == 0) {
Sleep(await);
cout << "socket listening without problems, looking for incoming request..." << endl;
}
else {
Sleep(await);
cout << "Error: could not listen on socket." << endl;
exit(EXIT_FAILURE);
}
}
else {
Sleep(await);
cout << "Error: could not create RAW_SOCKET..." << endl << "Dumping SockMode!\r\nint SockMode = " << SockMode << endl;
cout << "setsockopt = " << sockopt << endl;
cout << "WSAGetLastError: " << WSAGetLastError() << endl;
system("pause");
}
Your socket needs to be bound before you can listen. Moreover for this WSAIoctl option you have to obey (from the MSDN docs):
The socket also must be bound to an explicit local IPv4 or IPv6
interface, which means that you cannot bind to INADDR_ANY or
in6addr_any.
I'd suggest some basic self-education is in order before trying to progress this code. There are code samples for common ops like socket setup in MSDN.