The Hive
GitHubLinkedInEmail
  • 🏠Home
  • 🌐RECON
    • 📡Passive (OSINT)
      • ⏩Metadata
      • ⏩Social Platforms
        • Email
        • Tumbler
        • Redit
        • Github
        • Tinder
        • TikTok
        • Snapchat
        • Instagram
        • Facebook
        • Twitter
        • Google
        • LinkedIn
    • 📡Active
      • ⏩Host Discovery / Network Mapping
      • ⏩nmap cheat sheet
      • ⏩masscan cheat sheet
    • 📡Web Recon
      • ⏩Web Server Discovery
      • ⏩Hidden Hosts
      • ⏩Directories & Subdomains
      • ⏩SSL Certs
      • ⏩CMS
      • ⏩WAF Detection
    • 📡Firewall Evasion
  • 📗Web Attacks
    • 🟢Server Side
      • 🟩Authentication Mechanisms
      • 🟩Access Control (Authorization)
      • 🟩Directory Traversal
      • 🟩OS Command Injection
      • 🟩Server-Side Request Forgery (SSRF)
      • 🟩XML External Entity (XXE) Injection
      • 🟩File Upload
      • 🔧SQL Injection
      • 🟩Information Disclosure
      • 🟩Business Logic
    • 🟢Client Side
      • 🟩Cross-site request forgery (CSRF)
      • 🔧Cross-site scripting (XSS)
  • 📒Network attacks
    • 🟡Network Services
      • 🟨Brute Force
      • 🟨DNS
      • 🟨IPv6
      • 🟨FTP
      • 🟨SSH
      • 🟨SMB
      • 🟨SNMP
      • 🟨SMTP
      • 🟨POP3
      • 🟨IMAP
      • 🟨MSSQL
      • 🟨MySQL
      • 🟨MSRPC / RPCbind
      • 🟨LDAP
      • 🟨NTP
      • 🟨NFS
      • 🟨Telnet
      • 🟨WebDAV
      • 🟨RDP
      • 🟨RSIP
      • 🟨Rlogin
      • 🟨VPNs
      • 🟨Echo
      • 🔧RTP
      • 🔧VOIP
        • SIP
    • 🟡Network Devices
      • 🟨IPv6 Attacks
        • Neighbor Impersonation
        • Router Advertisement Flooding
      • 🟨Switch Attacks
        • Cisco Exploitation
        • STP Spoofing
        • VLAN Hopping
        • MAC Flood
      • 🟨Router Attacks
        • Router Exploitation
        • HSRP Hijacking
        • 🔧RIP Spoofing
        • 🔧OSPF Attacks
        • 🔧VRRP MitM
      • 🟨NAC Bypass
        • Captive Portal
        • 802.1X / EAP Bypass
      • 🟨Printer Exploitation
    • 🟡MITM & Poisoning
      • 🟨Bettercap
      • 🟨HTTPS Downgrade / HSTS Bypass
      • 🟨Session Hijackings
      • 🟨Malicious Update
      • 🟨RDP Downgrade
      • 🟨DNS Spoofing
      • 🟨NTP Spoofing
      • 🟨ARP Spoofing
      • 🟨DHCP Poisoning
      • 🟨DHCPv6 Spoofing
      • 🟨SSDP Spoofing
      • 🟨WSUS Spoofing
      • 🟨ADIDNS Poisoning
      • 🟨WPAD Abuse
    • 🟡Wireless Attacks
      • 🟨Protocol Concepts
      • 🟨Basics
      • 🟨Attacks
    • 🟡Sniffing
      • 🟨Wireshark
      • 🟨tcpdump
    • 🟡Denial of Service
  • 📕Red Team
    • 🔴Windows
      • ⭕Security Concepts
        • Windows Security Components
        • Active Directory Components
        • Kerberos
        • Loggon Sessions and Access Tokens
        • Permissions and Access Control
        • Windows Registry
        • Object Management
      • ⭕Physical Attack
      • ⭕Enumeration
      • ⭕Privilege Escalation
        • DLL Hijacking
          • Phantom DLL Hijacking / Replacement
          • Search Order Hijacking ( Preloading )
          • DLL Side-Loading
        • Service Misconfigurations
          • Weak Registry Permissions
          • Insecure Service Executables
          • Insecure Permission
          • Unquoted Service Path
        • Creating a New Service (admin to system)
        • Registry
          • AlwaysInstallElevated
          • AutoRuns
        • Scheduled Tasks
        • Mass Roll-outs
        • Startup Apps
        • Installed Applications
        • Loopback Services
        • Insecure GUI APPs
        • Potatos
        • Printspoofer / SEImpersonate
        • PSEXEC (admin to system)
      • ⭕Credential Dumping
      • ⭕Persistence
        • Invisible Account Forger
        • Add User
        • Scheduled Tasks
        • Run Registry Keys
        • Logon Scripts
        • Screensavers Hijack
        • Powershell Profiles & Modules
        • Service Creation/Modification
        • Shortcut Modification
        • Startup Folder
        • RDP backdoors
        • COM Hijacking
    • 🔴Active Directory
      • ⭕Domain Enumeration
      • ⭕Tools & Frameworks
        • Evil-WinRM
        • CME cheat sheet
        • SharpSploit
        • impacket cheat sheet
        • DeathStar
      • ⭕Exploitation
        • LLMNR Poisoning
        • SMB/NTLM Relay
        • DNS Takeover + LDAP Relay
        • Cracking Hashes
        • Password spraying
        • ADCS + PetitPotam NTLM Relay
        • EternalBlue
        • ZeroLogon
        • MS Exchange ProxyShell
        • MS Exchange ProxyLogon
        • Java JBOSS
      • ⭕Privilege Escalation
        • Token Impersonation
        • DNS Admins
        • AD CS Abuse
        • ACL Abuse
          • GenericAll
          • Write Property
          • Self-membership
          • ForceChangePassword
          • Managed Security Groups
          • Exchange Windows Permissions
        • Group Policy Objects (GPOs)
        • Custom SSPs
        • PrintNightmare
      • ⭕Lateral Movement
        • RDP Password Decryption
        • RDP Session Hijacking
        • headless RDP with SharpRDP
        • Domain Shares
        • SCF File Attacks
        • Pass the Hash / Password
        • Overpass the Hash / Pass the Key
        • Pass The Ticket
        • Kerberosting / AS-REP Rosting
        • Kerberos Delegation
      • ⭕Credential Dumping
        • CredSSP / TSPKG
        • Wdigest Clear Text
        • DPAPI secrets
        • SAM & Registry
        • NTDS.dit & vshadow
        • comsvcs.dll
        • Meterpreter
        • Procdump & LSASS
        • AD User Comments
        • SYSVOL & Group Policy Preferences
        • LAPS Passwords
        • GSMA Passwords
        • HiveNightmare
        • Mimikatz Cheat sheet
        • Other Tools / Techniques
      • ⭕Persistence
        • Certificates
        • DCSync
        • DCShadow
        • Silver Ticket
        • Golden Ticket
        • Skeleton Key
        • WMI
        • PowerShell Remoting
        • Remote Registry
        • Rights Abuse
        • AdminSDHolder
        • DSRM
        • Kerberos Checksum Validation ( MS14-068 )
    • 🔴Linux
      • ⭕Physical Attacks
      • ⭕Enumeration
      • ⭕Privilege Escalation
        • SUID / SGID abuse
        • /etc/shadow & /etc/passwd
        • cron/crontab abuse
        • Sudo Abuse
        • Capabilities Abuse
        • Environment Variables
          • LD_LIBRARY_PATH
          • LD_PRELOAD
        • Shared Object Injection
        • NFS
        • man CE Pager Argument
        • MySQL UDF
        • UDEVD
        • STDIN/STDOUT
        • Unix Socket Exploitation
        • Dirty Pipe
        • Docker
          • SUID Docker
      • ⭕Lateral Movement
        • Infecting Running Processes
        • VIM Config File Keylogger
        • SSH Hijacking
        • Samba Secrets to Domain Admin
        • Hiding Processes
        • Simple User-mode Rootkits
        • Vino VNC Server
      • ⭕Credential Dumping
        • Swap Dump
        • mimipinguin
        • unshadow
        • 3snake
      • ⭕Persistence
        • Startup User File Backdoor
        • PHP Backdoor
        • Apache mod_rootme
        • Startup Service Backdoor
        • xdg Backdoor
        • rootbash SUID
        • apt Backdoor
        • Driver Backdoor
        • Core Pattern
        • dash Backdoor
        • Creating an SUID Binary
        • Systemd netcat bind shell
        • Xinetd UDP portnock
        • openSSL reverse shell
        • motd Backdoor
        • Auth Log Backdoor
        • RSYSLOG Backdoor
        • sshd Backdoor
        • VIM Config Backdoor
        • .bashrc Backdoor
        • Adding a Root user
        • Crontab Reverse Shell
        • SSH persistence password-less
      • ⭕Covering Tracks
    • 🔴Command & Control (C2)
      • ⭕Cobalt Strike
      • ⭕Metasploit
      • ⭕Empire & Starkiller
      • ⭕Covenant
    • 🔴Shells and Payloads
      • ⭕Shell Escape / Interactive Shell
      • ⭕LOL Binaries
      • ⭕msfvenom
      • ⭕SharpShooter & Ivy
      • ⭕Other Payloads
    • 🔴Payload Delivery
      • ⭕Powershell Reflective DLL Load
      • ⭕HTML Smuggling
      • ⭕Office Macros
      • ⭕DDE Auto - Word/Excel
      • ⭕.SLK Excel
      • ⭕XLM Macro 4.0
      • ⭕LNK
      • ⭕embedded OLE + LNK objects
      • ⭕JScript
      • ⭕HTA
      • ⭕VBS
      • ⭕VBA
      • ⭕RTF
      • ⭕REG
      • ⭕MSI / MSIEXEC
      • ⭕IQY
      • ⭕CHM / HHC
      • ⭕SCR
    • 🔴Pivoting
      • ⭕SSH Forwarding
      • ⭕Socat Stealth Port Forward
      • ⭕Socat Reverse Shell Relay
      • ⭕HTTP Tunneling
      • ⭕ICMP Tunneling
      • ⭕DNS Tunneling
      • ⭕Metasploit Pivoting
      • ⭕Cobalt Strike Pivoteing
      • ⭕VPN Tunneling
      • ⭕Other Tools
    • 🔴Exfiltration / File Transfer
      • ⭕Encode / Decode Files
      • ⭕TCP / UDP
      • ⭕DNS
      • ⭕SSH
      • ⭕ICMP
      • ⭕SMB
      • ⭕FTP
      • ⭕HTTP
      • ⭕Other Methods
    • 🔴Password Attacks
      • ⭕Online Attacks
      • ⭕Offline Attack
      • ⭕Word List
      • ⭕Cheat Sheet
    • 🔴Defense Evasion
      • ⭕Basic Tricks
      • 🔧Powershell Tricks
      • ⭕Disabling Defenses
      • ⭕UAC Bypass
      • ⭕Process Migration
      • ⭕Dechaining Macros
      • ⭕VBA Sandbox Evasion
      • ⭕AMSI Bypass
      • ⭕SRP & AppLocker Bypass
      • ⭕GPO Bypass
  • 📘Blue Team
    • 🔵Threat Modeling / Hunting / Intelligence
    • 🔵Linux Hardening
      • 🔹OS Security
        • Update Strategy
        • Service Management
        • Physical Security
        • Grub Hardening
        • Kernel Parameters
        • Process Isolation
      • 🔹Accounts & Passwords
        • Users & Groups
        • Password Security & Sudoers
      • 🔹Access Control & Ownership
      • 🔹File System Security
      • 🔹Integrity Check
      • 🔹Sandboxing
      • 🔹Network
      • 🔹iptables
        • Rule Sets
      • 🔹Service Hardening
        • BIND9
        • vsftpd
        • Nginx
        • Apache
        • SSH
      • 🔹System Audit
      • 🔹Logging
        • auditd
      • 🔹Encryption
    • 🔵Security Architecture
      • 🔹Layered Security
  • 🟪Purple Teaming
    • 🟣Adversary Emulation
  • 🟧programming
    • 🟠C Programming
      • 🔸Basic Structure
      • 🔸GCC Compiler
      • 🔸Preprocessors
      • 🔸Data Types
      • 🔸Type Qualifiers
      • 🔸Pointers
      • 🔸Dynamic Memory Allocation
      • 🔸Loops
      • 🔸Conditional Statements
      • 🔸Functions
      • 🔸Input / Output
      • 🔸Macros
      • 🔸Files
      • 🔸Strings Manipulation
      • 🔸Bit Manipulation
      • 🔸Data Structures
        • Arrays
        • Structures
        • Unions
      • 🔸Abstract Data Types
        • Stack
        • Queue
        • Linked List
          • Singly Linked List
          • Doubly Linked List
      • 🔸Libraries & Linking
      • 🔸Error Recovery
    • 🔧Assembly ( NASM )
      • Intel IA-32 Environment
      • Basic Structure
      • Variables and Data Types
      • Most-used Instructions
      • input / output
  • 🟫Miscellaneous
    • 🟤GNU Screen / tmux
    • 🟤SSH Tricks
    • 🟤Cats
      • netcat
      • ncat
      • pwncat
      • socat
      • 🔧powercat
    • 🟤Curl
    • 🟤Cross-compiling Binaries
