// File: /workspace/github_c_makefile_star2_O0/dropletzhu[P]msuite/msender.c
// Function: main
int
main (int argc, char *argv[])
{
	struct sockaddr_in addr;
	int fd, ch, i = 1;
	char ttl = 1;
	char msgbuf[BUF_LEN], source[IP_LEN], group[IP_LEN], port[PORT_LEN];
	struct in_addr interface_addr;
	int length = 256;
	int count = 0;
	struct ip *iph = NULL;
	struct udphdr *udp = NULL;
	char *payload = NULL;
	int hdrincl = 1;
	int retcode;
	int manual_header = 0;
	pseudo_header_t pseudo;
	unsigned short sport = (unsigned short)random();

	if (argc <= 1)
	{
	    usage();
	    return 0;
	}

	while ((ch = getopt (argc, argv, "s:g:p:t:l:c:")) != -1)
	{
		switch (ch)
		{
		case 's':
			memset(source,0,IP_LEN);
			strncpy(source, optarg, IP_LEN - 1);
			break;
		case 'g':
			memset (group, 0, IP_LEN);
			strncpy (group, optarg, IP_LEN - 1);
			break;
		case 'p':
			memset (port, 0, PORT_LEN);
			strncpy (port, optarg, PORT_LEN - 1);
			break;
		case 't':
			ttl = atoi (optarg);
			break;
		case 'l':
			length = atoi(optarg);
			break;
		case 'c':
			count = atoi(optarg);
			break;
		default:
			usage();
			return 0;
		}
	}

	/* raw socket can not send large packet with HDRINCL option */
	if( length < MTU ) {
		manual_header = 1;
	} else {
		manual_header = 0;
	}

	if( manual_header ) {
		/* set raw socket */
		fd = socket (AF_INET, SOCK_RAW, IPPROTO_UDP);
	} else {
		fd = socket (AF_INET, SOCK_DGRAM, 0 );
	}

	if (fd < 0)
	{
		perror ("socket");
		return -1;
	}

	if( manual_header ) {
		/* we need to build ip header manually */
		retcode = setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &hdrincl, sizeof(hdrincl));
		if( retcode != 0 ) {
			perror("setsockopt\n");
			return -1;
		}
	}

	/* set up source address */
	interface_addr.s_addr = inet_addr (source);

	/* set up destination address */
	memset (&addr, 0, sizeof (addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr (group);
	addr.sin_port = htons (atoi (port));

	if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr,
		 sizeof (interface_addr)))
	{
		perror ("setsockopt");
		return -1;
	}

	if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof (ttl)))
	{
		perror ("setsockopt");
		return -1;
	}

	/* now just sendto() our destination! */
	while (1)
	{
		if ( count && ( i > count ) ) {
			break;
		}
		memset(msgbuf,0,BUF_LEN);

		if( manual_header ) {
			iph = (struct ip*)msgbuf;
			udp = (struct udphdr*)(msgbuf + sizeof(struct ip));
			payload = msgbuf + sizeof(struct ip) + 
				sizeof(struct udphdr);

			/* ip header */
    		iph->ip_hl = 5;
    		iph->ip_v = 4;
    		iph->ip_tos = 0;
    		iph->ip_len = htons((short)length);
			if ( i == 0 )
				iph->ip_id = 0;
			else
    			iph->ip_id = htons((short)i);
    		iph->ip_off = 0;
    		iph->ip_ttl = ttl;
    		iph->ip_p = IPPROTO_UDP;
    		iph->ip_src.s_addr = inet_addr (source);
    		iph->ip_dst.s_addr = inet_addr (group);
    		iph->ip_sum = csum((unsigned short*)iph,
					sizeof(struct ip)>>1);

			/* udp header */
			udp->source = htons(sport);
			udp->dest = htons((short)atoi(port));
			udp->len = htons((short)(length - sizeof(struct ip)));
			pseudo.src = iph->ip_src.s_addr;
			pseudo.dst = iph->ip_dst.s_addr;
			pseudo.zero = 0;
			pseudo.proto = iph->ip_p;
			pseudo.length = udp->len;

			/* payload */
			snprintf(payload,
				length-sizeof(struct ip)-sizeof(struct udphdr),
				"Sender %s->%s: %d", source, group, i++);
			udp->check = udp_csum((unsigned short*)&pseudo,
				(unsigned short*)udp, 
				(length - sizeof(struct ip))>>1);

			if (udp->check == 0)
				udp->check = 0xFFFF;
		} else {
			payload = msgbuf;
			snprintf(payload,length,"Sender %s->%s: %d", source, group, i++);
		}

		if (sendto(fd, msgbuf, length, 0, (struct sockaddr *) &addr, 
					sizeof (addr)) < 0)
		{
			perror ("sendto");
			return -1;
		}
		else
		{
			printf ("%s\n",payload);
		}
		sleep (1);
	}
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100b0, %rsp          # imm = 0x100B0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x1, -0x2c(%rbp)
movb $0x1, -0x2d(%rbp)
movl $0x100, -0x10060(%rbp)  # imm = 0x100
movl $0x0, -0x10064(%rbp)
movq $0x0, -0x10070(%rbp)
movq $0x0, -0x10078(%rbp)
movq $0x0, -0x10080(%rbp)
movl $0x1, -0x10084(%rbp)
movl $0x0, -0x1008c(%rbp)
callq 0x10b0
movw %ax, -0x1009a(%rbp)
cmpl $0x1, -0x8(%rbp)
jg 0x1450
callq 0x1340
movl $0x0, -0x4(%rbp)
jmp 0x1a4a
jmp 0x1452
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0xd20(%rip), %rdx       # 0x2180
callq 0x10d0
movl %eax, -0x28(%rbp)
cmpl $-0x1, %eax
je 0x158e
movl -0x28(%rbp), %eax
addl $-0x63, %eax
movl %eax, %ecx
movq %rcx, -0x100a8(%rbp)
subl $0x11, %eax
ja 0x1578
movq -0x100a8(%rbp), %rax
leaq 0xb6d(%rip), %rcx       # 0x2004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0x10040(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x1080
leaq -0x10040(%rbp), %rdi
movq 0x2b1f(%rip), %rax      # 0x3fe0
movq (%rax), %rsi
movl $0xf, %edx
callq 0x1030
jmp 0x1589
leaq -0x10050(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x1080
leaq -0x10050(%rbp), %rdi
movq 0x2aec(%rip), %rax      # 0x3fe0
movq (%rax), %rsi
movl $0xf, %edx
callq 0x1030
jmp 0x1589
leaq -0x10056(%rbp), %rdi
xorl %esi, %esi
movl $0x6, %edx
callq 0x1080
leaq -0x10056(%rbp), %rdi
movq 0x2ab9(%rip), %rax      # 0x3fe0
movq (%rax), %rsi
movl $0x5, %edx
callq 0x1030
jmp 0x1589
movq 0x2aa3(%rip), %rax      # 0x3fe0
movq (%rax), %rdi
callq 0x10e0
movb %al, -0x2d(%rbp)
jmp 0x1589
movq 0x2a8f(%rip), %rax      # 0x3fe0
movq (%rax), %rdi
callq 0x10e0
movl %eax, -0x10060(%rbp)
jmp 0x1589
movq 0x2a78(%rip), %rax      # 0x3fe0
movq (%rax), %rdi
callq 0x10e0
movl %eax, -0x10064(%rbp)
jmp 0x1589
callq 0x1340
movl $0x0, -0x4(%rbp)
jmp 0x1a4a
jmp 0x1452
cmpl $0x5ce, -0x10060(%rbp)  # imm = 0x5CE
jge 0x15a6
movl $0x1, -0x1008c(%rbp)
jmp 0x15b0
movl $0x0, -0x1008c(%rbp)
cmpl $0x0, -0x1008c(%rbp)
je 0x15d2
movl $0x2, %edi
movl $0x3, %esi
movl $0x11, %edx
callq 0x1100
movl %eax, -0x24(%rbp)
jmp 0x15e3
movl $0x2, %esi
xorl %edx, %edx
movl %esi, %edi
callq 0x1100
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jge 0x1601
leaq 0xb9d(%rip), %rdi       # 0x218d
callq 0x10c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a4a
cmpl $0x0, -0x1008c(%rbp)
je 0x164f
movl -0x24(%rbp), %edi
xorl %esi, %esi
movl $0x3, %edx
leaq -0x10084(%rbp), %rcx
movl $0x4, %r8d
callq 0x1040
movl %eax, -0x10088(%rbp)
cmpl $0x0, -0x10088(%rbp)
je 0x164d
leaq 0xb58(%rip), %rdi       # 0x2194
callq 0x10c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a4a
jmp 0x164f
leaq -0x10040(%rbp), %rdi
callq 0x10a0
movl %eax, -0x1005c(%rbp)
leaq -0x20(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x1080
movw $0x2, -0x20(%rbp)
leaq -0x10050(%rbp), %rdi
callq 0x10a0
movl %eax, -0x1c(%rbp)
leaq -0x10056(%rbp), %rdi
callq 0x10e0
movzwl %ax, %edi
callq 0x1050
movw %ax, -0x1e(%rbp)
movl -0x24(%rbp), %edi
xorl %esi, %esi
movl $0x20, %edx
leaq -0x1005c(%rbp), %rcx
movl $0x4, %r8d
callq 0x1040
cmpl $0x0, %eax
je 0x16d7
leaq 0xada(%rip), %rdi       # 0x21a0
callq 0x10c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a4a
movl -0x24(%rbp), %edi
xorl %esi, %esi
movl $0x21, %edx
leaq -0x2d(%rbp), %rcx
movl $0x1, %r8d
callq 0x1040
cmpl $0x0, %eax
je 0x170d
leaq 0xaa4(%rip), %rdi       # 0x21a0
callq 0x10c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a4a
jmp 0x170f
cmpl $0x0, -0x10064(%rbp)
je 0x1728
movl -0x2c(%rbp), %eax
cmpl -0x10064(%rbp), %eax
jle 0x1728
jmp 0x1a43
leaq -0x10030(%rbp), %rdi
xorl %esi, %esi
movl $0xffff, %edx           # imm = 0xFFFF
callq 0x1080
cmpl $0x0, -0x1008c(%rbp)
je 0x199d
leaq -0x10030(%rbp), %rax
movq %rax, -0x10070(%rbp)
leaq -0x10030(%rbp), %rax
addq $0x14, %rax
movq %rax, -0x10078(%rbp)
leaq -0x10030(%rbp), %rax
addq $0x14, %rax
addq $0x8, %rax
movq %rax, -0x10080(%rbp)
movq -0x10070(%rbp), %rax
movb (%rax), %cl
andb $-0x10, %cl
orb $0x5, %cl
movb %cl, (%rax)
movq -0x10070(%rbp), %rax
movb (%rax), %cl
andb $0xf, %cl
orb $0x40, %cl
movb %cl, (%rax)
movq -0x10070(%rbp), %rax
movb $0x0, 0x1(%rax)
movl -0x10060(%rbp), %eax
movzwl %ax, %edi
callq 0x1050
movw %ax, %cx
movq -0x10070(%rbp), %rax
movw %cx, 0x2(%rax)
cmpl $0x0, -0x2c(%rbp)
jne 0x17dc
movq -0x10070(%rbp), %rax
movw $0x0, 0x4(%rax)
jmp 0x17f5
movl -0x2c(%rbp), %eax
movzwl %ax, %edi
callq 0x1050
movw %ax, %cx
movq -0x10070(%rbp), %rax
movw %cx, 0x4(%rax)
movq -0x10070(%rbp), %rax
movw $0x0, 0x6(%rax)
movb -0x2d(%rbp), %cl
movq -0x10070(%rbp), %rax
movb %cl, 0x8(%rax)
movq -0x10070(%rbp), %rax
movb $0x11, 0x9(%rax)
leaq -0x10040(%rbp), %rdi
callq 0x10a0
movl %eax, %ecx
movq -0x10070(%rbp), %rax
movl %ecx, 0xc(%rax)
leaq -0x10050(%rbp), %rdi
callq 0x10a0
movl %eax, %ecx
movq -0x10070(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x10070(%rbp), %rdi
movl $0xa, %esi
callq 0x1210
movw %ax, %cx
movq -0x10070(%rbp), %rax
movw %cx, 0xa(%rax)
movzwl -0x1009a(%rbp), %edi
callq 0x1050
movw %ax, %cx
movq -0x10078(%rbp), %rax
movw %cx, (%rax)
leaq -0x10056(%rbp), %rdi
callq 0x10e0
movzwl %ax, %edi
callq 0x1050
movw %ax, %cx
movq -0x10078(%rbp), %rax
movw %cx, 0x2(%rax)
movslq -0x10060(%rbp), %rax
subq $0x14, %rax
movzwl %ax, %edi
callq 0x1050
movw %ax, %cx
movq -0x10078(%rbp), %rax
movw %cx, 0x4(%rax)
movq -0x10070(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x10098(%rbp)
movq -0x10070(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x10094(%rbp)
movb $0x0, -0x10090(%rbp)
movq -0x10070(%rbp), %rax
movb 0x9(%rax), %al
movb %al, -0x1008f(%rbp)
movq -0x10078(%rbp), %rax
movw 0x4(%rax), %ax
movw %ax, -0x1008e(%rbp)
movq -0x10080(%rbp), %rdi
movslq -0x10060(%rbp), %rsi
subq $0x14, %rsi
subq $0x8, %rsi
leaq -0x10040(%rbp), %rcx
leaq -0x10050(%rbp), %r8
movl -0x2c(%rbp), %r9d
movl %r9d, %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
leaq 0x865(%rip), %rdx       # 0x21ab
movb $0x0, %al
callq 0x1070
movq -0x10078(%rbp), %rsi
movslq -0x10060(%rbp), %rax
subq $0x14, %rax
shrq %rax
movl %eax, %edx
leaq -0x10098(%rbp), %rdi
callq 0x1290
movw %ax, %cx
movq -0x10078(%rbp), %rax
movw %cx, 0x6(%rax)
movq -0x10078(%rbp), %rax
movzwl 0x6(%rax), %eax
cmpl $0x0, %eax
jne 0x199b
movq -0x10078(%rbp), %rax
movw $0xffff, 0x6(%rax)      # imm = 0xFFFF
jmp 0x19e2
leaq -0x10030(%rbp), %rax
movq %rax, -0x10080(%rbp)
movq -0x10080(%rbp), %rdi
movslq -0x10060(%rbp), %rsi
leaq -0x10040(%rbp), %rcx
leaq -0x10050(%rbp), %r8
movl -0x2c(%rbp), %r9d
movl %r9d, %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
leaq 0x7d0(%rip), %rdx       # 0x21ab
movb $0x0, %al
callq 0x1070
movl -0x24(%rbp), %edi
leaq -0x10030(%rbp), %rsi
movslq -0x10060(%rbp), %rdx
xorl %ecx, %ecx
leaq -0x20(%rbp), %r8
movl $0x10, %r9d
callq 0x1090
cmpq $0x0, %rax
jge 0x1a1f
leaq 0x7ac(%rip), %rdi       # 0x21bd
callq 0x10c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1a4a
movq -0x10080(%rbp), %rsi
leaq 0x74b(%rip), %rdi       # 0x2178
movb $0x0, %al
callq 0x1060
movl $0x1, %edi
callq 0x10f0
jmp 0x170f
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x100b0, %rsp          # imm = 0x100B0
popq %rbp
retq