coding101 0 Junior Poster in Training

Need help dhcpdiscovery message...using raw sockets..dont want dhcp headers or libraries..do it myself

anyway im getting error on sending my packet..any USEFUL help?

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <string.h>

#define DHCP_UDP_OVERHEAD   (14 + /* Ethernet header */     \
20 + /* IP header */           \
8)   /* UDP header */
#define DHCP_SNAME_LEN      64
#define DHCP_FILE_LEN       128
#define DHCP_FIXED_NON_UDP  236
#define DHCP_FIXED_LEN      (DHCP_FIXED_NON_UDP + DHCP_UDP_OVERHEAD)
/* Everything but options. */
#define DHCP_MTU_MAX        1500
#define DHCP_OPTION_LEN     (DHCP_MTU_MAX - DHCP_FIXED_LEN)

#define BOOTP_MIN_LEN       300
#define DHCP_MIN_LEN            548


#define DHCP_CLIENT_PORT        68      
#define DHCP_SERVER_PORT        67

#define DHCP_CHADDR_LEN         16
#define DHCP_SNAME_LEN          64
#define DHCP_FILE_LEN           128
#define DHCP_OPTIONS_LEN        512
#define DHCP_MIN_OPTIONS_LEN    68


struct dhcp {

  unsigned char op;                       // Message opcode/type
  unsigned char htype;                    // Hardware addr type
  unsigned char hlen;                     // Hardware addr length
  unsigned char hops;                     // Number of relay agent hops from client
  unsigned long xid;                      // Transaction ID
  unsigned short secs;                    // Seconds since client started looking
  unsigned short flags;                   // Flag bits
  struct in_addr ciaddr;                  // Client IP address (if already in use)
  struct in_addr yiaddr;                  // Client IP address
  struct in_addr siaddr;                  // IP address of next server to talk to
  struct in_addr giaddr;                  // DHCP relay agent IP address
  unsigned char chaddr[DHCP_CHADDR_LEN];  // Client hardware address
  char sname[DHCP_SNAME_LEN];             // Server name
  char file[DHCP_FILE_LEN];               // Boot filename
  unsigned long cookie;                   // DHCP option cookie
  unsigned char options[0];               // Optional parameters (actual length dependent on MTU).
};


unsigned short in_cksum(unsigned short *addr, int len);


int main(void){


    int sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_UDP);
    if(sockfd < 0){ printf("socket error\n"); return 1; }


    int on = 1;
    int ret = setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(int));
    if(ret < 0) { printf("socket eror\n"); return 1; }

    struct sockaddr_in server;
    server.sin_addr.s_addr = inet_addr("255.255.255.255");
    server.sin_port = htons(67);
    server.sin_family = AF_INET;

    unsigned int packetsize = sizeof(struct iphdr)  + sizeof(struct dhcp);
    unsigned char packet[packetsize];

    struct iphdr *ip = malloc(sizeof(struct ipdhr *));
    if(ip == NULL) return 1;

    ip->ihl = 5;
        ip->version = 4;
        ip->tot_len = sizeof(struct iphdr) + sizeof(struct dhcp);
        ip->protocol = IPPROTO_UDP;
        ip->saddr = inet_addr("0.0.0.0");
        ip->daddr = inet_addr("255.255.255.255");
        ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));

    struct dhcp *p = malloc(sizeof(struct dhcp *));
    if(p == NULL) return 1;

    struct in_addr remote, client;
    remote.s_addr = inet_addr("255.255.255.255");
    client.s_addr = inet_addr("0.0.0.0");   

    p->op = 1;
    p->htype = 1;
    p->hlen = 6;
    p->hops = 0;
    p->xid = htonl(1000);
    p->secs = htons(0);
    p->flags = htons(0x8000);
    p->ciaddr = client;
    p->yiaddr = client;
    p->siaddr = server.sin_addr;
    p->giaddr = server.sin_addr;

    p->chaddr[0] = 'c';
    p->chaddr[1] = '7';
    p->chaddr[2] = '3';
    p->chaddr[3] = '0';
    p->chaddr[4] = '0';
    p->chaddr[5] = '0';
    p->chaddr[6] = 'b';
    p->chaddr[7] = 'd';
    p->chaddr[8] = '4';
    p->chaddr[9] = 'a';
    p->chaddr[10] = '4';
    p->chaddr[11] = 'g';

    memcpy(packet,ip,sizeof(ip));   
    memcpy(packet + sizeof(ip),p,sizeof(p));

    ret = sendto(sockfd,packet,packetsize,0,(struct sockaddr *)&server,sizeof(server));
    if(ret < 0){ printf("Error\n") ; return 1; }







    //if(ip != NULL){   free(ip); }

    //if(p != NULL){    free(p); }


    return 0;

}//mai

unsigned short in_cksum(unsigned short *addr, int len){

    register int sum = 0;
    u_short answer = 0;
    register u_short *w = addr;
    register int nleft = len;
    /*
     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
     * sequential 16 bit words to it, and at the end, fold back all the
     * carry bits from the top 16 bits into the lower 16 bits.
     */
    while (nleft > 1)
    {
      sum += *w++;
      nleft -= 2;
    }
    /* mop up an odd byte, if necessary */
    if (nleft == 1)
    {
      *(u_char *) (&answer) = *(u_char *) w;
      sum += answer;
    }
    /* add back carry outs from top 16 bits to low 16 bits */
    sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
    sum += (sum >> 16);             /* add carry */
    answer = ~sum;              /* truncate to 16 bits */

    return answer;

}