Python Raw Socket Introduction

Source: Internet
Author: User
Tags set socket htons

Because you want to use the python underlying package module, which is the raw socket bundle pattern, here's an in-depth look at Python socket communication.

The functions involved:

import socketsocket()setsockopt()sendto()recvfrom()

Since we are using the original socket, we do not use the Bind/connect function, as in the case of UNIX network programming

The BIND function simply sets the local address. In terms of output, calling the BIND function sets the source IP address of all datagrams that will be used to send from this raw socket. If BIND is not called, the kernel will have the source IP address set to the primary IP address of the out-of-office interface.

The Connect function only sets the field address, also because the original socket does not have the concept of a port number. As far as the output is concerned, we can change the sendto call to write or send call after we call connect, because the destination IP address is already specified.

By the way, the Connect function is also the process of three handshake, see links

Socket parameters

Website Introduction:

socket.socket([family[, type[, proto]]])

Parameter description:

Family: protocol cluster/Address cluster.

The most common is socket.af_inet, tcp/udp communication belongs to this type.

PS: Sometimes we see the protocol constants named Af_xxx, and sometimes pf_xxx, can be understood as address family and protocol family, there is no difference in actual use. It is generally customary to use PF when distinguishing between protocols, and to use AF when differentiating addresses. You can refer to the explanation of this link:

Yes. Af_foo means address family foo, and Pf_foo means protocol family foo. In Linux, they is always been the same values, I believe.

Traditionally, the Pf_foo constants were used for sockets (), but af_foo in the struct SOCKADDR structure.

According to man 2 socket, even the (historical) BSD 4.x mans page states that "the protocol family generally is the same a s the address family ", and subsequent standards use af_* everywhere.

Thus, today, there really should being no difference between Af_foo and Pf_foo.

In addition to the commonly used af_unix/af_local, which represents the UNIX domain protocol, is a way of IPC (interprocess communication); Af_inet6, IPv6 communication.

    • Socket.af_unix can only be used for single UNIX system interprocess communication
    • Socket.af_inet network communication between servers
    • Socket.af_inet6 IPV6

Type: Types of sockets

The following list is given on the website:

    • Socket. Sock_stream
    • Socket. Sock_dgram
    • Socket. Sock_raw the original socket, the ordinary socket can not handle ICMP, IGMP and other network messages, and Sock_raw May, second, Sock_raw can also handle special IPV4 messages, in addition, the use of the original socket, can be IP_ The HDRINCL socket option constructs an IP header by the user.

There are two other kinds of sockets. SOCK_RDM and sockets. Sock_seqpacket, I haven't seen it in a while.

The first two represent both stream-oriented (TCP) and datagram-oriented (UDP) socket traffic.

(My understanding is: Sock_raw = Protocol Head I also send myself)

Proto: protocol type

Common for

IPPROTO_ICMP = 1IPPROTO_IP = 0IPPROTO_RAW = 255IPPROTO_TCP = 6IPPROTO_UDP = 17
Set socket options

setsockopt: Set socket options

socket.setsockopt(level, optname, value)

Specific Parameters View Links

Level: The scope of the parameters, common include:

Sol_socket Sol should refer to the SOck level, meaning socket Layer option, common SO_REUSEADDR, can take the port in the TIME_WAIT state.

IPPROTO_IP IP packet option, one will use IP_HDRINCL, if the TRUE,IP header will be submitted with the data being sent and returned from the read data.

There are ipproto_tcp and so on, here do not introduce more.

Socket Communication Example TCP/UDP communication

Let's start with a two simple example.

UDP Server:

import socket    address = (‘127.0.0.1‘, 31500)  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  s.bind(address)    while True:      data, addr = s.recvfrom(2048)      if not data:          print "client has exist"          break      print "received:", data, "from", addr    s.close()

UDP Client:

import socket    address = (‘127.0.0.1‘, 31500)  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    while True:      msg = raw_input()      if not msg:          break      s.sendto(msg, address)    s.close()  

TCP Server:

import socket    address = (‘127.0.0.1‘, 31500)  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # s = socket.socket()  s.bind(address)  s.listen(5)    ss, addr = s.accept()  print ‘got connected from‘,addr    ss.send(‘byebye‘)  ra = ss.recv(512)  print ra    ss.close()  s.close()

TCP Client:

import socket    address = (‘127.0.0.1‘, 31500)  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  s.connect(address)    data = s.recv(512)  print ‘the data received is‘,data    s.send(‘hihi‘)    s.close()  
RAW SOCKET Communication

Next we look at an example of raw socket communication