Powered by GitBook
On this page
  1. programming
  2. C Programming
  3. Abstract Data Types
  4. Linked List

Doubly Linked List

PreviousSingly Linked ListNextLibraries & Linking

Last updated 2 years ago

Doubly linked lists consist of data plus links to the next item as well as the preceding item.

Having two links instead of just one has several advantages. Perhaps the most important is that the list can be read in either direction. This simplifies list management, making insertions and deletions easier. It also allows a user to scan the list in either direction. Another advantage is meaningful only in the case of some type of failure. Since the entire list can be read using either forward links or backward links, should one of the links become invalid, the list could be reconstructed by using the other.

A new element can be inserted into a doubly linked list in three ways: insert a new first element,

Building a doubly linked list is similar to building a singly linked list except that two links are maintained. Therefore, the structure must have room for both links. Using the mailing list example again, you can modify the structure address as shown here to accommodate both links:

struct address {
    char name[40];
    char street[40];
    char city[20];
    char state[3];
    char zip[11];
    struct address *next;
    struct address *prior;
} info;

Using address as the basic data item, the following function, dlstore( ), builds a doubly linked list:

void dlstore(struct address *i, struct address **last){
    if(!*last) 
        *last = i; /* is first item in list */
    else 
        (*last)->next = i;
    i->next = NULL;
    i->prior = *last;
    *last = i;
}

