Hello All. I'm starting to make an application using a raw socket on windows. I can create a socket and send a package but I don't understand the purpose of this function:

int setsockopt(
_In_ SOCKET s,
_In_ int level,
_In_ int optname,
_In_ const char *optval,
_In_ int optlen
);

Why does it do? optname and levels set the option for the socket. Can I keep out this function in the code? What Im trying to do is a ICMP package with also a definition for IP header.

Code:
#include "stdio.h"
#include "winsock2.h"
#include "ws2tcpip.h" //IP_HDRINCL is here
#include "conio.h"

#pragma comment(lib,"ws2_32.lib")

typedef struct ip_hdr
{
unsigned char ip_header_len:4; // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
unsigned char ip_version :4; // 4-bit IPv4 version
unsigned char ip_tos; // IP type of service
unsigned short ip_total_length; // Total length
unsigned short ip_id; // Unique identifier

unsigned char ip_frag_offset :5; // Fragment offset field

unsigned char ip_more_fragment :1;
unsigned char ip_dont_fragment :1;
unsigned char ip_reserved_zero :1;

unsigned char ip_frag_offset1; //fragment offset

unsigned char ip_ttl; // Time to live
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
unsigned short ip_checksum; // IP checksum
unsigned int ip_srcaddr; // Source address
unsigned int ip_destaddr; // Source address
} IPV4_HDR;



typedef struct icmp_header
{
    unsigned char type;
    unsigned char code;
    unsigned int verificationSum;
    unsigned int iden;
    unsigned int secuence;
    char *data;
}ICMP_HDR;

typedef struct datos
{
    IPV4_HDR ip;
    ICMP_HDR icmp;
}Datos;

/////////////////////////main//////////////////////////////

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    char buf[1000], bufRecibir[1000];

    SOCKET s;
    int k=1;

    IPV4_HDR *v4hdr=NULL;
    IPV4_HDR *ip2=NULL;
    ICMP_HDR *icmp=NULL;
    ICMP_HDR *icmp2=NULL;

    int optval=0;
    SOCKADDR_IN dest;
    hostent *server;

    Datos enviados;
    Datos recibidos;

    //Initialise Winsock
    WSADATA wsock;
    printf("\nInicializando Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsock) != 0)
    {
    fprintf(stderr,"WSAStartup() fallo");
    exit(EXIT_FAILURE);
    }
    printf("Inicializo con exito.");
    ////////////////////////////////////////////////

    //Create Raw TCP Packet
    printf("\nCreando Raw TCP Socket...");

   if((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP))==SOCKET_ERROR)
    {
    printf("Creacion de raw socket fallo.");
    return 0;
    }
    printf("Raw TCP Socket Created successfully.");
    ////////////////////////////////////////////////

    //Put Socket in RAW Mode.
    printf("\nSetting the socket in RAW mode...");
    if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR) //primero el descriptor del socket, segundo el nivel IP_HDRINCL a nivel IP,
    {
    printf("failed to set socket in raw mode.");
    return 0;
    }
    printf("Successful.");
    ////////////////////////////////////////////////



    v4hdr = (IPV4_HDR *)buf; //lets point to the ip header portion
    v4hdr->ip_version=4;
    v4hdr->ip_header_len=5;
    v4hdr->ip_tos = 0;
    v4hdr->ip_total_length = htons ( sizeof(IPV4_HDR) + sizeof(ICMP_HDR));
    v4hdr->ip_id = htons(2);
    v4hdr->ip_frag_offset = 0;
    v4hdr->ip_frag_offset1 = 0;
    v4hdr->ip_reserved_zero = 0;
    v4hdr->ip_dont_fragment = 1;
    v4hdr->ip_more_fragment = 0;
    v4hdr->ip_ttl = 8;
    v4hdr->ip_protocol = IPPROTO_ICMP;
    v4hdr->ip_srcaddr = inet_addr("192.168.1.103");
    v4hdr->ip_destaddr = inet_addr("8.8.8.8");
    v4hdr->ip_checksum = 0;

    char d[]="asdf";
    icmp = (ICMP_HDR *)&buf[sizeof(IPV4_HDR)];
    icmp->type= 0;
    icmp->code= 0;
    icmp->secuence=1;
    icmp->iden=1;
    icmp->VerificationSum=0;
    icmp->data= d;


    printf("\nSending packet...\n");

    sendto(s , buf , sizeof(IPV4_HDR)+sizeof(ICMP_HDR), 0, (SOCKADDR *)&dest, sizeof(dest));