I want extract payload from ICMP pakage, here a code from internet in linux (I'm on windows) but not work.
/*..........*/
char * data_re;
char buf[1024];
memset(buf, 0, sizeof(buf));
int nbytes = recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr *)&dest,&af);
if (nbytes < 0)
{return 0;}
if(nbytes > 0){
struct iphdr *ip;
icmph = NULL;
ip = (struct iphdr *) buf;
if (nbytes > sizeof(ip)) {
nbytes -= sizeof(ip);
icmph = (struct icmphdr *) ip + 1;
if (nbytes > sizeof(icmphdr)) {
nbytes -= sizeof(icmphdr);
data_re = (char *) (icmph + 1);
data_re[nbytes] = '\0';
printf("%s", data_re);
//fflush(stdout);
}
}
}
/*..........*/
Related
I'm trying to send udp packet using socket raw with special structure sockaddr_ll, but I'm getting only an ethernet header with trailer and ip header without udp header. I would like to send a normal udp packet without the trailer and get my message. I checked the package using wireshark. How can I fix this?
My packet:
My code:
int main(int argc, char *argv[])
{
int sockfd;
struct ifreq if_idx;
struct ifreq if_mac;
struct ifreq ifreq_ip;
int tx_len = 0;
unsigned char* sendbuf;
sendbuf=(unsigned char*)malloc(64);
memset(sendbuf,0,64);
struct ether_header *eh = (struct ether_header *) sendbuf;
struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header));
struct udphdr *uph = (struct udphdr *) (sendbuf + sizeof(struct ether_header) + sizeof(struct iphdr));
struct sockaddr_ll socket_address;
char ifName[IFNAMSIZ];
/* Get interface name */
if (argc > 1)
strcpy(ifName, argv[1]);
else
strcpy(ifName, DEFAULT_IF);
/* Open RAW socket to send on */
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) {
perror("socket");
}
/* Get the index of the interface to send on */
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
perror("SIOCGIFINDEX");
/* Get the MAC address of the interface to send on */
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
perror("SIOCGIFHWADDR");
/* get ip */
memset(&ifreq_ip,0,sizeof(ifreq_ip));
strncpy(ifreq_ip.ifr_name,ifName,IFNAMSIZ-1);
if(ioctl(sockfd,SIOCGIFADDR,&ifreq_ip)<0)
{
printf("error in SIOCGIFADDR \n");
}
/* Construct the Ethernet header */
/* Ethernet header */
eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
eh->ether_dhost[0] = MY_DEST_MAC0;
eh->ether_dhost[1] = MY_DEST_MAC1;
eh->ether_dhost[2] = MY_DEST_MAC2;
eh->ether_dhost[3] = MY_DEST_MAC3;
eh->ether_dhost[4] = MY_DEST_MAC4;
eh->ether_dhost[5] = MY_DEST_MAC5;
/* Ethertype field */
eh->ether_type = htons(ETH_P_IP);
tx_len += sizeof(struct ether_header);
/* ip header */
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = htons(sizeof (struct iphdr));
iph->id = htonl (54321); //Id of this packet
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = IPPROTO_UDP;
iph->check = 0;
iph->saddr = inet_addr(inet_ntoa((((struct sockaddr_in *)&(ifreq_ip.ifr_addr))->sin_addr)));
iph->daddr = inet_addr ( "127.0.0.1" );
//Ip checksum
iph->check = csum ((unsigned short *) sendbuf, iph->tot_len);
tx_len += sizeof(struct iphdr);
uph->source = htons(80);
uph->dest = htons(43521);
uph->check = 0;
tx_len+= sizeof(struct udphdr);
sendbuf[tx_len++] = 0xAA;
sendbuf[tx_len++] = 0xBB;
sendbuf[tx_len++] = 0xCC;
sendbuf[tx_len++] = 0xDD;
sendbuf[tx_len++] = 0xEE;
uph->len = htons((tx_len - sizeof(struct iphdr) - sizeof(struct ethhdr)));
/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC */
socket_address.sll_addr[0] = MY_DEST_MAC0;
socket_address.sll_addr[1] = MY_DEST_MAC1;
socket_address.sll_addr[2] = MY_DEST_MAC2;
socket_address.sll_addr[3] = MY_DEST_MAC3;
socket_address.sll_addr[4] = MY_DEST_MAC4;
socket_address.sll_addr[5] = MY_DEST_MAC5;
/* Send packet */
if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
printf("Send failed\n");
return 0;
}
The IP Total Length field is only 20 bytes, which is just the size of the IP Header, so as far as IP is concerned, there is no payload. You need to ensure that the IP Total Length field is set to the size of the IP header plus the size of the entire payload. In particular, this line is wrong:
iph->tot_len = htons(sizeof (struct iphdr));
I have a Raspberry Pi that interface a CAN Bus though SPI. I've installed canutils and if I do a cansend the message is received by the controller and applied, but if I do it through code it doesn't. It must be something that I'm doing wrong in building the frame, so if somebody can help me to point out my error I'll appreciate it.
This is the cansend message that I send.
cansend can0 01f801f2#1212121223232323
This is my code to send the same message. The code runs in a pthread.
void *CANUpdate(void *userParam)
{
struct sockaddr_can addr;
struct ifreq ifr;
const char *ifname = "can0";
int can_s;
if ((can_s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
LogEntry(LOG_ERR, "Error while opening socket\n");
return 0;
}
strcpy(ifr.ifr_name, ifname);
ioctl(can_s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(can_s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
LogEntry(LOG_ERR, "Error in CAN socket bind\n");
return 0;
}
while (!stopServer)
{
if (can_s)
{
struct can_frame frame;
frame.can_id = 0x01f801f2;
frame.can_dlc = 8;
frame.data[0] = 0x12;
frame.data[1] = 0x12;
frame.data[2] = 0x12;
frame.data[3] = 0x12;
frame.data[4] = 0x34;
frame.data[5] = 0x34;
frame.data[6] = 0x34;
frame.data[7] = 0x34;
int res = write(can_s, &frame, sizeof(struct can_frame));
}
msleep(800);
}
}
There was basically 2 problems with the code.
1. I should have used the canfd_frame struct, and I should've 0'ed the values. Here is the code that worked at the end
void *CANUpdate(void *userParam)
{
struct sockaddr_can addr;
struct ifreq ifr;
const char *ifname = "can0";
int can_s;
if ((can_s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
LogEntry(LOG_ERR, "Error while opening socket\n");
return 0;
}
strcpy(ifr.ifr_name, ifname);
ioctl(can_s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
setsockopt(can_s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
if (bind(can_s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
LogEntry(LOG_ERR, "Error in CAN socket bind\n");
return 0;
}
while (!stopServer)
{
if (can_s)
{
struct canfd_frame frame;
memset(&frame, 0, sizeof(frame)); /* init CAN FD frame, e.g. LEN = 0 */
frame.can_id = 0x01f801f2;
frame.len = 8;
if (!(frame.can_id & CAN_ERR_FLAG)) /* 8 digits but no errorframe? */
frame.can_id |= CAN_EFF_FLAG; /* then it is an extended frame */
frame.data[0] = 0x12;
frame.data[1] = 0x12;
frame.data[2] = 0x12;
frame.data[3] = 0x12;
frame.data[4] = 0x34;
frame.data[5] = 0x34;
frame.data[6] = 0x34;
frame.data[7] = 0x34;
if(write(can_s, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame);
LogEntry(LOG_ERR, "Unable to write CAN message\n");
}
msleep(800);
}
}
Background:
I have a UDP server that can process clients' requests concurrently. Each client sends two datagrams to the server.
First datagram (Type - 1, Client num)
Second datagram (Type - 2, Client num)
To process all clients concurrently, I initially create a fixed number of server threads and one global UDP socket bound to a known port/address. Then each thread starts to run wherein they block on recvfrom() call on the same global socket. Whichever thread receives a datagram first checks
the type. If it is type 1, it generates a "special" number for the client num it received and stores it. It it is type 2, it sends back the stored "special" number for that client.
Server program:
#define SIZE 1024
int status;
int tnum;
int i;
vector<pthread_t> tid;
struct sockaddr_in server_sock_addr;
const char *server_addr = "127.0.0.1";
int sock;
int reuse = 1;
socklen_t addr_len = sizeof(sockaddr_in);
unordered_map<int, int> dic;
void report(int status){
if(status < 0){
perror("Error");
exit(EXIT_FAILURE);
}
}
void* server_func(void *arg){
int bytes;
char *buf = (char*)malloc(SIZE);
struct sockaddr_in client_sock_addr;
int type;
int num;
while(1){
bytes = recvfrom(sock, buf, SIZE, 0, (sockaddr*)&client_sock_addr, &addr_len);
cout<<bytes<<endl;
report(bytes);
memmove(&type, buf, sizeof(int));
memmove(&num, buf + sizeof(int), sizeof(int));
if(type == 1){
dic[num] = num * 1000;
}
else if(type == 2){
while(dic.find(num) == dic.end()){
};
memset(buf, 0, SIZE);
memmove(buf, &dic[num], sizeof(int));
status = sendto(sock, buf, sizeof(int), 0, (sockaddr*)&client_sock_addr, addr_len);
report(status);
cout<<"Mapped number is "<<num<<" - "<<dic[num]<<endl;
}
else{
report(-1);
}
}
free(buf);
}
int main() {
cout<<"-------------------------------------------"<<endl;
cout<<"SERVER STARTED on port 5000"<<endl;
cout<<"-------------------------------------------"<<endl;
tnum = 4;
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bzero((char*)&server_sock_addr, sizeof(server_sock_addr));
server_sock_addr.sin_family = AF_INET;
server_sock_addr.sin_port = htons(5000);
inet_aton(server_addr, &server_sock_addr.sin_addr);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
status = bind(sock, (struct sockaddr*)&server_sock_addr, sizeof(server_sock_addr));
report(status);
tid.resize(tnum);
dic.clear();
for (i = 0; i < tnum; i++) {
status = pthread_create(&tid[i], NULL, server_func, NULL);
report(status);
}
for (i = 0; i < tnum; i++) {
pthread_join(tid[i], NULL);
}
close(sock);
return 0;
}
Client program
#define SIZE 1024
int num;
int i;
vector<pthread_t> tid;
vector<int> client_num;
const char *server_addr = "127.0.0.1";
socklen_t addr_len = sizeof(sockaddr_in);
void report(int status){
if(status < 0){
perror("Error");
exit(EXIT_FAILURE);
}
}
void* client_func(void *arg){
struct sockaddr_in server_sock_addr;
int cnum = *((int*)arg);
char *buf = (char*)malloc(SIZE);
int type;
int sock;
int bytes;
int status;
int res;
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bzero((char*)&server_sock_addr, sizeof(server_sock_addr));
server_sock_addr.sin_family = AF_INET;
server_sock_addr.sin_port = htons(5000);
status = inet_aton(server_addr, &server_sock_addr.sin_addr);
report(status);
type = 1;
memset(buf, 0, SIZE);
memmove(buf, &type, sizeof(int));
memmove(buf + sizeof(int), &cnum, sizeof(int));
status = sendto(sock, buf, 2 * sizeof(int), 0, (sockaddr*)&server_sock_addr, addr_len);
report(status);
type = 2;
memset(buf, 0, SIZE);
memmove(buf, &type, sizeof(int));
memmove(buf + sizeof(int), &cnum, sizeof(int));
status = sendto(sock, buf, 2 * sizeof(int), 0, (sockaddr*)&server_sock_addr, addr_len);
report(status);
bytes = recvfrom(sock, buf, SIZE, 0, (sockaddr*)&server_sock_addr, &addr_len);
report(bytes);
memcpy(&res, buf, sizeof(int));
cout<<"Mapped number from the server for Client - "<<cnum<<" is "<<res<<endl;
free(buf);
close(sock);
}
int main(int argc, char *argv[]) {
int status;
if(argc < 2){
cout<<"Enter number of threads"<<endl;
exit(EXIT_FAILURE);
}
num = atoi(argv[1]);
tid.resize(num);
client_num.resize(num);
for (i = 0; i < num; i++) {
client_num[i] = i+1;
status = pthread_create(&tid[i], NULL, client_func, &client_num[i]);
}
for (i = 0; i < num; i++) {
pthread_join(tid[i],NULL);
}
cout << "Requested duration has ended. Finishing the program." << endl;
return 0;
}
Problem I am facing:
When 500 clients send datagrams concurrently, the server works as expected only when I include some kind of COUT statement after the recvfrom() call(First line in while(1) loop). If I delete that cout statement, it gives Segmentation fault because the server gets stuck on the while() loop to check whether an item exists or not. while(dic.find(num) == dic.end()){};. I am not able to figure out the reason for this problem. Please provide me your suggestions.
Thanks.
EDIT:
Having a mutex lock on "dic" data-structure(while writing it) solves the problem(I do not need to use "cout" anymore), but I want to confirm whether this is absolutely the correct fix and want to learn anyother subtle points that I could out of this program, because I'd building a much bigger version of this program soon with lots of global datastructures to be shared by all threads
When I'm connecting with a socket in NDK, as a result of the read call, I always get -1.(Error).
I was looking over the internet several times and I couldn't find a solution. Can you help me?
Here is my code.
void * SocketManager::socketCall(void *ptr) {
int socket_, n;
SocketManager *manager = (SocketManager*) ptr;
while (manager->semaph) ;
manager->semaph = true;
bool didConnect = false;
size_t bufferSize = 32000;
char buffer[bufferSize];
const char* value = manager->host.c_str();
stringstream strValue;
strValue << value;
unsigned int host;
strValue >> host;
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(10983);
inet_aton(manager->host.c_str(), &server_address.sin_addr);
socket_ = socket(AF_INET, SOCK_STREAM, 0);
if (socket_ < 0)
CCLog("ERROR ABRIENDO EL SOCKET");
n = ::connect(socket_, (struct sockaddr *) &server_address,sizeof(server_address));
if (n < 0)
close(socket_);
manager->onConnect();
didConnect = true;
while (!manager->mustDisconnect) {
n = read(socket_, &buffer, bufferSize);
if(n<=0)
break;
manager->onReadData(buffer, sizeof(buffer));
}
if (socket_) {
close(socket_);
if (didConnect)
manager->onDisconnect();
else
manager->onTimeout();
}
manager->semaph = false;
manager->mustDisconnect = false;
return 0;
}
i want to create a client server program in mfc
i found some really good source code from this website: http://www.softwareandfinance.com/Visual_CPP/TCP_Client_Server.html
ok can someone help me display the information in a listbox instead of the edit box?
here's the code to process the client:
static void f(void *p)
{
CSocketTestServerDlg *pDlg = reinterpret_cast<CSocketTestServerDlg*>(p);
pDlg->ProcessClientRequest();
}
void CSocketTestServerDlg::ProcessClientRequest()
{
SOCKADDR_IN clientaddr;
struct hostent *hostentry;
int len = sizeof(clientaddr);
SOCKET clientsocket = accept(m_serversocket, (sockaddr*)&clientaddr, &len);
if(len == -1)
{
AfxMessageBox("Error accpeting the client socket");
}
else
{
char *p = inet_ntoa(clientaddr.sin_addr);
int portno = ntohs(clientaddr.sin_port);
// int inet_pton(int af, const char *restrict src, void *restrict dst);
char rbuf[1024];
recv(clientsocket, rbuf, 1024, 0);
for(int i = 1024; i >= 1; i--)
{
if(rbuf[i] == '\n' && rbuf[i - 1] == '\r')
{
rbuf[i-1] = '\0';
break;
}
}
CString strRecvData;
strRecvData.Format("%s\r\n%s %d\r\n%s\r\n\r\n", (const char*)CTime::GetCurrentTime().Format("%B %d, %Y %H:%M:%S"), p, portno, rbuf);
m_recvData += strRecvData;
m_bRefershData = true;
strcat(rbuf, "\r\n");
send(clientsocket, rbuf, 1024, 0);
closesocket(clientsocket);
}
}
so how can i just get the ip address from the client to display in a list box? i don't need all the other information
Well, you already have the IP as a string in p, don't you?
You could create a CString from it to avoid UNICODE problems. Then use CListBox::AddString to output your string:
char *p = inet_ntoa(clientaddr.sin_addr);
CString str(p);
//CListBox listbox;
listbox.AddString(str);