data send using DeviceIoControl from app to driver - c

I can send data driver to app.
In app:
DeviceIoControl(dHandle, IOCTL_TEST, (PVOID)InputBuffer, sizeof(InputBuffer), (PVOID)OutputBuffer, sizeof(OutputBuffer), &dwRet, 0);
printf("num : %s\n", OutputBuffer);
In driver:
char pData[1024];
pData="eeee";
case IOCTL_TEST:
pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
pOutputBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = pStack->Parameters.DeviceIoControl.OutputBufferLength;
RtlCopyMemory(pOutputBuffer, pData, strlen(pData));
break;
Irp.IoStatus.Information=1024;
The result is printed "eeee" in application console.
But i don't know how to send app data to driver.
DeviceIoControl's 3, 4 parameters are input buffer and length.
If I add char InputBuffer[1024] = "InputBuffer's data"; in app, how driver can receive this data?
I want to use DbgPrint() for accepted data from app.
I want to select answer. plz answer not comment.

I solved it.
The solution is
the driver receive data from app with Irp->AssociatedIrp.Systembuffer; So, just print this pointer's data.

Related

porting synproxy to user space

I have ported the kernel's synproxy code to user space. I use it as a transparent proxy between the client and the web server.
When I request a web page, it works fine (the web page is below 512kbit). However, if I access a huge file (4Gbit or more), it will not continue to transfer after 3Gbits is transmitted.
I have adjusted the "confirmation" sent by the server to the client and the "seq" sent from the client to the server. At the same time, the tcp option "sack" sent from the client to the server is also adjusted.
if(tcpinp->state == CONNTRACK_SYN_SENT){
if(tcphdr->tcp_flags == (TCP_SYN_FLAG|TCP_ACK_FLAG)){
synproxy_parse_options(tcphdr, &opts);
tcpinp->tsoff = opts.tsval - tcpinp->its;
}
swap(opts.tsval, opts.tsecr);
synproxy_send_server_ack(iphdr,tcphdr, &opts);
/* send client ack,update tcp window */
swap(opts.tsval, opts.tsecr);
/*
* update window to client
*
* dir:server -> client
*
* save isn_off = client.ISN1 - server.ISN2
*/
tcpinp->isn_off = tcpinp->isn - tcphdr->seq;
synproxy_send_client_ack(tcpinp, &opts);
tcpinp->state = CONNTRACK_ESTABLISHED;
return 0;
}
if(tcpinp->dir == IP_CT_DIR_REPLY){
tcphdr->sent_seq = htonl(ntohl(tcphdr->sent_seq) + tcpinp->isn_off);
}else if(tcpinp->dir == IP_CT_DIR_ORIGINAL){
tcphdr->recv_ack = htonl(ntohl(tcphdr->recv_ack) - tcpinp->isn_off);
nf_ct_sack_adjust(tcph, other_way);
}
What should I adjust besides seq / ack and sack?
---I found that the client tcp'win' option has been increased to '828800' and then it does not change.
I have solved ,that it need 'mss' is always same.

Eclipse Paho MQTT Client: How to check for existing connection?

