I have studied the documentation on MSDN, but it doesn't work for me, I am wondering what I'm doing wrong?
My code is as follows, I am trying to filter my IE cache, for example, to get only the cookies:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <wininet.h>
int main(void) {
DWORD dwEntrySize;
DWORD dw;
LPCTSTR filter = "cookie:";
INTERNET_CACHE_ENTRY_INFO * entry;
DWORD MAX_CACHE_ENTRY_INFO_SIZE = 4096;
HANDLE hCacheDir;
int nCount=0;
BOOL ok = FALSE;
dwEntrySize = MAX_CACHE_ENTRY_INFO_SIZE;
entry = malloc(dwEntrySize);
entry->dwStructSize = dwEntrySize;
printf("Reading IE cache\n");
hCacheDir = FindFirstUrlCacheEntry(filter, entry, &dwEntrySize);
if ( hCacheDir ) {
printf("%ws\n", entry->lpszLocalFileName);
nCount++;
do {
dwEntrySize = MAX_CACHE_ENTRY_INFO_SIZE;
entry = malloc(dwEntrySize);
entry->dwStructSize = dwEntrySize;
ok = FindNextUrlCacheEntry(hCacheDir, entry, &dwEntrySize);
if (ok && entry->lpszLocalFileName != NULL) {
printf("%ws\n", entry->lpszLocalFileName);
nCount++;
}
} while ( ok );
printf("**** end cache, total count: %d\n", nCount);
}
else {
dw = GetLastError();
printf("error code: %d\n", dw);
}
free(entry);
FindCloseUrlCache(hCacheDir);
return 0;
}
Related
I have this c program which used to search for the mp3 files of given directory and add the files data to linked list.i use SDL2 for audio handling. so much far i would be able to get the playing of mp3 file and what i'm facing here is that i don't know how to play the next song when the first song is played in the linked list.
Here is my code for the program.
#include <dirent.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "file_handle.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
struct tags
{
const char *artist;
} tags;
Mix_Music *music = NULL;
bool loadmedia(char *filepath);
void play();
void init();
void load_file_directory(char *dir_path);
int main(int argc, char *argv[])
{
char *file_path;
if (argc <= 1)
{
fprintf(stderr, "no arguments provided!\n");
}
else
{
file_path = argv[2];
}
if (file_path)
{
load_file_directory(file_path);
}
init();
int count = 0;
for (struct song *node = head; node; node = node->next)
{
printf("%s\n", node->file_path);
}
for (struct song *node = head; node; node = node->next)
{
printf("%s\n", node->file_path);
printf("count is %d\n", count);
count++;
Mix_Music *song = Mix_LoadMUS(node->file_path);
if (Mix_PlayMusic(song, 1) != 0)
{
printf("something\n");
}
while (!SDL_QuitRequested())
SDL_Delay(250);
Mix_FreeMusic(song);
}
// char *file = argv[1];
// bool status = loadmedia(file);
// if(status){
// printf("%s - %s\n",Mix_GetMusicArtistTag(music),Mix_GetMusicTitleTag(music));
// if(Mix_PlayMusic(music,1)){
// printf("something wrong");
// Mix_FreeMusic(music);
// }
// }
// while(!SDL_QuitRequested())
// SDL_Delay(250);
}
bool loadmedia(char *file_path)
{
bool success = false;
if (file_path)
{
music = Mix_LoadMUS(file_path);
success = true;
}
else
{
printf("File Loaded Failed\n");
}
return success;
}
void init()
{
bool success;
if (SDL_Init(SDL_INIT_AUDIO) < 0)
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
success = false;
}
if (Mix_Init(MIX_INIT_MP3) != MIX_INIT_MP3)
{
fprintf(stderr, "could not initialized mixer\n", Mix_GetError());
}
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
{
printf("SDL_mixer could not be initialized %s\n", Mix_GetError());
success = false;
}
}
code:
```
#include "pch.h"
#include
extern "C"
{
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include <libavcodec/avcodec.h>
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/avutil.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include <libavutil/rational.h>
//#include "libavutil/avassert.h"
//#include "libavutil/attributes.h"
//#include "libavutil/avassert.h"
//#include "libavutil/frame.h"
//#include "libavutil/imgutils.h"
//#include "internal1.h"
//#include "libavutil/samplefmt.h"
}
#include <vld.h>
//#include "avcodec.h"
//#include "frame_thread_encoder.h"
//#include "internal.h"
// Globals
AVCodec* m_pCodec = NULL;
AVStream *m_pStream = NULL;
AVOutputFormat* m_pFormat = NULL;
AVFormatContext* m_pFormatContext = NULL;
AVCodecContext* m_pCodecContext = NULL;
AVFrame* m_pFrame = NULL;
int m_frameIndex;
// Output format
AVPixelFormat m_pixType = AV_PIX_FMT_NV12;
// Use for mpeg4
//AVPixelFormat m_pixType = AV_PIX_FMT_YUV420P;
// Output frame rate
int m_frameRate = 30;
// Output image dimensions
int m_imageWidth = 256;
int m_imageHeight = 1537;
// Number of frames to export
int m_frameCount = 20000;
// Output file name
const char* m_fileName = "test.h264";
// Output file type
const char* m_fileType = "H264";
// Codec name used to encode
const char* m_encoderName = "h264_qsv";
// use for mpeg4
//const char* m_encoderName = "mpeg4";
// Target bit rate
int m_targetBitRate = 400000;
void addVideoStream()
{
m_pStream = avformat_new_stream(m_pFormatContext, m_pCodec);
m_pStream->id = m_pFormatContext->nb_streams - 1;
m_pStream->time_base = m_pCodecContext->time_base;
m_pStream->codec->pix_fmt = m_pixType;
m_pStream->codec->flags = m_pCodecContext->flags;
m_pStream->codec->width = m_pCodecContext->width;
m_pStream->codec->height = m_pCodecContext->height;
m_pStream->codec->time_base = m_pCodecContext->time_base;
m_pStream->codec->bit_rate = m_pCodecContext->bit_rate;
}
AVFrame* allocatePicture(enum AVPixelFormat pix_fmt, int width, int height)
{
AVFrame *frame;
frame = av_frame_alloc();
if (!frame)
{
return NULL;
}
frame->format = pix_fmt;
frame->width = width;
frame->height = height;
int checkImage = av_image_alloc(frame->data, frame->linesize, width, height, pix_fmt, 32);
if (checkImage < 0)
{
return NULL;
}
return frame;
}
bool initialize()
{
AVRational frameRate;
frameRate.den = m_frameRate;
frameRate.num = 1;
av_register_all();
m_pCodec = avcodec_find_encoder_by_name(m_encoderName);
if (!m_pCodec)
{
return false;
}
m_pCodecContext = avcodec_alloc_context3(m_pCodec);
m_pCodecContext->width = m_imageWidth;
m_pCodecContext->height = m_imageHeight;
m_pCodecContext->time_base = frameRate;
m_pCodecContext->gop_size = 0;
m_pCodecContext->pix_fmt = m_pixType;
m_pCodecContext->codec_id = m_pCodec->id;
m_pCodecContext->bit_rate = m_targetBitRate;
av_opt_set(m_pCodecContext->priv_data, "+CBR", "", 0);
return true;
}
bool startExport()
{
m_frameIndex = 0;
char fakeFileName[512];
int checkAllocContext = avformat_alloc_output_context2(&m_pFormatContext, NULL, m_fileType, fakeFileName);
if (checkAllocContext < 0)
{
return false;
}
if (!m_pFormatContext)
{
return false;
}
m_pFormat = m_pFormatContext->oformat;
if (m_pFormat->video_codec != AV_CODEC_ID_NONE)
{
addVideoStream();
int checkOpen = avcodec_open2(m_pCodecContext, m_pCodec, NULL);
if (checkOpen < 0)
{
return false;
}
m_pFrame = allocatePicture(m_pCodecContext->pix_fmt, m_pCodecContext->width, m_pCodecContext->height);
if (!m_pFrame)
{
return false;
}
m_pFrame->pts = 0;
}
int checkOpen = avio_open(&m_pFormatContext->pb, m_fileName, AVIO_FLAG_WRITE);
if (checkOpen < 0)
{
return false;
}
av_dict_set(&(m_pFormatContext->metadata), "title", "QS Test", 0);
int checkHeader = avformat_write_header(m_pFormatContext, NULL);
if (checkHeader < 0)
{
return false;
}
return true;
}
int processFrame(AVPacket& avPacket)
{
avPacket.stream_index = 0;
avPacket.pts = av_rescale_q(m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base);
avPacket.dts = av_rescale_q(m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base);
m_pFrame->pts++;
int retVal = av_interleaved_write_frame(m_pFormatContext, &avPacket);
return retVal;
}
bool exportFrame()
{
int success = 1;
int result = 0;
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.data = NULL;
avPacket.size = 0;
AVPacket* avPacket1 = new AVPacket();
av_init_packet(avPacket1);
avPacket1->data = NULL;
avPacket1->size = 0;
fflush(stdout);
std::cout << "Before avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
success = avcodec_encode_video2(m_pCodecContext, &avPacket, m_pFrame, &result);
std::cout << "After avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
if (result)
{
success = processFrame(avPacket);
}
av_packet_unref(&avPacket);
av_free_packet(&avPacket);
//av_frame_free(&m_pFrame);
m_frameIndex++;
return (success == 0);
}
void endExport()
{
int result = 0;
int success = 0;
if (m_pFrame)
{
while (success == 0)
{
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.data = NULL;
avPacket.size = 0;
fflush(stdout);
success = avcodec_encode_video2(m_pCodecContext, &avPacket, NULL, &result);
if (result)
{
success = processFrame(avPacket);
}
av_packet_unref(&avPacket);
if (!result)
{
break;
}
}
}
if (m_pFormatContext)
{
av_write_trailer(m_pFormatContext);
if (m_pFrame)
{
av_frame_free(&m_pFrame);
}
avio_closep(&m_pFormatContext->pb);
avformat_free_context(m_pFormatContext);
m_pFormatContext = NULL;
}
}
void cleanup()
{
if (m_pFrame || m_pCodecContext)
{
if (m_pFrame)
{
av_frame_free(&m_pFrame);
}
if (m_pCodecContext)
{
avcodec_close(m_pCodecContext);
av_free(m_pCodecContext);
}
}
}
int main()
{
bool success = true;
if (initialize())
{
if (startExport())
{
for (int loop = 0; loop < m_frameCount; loop++)
{
if (!exportFrame())
{
std::cout << "Failed to export frame\n";
success = false;
break;
}
}
endExport();
}
else
{
std::cout << "Failed to start export\n";
success = false;
}
cleanup();
}
else
{
std::cout << "Failed to initialize export\n";
success = false;
}
if (success)
{
std::cout << "Successfully exported file\n";
}
return 1;
}
```
When I set the m_imageHeight to 1536, the memory usage is very high. But when set to 1535 or 1537 or other values, the memory usage is normal, can you tell me why?
I have navigated to avcodec_encode_video2
enter link description here
I am using the code from the link
I have updated to the latest IntelĀ® Graphics Driver
This code trying to perform queue, but that's queue has two fields: number and word. My problem is that field "word" prints incorrectly(field "number" is fine)
Expected output:
22
abc
12
efg
654
xyz
Unfortunately output looks like this
https://ibb.co/gjF446F
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#define MAX_capacity 1000
#define Max_len_napis 100
typedef struct{
int number;
char word[];
} data;
data intArray[MAX_capacity];
int peak = 0;
int rear = -1;
int itemCount = 0;
int front() {
return intArray[peak].number;
}
bool isEmpty() {
return itemCount == 0;
}
bool isFull() {
return itemCount == MAX_capacity;
}
int size() {
return itemCount;
}
void insert(data x) {
if(!isFull()) {
if(rear == MAX_capacity-1) {
rear = -1;
}
int indeks = ++rear;
intArray[indeks].number = x.number;
strcpy (intArray[indeks].word, x.word);
itemCount++;
}
}
data remove() {
data dat = intArray[peak++];
if(peak == MAX_capacity) {
peak = 0;
}
itemCount--;
return dat;
}
void print(int N){
for(int i=0;i<N;i++){
data n = remove();
printf("%d\n",n.number);
printf("%s\n",n.word); // that's line doesn't work correctly
}
}
int main() {
data tab[3];
tab[0].number = 22;
strcpy (tab[0].word, "abc");
insert(tab[0]);
tab[1].number = 12;
strcpy (tab[1].word, "efg");
insert(tab[1]);
tab[2].number = 654;
strcpy (tab[2].word, "xyz");
insert(tab[2]);
int siz = size();
print(siz);
return 0;
}
I think that printf("%s\n",n.word) is not work correctly. But if I dont use struct, all works properly.
You need to allocate memory for word. For example like this:
typedef struct{
int number;
char word[100];
} data;
Better way is to allocate memory for word dynamically.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#define MAX_capacity 1000
#define Max_len_napis 100
typedef struct{
int number;
char word[100];
} data;
data intArray[MAX_capacity];
int peak = 0;
int rear = -1;
int itemCount = 0;
int front() {
return intArray[peak].number;
}
bool isEmpty() {
return itemCount == 0;
}
bool isFull() {
return itemCount == MAX_capacity;
}
int size() {
return itemCount;
}
void insert(data x) {
if(!isFull()) {
if(rear == MAX_capacity-1) {
rear = -1;
}
int indeks = ++rear;
intArray[indeks].number = x.number;
strcpy (intArray[indeks].word, x.word);
itemCount++;
}
}
data remove() {
data dat = intArray[peak++];
if(peak == MAX_capacity) {
peak = 0;
}
itemCount--;
return dat;
}
void print(int N){
for(int i=0;i<N;i++){
data n = remove();
printf("%d\n",n.number);
printf("%s\n",n.word); // that's line doesn't work correctly
}
}
int main() {
data tab[3];
tab[0].number = 22;
strcpy (tab[0].word, "abc");
insert(tab[0]);
tab[1].number = 12;
strcpy (tab[1].word, "efg");
insert(tab[1]);
tab[2].number = 654;
strcpy (tab[2].word, "xyz");
insert(tab[2]);
int siz = size();
print(siz);
return 0;
}
I don't know if the code from https://learn.microsoft.com/en-us/windows/desktop/api/iphlpapi/nf-iphlpapi-getadaptersaddresses is wrong but when I try to use it in my C project I keep getting the infamous
Access violation reading location 0xFFFFFFFFFFFFFFFF
I have tried increasing the buffer size but nothing seems to fix it. I think this happens after the first adapter is passed through the loop.
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <winsock2.h>
#include <iptypes.h>
#include <iphlpapi.h>
#include <windows.h>
#pragma comment(lib, "IPHLPAPI.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
FILE* fLog = NULL;
void netinfo() {
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
DWORD dwRetVal = 0;
ULONG outBufLen = 15000;
ULONG iter = 0;
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
if (pAddresses == NULL) {
fwprintf(fLog, L"MALLOC error");
break;
dwRetVal = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX,
NULL,
pAddresses,
&outBufLen
);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pAddresses);
pAddresses = NULL;
fwprintf(fLog, L"GetAdaptersAddresses() error");
} else {
break;
}
iter++;
}
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));
wchar_t netAddressLog[256];
if (dwRetVal == NO_ERROR && pAddresses != NULL) {
pCurrAddresses = pAddresses;
while (pCurrAddresses) {
// this is where the debugger stops !!!
swprintf(netAddressLog, 256, L"Index: %u", pCurrAddresses->IfIndex);
fwprintf(fLog, netAddressLog);
pCurrAddresses = pCurrAddresses->Next;
}
} else {
fwprintf(fLog, L"GetAdaptersAddresses() error");
}
if (pAddresses) {
FREE(pAddresses);
}
}
int main(int argc, char **argv) {
errno_t error = _wfopen_s(&fLog, L"log.txt", L"a+");
netinfo();
fclose(fLog);
}
So, when trying to access pCurrAddresses->IfIndex it's where the program fails, after the first loop (in which it logs some weird large number for index). I am trying to compare mi slightly modified code to the one from MSDN but I can't figure it out.
I know my code needs better organization but for now this is a blocker
There is some problem in the while loop block:
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
if (pAddresses == NULL) {
fwprintf(fLog, L"MALLOC error");
break;
/* a } is missing here*/
dwRetVal = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX,
NULL,
pAddresses,
&outBufLen
);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pAddresses);
pAddresses = NULL;
fwprintf(fLog, L"GetAdaptersAddresses() error");
} else {
break;
}
iter++;
}
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));
The good corrected code could be:
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)MALLOC(outBufLen);
if (pAddresses == NULL) {
fwprintf(fLog, L"MALLOC error");
break;
}
dwRetVal = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX,
NULL,
pAddresses,
&outBufLen
);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pAddresses);
pAddresses = NULL;
fwprintf(fLog, L"GetAdaptersAddresses() error");
} else {
break;
}
iter++;
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (iter < 3));
I am sending single SSID and frequency to libnl for scanning, but i got multiple scan result along with my requested SSID and frequency,But i need single scan result (only for requested SSID), how to achieve this. Kindly help me , i am sending my code also.This code will run.
Compile: gcc -g -o scan scantesthandler.c -L /usr/lib/i386-linux-gnu/libnl.so -lnl
Run with debug log: NLCB=debug ./scan
#include<assert.h>
#include<errno.h>
#include<ifaddrs.h>
#include<netdb.h>
#include<stddef.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <asm/types.h>
#include <linux/rtnetlink.h>
#include <netlink/netlink.h>
#include <netlink/msg.h>
#include <netlink/cache.h>
#include <netlink/socket.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <stdlib.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <netlink/route/link.h>
#include <linux/nl80211.h>
static int expectedId;
static int ifIndex;
struct wpa_scan_res
{
unsigned char bssid[6];
int freq;
};
static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
{
int *ret = arg;
*ret = err->error;
return NL_SKIP;
}
static int finish_handler(struct nl_msg *msg, void *arg)
{
int *ret = arg;
*ret = 0;
return NL_SKIP;
}
static int ack_handler(struct nl_msg *msg, void *arg)
{
int *err = arg;
*err = 0;
return NL_STOP;
}
static int bss_info_handler(struct nl_msg *msg, void *arg)
{
printf("\nFunction: %s, Line: %d\n",__FUNCTION__,__LINE__);
struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *bss[NL80211_BSS_MAX + 1];
static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
[NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
[NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
[NL80211_BSS_TSF] = { .type = NLA_U64 },
[NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
[NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
[NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
[NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
[NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
[NL80211_BSS_STATUS] = { .type = NLA_U32 },
[NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
[NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
};
struct wpa_scan_res *r = NULL;
r = (struct wpa_scan_res*)malloc(sizeof(struct wpa_scan_res));
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb[NL80211_ATTR_BSS])
return NL_SKIP;
if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
bss_policy))
return NL_SKIP;
if (bss[NL80211_BSS_BSSID])
memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),6);
if (bss[NL80211_BSS_FREQUENCY])
r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
printf("\nFrequency: %d ,BSSID: %2x:%2x:%2x:%2x:%2x:%2x",r->freq,r->bssid[0],r->bssid[1],r->bssid[2],r->bssid[3],r->bssid[4],r->bssid[5]);
return NL_SKIP;
}
static struct nl_msg* nl80211_scan_common(uint8_t cmd, int expectedId)
{
const char* ssid = "amitssid";
int ret;
struct nl_msg *msg;
int err;
size_t i;
int flags = 0,ifIndex;
msg = nlmsg_alloc();
if (!msg)
return NULL;
// setup the message
if(NULL==genlmsg_put(msg, 0, 0, expectedId, 0, flags, cmd, 0))
{
printf("\nError return genlMsg_put\n");
}
else
{
printf("\nSuccess genlMsg_put\n");
}
ifIndex = if_nametoindex("wlan1");
if(nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifIndex) < 0)
{
goto fail;
}
struct nl_msg *ssids = nlmsg_alloc();
if(nla_put(ssids, 1,strlen(ssid) ,ssid) <0)
{
nlmsg_free(ssids);
goto fail;
}
err = nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS,ssids);
nlmsg_free(ssids);
if (err < 0)
goto fail;
struct nl_msg *freqs = nlmsg_alloc();
if( nla_put_u32(freqs,1 ,2437) < 0) //amitssid
{
printf("\nnla_put_fail\n");
goto fail;
}
else
{
printf("\nnla_put_u32 pass\n");
}
//add message attributes
if(nla_put_nested(msg, NL80211_FREQUENCY_ATTR_FREQ,freqs) < 0)
{
printf("\nnla_put_nested failing:\n");
}
else
{
printf("\nnla_put_nested pass\n");
}
nlmsg_free(freqs);
if (err < 0)
goto fail;
return msg;
nla_put_failure:
printf("\nnla_put_failure\n");
nlmsg_free(msg);
return NULL;
fail:
nlmsg_free(msg);
return NULL;
}
int main(int argc, char** argv)
{
struct nl_msg *msg= NULL;
int ret = -1;
struct nl_cb *cb = NULL;
int err = -ENOMEM;
int returnvalue,getret;
int ifIndex, callbackret=-1;
struct nl_sock* sk = (void*)nl_handle_alloc();
if(sk == NULL)
{
printf("\nmemory error\n");
return;
}
cb = nl_cb_alloc(NL_CB_CUSTOM);
if(cb == NULL)
{
printf("\nfailed to allocate netlink callback\n");
}
enum nl80211_commands cmd;
if(genl_connect((void*)sk))
{
printf("\nConnected failed\n");
return;
}
//find the nl80211 driverID
expectedId = genl_ctrl_resolve((void*)sk, "nl80211");
if(expectedId < 0)
{
printf("\nnegative error code returned\n");
return;
}
else
{
printf("\ngenl_ctrl_resolve returned:%d\n",expectedId);
}
msg = nl80211_scan_common(NL80211_CMD_TRIGGER_SCAN, expectedId);
if (!msg)
{
printf("\nmsgbal:\n");
return -1;
}
err = nl_send_auto_complete((void*)sk, msg);
if (err < 0)
goto out;
else
{
printf("\nSent successfully\n");
}
err = 1;
nl_cb_err(cb,NL_CB_CUSTOM,error_handler,&err);
nl_cb_set(cb,NL_CB_FINISH,NL_CB_CUSTOM,finish_handler,&err);
nl_cb_set(cb,NL_CB_ACK,NL_CB_CUSTOM,ack_handler,&err);
callbackret = nl_cb_set(cb,NL_CB_VALID,NL_CB_CUSTOM,bss_info_handler,&err);
if(callbackret < 0)
{
printf("\n*************CallbackRet failed:***************** %d\n",callbackret);
}
else
{
printf("\n*************CallbackRet pass:***************** %d\n",callbackret);
}
returnvalue=nl_recvmsgs((void*)sk,cb);
printf("\n returnval:%d\n",returnvalue);
nlmsg_free(msg);
msg = NULL;
msg = nlmsg_alloc();
if (!msg)
return -1;
if(NULL==genlmsg_put(msg, 0, 0, expectedId, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0))
{
printf("\nError return genlMsg_put\n");
}
else
{
printf("\nSuccess genlMsg_put\n");
}
ifIndex = if_nametoindex("wlan1");
printf("\nGet Scaninterface returned :%d\n",ifIndex);
nla_put_u32(msg,NL80211_ATTR_IFINDEX,ifIndex);
err = nl_send_auto_complete((void*)sk,msg);
if(err < 0) goto out;
err = 1;
getret= nl_recvmsgs((void*)sk,cb);
printf("\nGt Scan resultreturn:%d\n",getret);
out:
nlmsg_free(msg);
return err;
nla_put_failure:
printf("\nnla_put_failure\n");
nlmsg_free(msg);
return err;
}
You can just copy and paste this code on your system and run it.
As far as I know (and have seen) the scan command and result is dependent upon the vendor's device driver. One thing for certain there is no option to scan for a specific ssid; instead what you can do is to get all the scan result and loop through to check whether the ssid is in the list or not (wpa_supplicant uses this mechanism to match network configuration with scan result).
Now for the frequency, it should be possible to scan only a certain channel if the device driver has that functionality. But generally scan command scans all channel and returns the SSID (think your network-manager; it shows all the available SSID found for a scan command. which is essentially posted by device driver via cfg80211).