Import sysimport socketfrom impacket import Impactdecoder, Impactpacket def main (): If Len (SYS.ARGV) < 3:PR  int "Use:%s <src ip> <dst ip>"% sys.argv[0] print "use:%s <src ip> <dst ip> <cnt>"  % sys.argv[0] Sys.exit (1) elif len (sys.argv) = = 3:SRC = sys.argv[1] DST = sys.argv[2] cnt        = 1 Elif len (sys.argv) ==4:src = sys.argv[1] DST = sys.argv[2] cnt = sys.argv[3] Else:        Print "Input error!" Sys.exit (1) #print src, DST IP = Impactpacket.ip () ip.set_ip_src (SRC) ip.set_ip_dst (DST) TCP = IMPACTPACKET.TC     P () tcp.set_th_sport (55968) tcp.set_th_dport (+) tcp.set_th_seq (1) tcp.set_th_ack (1) tcp.set_th_flags (0x18) Tcp.set_th_win (Tcp.contains) (Impactpacket.data ("get/att/diylife/41264/528 http/1.1\r\nhost:192.168.111.1\r\n accept-encoding:identity\r\n\r\n ")) Ip.contains (TCP) # Open a raw socket. Special permissions is usually reQuired. s = socket.socket (socket.af_inet, socket. SOCK_RAW, Socket. IPPROTO_TCP) s.setsockopt (socket. IPPROTO_IP, Socket.        IP_HDRINCL, 1)///This option is set using our own constructed IP header seq_id = 0 while CNT >= 1: # Calculate its checksum.        seq_id = seq_id + 1 tcp.set_th_seq (seq_id) tcp.calculate_checksum () # Send it to the target host. S.sendto (Ip.get_packet (), (dst,80)) cnt= cnt-1 if __name__ = = ' __main__ ': Main ()

After reading these examples, say what I think.

The role of sockets is to encapsulate a variety of different underlying protocols, providing us with a unified operating interface. When using socket communication, we only need to initialize the corresponding socket according to the protocol type, and then pass the data we need to write into the socket.

So, after the initialization, the socket did a few things for us:

    1. For stream-oriented connections such as TCP, we can help automate the process of three handshake (connect function) and four wave (Close function)
    2. Each time we send the data, we will send the data according to the default or you set the option to wrap the Baotou, to the network card send buffer
    3. When receiving data, help us to remove the Baotou

Because different protocols can use the same interface for sending and receiving data, the process of distinguishing between different headers is done in the socket () function.

Summary Package Structure diagram

Create sockets above four layers

Direct use socket.socket(socket.AF_INET,socket.SOCK_STREAM/socket.SOCK_DGRAM , socket.IPPROTO_TCP) , proto can be automatically inferred (equivalent to IPPROTO_IP), can also be directly abbreviated tos = socket.socket()

means that what we need to populate is just the contents of the [Data] section of the package structure diagram.

Create three-level sockets
    1. Self-populating TCP header/udp header, IP header to kernel padding

means that we need to populate the [TCP header | data] in the package structure diagram

At this point, because the four-layer protocol head needs to be filled by ourselves, there is a problem: if it is more than four layers of sockets, we do not have to tell the socket protocol name, the program will automatically according to your port number to distinguish the application layer protocol. But if you populate the four-layer protocol header, the socket must know in advance what protocol is used to populate the Protocol field for the IP header, which means the Protocol field cannot be ipproto_ip.

Therefore, we need to pass in the third parameter of the socket function. For example, we want to construct our own TCP packets, which can be usedsocket.socket(socket.AF_INET,socket.SOCK_RAW , socket.IPPROTO_TCP )

    1. Self-populated four-layer protocol header and IP header (limited to IP protocol)

means that what we need to populate is the [IP header] in the package structure diagram | TCP Header | The contents of the data].

This is similar to the one above, except that we can modify the IP header in one way:

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)  # 设置 IP 头部自己发送

Another way is:

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)

Both of these approaches should be limited to sending IP protocols, so the Ethernet header's protocol fields are not populated with us ~

Create two-level sockets

Mode 1:

socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))

Self-populated Ethernet header

means that we need to populate the is in the [Mac header | IP Header | TCP Header | The contents of the data].

Mode 2:

socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))

Data sent using Sock_raw must contain the protocol header of the link layer, the received packet, and the link layer protocol header. The use of Sock_dgram does not include the protocol header for the link layer.

That is, the one that needs to be populated is in the [IP header | TCP Header | The contents of the data].

Python Raw Socket Introduction

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.