On the Eclipse Paho MQTT website, the developers provide a client example (http://www.eclipse.org/paho/files/mqttdoc/MQTTClient/html/pubsync.html) that does the following:
Create a client object with the specified parameters
Connect the client with the specified connection options
Publish a MQTT message
Disconnect the client
Destroy the client object
This works well if all you want is to publish one single message.
In my code, I have a function that contains pretty much the same code as in the aforementioned example, however, the function is called repeatedly from main() as I need to publish a large number of messages one after another. The problem is, if I use the code exactly as in the example, every time my function is called a new connection is created and shortly after destroyed. This happens again and again and again as long as the function is called repeatedly, causing a huge overhead.
Is there a way to check whether a client object has already been created, and if so, don't do it again but use the existing one?
In my understanding, the MQTTClient_isConnected() function is supposed to do that: https://www.eclipse.org/paho/files/mqttdoc/MQTTClient/html/_m_q_t_t_client_8h.html#ad9e40bdb7149ee3e5d075db7f51a735f
But if I try it like this, I get a Segmentation fault:
if (!MQTTClient_isConnected(client)) {
MQTTClient_create(&client, mqtt.addr, CLIENT_ID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.username = TOKEN;
if (MQTTClient_connect(client, &conn_opts) != MQTTCLIENT_SUCCESS) {
printf("\n==> Connection to MQTT Broker failed.\n");
MQTTClient_destroy(&client);
exit(EXIT_FAILURE);
}
}
[EDIT]
Here is a simple demo code that better illustrates what I'm trying to accomplish:
#include <stdio.h>
#include <MQTTClient.h>
MQTTClient client;
void publish_MQTT() {
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
char *payload = (char *)calloc(1024, sizeof(char));
strcpy(payload, "hello");
printf("DEBUG_BEFORE >> MQTTClient_isConnected(client) = %d\n", MQTTClient_isConnected(client)); // DEBUG OUTPUT
if (!MQTTClient_isConnected(client)) {
MQTTClient_create(&client, addr, CLIENT_ID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.username = TOKEN;
if (MQTTClient_connect(client, &conn_opts) != MQTTCLIENT_SUCCESS) {
fprintf(stderr, RED "\n==> Connection to MQTT Broker failed.\n" RESET_CL);
MQTTClient_destroy(&client);
free(payload);
exit(EXIT_FAILURE);
}
}
printf("DEBUG_AFTER >> MQTTClient_isConnected(client) = %d\n", MQTTClient_isConnected(client)); // DEBUG OUTPUT
pubmsg.payload = payload;
pubmsg.payloadlen = strlen(payload);
pubmsg.qos = QOS;
pubmsg.retained = 0;
MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
MQTTClient_waitForCompletion(client, token, TIMEOUT);
//MQTTClient_disconnect(client, 10000);
//MQTTClient_destroy(&client);
free(payload);
}
int main(void) {
for (i=0; i<1000; i++) {
publish_MQTT();
}
return 0;
}
Please ignore the fact that the addr parameter is never specified (in my real code it is) or that it is pretty useless specifying a message in the publish_MQTT() function (in my real code, data is passed from main() to that function).
I figured it out: Apparently, there is absolutely nothing wrong with the example codes in the original posting.
It turns out I was appending the port of the MQTT server to the addr parameter again and again (in a section of the code not shown here as I didn't suspect the source of the error to be there), every time the publish_MQTT() function was called. This made the addr char string grow and eventually exceed the specified length, thus causing the SegFault.
This way everything works just as intended:
printf("\nADDR = %s\n\n", addr); // DEBUG OUTPUT
if (!MQTTClient_isConnected(client)) {
strcat(strcat(addr, ":"), pt); // This line needed to be placed here, not before that if block
MQTTClient_create(&client, addr, CLIENT_ID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.username = TOKEN;
if (MQTTClient_connect(client, &conn_opts) != MQTTCLIENT_SUCCESS) {
printf("\n==> Connection to MQTT Broker failed.\n");
MQTTClient_destroy(&client);
free(payload);
exit(EXIT_FAILURE);
}
}
Probably you are setting up "clean session flag", what's mean: "
If the ClientId represents a Client already connected to the Server then the Server MUST disconnect the existing Client [MQTT-3.1.4-2]." (from mqtt standard). So you client is disconnected (the existing one).
Code from example seems to be reasobable. It looks like there is problem with passing function argument. For example if function needed address, and you are giving objects itself.
Morze from standard:
"3.2.2.2 Session Present
Position: bit 0 of the Connect Acknowledge Flags.
If the Server accepts a connection with CleanSession set to 1, the Server MUST set Session Present to 0 in the CONNACK packet in addition to setting a zero return code in the CONNACK packet [MQTT-3.2.2-1].
If the Server accepts a connection with CleanSession set to 0, the value set in Session Present depends on whether the Server already has stored Session state for the supplied client ID. If the Server has stored Session state, it MUST set Session Present to 1 in the CONNACK packet [MQTT-3.2.2-2]. If the Server does not have stored Session state, it MUST set Session Present to 0 in the CONNACK packet. This is in addition to setting a zero return code in the CONNACK packet".

Getting Host field from TCP packet payload

I'm writing a kernel module in C, and trying to get the Host field from a TCP packet's payload, carrying http request headers.
I've managed to do something similar with FTP (scan the payload and look for FTP commands), but I can't seem to be able to do the same and find the field.
My module is connected to the POST_ROUTING hook.
each packet that goes to that hook, if it has a dst port of 80, is being recognized as an HTTP packet, and so my module starts to parse it.
for some reason, I can't seem to be able to get the HOST line (matter of fact, I only see the server HTTP 200 ok)
are these headers always go on the packets that use port 80?
if so, what is the best way to parse those packt's payload? seems like going char by char is a lot of work. is there any better way?
Thanks
EDIT:
Got some progress.
every packet I get from the server, I can read the payload with no problem. but every packet I send - it's like the payload is empty.
I thought it's a problem of skb pointer, but i'm getting the TCP ports fine. just can't seem to read this damn payload.
this is how i parse it:
unsigned char* user_data = (unsigned char *)((int)tcphd + (int)(tcphd->doff * 4));
unsigned char *it;
for (it = user_data; it != tail; ++it) {
unsigned char c = *(unsigned char *)it;
http_command[http_command_index] = c;
http_command_index++;
}
where tail:
tail = skb_tail_pointer(skb);
The pointer doesn't advance at all on the loop. it's like it's empty from the start or something, and I can't figure out why.
help, please.
I've managed to solve this.
using this
, I've figured out how to parse all of the packet's payload.
I hope this code explains it
int http_command_offset = iphd->ihl*4 + tcphd->doff*4;
int http_command_length = skb->len - http_command_offset;
http_command = kmalloc(http_command_length + 1, GFP_ATOMIC);
skb_copy_bits(skb, http_command_offset , (void*)http_command, http_command_length);
skb_cop_bits, just copies the payload entirely into the buffer i've created. parsing it now is pretty simple.

SDLNet Networking Not Working

I am working on a game written in C using SDL. Given that it already uses SDL, SDL_image, and SDL_ttf, I decided to add SDL_mixer and SDL_net to my engine. Getting SDL_mixer set up and working was very easy, but I am having a lot of trouble with SDL_net.
To test I created a very simple application with the following rules:
Run without arguments act as a TCP server on port 9999
Run with an argument try to connect to the server at the given IP address on port 9999
Here are some of the key lines of the program (I'm not going to post my whole event-driven SDL engine because its too long):
char *host = NULL;
if (argc > 1) host = argv[1];
and...
IPaddress ip;
TCPsocket server = NULL;
TCPsocket conn = NULL;
if (host) { /* client mode */
if (SDLNet_ResolveHost(&ip,host,port) < 0)
return NULL; //this is actually inside an engine method
if (!(conn = SDLNet_TCP_Open(&ip)))
return NULL;
} else { /* server mode */
if (SDLNet_ResolveHost(&ip,NULL,port) < 0)
return NULL;
if (!(server = SDLNet_TCP_Open(&ip)))
return NULL;
}
and... inside the event loop
if (server) {
if (!conn)
conn = SDLNet_TCP_Accept(server);
}
if (conn) {
void *buf = malloc(size); //server, conn, size are actually members of a weird struct
while (SDLNet_TCP_Recv(conn,buf,size))
onReceive(buf); //my engine uses a callback system to handle things
free(buf);
}
The program seems to start up just fine. However for some reason when I run it in client mode trying to connect to my home computer (which I have on a different IP) from my laptop I find that the call to SDLNet_TCP_Open blocks the program for awhile (5-10 seconds) then returns NULL. Can anybody see what I did wrong? Should I post more of the code? Let me know.

QMI SDK start data session

I am using QMI SDK to start data session for the Sierra Wireless card MC7354 and Telus Sim Card. For now I can detect the device and the sim card like getting device info and IMSI number; however, I got some trouble with starting the data session. I follow the instructions in QMI SDK Documents and do the following code:
//set the default profile
ULONG rc3 = SetDefaultProfile(0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
fprintf(stderr, "SetProfile - Return Code: %lu\n", rc3);
//start the session
ULONG technology = 1;
ULONG profile_idx = 1;
struct ssdatasession_params session;
session.action = 1;
session.pTechnology = &technology;
session.pProfileId3GPP = &profile_idx;
session.pProfileId3GPP2 = NULL;
session.ipfamily = 4;
ULONG rc4 = SLQSStartStopDataSession(&session);
fprintf(stderr, "Start Session - Return Code: %lu\n",rc4);
SetDefaultProfile is working fine because it returns me the success code, but for the SLQSStartStopDataSession method, it always gives me the return code "1026", which means
Requested operation would have no effect
Does anyone know where I make mistakes and how should I modify the code? What does this return code mean?
A "No Effect" error in WDS Start Network (the underlying command sent when you use SLQSStartStopDataSession()) actually means that the device is already connected. You likely have configured an automatic connection setup in the modem.

Resources