The function dlstore( ) puts each new entry on the end of the list. You must call it with a pointer to the data to be stored as well as a pointer to the end of the list, which must be null on the first call.

Like singly linked lists, a doubly linked list can be built by a function that stores each element in a specific location in the list instead of always placing each new item on the end. The function shown here, dls_store( ), creates a list that is sorted in ascending order:

* Create a doubly linked list in sorted order. */
void dls_store(
    struct address *i,
    /* new element */
    struct address **start, /* first element in list */
    struct address **last /* last element in list */
    }
    
{
    struct address *old, *p;
    if(*last==NULL) { /* first element in list */
        i->next = NULL;
        i->prior = NULL;
        *last = i;
        *start = i;
        return;
        }

    p = *start; /* start at top of list */
    old = NULL;
    while(p) {
        if(strcmp(p->name, i->name)<O){
        old = p;
        p = p->next;
            }
    else {
        if(p->prior) {
            p->prior->next = i;
            i->next = p;
            i->prior = p->prior;
            p->prior = i;
            return;
            }
    i->next = p; /* new first element */
    i->prior = NULL;
    p->prior = i;
    *start = i;

    return;
        }
    }
    old->next = i; /* put on end */
    i->next = NULL;
    i->prior = old;
    *last = i;
}

Because the first or last element in the list can change, the dls_store( ) function automatically updates pointers to the beginning and ending elements of the list through the start and last parameters. You must call the function with a pointer to the data to be stored and a pointer to the pointers to the first and last items in the list. When called the first time, the objects pointed to by first and last must be null. As in singly linked lists, retrieving a specific data item in a doubly linked list is simply the process of following the links until the proper element is found. There are three cases to consider when deleting an element from a doubly linked list: deleting the first item, deleting an item from the middle, and deleting the last item

