I am trying to parse a pcap to get the packet bytes of only the TLS Record Layer in the payload.
In my following code I have managed to get only the tcp protocol bytes from the payload which contains the TLS Record Layer. I want to further extract only the TLS Record Layer bytes from this.
Could you tell me how I can modify my code to extract only that part of the payload?
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
static int count = 1; /* packet counter */
/* declare pointers to packet headers */
const struct ether_header *ethernet; /* The ethernet header [1] */
const struct ip *ip; /* The IP header */
const struct tcphdr *tcp; /* The TCP header */
const struct sniff_udp *udp; /* The UDP header */
const char *payload; /* Packet payload */
int size_ip;
int size_tcp;
int size_udp;
int size_payload;
printf("\nPacket number %d:\n", count);
count++;
/* define ethernet header */
ethernet = (struct ether_header*)(packet);
/* define/compute ip header offset */
ip = (struct ip*)(packet + sizeof(struct ether_header));
size_ip = sizeof(struct ip);
if (size_ip < 20) {
//printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
/* print source and destination IP addresses */
printf(" From: %s\n", inet_ntoa(ip->ip_src));
printf(" To: %s\n", inet_ntoa(ip->ip_dst));
/* determine protocol */
switch(ip->ip_p) {
case IPPROTO_TCP:
printf(" Protocol: TCP\n");
break;
case IPPROTO_UDP:
printf(" Protocol: UDP\n");
break;
case IPPROTO_ICMP:
printf(" Protocol: ICMP\n");
return;
case IPPROTO_IP:
printf(" Protocol: IP\n");
return;
default:
printf(" Protocol: unknown\n");
return;
}
/*
* OK, this packet is TCP.
*/
/* define/compute tcp header offset */
if(ip->ip_p == IPPROTO_TCP)
{
tcp = (struct tcphdr *)(packet + sizeof(struct ether_header) + sizeof(struct ip));
size_tcp = sizeof(struct tcphdr);
printf(" Src port: %d\n", ntohs(tcp->th_sport));
printf(" Dst port: %d\n", ntohs(tcp->th_dport));
int sport = ntohs(tcp->th_sport);
int dport = ntohs(tcp->th_dport);
/* define/compute tcp payload (segment) offset */
payload = (u_char *)(packet + sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct tcphdr));
/* compute tcp payload (segment) size */
size_payload = header->len - (sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct tcphdr));
/*
* Print payload data; it might be binary, so don't just
* treat it as a string.
*/
if (size_payload > 0) {
printf(" Payload (%d bytes):\n", size_payload);
print_payload(payload, size_payload);
//if ((sport == 80) || (dport == 80))
//{
// printf(" HTTP prase:\n");
// prase_http(payload, size_payload);
//}
if(sport == 443 || dport == 443)
{
// printf(" SSL/TLS prase:\n");
//prase_ssl_tls(payload, size_payload);
//printf("%u",payload);
// print_payload(payload, size_payload);
parser(payload,size_payload);
}
}
}
/* UDP */
else if(ip->ip_p == IPPROTO_UDP)
{
udp = (struct sniff_udp*)(packet + SIZE_ETHERNET + size_ip);
size_udp = 8;
printf(" Src port: %d\n", ntohs(udp->uh_sport));
printf(" Dst port: %d\n", ntohs(udp->uh_dport));
int sport = ntohs(udp->uh_sport);
int dport = ntohs(udp->uh_dport);
payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_udp);
size_payload = ntohs(ip->ip_len) - (size_ip + size_udp);
if (size_payload > 0) {
//printf(" Payload (%d bytes:)\n", size_payload);
if(sport == 53 || dport == 53)
{
// printf(" DNS prase:\n");
// prase_dns(payload, size_payload);
}
}
}
return;
}
This is the got_packet function passed as argument to pcap_loop which is part of <pcap.h> .All reference structures are used from
<arpa/inet.h>,<net/ethernet.h>,<netinet/ip.h>,<netinet/tcp.h>
I am looking to extract this part of the packet(image link attached):
Screenshot from wireshark as to what I wish to parse
Could someone help me with this?
Related
Let me start by saying this is my first foray into the world of C after 20+ years of assembly programming for PLCs and MicroControllers.
I'm trying to send a UDP datagram to the network broadcast address, in this particular case, 192.168.1.255.
The error I'm getting is a bind failure with error code 10049 (from WSAGetLastError()). As you can see from the attached code, I've created the socket, populated sockaddr_in, and setsockopt() to SO_BROADCAST.
For the life of me I can't figure out what I'm doing wrong and any pointers would be gratefully received.
iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
if (iResult != NO_ERROR)
{
WSAErrorString("WSAStartup for TX failed");
return(-1);
}
XPLMDebugString("UDP Server: WSAStartup TX complete.\n");
if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
WSAErrorString("UDP Server: Could not create BECN socket");
return(-1);
}
// setup the sockaddr_in structure
//
si_beacon.sin_family = AF_INET;
si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");
si_beacon.sin_port = htons(_UDP_TX_PORT);
// setup to broadcast
//
char so_broadcast_enabled = '1';
if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
WSAErrorString("Error in setting Broadcast option");
closesocket(BeaconSocket);
return(-1);
}
// bind our socket
//
if (bind(BeaconSocket, (struct sockaddr *)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
{
char buf[256];
WSAErrorString("Bind to socket for UDP beacon failed");
sprintf(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
XPLMDebugString(buf);
return(-1);
}
// start the UDP beacon
//
udp_becn_thread_id = CreateThread(NULL, 0, BeaconThread, NULL, 0, NULL);
if (!udp_becn_thread_id) {
WSAErrorString("UDP Server: Error starting UDP Beacon");
return (-1);
}
XPLMDebugString("UDP Server: bind complete. beacon ACTIVE.\n");
return(0);
The issue is the IP address itself.
I copied the code to my computer (changed it a bit to get it to compile) and I got the error:
UDP Server: WSAStartup TX complete.
Bind to socket for UDP beacon failed
Port 47977, address 192.168.1.255
I then changed the line:
si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");
To
si_beacon.sin_addr.s_addr = inet_addr("192.168.0.127");
And when I ran it again, everything worked:
UDP Server: WSAStartup TX complete.
Done successfully
The issue is that the "bind" address needs to be your computers address on the local network. Not the remote client.
Another alternative is to use the address:
si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");
which binds to all network interfaces on the computer at once.
For reference, here's the version of the code that I used:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <WinSock2.h>
#include <WS2tcpip.h> // For inet_pton
#pragma comment(lib, "ws2_32.lib")
int main()
{
{
WSADATA wsaTxData;
memset(&wsaTxData, 0, sizeof(WSADATA));
const int iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
if (iResult != NO_ERROR)
{
printf("%s", "WSAStartup for TX failed.\n");
return -1;
}
printf("%s", "UDP Server: WSAStartup TX complete.\n");
}
SOCKET BeaconSocket;
memset(&BeaconSocket, 0, sizeof(SOCKET));
if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
printf("%s", "UDP Server: Could not create BECN socket\n");
return -1;
}
// setup the sockaddr_in structure
//
sockaddr_in si_beacon;
memset(&si_beacon, 0, sizeof(sockaddr_in));
si_beacon.sin_family = AF_INET;
si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");
const unsigned short port_num = 0xbb69;
si_beacon.sin_port = htons(port_num);
// setup to broadcast
//
char so_broadcast_enabled = '1';
if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
printf("%s", "Error in setting Broadcast option\n");
closesocket(BeaconSocket);
return(-1);
}
// bind our socket
//
if (bind(BeaconSocket, (struct sockaddr*)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
{
char buf[256];
printf("%s", "Bind to socket for UDP beacon failed\n");
sprintf_s(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
printf("%s", buf);
return(-1);
}
printf("%s", "Done successfully");
return 0;
}
I am trying to understand the forwarding mechanism of the basicfwd example of DPDK. Can anyone help me with initializing and editing the payload of the rte_mbuf? Here is the class.
I plan on using tcpdumpand rte_pktmbuf_dump to view the packet contents.
Here is the rte_mbuf I wish to add my own payload to:
struct rte_mbuf *bufs[BURST_SIZE];
This is the rte_mbuf being received:
const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
This is the rte_mbuf being transmitted:
const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0,
bufs, nb_rx);
I have modified the sample application basicfwd.c in the DPDK examples to print the forwarded packets in a file:
/* Get burst of RX packets, from first port of pair. */
const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
FILE *fp;
fp = fopen("dump.txt", "a");
fprintf(fp, "\n-----------------------\n fprintf... %d<->%d\n", count, port);
rte_pktmbuf_dump(fp, bufs[0], 1000);
fclose(fp);
if (unlikely(nb_rx == 0))
continue;
/* Send burst of TX packets, to second port of pair. */
const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0,bufs, nb_rx);
These are the packets I see in the output file:
I would like to be able to modify the contents for better understanding. I have tried rte_pktmbuf_init and bufs->userdata =*(unsigned short*) 0xAAAAAAAA but it does not work for me.
I solved the issue by creating my own packets in the memory pool.
Create a memory pool for the program.
Allocate a packet in memory pool.
Populate the packet with data, source address, destination address, and initialize packet fields.
The complete lcore_main function:
/*
* The main thread that does the work, reading from
* an input port and writing to an output port.
*/
struct message {
char data[DATA_SIZE];
};
static __attribute__(()) void
lcore_main(void)
{
const uint8_t nb_ports = rte_eth_dev_count();
uint8_t port;
for (port = 0; port < nb_ports; port++)
if (rte_eth_dev_socket_id(port) > 0 &&
rte_eth_dev_socket_id(port) !=
(int)rte_socket_id())
printf("WARNING, port %u is on remote NUMA node to "
"polling thread.\n\tPerformance will "
"not be optimal.\n", port);
struct rte_mbuf *pkt;
struct ether_hdr *eth_hdr;
struct message obj;
struct message *msg;
int nb_rx = 0, nb_tx = 0, cnt = 0, pkt_size = 0;
int count = 0;
int k = 0;
for (count = 0; count < DATA_SIZE; count++){
obj.data[count] = (char)(97 + (k++));
if (k == 26)
k = 0;
}
time_t endtime = time(NULL) + 10;
port = 0;
while (time(NULL) < endtime) {
cnt = rte_eth_rx_burst(port, 0, &pkt, 1);
nb_rx += cnt;
if (cnt > 0)
{
eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
rte_eth_macaddr_get(port, ð_hdr->s_addr);
pkt_size = sizeof(struct message) + sizeof(struct ether_hdr);
msg = (struct message *) (rte_pktmbuf_mtod(pkt, char*)) + sizeof(struct ether_hdr);
rte_pktmbuf_free(pkt);
}
msg = &obj;
pkt = rte_pktmbuf_alloc(mbuf_pool);
pkt_size = sizeof(struct message) + sizeof(struct ether_hdr);
pkt->data_len = pkt_size;
pkt->pkt_len = pkt_size;
eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
rte_eth_macaddr_get(port, ð_hdr->d_addr);
rte_eth_macaddr_get(port ^ 1, ð_hdr->s_addr);
eth_hdr->ether_type = htons(PTP_PROTOCOL);
char* data;
data = rte_pktmbuf_append(pkt, sizeof(struct message));
if (data != NULL)
rte_memcpy(data, msg, sizeof(struct message));
nb_tx += rte_eth_tx_burst(port ^ 1, 0, &pkt, 1);
}
printf("----\nData size: %d\nPacket size: %d\nRX : %d, TX : %d\n\n", DATA_SIZE, pkt_size, nb_rx, nb_tx);
}
I am using Microsoft Visual Studio 2010 and wolfSSL 3.7.0.
I create server context with these functions:
WOLFSSL_CTX *sslContext = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
if(!sslContext)
{
closesocket(socketListen);
return FALSE;
}
wolfSSL_CTX_use_certificate_buffer(sslContext, (unsigned char*)szServerCert, strlen(szServerCert), SSL_FILETYPE_PEM);
wolfSSL_CTX_use_PrivateKey_buffer(sslContext, (unsigned char*)szServerKey, strlen(szServerKey), SSL_FILETYPE_PEM);
It is OK. Then, I accept the connection, create WOLFSSL* context and associate it with my socket descriptor:
WOLFSSL *ssl = wolfSSL_new(sslContext);
wolfSSL_set_fd(ssl, Socket);
CHAR Buffer[1024];
int retVal = wolfSSL_read(ssl, Buffer, 1024);
But when I try to connect to 127.0.0.1:443 via browser, wolfSSL_read() returns 0. wolfSSL_get_error() returns -397 (SOCKET_PEER_CLOSED_E). Browser shows me that page is still loading. What is the reason?
wolfSSL provides a good reference example here: https://github.com/wolfSSL/wolfssl-examples/blob/master/tls/server-tls.c
Please find referenced code below:
/* server-tls.c
*
* Copyright (C) 2006-2015 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*=============================================================================
*
* This is a super basic example of what a TCP Server secured with TLS 1.2
* might look like. This server can also resume the session if a client
* inadvertantly disconnects.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
/* include the wolfSSL library for our TLS 1.2 security */
#include <wolfssl/ssl.h>
#define DEFAULT_PORT 11111
int AcceptAndRead(WOLFSSL_CTX* ctx, socklen_t sockfd, struct sockaddr_in
clientAddr);
int AcceptAndRead(WOLFSSL_CTX* ctx, socklen_t sockfd, struct sockaddr_in
clientAddr)
{
/* Create our reply message */
const char reply[] = "I hear ya fa shizzle!\n";
socklen_t size = sizeof(clientAddr);
/* Wait until a client connects */
socklen_t connd = accept(sockfd, (struct sockaddr *)&clientAddr, &size);
/* If fails to connect,int loop back up and wait for a new connection */
if (connd == -1) {
printf("failed to accept the connection..\n");
}
/* If it connects, read in and reply to the client */
else {
printf("Client connected successfully\n");
WOLFSSL* ssl;
if ( (ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "wolfSSL_new error.\n");
exit(EXIT_FAILURE);
}
/* direct our ssl to our clients connection */
wolfSSL_set_fd(ssl, connd);
printf("Using Non-Blocking I/O: %d\n", wolfSSL_get_using_nonblock(
ssl));
for ( ; ; ) {
char buff[256];
int ret = 0;
/* Clear the buffer memory for anything possibly left over */
memset(&buff, 0, sizeof(buff));
/* Read the client data into our buff array */
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) > 0) {
/* Print any data the client sends to the console */
printf("Client: %s\n", buff);
/* Reply back to the client */
if ((ret = wolfSSL_write(ssl, reply, sizeof(reply)-1))
< 0)
{
printf("wolfSSL_write error = %d\n", wolfSSL_get_error(ssl, ret));
}
}
/* if the client disconnects break the loop */
else {
if (ret < 0)
printf("wolfSSL_read error = %d\n", wolfSSL_get_error(ssl
,ret));
else if (ret == 0)
printf("The client has closed the connection.\n");
break;
}
}
wolfSSL_free(ssl); /* Free the WOLFSSL object */
}
close(connd); /* close the connected socket */
return 0;
}
int main()
{
/* Create a ctx pointer for our ssl */
WOLFSSL_CTX* ctx;
/*
* Creates a socket that uses an internet IP address,
* Sets the type to be Stream based (TCP),
* 0 means choose the default protocol.
*/
socklen_t sockfd = socket(AF_INET, SOCK_STREAM, 0);
int loopExit = 0; /* 0 = False, 1 = True */
int ret = 0; /* Return value */
/* Server and client socket address structures */
struct sockaddr_in serverAddr = {0}, clientAddr = {0};
/* Initialize wolfSSL */
wolfSSL_Init();
/* If positive value, the socket is valid */
if (sockfd == -1) {
printf("ERROR: failed to create the socket\n");
return EXIT_FAILURE; /* Kill the server with exit status 1 */
}
/* create and initialize WOLFSSL_CTX structure */
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) {
fprintf(stderr, "wolfSSL_CTX_new error.\n");
return EXIT_FAILURE;
}
/* Load server certificate into WOLFSSL_CTX */
if (wolfSSL_CTX_use_certificate_file(ctx, "../certs/server-cert.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-cert.pem, please check"
"the file.\n");
return EXIT_FAILURE;
}
/* Load server key into WOLFSSL_CTX */
if (wolfSSL_CTX_use_PrivateKey_file(ctx, "../certs/server-key.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-key.pem, please check"
"the file.\n");
return EXIT_FAILURE;
}
/* load DH params */
ret = wolfSSL_CTX_SetTmpDH_file(ctx, "../certs/dh2048.pem" , SSL_FILETYPE_PEM);
if (ret != SSL_SUCCESS) {
fprintf(stderr, "Error setting DH parameters.\n");
return EXIT_FAILURE;
}
/* Initialize the server address struct to zero */
memset((char *)&serverAddr, 0, sizeof(serverAddr));
/* Fill the server's address family */
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(DEFAULT_PORT);
/* Attach the server socket to our port */
if (bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr))
< 0) {
printf("ERROR: failed to bind\n");
return EXIT_FAILURE;
}
printf("Waiting for a connection...\n");
/* Continuously accept connects while not currently in an active connection
or told to quit */
while (loopExit == 0) {
/* listen for a new connection, allow 5 pending connections */
ret = listen(sockfd, 5);
if (ret == 0) {
/* Accept client connections and read from them */
loopExit = AcceptAndRead(ctx, sockfd, clientAddr);
}
}
wolfSSL_CTX_free(ctx); /* Free WOLFSSL_CTX */
wolfSSL_Cleanup(); /* Free wolfSSL */
return EXIT_SUCCESS;
}
I would like to search Sat>IP servers on the network. Sat>IP servers advertise their presence to other Sat>IP servers and clients.
I must not continuosly send M-SEARCH messages but that instead it listens to server NOTIFY messages.
After initalizing network settings of my device, I'm sending M-SEARCH message and getting response if there is already any active Sat>IP server.
However, I couldn't get any response, If I opens Sat>IP server after sending M-SEARCH message.
Here's my code.
void SatIP::InitDiscoverThread()
{
if(INVALID_THREAD_CHK == DiscoverThreadChk)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE);
printf("InitDiscoverThread pthread_create\n");
DiscoverThreadChk = PTH_RET_CHK(pthread_create(&DiscoverThreadID, &attr, DiscoverThreadFunc, this));
if(DiscoverThreadChk != 0)
{
ASSERT(0);
}
}
}
void SatIP::FinalizeDiscoverThread()
{
if(INVALID_THREAD_CHK != DiscoverThreadChk)
{
printf("FinalizeDiscoverThread pthread_cancel\n");
pthread_cancel(DiscoverThreadID);
DiscoverThreadChk = INVALID_THREAD_CHK;
close(discoverSocket);
}
}
void *SatIP::DiscoverThreadFunc(void* arg)
{
SatIP* satip = (SatIP *)arg;
satip->ListenSSDPResponse();
pthread_exit(NULL);
}
bool SatIP::SendMSearchMessage()
{
vSatIPServers.clear();
FinalizeDiscoverThread();
const char *searchSatIPDevice = "M-SEARCH * HTTP/1.1\r\n" \
"HOST: 239.255.255.250:1900\r\n" \
"MAN: \"ssdp:discover\"\r\n" \
"MX: 2\r\n" \
"ST: urn:ses-com:device:SatIPServer:1\r\n\r\n";
struct sockaddr_in upnpControl, broadcast_addr;
discoverSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (discoverSocket == INVALID_SOCKET)
{
printf("socked failed INVALID_SOCKET\n");
return false;
}
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
if(setsockopt(discoverSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)) == SOCKET_ERROR)
{
printf("setsockopt timeout failed\n");
close(discoverSocket);
return false;
}
socklen_t ttl = 2;
if(setsockopt(discoverSocket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == SOCKET_ERROR)
{
printf("setsockopt TTL failed\n");
close(discoverSocket);
return false;
}
if(setsockopt(discoverSocket, SOL_SOCKET, SO_BROADCAST, searchSatIPDevice, sizeof(searchSatIPDevice)) == SOCKET_ERROR)
{
printf("setsockopt broadcast failed\n");
close(discoverSocket);
return false;
}
upnpControl.sin_family = AF_INET;
upnpControl.sin_port = htons(0);
upnpControl.sin_addr.s_addr = INADDR_ANY;
if (bind(discoverSocket, (sockaddr*)&upnpControl, sizeof(upnpControl)) == SOCKET_ERROR)
{
printf("bind failed\n");
close(discoverSocket);
return false;
}
broadcast_addr.sin_family = AF_INET;
broadcast_addr.sin_port = htons(1900);
broadcast_addr.sin_addr.s_addr = inet_addr("239.255.255.250");
for(int i = 0; i < 3; i++)
{
if(sendto(discoverSocket, searchSatIPDevice, strlen(searchSatIPDevice), 0, (sockaddr *)&broadcast_addr, sizeof(broadcast_addr)) == SOCKET_ERROR)
{
//printf("sendto failed\n");
close(discoverSocket);
return false;
}
else
{
usleep(10*100);
}
}
InitDiscoverThread();
return true;
}
void SatIP::ListenSSDPResponse()
{
while(1)
{
char buf[512];
memset(buf, 0, 512);
struct sockaddr_in broadcast_addr;
broadcast_addr.sin_family = AF_INET;
broadcast_addr.sin_port = htons(1900);
broadcast_addr.sin_addr.s_addr = inet_addr("239.255.255.250");
int bcLen = sizeof(broadcast_addr);
//bool bRet = false;
while (recvfrom(discoverSocket, buf, 512, 0, (struct sockaddr*)&broadcast_addr, (socklen_t*)&bcLen) > 0)
{
printf("buf:%s\n",buf);
SATIP_SERVER_DESCRIPTION stServerDesc;
ostringstream ss;
if(strstr(buf, "device:SatIPServer"))
{
int i = 0;
char *deviceIp = strstr(buf, "LOCATION:") + 9; // get xml location including server description
while(deviceIp[i] == ' ') i++; // remove spaces from string
while(!isspace(deviceIp[i]))
{
ss << deviceIp[i];
++i;
}
stServerDesc.location = ss.str().c_str();
printf("location:%s\n",stServerDesc.location.c_str());
ss.str(""); // clear ss
i=0; // clear counter
deviceIp = strstr(buf, "http://") + 7; // get ip address
while(deviceIp[i] != ':')
{
ss << deviceIp[i];
++i;
}
stServerDesc.ipAddr = ss.str().c_str();
printf("ipAddr:%s\n", stServerDesc.ipAddr.c_str());
DownloadDeviceDescription(&stServerDesc);
stServerDesc.macAddr = GetMACAddressviaIP(stServerDesc.ipAddr);
printf("macAddr:%s\n", stServerDesc.macAddr.c_str());
if(IsServerProperToAdd(&stServerDesc))
vSatIPServers.push_back(stServerDesc);
printf("\n");
//bRet = true;
}
memset(buf, 0, 512);
}
}
}
How can I fix this issue? Any help would be appreciated.
Listening SSDP notify message is not related to sending M-SEARCH message. Devices like Sat>IP send NOTIFY message to 239.255.255.250 periodically even if you don't send M-SEARCH message. So, you should join a multicast group and receives from the group.
You can use the listener program in the following link by changing HELLO_PORT as 1900 and HELLO_GROUP as "239.255.255.250".
http://ntrg.cs.tcd.ie/undergrad/4ba2/multicast/antony/example.html
/*
* listener.c -- joins a multicast group and echoes all data it receives from
* the group to its stdout...
*
* Antony Courtney, 25/11/94
* Modified by: Frédéric Bastien (25/03/04)
* to compile without warning and work correctly
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define HELLO_PORT 1900
#define HELLO_GROUP "239.255.255.250"
#define MSGBUFSIZE 256
main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes,addrlen;
struct ip_mreq mreq;
char msgbuf[MSGBUFSIZE];
u_int yes=1; /*** MODIFICATION TO ORIGINAL */
/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}
/**** MODIFICATION TO ORIGINAL */
/* allow multiple sockets to use the same PORT number */
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
/*** END OF MODIFICATION TO ORIGINAL */
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */
addr.sin_port=htons(HELLO_PORT);
/* bind to receive address */
if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
/* use setsockopt() to request that the kernel join a multicast group */
mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP);
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) {
perror("setsockopt");
exit(1);
}
/* now just enter a read-print loop */
while (1) {
addrlen=sizeof(addr);
if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0,
(struct sockaddr *) &addr,&addrlen)) < 0) {
perror("recvfrom");
exit(1);
}
puts(msgbuf);
}
}
i'm a beginner in network programming and i have a project in which i have to create a system explorer. That means that i will have the ability to write a http request with a directory in a browser and if the connection with the server is succesfull, the files from the above directory will open.
int main(int argc, char** argv)
{
typedef struct tcpip_connection
{
int connfd;
struct sockaddr_in peer_addr;
} tcpip_connection;
int s_socket, *fd, port;
char buffer[256];
struct sockaddr_in lis_addr;
struct sockaddr_in peer_addr;
int sopt = 1, n;
s_socket=socket(AF_INET, SOCK_STREAM, 0);
if(s_socket<0){
printf("error: the socket was not created!");
}
if(setsockopt(s_socket , SOL_SOCKET, SO_REUSEADDR, &sopt, sizeof(sopt))){
printf("Setsokopt error!");
}
memset(&lis_addr, 0, sizeof(lis_addr));
lis_addr.sin_family = AF_INET;
lis_addr.sin_addr.s_addr = htonl(INADDR_ANY);
lis_addr.sin_port = htons(port);
if ( bind( s_socket, (struct sockaddr*) &lis_addr, sizeof(lis_addr) ) < 0 ){
perror(NULL);
exit(-1);
}
if(listen(s_socket,15)<0){
perror("server.listen");
}
socklen_t peer_addrlen;
while(1){
if((fd = malloc(sizeof(int))) == NULL){
fprintf(stderr, "Out of memory\n");
abort();
}
*fd=accept(s_socket, (struct sockaddr*)&peer_addr,&peer_addrlen);
if(fd<0){
if( errno==EINTR /* Call interrupted by signal */
|| errno==ECONNABORTED /* connection was aborted */
|| errno==EMFILE /* per-process limit of open fds */
|| errno==ENFILE /* system-wide limit of open fds */
|| errno==ENOBUFS /* no space for socket buffers */
|| errno==ENOMEM /* no space for socket buffers */
|| errno==EPERM /* Firewall blocked the connection */
)
continue;
}
}
if(errno == EBADF)
break; /* return, the server_socket is closed */
}
bzero(buffer,1024);
n = read(*fd,buffer,1023);
if (n < 0)
{
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
/* Write a response to the client
n = write(*fd,"I got your message",18);
if (n < 0)
{
perror("ERROR writing to socket");
exit(1);
}
return 0;*/
}
I don't know if there is anything wrong with my code, but the main problem is that i don't know how to make the browser connect with the server. Is there anything i have to write in the browser or do i have to add some extra code?
You forgot to initialize the port variable. Try setting port = 8080 before you call bind and listen.
Then, in your browser, go to http://localhost:8080/ and it should connect.