void dldelete(
struct address *i, /* item to delete */
struct address **start, /* first item */
struct address **last) /* last item */
{
if(i->prior) i->prior->next = i->next;
else { /* new first item */
*start = i->next;
if(start) start->prior = NULL;
}
if(i->next) i->next->prior = i->prior;
else
/* deleting last element */
*last = i->prior;
}

Because the first or last element in the list could be deleted, the dldelete( ) function automatically updates pointers to the beginning and ending elements of the list through the start and last parameters. You must call the function with a pointer to the data to be deleted and a pointer to the pointers to the first and last items in the list.

example:

this is an example of a doubly linked list used to store some values with capabilities to add, delete and display each node:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

/* self-referential structure */
struct node
{
    int value;
    struct node *next;
};

struct node* createNode(int);
void insertNodeAtTheBeginning();
void insertNodeAtTheEnd();
void insertNodeAtPosition();
void deletePosition();
void search();
void updateValue();
void display();

struct node *newnode, *ptr, *prev, *temp;
struct node *head = NULL, *tail = NULL;

int main() {
    int ch = '\0';

    while (true)
    {
        printf("\n---------------------------------\n");
        printf("\nOperations on a linked list\n");
        printf("\n---------------------------------\n");
        printf("\n1.Insert node at beginning");
        printf("\n2.Insert node at end");
        printf("\n3.Insert node at a specific position");
        printf("\n4.Delete Node from any Position");
        printf("\n5.Update Node Value");
        printf("\n6.Search Element in the linked list");
        printf("\n7.Display List");
        printf("\n8.Exit\n");
        printf("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        printf("\nEnter your choice: ");
        scanf("%d", &ch);

        switch (ch)
        {
            case 1:
                insertNodeAtTheBeginning();
                break;
            case 2:
                insertNodeAtTheEnd();
                break;
            case 3:
                insertNodeAtPosition();
                break;
            case 4:
                deletePosition();
                break;
            case 5:
                updateValue();
                break;
            case 6:
                search();
                break;
            case 7:
                display();
                break;
            case 8:
                printf("\n...Exiting...\n");
                return 0;
            default:
                printf("\n...Invalid Choice...\n");
                break;
        }
    }
    return 0;
}

/*
 * Creating Node
 */
struct node* createNode(int val)
{
    newnode = (struct node *)malloc(sizeof(struct node));
    if (newnode == NULL)
    {
        printf("\nMemory was not allocated");
        return 0;
    }
    else
    {
        newnode->value = val;
        newnode->next = NULL;
        return newnode;
    }
}

void insertNodeAtTheBeginning()
{
    int val = 0;

    printf("\nEnter the value for the node: ");
    scanf("%d", &val);
    newnode = createNode(val);
    if (head== tail && head == NULL)
    {
        head = tail = newnode;
        head->next = NULL;
        tail->next = NULL;
    }
    else
    {
        temp = head;
        head = newnode;
        head->next = temp;
    }
}

void insertNodeAtTheEnd()
{
    int val = 0;

    printf("\nEnter the value for the Node: ");
    scanf("%d", &val);
    newnode = createNode(val);
    if (head == tail && tail == NULL)
    {
        head = tail = newnode;
        head->next = NULL;
        tail->next = NULL;
    }
    else
    {
        tail->next = newnode;
        tail = newnode;
        tail->next = NULL;
    }

    printf("\n----INSERTED----");
}

void insertNodeAtPosition()
{
    int pos, val, cnt = 0, i;

    printf("\nEnter the value for the Node: ");
    scanf("%d", &val);
    newnode = createNode(val);
    printf("\nEnter the position ");
    scanf("%d", &pos);
    ptr = head;
    while (ptr != NULL)
    {
        ptr = ptr->next;
        cnt++;
    }
    if (pos == 1)
    {
        if (head == tail && head == NULL)
        {
            head = tail = newnode;
            head->next = NULL;
            tail->next = NULL;
        }
        else
        {
            temp = head;
            head = newnode;
            head->next = temp;
        }
        printf("\nInserted");
    }
    else if (pos>1 && pos<=cnt)
    {
        ptr = head;
        for (i = 1;i < pos;i++)
        {
            prev = ptr;
            ptr = ptr->next;
        }
        prev->next = newnode;
        newnode->next = ptr;
        printf("\n----INSERTED----");
    }
    else
    {
        printf("Position is out of range");
    }
}


void deletePosition()
{
    int pos, cnt = 0, i;

    if (head == NULL)
    {
        printf("List is empy\n");
        printf(":No node to delete\n");
    }
    else
    {
        printf("\nEnter the position of value to be deleted: ");
        scanf(" %d", &pos);
        ptr = head;
        if (pos == 1)
        {
            head = ptr->next;
            printf("\nElement deleted");
        }
        else
        {
            while (ptr != NULL)
            {
                ptr = ptr->next;
                cnt = cnt + 1;
            }
            if (pos > 0 && pos <= cnt)
            {
                ptr = head;
                for (i = 1;i < pos;i++)
                {
                    prev = ptr;
                    ptr = ptr->next;
                }
                prev->next = ptr->next;
            }
            else
            {
                printf("Position is out of range ");
            }
            free(ptr);
            printf("\nElement deleted");
        }
    }
}


void updateValue()
{
    int oldval, newval, flag = 0;

    if (head == NULL)
    {
        printf("List is empty\n");
        printf(":No nodes in the list to update\n");
    }
    else
    {
        printf("\nEnter the value to be updated: ");
        scanf("%d", &oldval);
        printf("\nEnter the new value:");
        scanf("%d", &newval);
        for (ptr = head;ptr != NULL;ptr = ptr->next)
        {
            if (ptr->value == oldval)
            {
                ptr->value = newval;
                flag = 1;
                break;
            }
        }
        if (flag == 1)
        {
            printf("\nUpdated Successfully");
        }
        else
        {
            printf("\nValue not found in List");
        }
    }
}

void search()
{
    int flag = 0, key, pos = 0;

    if (head == NULL)
    {
        printf("List is empty\n");
        printf(":No nodes in the list\n");
    }
    else
    {
        printf("\nEnter the value to search ");
        scanf("%d", &key);
        for (ptr = head;ptr != NULL;ptr = ptr->next)
        {
            pos = pos + 1;
            if (ptr->value == key)
            {
                flag = 1;
                break;
            }
        }
        if (flag == 1)
        {
            printf("\nElement %d found at %d position\n", key, pos);
        }
        else
        {
            printf("\nElement %d not found in list\n", key);
        }
    }
}

void display()
{
    if (head == NULL)
    {
        printf("List is empty\n");
        printf(":No nodes in the list to display\n");
    }
    else
    {
        for (ptr = head;ptr != NULL;ptr = ptr->next)
        {
            printf("%d\t", ptr->value);
        }
    }
}
🟧
🟠
🔸